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 */
36 Type FloatType; /* generic float placeholder */
41 Type PointerType; /* generic pointer placeholder */
42 Type CCharType; /* const uchar */
43 Type StrType; /* const uchar * */
44 Type UCharPtrType; /* uchar * */
45 Type UCharPtrPtrType; /* uchar ** */
46 Type CUCharPtrPtrType; /* const uchar ** */
47 Type VoidPtrType; /* void * */
48 Type VoidRefType; /* void @ */
49 Type CVoidPtrType; /* const void * */
50 Type LVoidPtrType; /* lvalue void * */
52 Type LexRefType; /* run-time access class tie-ins */
61 typelist_t DynamicTypeList = RUNE_HEAD_INITIALIZER(DynamicTypeList);
62 typelist_t CompoundTypeList = RUNE_HEAD_INITIALIZER(CompoundTypeList);
63 typelist_t ArgsTypeList = RUNE_HEAD_INITIALIZER(ArgsTypeList);
64 typelist_t StorageTypeList = RUNE_HEAD_INITIALIZER(StorageTypeList);
66 static void initInternalClassType(Type *type, Declaration *d);
68 Type *BaseTypeAry[] = {
69 &DynamicLValueType, &DynamicRValueType, &NumericType,
70 &IntegralType, &SIntegerType, &UIntegerType,
71 &VoidType, &BoolType, &Int8Type, &UInt8Type,
72 &Int16Type, &UInt16Type, &Int32Type, &UInt32Type,
73 &Int64Type, &UInt64Type, &Int128Type, &UInt128Type,
75 &IntPtrType, &UIntPtrType, &OffType, &SizeType,
77 &FloatType, &Float32Type, &Float64Type, &Float128Type,
79 &PointerType, &CCharType, &StrType, &UCharPtrType,
80 &UCharPtrPtrType, &CUCharPtrPtrType,
81 &VoidPtrType, &VoidRefType, &CVoidPtrType,
84 &LexRefType, &ScopeType, &DeclarationType, &SemGroupType,
85 &PointerInfoType, &TypeType,
86 &FILLERTypeType, &FILLERDeclType,
91 initType(Type *type, typelist_t *list, int op)
94 RUNE_INIT(&type->ty_QList);
96 RUNE_INSERT_TAIL(list, type, ty_Node);
97 type->ty_SQList = list;
98 type->ty_Info.in_Type = type;
99 type->ty_Info.in_Refs = PINFO_STATIC;
103 initQualType(Type *type, typelist_t *list, int op, int sqflags)
105 initType(type, list, op);
106 type->ty_SQFlags = sqflags;
110 initPtrType(Type *type, Type *ptrto, int sqflags)
112 initQualType(type, &ptrto->ty_QList, TY_PTRTO, sqflags);
113 type->ty_PtrType.et_Type = ptrto;
114 /*type->ty_Bytes = sizeof(PointerStor);*/
115 type->ty_AlignMask = POINTERSTOR_ALIGN;
119 initCPtrType(Type *type, Type *ptrto, int sqflags)
121 initQualType(type, &ptrto->ty_QList, TY_CPTRTO, sqflags);
122 type->ty_PtrType.et_Type = ptrto;
123 /*type->ty_Bytes = sizeof(void *);*/
124 type->ty_AlignMask = sizeof(void *) - 1;
128 initRefType(Type *type, Type *refto, int sqflags)
130 initQualType(type, &refto->ty_QList, TY_REFTO, sqflags);
131 type->ty_RefType.et_Type = refto;
132 /*type->ty_Bytes = sizeof(PointerStor);*/
133 type->ty_AlignMask = POINTERSTOR_ALIGN;
141 initQualType(&DynamicLValueType, &DynamicTypeList,
142 TY_DYNAMIC, SF_LVALUE);
143 initType(&DynamicRValueType, &DynamicTypeList, TY_DYNAMIC);
144 initType(&NumericType, NULL, TY_UNRESOLVED);
145 initType(&IntegralType, NULL, TY_UNRESOLVED);
146 initType(&SIntegerType, NULL, TY_UNRESOLVED);
147 initType(&UIntegerType, NULL, TY_UNRESOLVED);
148 initType(&FloatType, NULL, TY_UNRESOLVED);
149 initType(&PointerType, NULL, TY_UNRESOLVED);
150 PointerType.ty_AlignMask = POINTERSTOR_ALIGN;
152 initType(&VoidType, NULL, TY_UNRESOLVED);
153 initType(&BoolType, NULL, TY_UNRESOLVED);
154 initType(&Int8Type, NULL, TY_UNRESOLVED);
155 initType(&UInt8Type, NULL, TY_UNRESOLVED);
156 initType(&Int16Type, NULL, TY_UNRESOLVED);
157 initType(&UInt16Type, NULL, TY_UNRESOLVED);
158 initType(&Int32Type, NULL, TY_UNRESOLVED);
159 initType(&UInt32Type, NULL, TY_UNRESOLVED);
160 initType(&Int64Type, NULL, TY_UNRESOLVED);
161 initType(&UInt64Type, NULL, TY_UNRESOLVED);
163 initType(&IntPtrType, NULL, TY_UNRESOLVED);
164 initType(&UIntPtrType, NULL, TY_UNRESOLVED);
165 initType(&OffType, NULL, TY_UNRESOLVED);
166 initType(&SizeType, NULL, TY_UNRESOLVED);
168 initType(&Float32Type, NULL, TY_UNRESOLVED);
169 initType(&Float64Type, NULL, TY_UNRESOLVED);
170 initType(&Float128Type, NULL, TY_UNRESOLVED);
172 initQualType(&CCharType, NULL, TY_UNRESOLVED, SF_CONST);
173 initPtrType(&StrType, &CCharType, 0);
174 initPtrType(&UCharPtrType, &UInt8Type, 0);
175 initPtrType(&UCharPtrPtrType, &UCharPtrType, 0);
176 initPtrType(&CUCharPtrPtrType, &StrType, 0);
177 initPtrType(&VoidPtrType, &VoidType, 0);
178 initRefType(&VoidRefType, &VoidType, 0);
179 initCPtrType(&CVoidPtrType, &VoidType, SF_CONST);
180 initPtrType(&LVoidPtrType, &VoidType, SF_LVALUE);
183 * Mark internal types (not all are bound to classes so it is
184 * easiest to just do it here). This will prevent the collapse
185 * code from trying to collapse our base types.
187 for (i = 0; BaseTypeAry[i]; ++i)
188 BaseTypeAry[i]->ty_Flags |= TF_ISINTERNAL;
190 StrTableAlloc("void", 4, SPECIAL_INTERNAL_VOID);
191 StrTableAlloc("bool", 4, SPECIAL_INTERNAL_BOOL);
192 StrTableAlloc("int8_t", 6, SPECIAL_INTERNAL_INT8);
193 StrTableAlloc("uint8_t", 7, SPECIAL_INTERNAL_UINT8);
194 StrTableAlloc("int16_t", 7, SPECIAL_INTERNAL_INT16);
195 StrTableAlloc("uint16_t", 8, SPECIAL_INTERNAL_UINT16);
196 StrTableAlloc("int32_t", 7, SPECIAL_INTERNAL_INT32);
197 StrTableAlloc("uint32_t", 8, SPECIAL_INTERNAL_UINT32);
198 StrTableAlloc("int64_t", 7, SPECIAL_INTERNAL_INT64);
199 StrTableAlloc("uint64_t", 8, SPECIAL_INTERNAL_UINT64);
200 StrTableAlloc("int128_t", 8, SPECIAL_INTERNAL_INT128);
201 StrTableAlloc("uint128_t", 9, SPECIAL_INTERNAL_UINT128);
203 StrTableAlloc("float32_t", 9, SPECIAL_INTERNAL_FLOAT32);
204 StrTableAlloc("float64_t", 9, SPECIAL_INTERNAL_FLOAT64);
205 StrTableAlloc("float128_t", 10, SPECIAL_INTERNAL_FLOAT128);
207 StrTableAlloc("intptr_t", 8, SPECIAL_INTERNAL_INTPTR);
208 StrTableAlloc("uintptr_t", 9, SPECIAL_INTERNAL_UINTPTR);
209 StrTableAlloc("size_t", 6, SPECIAL_INTERNAL_SIZE);
210 StrTableAlloc("off_t", 5, SPECIAL_INTERNAL_OFF);
212 StrTableAlloc("Float", 5, SPECIAL_INTERNAL_FLOAT);
213 StrTableAlloc("Pointer", 7, SPECIAL_INTERNAL_POINTER);
214 StrTableAlloc("Numeric", 7, SPECIAL_INTERNAL_NUMERIC);
215 StrTableAlloc("Integral", 8, SPECIAL_INTERNAL_INTEGRAL);
216 StrTableAlloc("SInteger", 8, SPECIAL_INTERNAL_SINTEGER);
217 StrTableAlloc("UInteger", 8, SPECIAL_INTERNAL_UINTEGER);
219 StrTableAlloc("LexRef", 6, SPECIAL_INTERNAL_LEXREF);
220 StrTableAlloc("Scope", 5, SPECIAL_INTERNAL_SCOPE);
221 StrTableAlloc("Declaration", 11, SPECIAL_INTERNAL_DECLARATION);
222 StrTableAlloc("SemGroup", 8, SPECIAL_INTERNAL_SEMGROUP);
223 StrTableAlloc("PointerInfo", 11, SPECIAL_INTERNAL_POINTERINFO);
224 StrTableAlloc("Type", 4, SPECIAL_INTERNAL_TYPE);
225 StrTableAlloc("FILLERType", 10, SPECIAL_INTERNAL_FILLERTYPE);
226 StrTableAlloc("FILLERDecl", 10, SPECIAL_INTERNAL_FILLERDECL);
228 StrTableAlloc("__count", 7, SPECIAL_COUNT);
229 StrTableAlloc("__data", 6, SPECIAL_DATA);
230 StrTableAlloc("__type", 6, SPECIAL_TYPE);
231 StrTableAlloc("__varcount", 10, SPECIAL_VAR_COUNT);
232 StrTableAlloc("__vardata", 9, SPECIAL_VAR_DATA);
233 StrTableAlloc("__vartype", 9, SPECIAL_VAR_TYPE);
234 StrTableAlloc("__typeid", 8, SPECIAL_TYPEID);
235 StrTableAlloc("__typestr", 9, SPECIAL_TYPESTR);
236 StrTableAlloc("NULL", 4, SPECIAL_NULL);
240 * Attach an internal class, creating a global summary type for it that
241 * allows our interpreter and code generator to make various assumptions.
244 InternalClassAttach(Parse *p __unused, int t, Declaration *d)
249 dassert_decl(d, d->d_Op == DOP_CLASS);
251 if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
253 case SPECIAL_INTERNAL_VOID:
256 case SPECIAL_INTERNAL_BOOL:
258 * Special flag helper (resolver sets TF_ISBOOL in
262 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISBOOL;
264 case SPECIAL_INTERNAL_INT8:
267 case SPECIAL_INTERNAL_UINT8:
270 case SPECIAL_INTERNAL_INT16:
273 case SPECIAL_INTERNAL_UINT16:
276 case SPECIAL_INTERNAL_INT32:
279 case SPECIAL_INTERNAL_UINT32:
282 case SPECIAL_INTERNAL_INT64:
285 case SPECIAL_INTERNAL_UINT64:
288 case SPECIAL_INTERNAL_INT128:
291 case SPECIAL_INTERNAL_UINT128:
292 itype = &UInt128Type;
295 case SPECIAL_INTERNAL_FLOAT:
297 * Special flag helper (resolver sets TF_ISFLOATING in
301 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISFLOATING;
303 case SPECIAL_INTERNAL_FLOAT32:
304 itype = &Float32Type;
306 case SPECIAL_INTERNAL_FLOAT64:
307 itype = &Float64Type;
309 case SPECIAL_INTERNAL_FLOAT128:
310 itype = &Float128Type;
313 case SPECIAL_INTERNAL_INTPTR:
316 case SPECIAL_INTERNAL_UINTPTR:
317 itype = &UIntPtrType;
319 case SPECIAL_INTERNAL_OFF:
322 case SPECIAL_INTERNAL_SIZE:
325 /* NOTE: There is no ssize_t in rune. size_t is signed */
327 case SPECIAL_INTERNAL_POINTER:
328 itype = &PointerType;
330 case SPECIAL_INTERNAL_NUMERIC:
331 itype = &NumericType;
333 case SPECIAL_INTERNAL_INTEGRAL:
334 itype = &IntegralType;
336 case SPECIAL_INTERNAL_SINTEGER:
338 * Special flag helper (resolver sets TF_ISINTEGER in
341 itype = &SIntegerType;
342 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
344 case SPECIAL_INTERNAL_UINTEGER:
346 * Special flag helper (resolver sets TF_ISINTEGER
347 * and TF_ISUNSIGNED in the type)
349 itype = &UIntegerType;
350 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISUNSIGNED;
351 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
354 case SPECIAL_INTERNAL_LEXREF:
357 case SPECIAL_INTERNAL_SCOPE:
360 case SPECIAL_INTERNAL_DECLARATION:
361 itype = &DeclarationType;
363 case SPECIAL_INTERNAL_SEMGROUP:
364 itype = &SemGroupType;
366 case SPECIAL_INTERNAL_POINTERINFO:
367 itype = &PointerInfoType;
369 case SPECIAL_INTERNAL_TYPE:
372 case SPECIAL_INTERNAL_FILLERTYPE:
373 itype = &FILLERTypeType;
375 case SPECIAL_INTERNAL_FILLERDECL:
376 itype = &FILLERDeclType;
379 dpanic("Unknown internal class: %s", d->d_Id);
383 initInternalClassType(itype, d);
386 * Fixup for const int8 pointers... we did not have
387 * a QList to put CCharType on until now. It will
388 * wind up on the SemGroup's sg_ClassList.
390 if (itype == &UInt8Type) {
391 TypeToQualType(itype, &CCharType,
392 itype->ty_SQFlags | SF_CONST, NULL);
399 * This is mostly deprecated except for official type aliases such as
403 InternalTypeAttach(Parse *p, int t, Declaration *d)
408 dassert_decl(d, d->d_Op == DOP_TYPEDEF);
410 if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
412 case SPECIAL_INTERNAL_VOID:
415 case SPECIAL_INTERNAL_BOOL:
418 case SPECIAL_INTERNAL_INT8:
421 case SPECIAL_INTERNAL_UINT8:
424 case SPECIAL_INTERNAL_INT16:
427 case SPECIAL_INTERNAL_UINT16:
430 case SPECIAL_INTERNAL_INT32:
433 case SPECIAL_INTERNAL_UINT32:
436 case SPECIAL_INTERNAL_INT64:
439 case SPECIAL_INTERNAL_UINT64:
443 case SPECIAL_INTERNAL_FLOAT32:
444 itype = &Float32Type;
446 case SPECIAL_INTERNAL_FLOAT64:
447 itype = &Float64Type;
449 case SPECIAL_INTERNAL_FLOAT128:
450 itype = &Float128Type;
453 case SPECIAL_INTERNAL_INTPTR:
456 case SPECIAL_INTERNAL_UINTPTR:
457 itype = &UIntPtrType;
459 case SPECIAL_INTERNAL_OFF:
462 case SPECIAL_INTERNAL_SIZE:
465 /* NOTE: There is no ssize_t in rune. size_t is signed */
467 case SPECIAL_INTERNAL_POINTER:
468 itype = &PointerType;
470 case SPECIAL_INTERNAL_NUMERIC:
471 itype = &NumericType;
473 case SPECIAL_INTERNAL_INTEGRAL:
474 itype = &IntegralType;
476 case SPECIAL_INTERNAL_SINTEGER:
477 itype = &SIntegerType;
479 case SPECIAL_INTERNAL_UINTEGER:
480 itype = &UIntegerType;
483 itype = InternalRegisteredTypeLookup(d->d_Id);
485 dpanic("Unknown internal type: %s", d->d_Id);
490 if (itype->ty_Op != TY_UNRESOLVED) {
491 t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
493 Type *ntype = d->d_TypedefDecl.ed_Type;
495 TypeToQualType(ntype, itype, ntype->ty_SQFlags, NULL);
498 t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
504 AllocType(typelist_t *list, int op)
506 Type *type = zalloc(sizeof(Type));
508 initType(type, list, op);
513 * May be used to generate a varargs compound type, in which case the
514 * semgroup may already be resolved.
516 * We do no matching/caching at this time and callers assume that (for
517 * making adjustments) to the underlying sg at parse-time via
521 AllocCompoundType(SemGroup *sg)
525 type = AllocType(&CompoundTypeList, TY_COMPOUND);
526 type->ty_CompType.et_SemGroup = sg;
527 dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
532 * XXX match the compound type(s)
535 AllocArgsType(SemGroup *sg)
539 type = AllocType(&ArgsTypeList, TY_ARGS);
540 type->ty_ArgsType.et_SemGroup = sg;
545 AllocStorageType(runesize_t bytes)
549 RUNE_FOREACH(type, &StorageTypeList, ty_Node) {
550 if (type->ty_Op == TY_STORAGE &&
551 type->ty_StorType.et_Bytes == bytes
556 type = AllocType(&StorageTypeList, TY_STORAGE);
557 type->ty_StorType.et_Bytes = bytes;
562 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, string_t *ary, int eatAry)
566 dassert_semgrp(sg, ary != NULL);
568 RUNE_FOREACH(type, &sg->sg_ClassList, ty_Node) {
571 if (type->ty_Op != TY_UNRESOLVED)
573 if (type->ty_UnresType.et_ImportSemGroup != isg)
576 for (i = 0; ary[i]; ++i) {
577 if (ary[i] != type->ty_UnresType.et_DottedId[i])
580 if (ary[i] == NULL &&
581 type->ty_UnresType.et_DottedId[i] == NULL) {
587 type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
588 type->ty_UnresType.et_DottedId = ary;
589 type->ty_UnresType.et_SemGroup = sg; /* may be NULL */
590 type->ty_UnresType.et_ImportSemGroup = isg; /* may be NULL */
595 * AllocClassType() - allocate a type representing a the semgroup which
596 * in turn represents (typically) a class.
599 AllocClassType(typelist_t *list, Type *super, SemGroup *sg, int visibility)
604 list = &sg->sg_ClassList;
606 RUNE_FOREACH(type, list, ty_Node) {
607 if (type->ty_Op == TY_CLASS &&
608 type->ty_ClassType.et_SemGroup == sg &&
609 type->ty_ClassType.et_Super == super &&
610 type->ty_Visibility == visibility
616 dassert(&sg->sg_ClassList == list);
617 type = AllocType(list, TY_CLASS);
618 type->ty_ClassType.et_SemGroup = sg;
619 type->ty_ClassType.et_Super = super;
620 type->ty_Visibility = visibility;
626 initInternalClassType(Type *type, Declaration *d)
628 SemGroup *sg = d->d_ClassDecl.ed_SemGroup;
630 initType(type, &sg->sg_ClassList, TY_CLASS);
631 RUNE_REMOVE(&sg->sg_ClassList, type, ty_Node);
632 RUNE_INSERT_HEAD(&sg->sg_ClassList, type, ty_Node);
633 type->ty_ClassType.et_SemGroup = d->d_ClassDecl.ed_SemGroup;
634 type->ty_ClassType.et_Super = d->d_ClassDecl.ed_Super;
635 type->ty_Visibility = d->d_ScopeFlags & SCOPE_ALL_VISIBLE;
636 type->ty_Flags |= TF_ISINTERNAL;
640 AllocImportType(typelist_t *list, SemGroup *sg, int visibility)
642 Type *type = AllocType(list, TY_IMPORT);
644 type->ty_ImportType.et_SemGroup = sg;
645 type->ty_Visibility = visibility;
650 * adjtype must be moved to type's QList because type is being modified
651 * such that that is where it is expected to be.
654 TypeAdjustQList(Type *type, Type *adjtype)
657 if (adjtype->ty_SQList)
658 RUNE_REMOVE(adjtype->ty_SQList, adjtype, ty_Node);
659 adjtype->ty_SQList = &type->ty_QList;
660 RUNE_INSERT_TAIL(adjtype->ty_SQList, adjtype, ty_Node);
666 * Compound types inherit locking modes if not specifically
670 TypeFixupInheritedFlags(Type *type, int rqflags)
675 if (type->ty_Op != TY_COMPOUND)
679 * Assume no matching collapse yet
681 sg = type->ty_CompType.et_SemGroup;
682 RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
683 if (d->d_Op != DOP_GROUP_STORAGE)
685 if ((d->d_ScopeFlags & SCOPE_LOCKING_MASK) == 0) {
686 if (rqflags & SF_UNTRACKED)
687 d->d_ScopeFlags |= SCOPE_UNTRACKED;
688 if (rqflags & SF_UNLOCKED)
689 d->d_ScopeFlags |= SCOPE_UNLOCKED;
690 if (rqflags & SF_SOFT)
691 d->d_ScopeFlags |= SCOPE_SOFT;
692 if (rqflags & SF_HARD)
693 d->d_ScopeFlags |= SCOPE_HARD;
700 TypeToQualType(Type *otype, Type *ntype, int sqFlags, Exp *exp)
705 * Combine with existing qualifiers, Shortcut if no changes made.
708 sqFlags == otype->ty_SQFlags &&
709 (exp == NULL || exp == otype->ty_AssExp)
715 * See if we already have a matching qualified type (only if storage
716 * for the new type is not being provided). Note: the provided storage
717 * has already been initType()d
720 RUNE_FOREACH(ntype, otype->ty_SQList, ty_Node) {
721 if (ntype->ty_Op == otype->ty_Op &&
722 ntype->ty_SQFlags == sqFlags &&
723 (exp == NULL || ntype->ty_AssExp == exp)
725 if (SameType(ntype, otype, sqFlags))
732 * Build a new qualified type and set its qualifiers, then duplicate
733 * appropriate sections of the old type.
735 * Default to the same SQList as otype.
738 ntype = AllocType(otype->ty_SQList, otype->ty_Op);
740 if (ntype->ty_SQList)
741 RUNE_REMOVE(ntype->ty_SQList, ntype, ty_Node);
742 ntype->ty_SQList = otype->ty_SQList;
743 RUNE_INSERT_TAIL(ntype->ty_SQList, ntype, ty_Node);
747 * Set the op and the expression. Unlike SQFlags, if exp is passed as
748 * NULL we inherit the old type's default.
750 * The DupExp() call here is special, see DupExp()'s handling of
753 * Normally DupExp() is called during resolution prior to ex_Decl
754 * being set. This is the one case where it may be called with
755 * ex_Decl already set.
757 * WARNING! We do not try to resolve the type here. Various resolve
758 * related flags in ty_Flags will be resolved later. This
759 * includes TF_ISUNSIGNED and other TF_* flags.
761 ntype->ty_Op = otype->ty_Op;
763 ntype->ty_AssExp = exp;
764 else if (otype->ty_AssExp)
765 ntype->ty_AssExp = SetDupExp(NULL, otype->ty_AssExp);
766 ntype->ty_SQFlags = sqFlags;
767 ntype->ty_Visibility = otype->ty_Visibility;
769 switch(otype->ty_Op) {
772 * When updating the class, alternative forms are collapsed
773 * into it's SemGroup->sg_ClassList and not into some
774 * potentially long recursive chain based on ty_QList.
776 sg = otype->ty_ClassType.et_SemGroup;
778 dassert(ntype->ty_SQList == &sg->sg_ClassList);
779 if (ntype->ty_ClassType.et_SemGroup != sg) {
780 ntype->ty_ClassType.et_SemGroup = sg;
782 ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
785 ntype->ty_Visibility = otype->ty_Visibility;
786 ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
789 ntype->ty_CPtrType.et_Type = otype->ty_CPtrType.et_Type;
792 ntype->ty_PtrType.et_Type = otype->ty_PtrType.et_Type;
795 ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
799 * note: multiple type structures may share the same array size
800 * expression in simple qualified-type cases. YYY XXX bad bad.
802 ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
803 ntype->ty_AryType.et_ArySize = otype->ty_AryType.et_ArySize;
804 ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
805 ntype->ty_AryType.et_Count = otype->ty_AryType.et_Count;
808 ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
811 ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
812 ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
815 ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
818 ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
819 ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
820 ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
821 dassert(ntype->ty_SQList ==
822 &otype->ty_ProcType.et_RetType->ty_QList);
825 ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
829 * It is not legal to qualify a dynamic type other then to
830 * add or remove SF_LVALUE.
832 dpanic("Dynamic type cannot be qualified");
835 ntype->ty_UnresType.et_DottedId =
836 otype->ty_UnresType.et_DottedId;
837 ntype->ty_UnresType.et_SemGroup =
838 otype->ty_UnresType.et_SemGroup;
839 ntype->ty_UnresType.et_ImportSemGroup =
840 otype->ty_UnresType.et_ImportSemGroup;
843 dassert_type(otype, 0);
849 * Convert a return-type + argument-type into a procedure type. If
850 * adjret is non-zero the return-type is converted to locked storage
851 * (which is generally what we want).
853 * Match the procedure type(s) (after adjustment?)
856 TypeToProcType(Type *rtype, Type *atype, int adjret)
859 runesize_t count = 0;
863 dassert_type(atype, atype->ty_Op == TY_ARGS);
866 rtype = TypeFixupInheritedFlags(rtype, rtype->ty_SQFlags);
868 sg = atype->ty_CompType.et_SemGroup;
870 RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
873 RUNE_FOREACH(type, &rtype->ty_QList, ty_Node) {
874 if (type->ty_Op == TY_PROC) {
875 if (type->ty_ProcType.et_ArgsType == atype &&
876 type->ty_ProcType.et_RetType == rtype &&
877 type->ty_ProcType.et_ArgCount == count
883 type = AllocType(&rtype->ty_QList, TY_PROC);
884 type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
885 type->ty_ProcType.et_RetType = rtype;
886 type->ty_ProcType.et_ArgCount = count;
891 * Convert type to pointer-to-type
894 TypeToPtrType(Type *otype)
898 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
899 if (type->ty_Op == TY_PTRTO)
902 type = AllocType(&otype->ty_QList, TY_PTRTO);
903 type->ty_PtrType.et_Type = otype;
908 * Convert type to pointer-to-type
911 TypeToCPtrType(Type *otype)
915 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
916 if (type->ty_Op == TY_CPTRTO)
919 type = AllocType(&otype->ty_QList, TY_CPTRTO);
920 type->ty_CPtrType.et_Type = otype;
925 * Convert type to ref-to-type
927 * A reference type is similar to a pointer type except that the
928 * resolver is not able to entirely know what it is pointing to.
929 * The reference type is a superclass, but the actual type is
930 * stored in the run-time structure.
933 TypeToRefType(Type *otype)
937 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
938 if (type->ty_Op == TY_REFTO)
941 type = AllocType(&otype->ty_QList, TY_REFTO);
942 type->ty_RefType.et_Type = otype;
947 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
952 * XXX handle constant expression optimization for QList
953 * XXX handle qualifiers
955 type = AllocType(&otype->ty_QList, TY_ARYOF);
956 type->ty_AryType.et_ArySize = exp;
957 type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
958 type->ty_AryType.et_SemGroup = sg;
959 type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
966 TypeToRunTimeAryType(Type *otype, int count)
969 Type *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
971 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
972 if (type->ty_Op == TY_ARYOF &&
973 type->ty_AryType.et_Type == t2 &&
974 type->ty_AryType.et_Count == count &&
976 (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
981 type = AllocType(&otype->ty_QList, TY_ARYOF);
982 type->ty_AryType.et_Count = count;
983 type->ty_AryType.et_Type = t2;
984 type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
991 TypeToVarType(Type *otype, SemGroup *sg)
995 /*dassert(sg->sg_Flags & SGF_RESOLVED);*/
996 /*dassert(otype->ty_Flags & TF_RESOLVED);*/
998 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
999 if (type->ty_Op == TY_VAR &&
1000 type->ty_VarType.et_Type == otype &&
1001 type->ty_VarType.et_SemGroup == sg
1003 puts("SG2"); /* YYY */
1007 type = AllocType(&otype->ty_QList, TY_VAR);
1008 type->ty_VarType.et_Type = otype;
1009 type->ty_VarType.et_SemGroup = sg;
1011 /* XXX doesn't work for var-args */
1012 if (sg->sg_Flags & SGF_RESOLVED) {
1013 type->ty_Flags |= TF_RESOLVED;
1014 type->ty_Bytes = sg->sg_Bytes;
1015 type->ty_AlignMask = sg->sg_AlignMask;
1022 * ChangeType() - given pointer, C pointer, or array of something,
1023 * return 'op' of something instead.
1026 ChangeType(Type *type, int op)
1028 switch(type->ty_Op) {
1032 type = TypeToCPtrType(type->ty_PtrType.et_Type);
1035 type = TypeToAryType(type->ty_PtrType.et_Type,
1039 dpanic("Illegal type convesion (A)");
1045 type = TypeToPtrType(type->ty_CPtrType.et_Type);
1048 type = TypeToAryType(type->ty_CPtrType.et_Type,
1052 dpanic("Illegal type convesion (B)");
1058 type = TypeToPtrType(type->ty_AryType.et_Type);
1061 type = TypeToCPtrType(type->ty_AryType.et_Type);
1064 dpanic("Illegal type convesion (C)");
1068 dpanic("Illegal type convesion (D)");
1074 * BaseType() - return base type
1076 * Traverse the type to locate the base type. Store the base type
1077 * in *ptype and return the SemGroup, or return NULL if the base type
1078 * does not have a SemGroup.
1081 BaseType(Type **ptype)
1083 Type *type = *ptype;
1086 switch(type->ty_Op) {
1088 type = type->ty_CPtrType.et_Type;
1091 type = type->ty_PtrType.et_Type;
1094 type = type->ty_RefType.et_Type;
1097 type = type->ty_AryType.et_Type;
1105 switch(type->ty_Op) {
1107 return(type->ty_ClassType.et_SemGroup);
1109 return(type->ty_CompType.et_SemGroup);
1111 return(type->ty_ArgsType.et_SemGroup);
1119 dassert_type(type, 0);
1120 return(NULL); /* avoid compiler complaints */
1125 * DupType() - create a duplicate of a type, possibly in a new SemGroup.
1127 * This code is used when duplicating procedures and other elements
1128 * when merging a superclass into a subclass.
1130 * If sg is NULL, stype is simply returned. The case is used when we
1131 * try to duplciate an expression with DupExp()... in that case we
1132 * want to dup the expression tree but use the same types.
1135 DupType(SemGroup *sg, Type *stype)
1143 * XXX type may be resolved if it is part of a varargs dup
1147 (stype->ty_Flags & (TF_RESOLVED|TF_RESOLVING)) == 0);
1150 switch(stype->ty_Op) {
1153 * This only occurs because the resolver has resolved an
1154 * unresolved type on the original SemGroup. We duplicate
1155 * that on the new SemGroup.
1157 type = AllocClassType(&sg->sg_ClassList,
1158 stype->ty_ClassType.et_Super,
1159 stype->ty_ClassType.et_SemGroup,
1160 stype->ty_Visibility);
1167 type = TypeToCPtrType(DupType(sg, stype->ty_CPtrType.et_Type));
1170 type = TypeToPtrType(DupType(sg, stype->ty_PtrType.et_Type));
1173 type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1176 type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1177 SetDupExp(sg, stype->ty_AryType.et_ArySize),
1178 stype->ty_AryType.et_SemGroup);
1179 type->ty_AryType.et_Count = stype->ty_AryType.et_Count;
1182 type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1183 DupSemGroup(sg, NULL,
1184 stype->ty_VarType.et_SemGroup, 1));
1187 type = AllocCompoundType(
1188 DupSemGroup(sg, NULL,
1189 stype->ty_CompType.et_SemGroup, 1));
1193 * At the moment we always formally duplicate the arguments
1194 * so we can modify them for methods below.
1196 type = AllocArgsType(
1197 DupSemGroup(sg, NULL,
1198 stype->ty_CompType.et_SemGroup, 1));
1201 type = DupType(sg, stype->ty_ProcType.et_RetType);
1202 type = TypeToProcType(type,
1203 DupType(sg, stype->ty_ProcType.et_ArgsType),
1207 * If this is a method procedure, we have to change the
1208 * first argument to point at our new subclass. It was
1209 * previously pointing at our superclass. XXX the
1210 * programmer can override the argument. If it isn't a
1211 * reference we have to assert.
1213 if (sg->sg_Stmt->st_Op != ST_Class) {
1215 * XXX probably an inlined procedure, the type is
1216 * already correct. Need an assertrion here.
1218 } else if (stype->ty_SQFlags & SF_METHOD) {
1219 SemGroup *asg = type->ty_ProcType.et_ArgsType->ty_ArgsType.et_SemGroup;
1220 Declaration *d = RUNE_FIRST(&asg->sg_DeclList);
1221 Type *thisType = d->d_StorDecl.ed_Type;
1223 dassert_decl(d, d->d_Id == String_This &&
1224 d->d_Op == DOP_ARGS_STORAGE);
1225 dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1226 if (thisType->ty_Op == TY_CLASS) {
1227 /* XXX sg_ClassList? right sg? */
1228 /* XXX correct visibility? */
1229 if (d->d_Search == NULL) {
1230 d->d_Search = d->d_StorDecl.ed_Type->
1231 ty_ClassType.et_SemGroup;
1233 d->d_StorDecl.ed_Type =
1234 AllocClassType(&sg->sg_ClassList,
1235 sg->sg_Stmt->st_ClassStmt.es_Super,
1236 sg->sg_Stmt->st_MyGroup,
1239 dassert_decl(d, thisType->ty_Op == TY_REFTO);
1241 } else if (stype->ty_SQFlags & SF_GMETHOD) {
1245 asg = type->ty_ProcType.et_ArgsType->
1246 ty_ArgsType.et_SemGroup;
1247 d = RUNE_FIRST(&asg->sg_DeclList);
1249 dassert_decl(d, d->d_Id == String_This &&
1250 d->d_Op == DOP_TYPEDEF);
1251 dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1252 dassert_decl(d, d->d_TypedefDecl.ed_Type->ty_Op ==
1254 /* XXX sg_ClassList? right sg? */
1255 /* XXX correct visibility? */
1256 if (d->d_Search == NULL) {
1257 d->d_Search = d->d_TypedefDecl.ed_Type->
1258 ty_ClassType.et_SemGroup;
1260 d->d_TypedefDecl.ed_Type =
1261 AllocClassType(&sg->sg_ClassList,
1262 sg->sg_Stmt->st_ClassStmt.es_Super,
1263 sg->sg_Stmt->st_MyGroup,
1272 * e.g. so elements in a superclass will see refined elements
1273 * in the subclass. Note that the original import semgroup
1274 * is left intact so the semantic search mechanism uses it
1275 * when the base sg (typically a subclass) fails.
1277 type = AllocUnresolvedType(
1278 stype->ty_UnresType.et_ImportSemGroup,
1280 stype->ty_UnresType.et_DottedId,
1284 dassert_type(stype, 0);
1287 if (type != stype) {
1288 type->ty_Flags = stype->ty_Flags &
1289 ~(TF_ISINTERNAL | TF_RESOLVING | TF_RESOLVED |
1290 TF_ALIGNRESOLVED | TF_TMPRESOLVED);
1291 type->ty_Bytes = stype->ty_Bytes;
1292 type->ty_AlignMask = stype->ty_AlignMask;
1293 type->ty_Visibility = stype->ty_Visibility;
1294 type->ty_DynamicVector = stype->ty_DynamicVector;
1296 if (stype->ty_AssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1297 type = TypeToQualType(type, NULL,
1299 SetDupExp(sg, stype->ty_AssExp));
1305 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1308 InternalRegisterType(const char *str, const char *linkname, Type *type)
1310 static int Special = SPECIALF_REGISTERED|SPECIALF_INTERNAL|1;
1313 dassert(Special & SPECIALF_MASK);
1314 tr = zalloc(sizeof(TypeRegNode));
1315 tr->tr_Id = StrTableAlloc(str, strlen(str), Special++);
1317 tr->tr_LinkName = linkname;
1318 RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1322 InternalRegisteredTypeLookup(string_t id)
1326 RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1327 if (tr->tr_Id == id)
1328 return(tr->tr_Type);