4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
10 Type DynamicLValueType;
11 Type DynamicRValueType;
13 Type NumericType; /* generic numeric placeholder */
14 Type IntegralType; /* generic integral placeholder */
15 Type SIntegerType; /* generic signed integer placeholder */
16 Type UIntegerType; /* generic unsigned integer placeholder */
37 Type FloatType; /* generic float placeholder */
42 Type PointerType; /* generic pointer placeholder */
43 Type CCharType; /* const uchar */
44 Type StrType; /* const uchar * */
45 Type UCharPtrType; /* uchar * */
46 Type UCharPtrPtrType; /* uchar ** */
47 Type CUCharPtrPtrType; /* const uchar ** */
48 Type VoidPtrType; /* void * */
49 Type VoidRefType; /* void @ */
50 Type CVoidPtrType; /* const void * */
51 Type LVoidPtrType; /* lvalue void * */
53 Type LexRefType; /* run-time access class tie-ins */
62 typelist_t DynamicTypeList = RUNE_HEAD_INITIALIZER(DynamicTypeList);
63 typelist_t CompoundTypeList = RUNE_HEAD_INITIALIZER(CompoundTypeList);
64 typelist_t ArgsTypeList = RUNE_HEAD_INITIALIZER(ArgsTypeList);
65 typelist_t StorageTypeList = RUNE_HEAD_INITIALIZER(StorageTypeList);
67 static void initInternalClassType(Type *type, Declaration *d);
69 Type *BaseTypeAry[] = {
70 &DynamicLValueType, &DynamicRValueType, &NumericType,
71 &IntegralType, &SIntegerType, &UIntegerType,
72 &VoidType, &BoolType, &Int8Type, &UInt8Type,
73 &Int16Type, &UInt16Type, &Int32Type, &UInt32Type,
74 &Int64Type, &UInt64Type, &Int128Type, &UInt128Type,
76 &IntPtrType, &UIntPtrType, &OffType, &USizeType, &SSizeType,
78 &FloatType, &Float32Type, &Float64Type, &Float128Type,
80 &PointerType, &CCharType, &StrType, &UCharPtrType,
81 &UCharPtrPtrType, &CUCharPtrPtrType,
82 &VoidPtrType, &VoidRefType, &CVoidPtrType,
85 &LexRefType, &ScopeType, &DeclarationType, &SemGroupType,
86 &PointerInfoType, &TypeType,
87 &FILLERTypeType, &FILLERDeclType,
92 initType(Type *type, typelist_t *list, int op)
95 RUNE_INIT(&type->ty_QList);
97 RUNE_INSERT_TAIL(list, type, ty_Node);
98 type->ty_SQList = list;
99 type->ty_Info.in_Type = type;
100 type->ty_Info.in_Refs = PINFO_STATIC;
104 initQualType(Type *type, typelist_t *list, int op, int sqflags)
106 initType(type, list, op);
107 type->ty_SQFlags = sqflags;
111 initPtrType(Type *type, Type *ptrto, int sqflags)
113 initQualType(type, &ptrto->ty_QList, TY_PTRTO, sqflags);
114 type->ty_PtrType.et_Type = ptrto;
115 /* type->ty_Bytes = sizeof(PointerStor); */
116 type->ty_AlignMask = POINTERSTOR_ALIGN;
120 initCPtrType(Type *type, Type *ptrto, int sqflags)
122 initQualType(type, &ptrto->ty_QList, TY_CPTRTO, sqflags);
123 type->ty_PtrType.et_Type = ptrto;
124 /* type->ty_Bytes = sizeof(void *); */
125 type->ty_AlignMask = sizeof(void *) - 1;
129 initRefType(Type *type, Type *refto, int sqflags)
131 initQualType(type, &refto->ty_QList, TY_REFTO, sqflags);
132 type->ty_RefType.et_Type = refto;
133 /* type->ty_Bytes = sizeof(PointerStor); */
134 type->ty_AlignMask = POINTERSTOR_ALIGN;
142 initQualType(&DynamicLValueType, &DynamicTypeList,
143 TY_DYNAMIC, SF_LVALUE);
144 initType(&DynamicRValueType, &DynamicTypeList, TY_DYNAMIC);
145 initType(&NumericType, NULL, TY_UNRESOLVED);
146 initType(&IntegralType, NULL, TY_UNRESOLVED);
147 initType(&SIntegerType, NULL, TY_UNRESOLVED);
148 initType(&UIntegerType, NULL, TY_UNRESOLVED);
149 initType(&FloatType, NULL, TY_UNRESOLVED);
150 initType(&PointerType, NULL, TY_UNRESOLVED);
151 PointerType.ty_AlignMask = POINTERSTOR_ALIGN;
153 initType(&VoidType, NULL, TY_UNRESOLVED);
154 initType(&BoolType, NULL, TY_UNRESOLVED);
155 initType(&Int8Type, NULL, TY_UNRESOLVED);
156 initType(&UInt8Type, NULL, TY_UNRESOLVED);
157 initType(&Int16Type, NULL, TY_UNRESOLVED);
158 initType(&UInt16Type, NULL, TY_UNRESOLVED);
159 initType(&Int32Type, NULL, TY_UNRESOLVED);
160 initType(&UInt32Type, NULL, TY_UNRESOLVED);
161 initType(&Int64Type, NULL, TY_UNRESOLVED);
162 initType(&UInt64Type, NULL, TY_UNRESOLVED);
164 initType(&IntPtrType, NULL, TY_UNRESOLVED);
165 initType(&UIntPtrType, NULL, TY_UNRESOLVED);
166 initType(&OffType, NULL, TY_UNRESOLVED);
167 initType(&USizeType, NULL, TY_UNRESOLVED);
168 initType(&SSizeType, NULL, TY_UNRESOLVED);
170 initType(&Float32Type, NULL, TY_UNRESOLVED);
171 initType(&Float64Type, NULL, TY_UNRESOLVED);
172 initType(&Float128Type, NULL, TY_UNRESOLVED);
174 initQualType(&CCharType, NULL, TY_UNRESOLVED, SF_CONST);
175 initPtrType(&StrType, &CCharType, 0);
176 initPtrType(&UCharPtrType, &UInt8Type, 0);
177 initPtrType(&UCharPtrPtrType, &UCharPtrType, 0);
178 initPtrType(&CUCharPtrPtrType, &StrType, 0);
179 initPtrType(&VoidPtrType, &VoidType, 0);
180 initRefType(&VoidRefType, &VoidType, 0);
181 initCPtrType(&CVoidPtrType, &VoidType, SF_CONST);
182 initPtrType(&LVoidPtrType, &VoidType, SF_LVALUE);
185 * Mark internal types (not all are bound to classes so it is easiest to
186 * just do it here). This will prevent the collapse code from trying to
187 * collapse our base types.
189 for (i = 0; BaseTypeAry[i]; ++i)
190 BaseTypeAry[i]->ty_Flags |= TF_ISINTERNAL;
194 * Attach an internal class, creating a global summary type for it that
195 * allows our interpreter and code generator to make various assumptions.
198 InternalClassAttach(Parse *p __unused, int t, Declaration *d)
202 dassert_decl(d, d->d_Op == DOP_CLASS);
210 * Special flag helper (resolver sets TF_ISBOOL in in the type)
213 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISBOOL;
243 itype = &UInt128Type;
248 * Special flag helper (resolver sets TF_ISFLOATING in in the
252 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISFLOATING;
255 itype = &Float32Type;
258 itype = &Float64Type;
260 case RUNEID_FLOAT128:
261 itype = &Float128Type;
268 itype = &UIntPtrType;
280 itype = &PointerType;
283 itype = &NumericType;
285 case RUNEID_INTEGRAL:
286 itype = &IntegralType;
288 case RUNEID_SINTEGER:
290 * Special flag helper (resolver sets TF_ISINTEGER in in the
293 itype = &SIntegerType;
294 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
296 case RUNEID_UINTEGER:
298 * Special flag helper (resolver sets TF_ISINTEGER and
299 * TF_ISUNSIGNED in the type)
301 itype = &UIntegerType;
302 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISUNSIGNED;
303 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
311 case RUNEID_DECLARATION:
312 itype = &DeclarationType;
314 case RUNEID_SEMGROUP:
315 itype = &SemGroupType;
317 case RUNEID_POINTERINFO:
318 itype = &PointerInfoType;
323 case RUNEID_FILLERTYPE:
324 itype = &FILLERTypeType;
326 case RUNEID_FILLERDECL:
327 itype = &FILLERDeclType;
331 char buf[RUNE_IDTOSTR_LEN];
333 dpanic("Unknown internal class: %s", runeid_text(d->d_Id, buf));
338 initInternalClassType(itype, d);
341 * Fixup for const int8 pointers... we did not have a QList to put
342 * CCharType on until now. It will wind up on the SemGroup's
345 if (itype == &UInt8Type) {
346 TypeToQualType(itype, &CCharType,
347 itype->ty_SQFlags | SF_CONST, NULL);
354 * This is mostly deprecated except for official type aliases such as
358 InternalTypeAttach(Parse *p, int t, Declaration *d)
362 dassert_decl(d, d->d_Op == DOP_TYPEDEF);
397 itype = &Float32Type;
400 itype = &Float64Type;
402 case RUNEID_FLOAT128:
403 itype = &Float128Type;
410 itype = &UIntPtrType;
422 itype = &PointerType;
425 itype = &NumericType;
427 case RUNEID_INTEGRAL:
428 itype = &IntegralType;
430 case RUNEID_SINTEGER:
431 itype = &SIntegerType;
433 case RUNEID_UINTEGER:
434 itype = &UIntegerType;
437 itype = InternalRegisteredTypeLookup(d->d_Id);
439 dpanic("Unknown internal type: %s", d->d_Id);
444 if (itype->ty_Op != TY_UNRESOLVED) {
445 t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
447 Type *ntype = d->d_TypedefDecl.ed_Type;
449 TypeToQualType(ntype, itype, ntype->ty_SQFlags, NULL);
452 t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
458 AllocType(typelist_t *list, int op)
460 Type *type = zalloc(sizeof(Type));
462 initType(type, list, op);
467 * May be used to generate a varargs compound type, in which case the
468 * semgroup may already be resolved.
470 * We do no matching/caching at this time and callers assume that (for making
471 * adjustments) to the underlying sg at parse-time via TypeToProcType()
474 AllocCompoundType(SemGroup *sg)
478 type = AllocType(&CompoundTypeList, TY_COMPOUND);
479 type->ty_CompType.et_SemGroup = sg;
480 dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
485 * XXX match the compound type(s)
488 AllocArgsType(SemGroup *sg)
492 type = AllocType(&ArgsTypeList, TY_ARGS);
493 type->ty_ArgsType.et_SemGroup = sg;
498 AllocStorageType(urunesize_t bytes)
502 RUNE_FOREACH(type, &StorageTypeList, ty_Node) {
503 if (type->ty_Op == TY_STORAGE &&
504 type->ty_StorType.et_Bytes == bytes
509 type = AllocType(&StorageTypeList, TY_STORAGE);
510 type->ty_StorType.et_Bytes = bytes;
515 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, runeid_t *ary, int eatAry)
519 dassert_semgrp(sg, ary != NULL);
521 RUNE_FOREACH(type, &sg->sg_ClassList, ty_Node) {
524 if (type->ty_Op != TY_UNRESOLVED)
526 if (type->ty_UnresType.et_ImportSemGroup != isg)
529 for (i = 0; ary[i]; ++i) {
530 if (ary[i] != type->ty_UnresType.et_DottedId[i])
533 if (ary[i] == 0 && type->ty_UnresType.et_DottedId[i] == 0) {
539 type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
540 type->ty_UnresType.et_DottedId = ary;
541 type->ty_UnresType.et_SemGroup = sg; /* may be NULL */
542 type->ty_UnresType.et_ImportSemGroup = isg; /* may be NULL */
547 * AllocClassType() - allocate a type representing a the semgroup which in
548 * turn represents (typically) a class.
551 AllocClassType(typelist_t *list, Type *super, SemGroup *sg, int visibility)
556 list = &sg->sg_ClassList;
558 RUNE_FOREACH(type, list, ty_Node) {
559 if (type->ty_Op == TY_CLASS &&
560 type->ty_ClassType.et_SemGroup == sg &&
561 type->ty_ClassType.et_Super == super &&
562 type->ty_Visibility == visibility
568 dassert(&sg->sg_ClassList == list);
569 type = AllocType(list, TY_CLASS);
570 type->ty_ClassType.et_SemGroup = sg;
571 type->ty_ClassType.et_Super = super;
572 type->ty_Visibility = visibility;
578 initInternalClassType(Type *type, Declaration *d)
580 SemGroup *sg = d->d_ClassDecl.ed_SemGroup;
582 initType(type, &sg->sg_ClassList, TY_CLASS);
583 RUNE_REMOVE(&sg->sg_ClassList, type, ty_Node);
584 RUNE_INSERT_HEAD(&sg->sg_ClassList, type, ty_Node);
585 type->ty_ClassType.et_SemGroup = d->d_ClassDecl.ed_SemGroup;
586 type->ty_ClassType.et_Super = d->d_ClassDecl.ed_Super;
587 type->ty_Visibility = d->d_ScopeFlags & SCOPE_ALL_VISIBLE;
588 type->ty_Flags |= TF_ISINTERNAL;
592 AllocImportType(typelist_t *list, SemGroup *sg, int visibility)
594 Type *type = AllocType(list, TY_IMPORT);
596 type->ty_ImportType.et_SemGroup = sg;
597 type->ty_Visibility = visibility;
602 * adjtype must be moved to type's QList because type is being modified such
603 * that that is where it is expected to be.
606 TypeAdjustQList(Type *type, Type *adjtype)
609 if (adjtype->ty_SQList)
610 RUNE_REMOVE(adjtype->ty_SQList, adjtype, ty_Node);
611 adjtype->ty_SQList = &type->ty_QList;
612 RUNE_INSERT_TAIL(adjtype->ty_SQList, adjtype, ty_Node);
618 * Compound types inherit locking modes if not specifically overridden.
621 TypeFixupInheritedFlags(Type *type, int rqflags)
626 if (type->ty_Op != TY_COMPOUND)
630 * Assume no matching collapse yet
632 sg = type->ty_CompType.et_SemGroup;
633 RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
634 if (d->d_Op != DOP_GROUP_STORAGE)
636 if ((d->d_ScopeFlags & SCOPE_LOCKING_MASK) == 0) {
637 if (rqflags & SF_UNTRACKED)
638 d->d_ScopeFlags |= SCOPE_UNTRACKED;
639 if (rqflags & SF_UNLOCKED)
640 d->d_ScopeFlags |= SCOPE_UNLOCKED;
641 if (rqflags & SF_SOFT)
642 d->d_ScopeFlags |= SCOPE_SOFT;
643 if (rqflags & SF_HARD)
644 d->d_ScopeFlags |= SCOPE_HARD;
651 TypeToQualType(Type *otype, Type *ntype, int sqFlags, Exp *exp)
656 * Combine with existing qualifiers, Shortcut if no changes made.
659 sqFlags == otype->ty_SQFlags &&
660 (exp == NULL || exp == otype->ty_AssExp)
666 * See if we already have a matching qualified type (only if storage for
667 * the new type is not being provided). Note: the provided storage has
668 * already been initType()d
671 RUNE_FOREACH(ntype, otype->ty_SQList, ty_Node) {
672 if (ntype->ty_Op == otype->ty_Op &&
673 ntype->ty_SQFlags == sqFlags &&
674 (exp == NULL || ntype->ty_AssExp == exp)
676 if (SameType(ntype, otype, sqFlags))
683 * Build a new qualified type and set its qualifiers, then duplicate
684 * appropriate sections of the old type.
686 * Default to the same SQList as otype.
689 ntype = AllocType(otype->ty_SQList, otype->ty_Op);
691 if (ntype->ty_SQList)
692 RUNE_REMOVE(ntype->ty_SQList, ntype, ty_Node);
693 ntype->ty_SQList = otype->ty_SQList;
694 RUNE_INSERT_TAIL(ntype->ty_SQList, ntype, ty_Node);
698 * Set the op and the expression. Unlike SQFlags, if exp is passed as
699 * NULL we inherit the old type's default.
701 * The DupExp() call here is special, see DupExp()'s handling of ex_Decl.
703 * Normally DupExp() is called during resolution prior to ex_Decl being
704 * set. This is the one case where it may be called with ex_Decl already
707 * WARNING! We do not try to resolve the type here. Various resolve
708 * related flags in ty_Flags will be resolved later. This includes
709 * TF_ISUNSIGNED and other TF_* flags.
711 ntype->ty_Op = otype->ty_Op;
713 ntype->ty_AssExp = exp;
714 else if (otype->ty_AssExp)
715 ntype->ty_AssExp = SetDupExp(NULL, otype->ty_AssExp);
716 ntype->ty_SQFlags = sqFlags;
717 ntype->ty_Visibility = otype->ty_Visibility;
719 switch (otype->ty_Op) {
722 * When updating the class, alternative forms are collapsed into it's
723 * SemGroup->sg_ClassList and not into some potentially long
724 * recursive chain based on ty_QList.
726 sg = otype->ty_ClassType.et_SemGroup;
728 dassert(ntype->ty_SQList == &sg->sg_ClassList);
729 if (ntype->ty_ClassType.et_SemGroup != sg) {
730 ntype->ty_ClassType.et_SemGroup = sg;
732 ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
735 ntype->ty_Visibility = otype->ty_Visibility;
736 ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
739 ntype->ty_CPtrType.et_Type = otype->ty_CPtrType.et_Type;
742 ntype->ty_PtrType.et_Type = otype->ty_PtrType.et_Type;
745 ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
749 * note: multiple type structures may share the same array size
750 * expression in simple qualified-type cases. YYY XXX bad bad.
752 ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
753 ntype->ty_AryType.et_ArySize = otype->ty_AryType.et_ArySize;
754 ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
755 ntype->ty_AryType.et_Count = otype->ty_AryType.et_Count;
758 ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
761 ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
762 ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
765 ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
768 ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
769 ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
770 ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
771 dassert(ntype->ty_SQList ==
772 &otype->ty_ProcType.et_RetType->ty_QList);
775 ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
779 * It is not legal to qualify a dynamic type other then to add or
782 dpanic("Dynamic type cannot be qualified");
785 ntype->ty_UnresType.et_DottedId =
786 otype->ty_UnresType.et_DottedId;
787 ntype->ty_UnresType.et_SemGroup =
788 otype->ty_UnresType.et_SemGroup;
789 ntype->ty_UnresType.et_ImportSemGroup =
790 otype->ty_UnresType.et_ImportSemGroup;
793 dassert_type(otype, 0);
799 * Convert a return-type + argument-type into a procedure type. If adjret is
800 * non-zero the return-type is converted to locked storage (which is
801 * generally what we want).
803 * Match the procedure type(s) (after adjustment?)
806 TypeToProcType(Type *rtype, Type *atype, int adjret)
808 urunesize_t count = 0;
813 dassert_type(atype, atype->ty_Op == TY_ARGS);
816 rtype = TypeFixupInheritedFlags(rtype, rtype->ty_SQFlags);
818 sg = atype->ty_CompType.et_SemGroup;
820 RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
823 RUNE_FOREACH(type, &rtype->ty_QList, ty_Node) {
824 if (type->ty_Op == TY_PROC) {
825 if (type->ty_ProcType.et_ArgsType == atype &&
826 type->ty_ProcType.et_RetType == rtype &&
827 type->ty_ProcType.et_ArgCount == count
833 type = AllocType(&rtype->ty_QList, TY_PROC);
834 type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
835 type->ty_ProcType.et_RetType = rtype;
836 type->ty_ProcType.et_ArgCount = count;
841 * Convert type to pointer-to-type
844 TypeToPtrType(Type *otype)
848 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
849 if (type->ty_Op == TY_PTRTO)
852 type = AllocType(&otype->ty_QList, TY_PTRTO);
853 type->ty_PtrType.et_Type = otype;
858 * Convert type to pointer-to-type
861 TypeToCPtrType(Type *otype)
865 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
866 if (type->ty_Op == TY_CPTRTO)
869 type = AllocType(&otype->ty_QList, TY_CPTRTO);
870 type->ty_CPtrType.et_Type = otype;
875 * Convert type to ref-to-type
877 * A reference type is similar to a pointer type except that the resolver is
878 * not able to entirely know what it is pointing to. The reference type is a
879 * superclass, but the actual type is stored in the run-time structure.
882 TypeToRefType(Type *otype)
886 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
887 if (type->ty_Op == TY_REFTO)
890 type = AllocType(&otype->ty_QList, TY_REFTO);
891 type->ty_RefType.et_Type = otype;
896 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
901 * XXX handle constant expression optimization for QList XXX handle
904 type = AllocType(&otype->ty_QList, TY_ARYOF);
905 type->ty_AryType.et_ArySize = exp;
906 type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
907 type->ty_AryType.et_SemGroup = sg;
908 type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
915 TypeToRunTimeAryType(Type *otype, int count)
918 Type *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
920 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
921 if (type->ty_Op == TY_ARYOF &&
922 type->ty_AryType.et_Type == t2 &&
923 type->ty_AryType.et_Count == count &&
925 (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
930 type = AllocType(&otype->ty_QList, TY_ARYOF);
931 type->ty_AryType.et_Count = count;
932 type->ty_AryType.et_Type = t2;
933 type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
940 TypeToVarType(Type *otype, SemGroup *sg)
944 /* dassert(sg->sg_Flags & SGF_RESOLVED); */
945 /* dassert(otype->ty_Flags & TF_RESOLVED); */
947 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
948 if (type->ty_Op == TY_VAR &&
949 type->ty_VarType.et_Type == otype &&
950 type->ty_VarType.et_SemGroup == sg
952 puts("SG2"); /* YYY */
956 type = AllocType(&otype->ty_QList, TY_VAR);
957 type->ty_VarType.et_Type = otype;
958 type->ty_VarType.et_SemGroup = sg;
960 /* XXX doesn't work for var-args */
961 if (sg->sg_Flags & SGF_RESOLVED) {
962 type->ty_Flags |= TF_RESOLVED;
963 type->ty_Bytes = sg->sg_Bytes;
964 type->ty_AlignMask = sg->sg_AlignMask;
971 * ChangeType() - given pointer, C pointer, or array of something, return
972 * 'op' of something instead.
975 ChangeType(Type *type, int op)
977 switch (type->ty_Op) {
981 type = TypeToCPtrType(type->ty_PtrType.et_Type);
984 type = TypeToAryType(type->ty_PtrType.et_Type,
988 dpanic("Illegal type convesion (A)");
994 type = TypeToPtrType(type->ty_CPtrType.et_Type);
997 type = TypeToAryType(type->ty_CPtrType.et_Type,
1001 dpanic("Illegal type convesion (B)");
1007 type = TypeToPtrType(type->ty_AryType.et_Type);
1010 type = TypeToCPtrType(type->ty_AryType.et_Type);
1013 dpanic("Illegal type convesion (C)");
1017 dpanic("Illegal type convesion (D)");
1023 * BaseType() - return base type
1025 * Traverse the type to locate the base type. Store the base type in *ptype
1026 * and return the SemGroup, or return NULL if the base type does not have a
1030 BaseType(Type **ptype)
1032 Type *type = *ptype;
1035 switch (type->ty_Op) {
1037 type = type->ty_CPtrType.et_Type;
1040 type = type->ty_PtrType.et_Type;
1043 type = type->ty_RefType.et_Type;
1046 type = type->ty_AryType.et_Type;
1054 switch (type->ty_Op) {
1056 return (type->ty_ClassType.et_SemGroup);
1058 return (type->ty_CompType.et_SemGroup);
1060 return (type->ty_ArgsType.et_SemGroup);
1068 dassert_type(type, 0);
1069 return (NULL); /* avoid compiler complaints */
1074 * DupType() - create a duplicate of a type, possibly in a new SemGroup.
1076 * This code is used when duplicating procedures and other elements when
1077 * merging a superclass into a subclass.
1079 * If sg is NULL, stype is simply returned. The case is used when we try to
1080 * duplciate an expression with DupExp()... in that case we want to dup the
1081 * expression tree but use the same types.
1084 DupType(SemGroup *sg, Type *stype)
1092 * XXX type may be resolved if it is part of a varargs dup
1096 (stype->ty_Flags & (TF_RESOLVED | TF_RESOLVING)) == 0);
1099 switch (stype->ty_Op) {
1102 * This only occurs because the resolver has resolved an unresolved
1103 * type on the original SemGroup. We duplicate that on the new
1106 type = AllocClassType(&sg->sg_ClassList,
1107 stype->ty_ClassType.et_Super,
1108 stype->ty_ClassType.et_SemGroup,
1109 stype->ty_Visibility);
1116 type = TypeToCPtrType(DupType(sg, stype->ty_CPtrType.et_Type));
1119 type = TypeToPtrType(DupType(sg, stype->ty_PtrType.et_Type));
1122 type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1125 type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1126 SetDupExp(sg, stype->ty_AryType.et_ArySize),
1127 stype->ty_AryType.et_SemGroup);
1128 type->ty_AryType.et_Count = stype->ty_AryType.et_Count;
1131 type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1132 DupSemGroup(sg, NULL,
1133 stype->ty_VarType.et_SemGroup, 1));
1136 type = AllocCompoundType(
1137 DupSemGroup(sg, NULL,
1138 stype->ty_CompType.et_SemGroup, 1));
1142 * At the moment we always formally duplicate the arguments so we can
1143 * modify them for methods below.
1145 type = AllocArgsType(
1146 DupSemGroup(sg, NULL,
1147 stype->ty_CompType.et_SemGroup, 1));
1150 type = DupType(sg, stype->ty_ProcType.et_RetType);
1151 type = TypeToProcType(type,
1152 DupType(sg, stype->ty_ProcType.et_ArgsType),
1156 * If this is a method procedure, we have to change the first
1157 * argument to point at our new subclass. It was previously pointing
1158 * at our superclass. XXX the programmer can override the argument.
1159 * If it isn't a reference we have to assert.
1161 if (sg->sg_Stmt->st_Op != ST_Class) {
1163 * XXX probably an inlined procedure, the type is already
1164 * correct. Need an assertrion here.
1166 } else if (stype->ty_SQFlags & SF_METHOD) {
1167 SemGroup *asg = type->ty_ProcType.et_ArgsType->ty_ArgsType.et_SemGroup;
1168 Declaration *d = RUNE_FIRST(&asg->sg_DeclList);
1169 Type *thisType = d->d_StorDecl.ed_Type;
1171 dassert_decl(d, d->d_Id == RUNEID_THIS &&
1172 d->d_Op == DOP_ARGS_STORAGE);
1173 dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1174 if (thisType->ty_Op == TY_CLASS) {
1175 /* XXX sg_ClassList? right sg? */
1176 /* XXX correct visibility? */
1177 if (d->d_Search == NULL) {
1178 d->d_Search = d->d_StorDecl.ed_Type->
1179 ty_ClassType.et_SemGroup;
1181 d->d_StorDecl.ed_Type =
1182 AllocClassType(&sg->sg_ClassList,
1183 sg->sg_Stmt->st_ClassStmt.es_Super,
1184 sg->sg_Stmt->st_MyGroup,
1187 dassert_decl(d, thisType->ty_Op == TY_REFTO);
1189 } else if (stype->ty_SQFlags & SF_GMETHOD) {
1193 asg = type->ty_ProcType.et_ArgsType->
1194 ty_ArgsType.et_SemGroup;
1195 d = RUNE_FIRST(&asg->sg_DeclList);
1197 dassert_decl(d, d->d_Id == RUNEID_THIS && d->d_Op == DOP_TYPEDEF);
1198 dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1199 dassert_decl(d, d->d_TypedefDecl.ed_Type->ty_Op == TY_CLASS);
1200 /* XXX sg_ClassList? right sg? */
1201 /* XXX correct visibility? */
1202 if (d->d_Search == NULL) {
1203 d->d_Search = d->d_TypedefDecl.ed_Type->
1204 ty_ClassType.et_SemGroup;
1206 d->d_TypedefDecl.ed_Type =
1207 AllocClassType(&sg->sg_ClassList,
1208 sg->sg_Stmt->st_ClassStmt.es_Super,
1209 sg->sg_Stmt->st_MyGroup,
1218 * e.g. so elements in a superclass will see refined elements in the
1219 * subclass. Note that the original import semgroup is left intact
1220 * so the semantic search mechanism uses it when the base sg
1221 * (typically a subclass) fails.
1223 type = AllocUnresolvedType(
1224 stype->ty_UnresType.et_ImportSemGroup,
1226 stype->ty_UnresType.et_DottedId,
1230 dassert_type(stype, 0);
1233 if (type != stype) {
1234 type->ty_Flags = stype->ty_Flags &
1235 ~(TF_ISINTERNAL | TF_RESOLVING | TF_RESOLVED |
1236 TF_ALIGNRESOLVED | TF_TMPRESOLVED);
1237 type->ty_Bytes = stype->ty_Bytes;
1238 type->ty_AlignMask = stype->ty_AlignMask;
1239 type->ty_Visibility = stype->ty_Visibility;
1240 type->ty_DynamicVector = stype->ty_DynamicVector;
1242 if (stype->ty_AssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1243 type = TypeToQualType(type, NULL,
1245 SetDupExp(sg, stype->ty_AssExp));
1251 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1254 InternalRegisterType(const char *str, const char *linkname, Type *type)
1258 tr = zalloc(sizeof(TypeRegNode));
1259 tr->tr_Id = runeid_hash(str, strlen(str));
1261 tr->tr_LinkName = linkname;
1262 RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1266 InternalRegisteredTypeLookup(runeid_t id)
1270 RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1271 if (tr->tr_Id == id)
1272 return (tr->tr_Type);