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 char */
43 Type StrType; /* const char * */
44 Type CharPtrType; /* char * */
45 Type CharPtrPtrType; /* char ** */
46 Type VoidPtrType; /* void * */
47 Type VoidRefType; /* void @ */
48 Type CVoidPtrType; /* const void * */
49 Type LVoidPtrType; /* lvalue void * */
51 Type LexRefType; /* run-time access class tie-ins */
59 typelist_t DynamicTypeList = RUNE_HEAD_INITIALIZER(DynamicTypeList);
60 typelist_t CompoundTypeList = RUNE_HEAD_INITIALIZER(CompoundTypeList);
61 typelist_t ArgsTypeList = RUNE_HEAD_INITIALIZER(ArgsTypeList);
62 typelist_t StorageTypeList = RUNE_HEAD_INITIALIZER(StorageTypeList);
64 static void initInternalClassType(Type *type, Declaration *d);
66 Type *BaseTypeAry[] = {
67 &DynamicLValueType, &DynamicRValueType, &NumericType,
68 &IntegralType, &SIntegerType, &UIntegerType,
69 &VoidType, &BoolType, &Int8Type, &UInt8Type,
70 &Int16Type, &UInt16Type, &Int32Type, &UInt32Type,
71 &Int64Type, &UInt64Type, &Int128Type, &UInt128Type,
73 &IntPtrType, &UIntPtrType, &OffType, &SizeType,
75 &FloatType, &Float32Type, &Float64Type, &Float128Type,
77 &PointerType, &CCharType, &StrType, &CharPtrType,
78 &CharPtrPtrType, &VoidPtrType, &VoidRefType, &CVoidPtrType,
81 &LexRefType, &ScopeType, &DeclarationType, &SemGroupType,
82 &TypeType, &FILLERTypeType, &FILLERDeclType,
87 initType(Type *type, typelist_t *list, int op)
90 RUNE_INIT(&type->ty_QList);
92 RUNE_INSERT_TAIL(list, type, ty_Node);
93 type->ty_SQList = list;
97 initQualType(Type *type, typelist_t *list, int op, int sqflags)
99 initType(type, list, op);
100 type->ty_SQFlags = sqflags;
104 initPtrType(Type *type, Type *ptrto, int sqflags)
106 initQualType(type, &ptrto->ty_QList, TY_PTRTO, sqflags);
107 type->ty_PtrType.et_Type = ptrto;
108 /*type->ty_Bytes = sizeof(PointerStor);*/
109 type->ty_AlignMask = sizeof(void *) - 1;
113 initCPtrType(Type *type, Type *ptrto, int sqflags)
115 initQualType(type, &ptrto->ty_QList, TY_CPTRTO, sqflags);
116 type->ty_PtrType.et_Type = ptrto;
117 /*type->ty_Bytes = sizeof(void *);*/
118 type->ty_AlignMask = sizeof(void *) - 1;
122 initRefType(Type *type, Type *refto, int sqflags)
124 initQualType(type, &refto->ty_QList, TY_REFTO, sqflags);
125 type->ty_RefType.et_Type = refto;
126 type->ty_AlignMask = sizeof(void *) - 1;
127 /*type->ty_Bytes = sizeof(PointerStor);*/
135 initQualType(&DynamicLValueType, &DynamicTypeList,
136 TY_DYNAMIC, SF_LVALUE);
137 initType(&DynamicRValueType, &DynamicTypeList, TY_DYNAMIC);
138 initType(&NumericType, NULL, TY_UNRESOLVED);
139 initType(&IntegralType, NULL, TY_UNRESOLVED);
140 initType(&SIntegerType, NULL, TY_UNRESOLVED);
141 initType(&UIntegerType, NULL, TY_UNRESOLVED);
142 initType(&FloatType, NULL, TY_UNRESOLVED);
143 initType(&PointerType, NULL, TY_UNRESOLVED);
144 PointerType.ty_AlignMask = sizeof(void *) - 1;
146 initType(&VoidType, NULL, TY_UNRESOLVED);
147 initType(&BoolType, NULL, TY_UNRESOLVED);
148 initType(&Int8Type, NULL, TY_UNRESOLVED);
149 initType(&UInt8Type, NULL, TY_UNRESOLVED);
150 initType(&Int16Type, NULL, TY_UNRESOLVED);
151 initType(&UInt16Type, NULL, TY_UNRESOLVED);
152 initType(&Int32Type, NULL, TY_UNRESOLVED);
153 initType(&UInt32Type, NULL, TY_UNRESOLVED);
154 initType(&Int64Type, NULL, TY_UNRESOLVED);
155 initType(&UInt64Type, NULL, TY_UNRESOLVED);
157 initType(&IntPtrType, NULL, TY_UNRESOLVED);
158 initType(&UIntPtrType, NULL, TY_UNRESOLVED);
159 initType(&OffType, NULL, TY_UNRESOLVED);
160 initType(&SizeType, NULL, TY_UNRESOLVED);
162 initType(&Float32Type, NULL, TY_UNRESOLVED);
163 initType(&Float64Type, NULL, TY_UNRESOLVED);
164 initType(&Float128Type, NULL, TY_UNRESOLVED);
166 initQualType(&CCharType, NULL, TY_UNRESOLVED, SF_CONST);
167 initPtrType(&StrType, &CCharType, 0);
168 initPtrType(&CharPtrType, &UInt8Type, 0);
169 initPtrType(&CharPtrPtrType, &CharPtrType, 0);
170 initPtrType(&VoidPtrType, &VoidType, 0);
171 initRefType(&VoidRefType, &VoidType, 0);
172 initCPtrType(&CVoidPtrType, &VoidType, SF_CONST);
173 initPtrType(&LVoidPtrType, &VoidType, SF_LVALUE);
176 * Mark internal types (not all are bound to classes so it is
177 * easiest to just do it here). This will prevent the collapse
178 * code from trying to collapse our base types.
180 for (i = 0; BaseTypeAry[i]; ++i)
181 BaseTypeAry[i]->ty_Flags |= TF_ISINTERNAL;
183 StrTableAlloc("void", 4, SPECIAL_INTERNAL_VOID);
184 StrTableAlloc("bool", 4, SPECIAL_INTERNAL_BOOL);
185 StrTableAlloc("int8_t", 6, SPECIAL_INTERNAL_INT8);
186 StrTableAlloc("uint8_t", 7, SPECIAL_INTERNAL_UINT8);
187 StrTableAlloc("int16_t", 7, SPECIAL_INTERNAL_INT16);
188 StrTableAlloc("uint16_t", 8, SPECIAL_INTERNAL_UINT16);
189 StrTableAlloc("int32_t", 7, SPECIAL_INTERNAL_INT32);
190 StrTableAlloc("uint32_t", 8, SPECIAL_INTERNAL_UINT32);
191 StrTableAlloc("int64_t", 7, SPECIAL_INTERNAL_INT64);
192 StrTableAlloc("uint64_t", 8, SPECIAL_INTERNAL_UINT64);
193 StrTableAlloc("int128_t", 8, SPECIAL_INTERNAL_INT128);
194 StrTableAlloc("uint128_t", 9, SPECIAL_INTERNAL_UINT128);
196 StrTableAlloc("float32_t", 9, SPECIAL_INTERNAL_FLOAT32);
197 StrTableAlloc("float64_t", 9, SPECIAL_INTERNAL_FLOAT64);
198 StrTableAlloc("float128_t", 10, SPECIAL_INTERNAL_FLOAT128);
200 StrTableAlloc("intptr_t", 8, SPECIAL_INTERNAL_INTPTR);
201 StrTableAlloc("uintptr_t", 9, SPECIAL_INTERNAL_UINTPTR);
202 StrTableAlloc("size_t", 6, SPECIAL_INTERNAL_SIZE);
203 StrTableAlloc("off_t", 5, SPECIAL_INTERNAL_OFF);
205 StrTableAlloc("Float", 5, SPECIAL_INTERNAL_FLOAT);
206 StrTableAlloc("Pointer", 7, SPECIAL_INTERNAL_POINTER);
207 StrTableAlloc("Numeric", 7, SPECIAL_INTERNAL_NUMERIC);
208 StrTableAlloc("Integral", 8, SPECIAL_INTERNAL_INTEGRAL);
209 StrTableAlloc("SInteger", 8, SPECIAL_INTERNAL_SINTEGER);
210 StrTableAlloc("UInteger", 8, SPECIAL_INTERNAL_UINTEGER);
212 StrTableAlloc("LexRef", 6, SPECIAL_INTERNAL_LEXREF);
213 StrTableAlloc("Scope", 5, SPECIAL_INTERNAL_SCOPE);
214 StrTableAlloc("Declaration", 11, SPECIAL_INTERNAL_DECLARATION);
215 StrTableAlloc("SemGroup", 8, SPECIAL_INTERNAL_SEMGROUP);
216 StrTableAlloc("Type", 4, SPECIAL_INTERNAL_TYPE);
217 StrTableAlloc("FILLERType", 10, SPECIAL_INTERNAL_FILLERTYPE);
218 StrTableAlloc("FILLERDecl", 10, SPECIAL_INTERNAL_FILLERDECL);
220 StrTableAlloc("__count", 7, SPECIAL_COUNT);
221 StrTableAlloc("__data", 6, SPECIAL_DATA);
222 StrTableAlloc("__varcount", 10, SPECIAL_VAR_COUNT);
223 StrTableAlloc("__vardata", 9, SPECIAL_VAR_DATA);
224 StrTableAlloc("__typeid", 8, SPECIAL_TYPEID);
225 StrTableAlloc("__typestr", 9, SPECIAL_TYPESTR);
226 StrTableAlloc("NULL", 4, SPECIAL_NULL);
230 * Attach an internal class, creating a global summary type for it that
231 * allows our interpreter and code generator to make various assumptions.
234 InternalClassAttach(Parse *p __unused, int t, Declaration *d)
239 dassert_decl(d, d->d_Op == DOP_CLASS);
241 if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
243 case SPECIAL_INTERNAL_VOID:
246 case SPECIAL_INTERNAL_BOOL:
248 * Special flag helper (resolver sets TF_ISBOOL in
252 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISBOOL;
254 case SPECIAL_INTERNAL_INT8:
257 case SPECIAL_INTERNAL_UINT8:
260 case SPECIAL_INTERNAL_INT16:
263 case SPECIAL_INTERNAL_UINT16:
266 case SPECIAL_INTERNAL_INT32:
269 case SPECIAL_INTERNAL_UINT32:
272 case SPECIAL_INTERNAL_INT64:
275 case SPECIAL_INTERNAL_UINT64:
278 case SPECIAL_INTERNAL_INT128:
281 case SPECIAL_INTERNAL_UINT128:
282 itype = &UInt128Type;
285 case SPECIAL_INTERNAL_FLOAT:
287 * Special flag helper (resolver sets TF_ISFLOATING in
291 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISFLOATING;
293 case SPECIAL_INTERNAL_FLOAT32:
294 itype = &Float32Type;
296 case SPECIAL_INTERNAL_FLOAT64:
297 itype = &Float64Type;
299 case SPECIAL_INTERNAL_FLOAT128:
300 itype = &Float128Type;
303 case SPECIAL_INTERNAL_INTPTR:
306 case SPECIAL_INTERNAL_UINTPTR:
307 itype = &UIntPtrType;
309 case SPECIAL_INTERNAL_OFF:
312 case SPECIAL_INTERNAL_SIZE:
315 /* NOTE: There is no ssize_t in rune. size_t is signed */
317 case SPECIAL_INTERNAL_POINTER:
318 itype = &PointerType;
320 case SPECIAL_INTERNAL_NUMERIC:
321 itype = &NumericType;
323 case SPECIAL_INTERNAL_INTEGRAL:
324 itype = &IntegralType;
326 case SPECIAL_INTERNAL_SINTEGER:
328 * Special flag helper (resolver sets TF_ISINTEGER in
331 itype = &SIntegerType;
332 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
334 case SPECIAL_INTERNAL_UINTEGER:
336 * Special flag helper (resolver sets TF_ISINTEGER
337 * and TF_ISUNSIGNED in the type)
339 itype = &UIntegerType;
340 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISUNSIGNED;
341 d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
344 case SPECIAL_INTERNAL_LEXREF:
347 case SPECIAL_INTERNAL_SCOPE:
350 case SPECIAL_INTERNAL_DECLARATION:
351 itype = &DeclarationType;
353 case SPECIAL_INTERNAL_SEMGROUP:
354 itype = &SemGroupType;
356 case SPECIAL_INTERNAL_TYPE:
359 case SPECIAL_INTERNAL_FILLERTYPE:
360 itype = &FILLERTypeType;
362 case SPECIAL_INTERNAL_FILLERDECL:
363 itype = &FILLERDeclType;
370 initInternalClassType(itype, d);
373 * Fixup for const int8 pointers... we did not have
374 * a QList to put CCharType on until now. It will
375 * wind up on the SemGroup's sg_ClassList.
377 if (itype == &UInt8Type) {
378 TypeToQualType(itype, &CCharType,
379 itype->ty_SQFlags | SF_CONST, NULL);
386 * This is mostly deprecated except for official type aliases such as
390 InternalTypeAttach(Parse *p, int t, Declaration *d)
395 dassert_decl(d, d->d_Op == DOP_TYPEDEF);
397 if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
399 case SPECIAL_INTERNAL_VOID:
402 case SPECIAL_INTERNAL_BOOL:
405 case SPECIAL_INTERNAL_INT8:
408 case SPECIAL_INTERNAL_UINT8:
411 case SPECIAL_INTERNAL_INT16:
414 case SPECIAL_INTERNAL_UINT16:
417 case SPECIAL_INTERNAL_INT32:
420 case SPECIAL_INTERNAL_UINT32:
423 case SPECIAL_INTERNAL_INT64:
426 case SPECIAL_INTERNAL_UINT64:
430 case SPECIAL_INTERNAL_FLOAT32:
431 itype = &Float32Type;
433 case SPECIAL_INTERNAL_FLOAT64:
434 itype = &Float64Type;
436 case SPECIAL_INTERNAL_FLOAT128:
437 itype = &Float128Type;
440 case SPECIAL_INTERNAL_INTPTR:
443 case SPECIAL_INTERNAL_UINTPTR:
444 itype = &UIntPtrType;
446 case SPECIAL_INTERNAL_OFF:
449 case SPECIAL_INTERNAL_SIZE:
452 /* NOTE: There is no ssize_t in rune. size_t is signed */
454 case SPECIAL_INTERNAL_POINTER:
455 itype = &PointerType;
457 case SPECIAL_INTERNAL_NUMERIC:
458 itype = &NumericType;
460 case SPECIAL_INTERNAL_INTEGRAL:
461 itype = &IntegralType;
463 case SPECIAL_INTERNAL_SINTEGER:
464 itype = &SIntegerType;
466 case SPECIAL_INTERNAL_UINTEGER:
467 itype = &UIntegerType;
470 itype = InternalRegisteredTypeLookup(d->d_Id);
477 if (itype->ty_Op != TY_UNRESOLVED) {
478 t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
480 Type *ntype = d->d_TypedefDecl.ed_Type;
482 TypeToQualType(ntype, itype, ntype->ty_SQFlags, NULL);
485 t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
491 AllocType(typelist_t *list, int op)
493 Type *type = zalloc(sizeof(Type));
495 initType(type, list, op);
500 * XXX match the compound type(s)
502 * May be used to generate a varargs compound type, in which case the
503 * semgroup may already be resolved.
506 AllocCompoundType(SemGroup *sg)
510 type = AllocType(&CompoundTypeList, TY_COMPOUND);
511 type->ty_CompType.et_SemGroup = sg;
512 dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
517 * XXX match the compound type(s)
520 AllocArgsType(SemGroup *sg)
524 type = AllocType(&ArgsTypeList, TY_ARGS);
525 type->ty_ArgsType.et_SemGroup = sg;
530 AllocStorageType(runesize_t bytes)
534 RUNE_FOREACH(type, &StorageTypeList, ty_Node) {
535 if (type->ty_Op == TY_STORAGE &&
536 type->ty_StorType.et_Bytes == bytes
541 type = AllocType(&StorageTypeList, TY_STORAGE);
542 type->ty_StorType.et_Bytes = bytes;
547 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, string_t *ary, int eatAry)
551 dassert_semgrp(sg, ary != NULL);
553 RUNE_FOREACH(type, &sg->sg_ClassList, ty_Node) {
556 if (type->ty_Op != TY_UNRESOLVED)
558 if (type->ty_UnresType.et_ImportSemGroup != isg)
561 for (i = 0; ary[i]; ++i) {
562 if (ary[i] != type->ty_UnresType.et_DottedId[i])
565 if (ary[i] == NULL &&
566 type->ty_UnresType.et_DottedId[i] == NULL) {
572 type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
573 type->ty_UnresType.et_DottedId = ary;
574 type->ty_UnresType.et_SemGroup = sg; /* may be NULL */
575 type->ty_UnresType.et_ImportSemGroup = isg; /* may be NULL */
580 * AllocClassType() - allocate a type representing a the semgroup which
581 * in turn represents (typically) a class.
584 AllocClassType(typelist_t *list, Type *super, SemGroup *sg, int visibility)
589 list = &sg->sg_ClassList;
591 RUNE_FOREACH(type, list, ty_Node) {
592 if (type->ty_Op == TY_CLASS &&
593 type->ty_ClassType.et_SemGroup == sg &&
594 type->ty_ClassType.et_Super == super &&
595 type->ty_Visibility == visibility
601 dassert(&sg->sg_ClassList == list);
602 type = AllocType(list, TY_CLASS);
603 type->ty_ClassType.et_SemGroup = sg;
604 type->ty_ClassType.et_Super = super;
605 type->ty_Visibility = visibility;
611 initInternalClassType(Type *type, Declaration *d)
613 SemGroup *sg = d->d_ClassDecl.ed_SemGroup;
615 initType(type, &sg->sg_ClassList, TY_CLASS);
616 RUNE_REMOVE(&sg->sg_ClassList, type, ty_Node);
617 RUNE_INSERT_HEAD(&sg->sg_ClassList, type, ty_Node);
618 type->ty_ClassType.et_SemGroup = d->d_ClassDecl.ed_SemGroup;
619 type->ty_ClassType.et_Super = d->d_ClassDecl.ed_Super;
620 type->ty_Visibility = d->d_ScopeFlags & SCOPE_ALL_VISIBLE;
621 type->ty_Flags |= TF_ISINTERNAL;
625 AllocImportType(typelist_t *list, SemGroup *sg, int visibility)
627 Type *type = AllocType(list, TY_IMPORT);
629 type->ty_ImportType.et_SemGroup = sg;
630 type->ty_Visibility = visibility;
635 * adjtype must be moved to type's QList because type is being modified
636 * such that that is where it is expected to be.
639 TypeAdjustQList(Type *type, Type *adjtype)
642 if (adjtype->ty_SQList)
643 RUNE_REMOVE(adjtype->ty_SQList, adjtype, ty_Node);
644 adjtype->ty_SQList = &type->ty_QList;
645 RUNE_INSERT_TAIL(adjtype->ty_SQList, adjtype, ty_Node);
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
667 * for the new type is not being provided). Note: the provided storage
668 * has 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
704 * Normally DupExp() is called during resolution prior to ex_Decl
705 * being set. This is the one case where it may be called with
706 * ex_Decl already set.
708 * WARNING! We do not try to resolve the type here. Various resolve
709 * related flags in ty_Flags will be resolved later. This
710 * includes TF_ISUNSIGNED and other TF_* flags.
712 ntype->ty_Op = otype->ty_Op;
714 ntype->ty_AssExp = exp;
715 else if (otype->ty_AssExp)
716 ntype->ty_AssExp = SetDupExp(NULL, otype->ty_AssExp);
717 ntype->ty_SQFlags = sqFlags;
718 ntype->ty_Visibility = otype->ty_Visibility;
720 switch(otype->ty_Op) {
723 * When updating the class, alternative forms are collapsed
724 * into it's SemGroup->sg_ClassList and not into some
725 * potentially long recursive chain based on ty_QList.
727 sg = otype->ty_ClassType.et_SemGroup;
729 dassert(ntype->ty_SQList == &sg->sg_ClassList);
730 if (ntype->ty_ClassType.et_SemGroup != sg) {
731 ntype->ty_ClassType.et_SemGroup = sg;
733 ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
736 ntype->ty_Visibility = otype->ty_Visibility;
737 ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
740 ntype->ty_CPtrType.et_Type = otype->ty_CPtrType.et_Type;
743 ntype->ty_PtrType.et_Type = otype->ty_PtrType.et_Type;
746 ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
750 * note: multiple type structures may share the same array size
751 * expression in simple qualified-type cases. YYY XXX bad bad.
753 ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
754 ntype->ty_AryType.et_ArySize = otype->ty_AryType.et_ArySize;
755 ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
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
780 * add or remove SF_LVALUE.
785 ntype->ty_UnresType.et_DottedId =
786 otype->ty_UnresType.et_DottedId;
787 ntype->ty_UnresType.et_SemGroup =
788 otype->ty_UnresType.et_SemGroup;
791 dassert_type(otype, 0);
797 * XXX match the procedure type(s)
800 TypeToProcType(Type *rtype, Type *atype)
803 runesize_t count = 0;
807 dassert_type(atype, atype->ty_Op == TY_ARGS);
808 sg = atype->ty_CompType.et_SemGroup;
810 RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
813 RUNE_FOREACH(type, &rtype->ty_QList, ty_Node) {
814 if (type->ty_Op == TY_PROC) {
815 if (type->ty_ProcType.et_ArgsType == atype &&
816 type->ty_ProcType.et_RetType == rtype &&
817 type->ty_ProcType.et_ArgCount == count
819 puts("SG1"); /* YYY */
824 type = AllocType(&rtype->ty_QList, TY_PROC);
825 type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
826 type->ty_ProcType.et_RetType = rtype;
827 type->ty_ProcType.et_ArgCount = count;
832 * Convert type to pointer-to-type
835 TypeToPtrType(Type *otype)
839 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
840 if (type->ty_Op == TY_PTRTO)
843 type = AllocType(&otype->ty_QList, TY_PTRTO);
844 type->ty_PtrType.et_Type = otype;
849 * Convert type to pointer-to-type
852 TypeToCPtrType(Type *otype)
856 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
857 if (type->ty_Op == TY_CPTRTO)
860 type = AllocType(&otype->ty_QList, TY_CPTRTO);
861 type->ty_CPtrType.et_Type = otype;
866 * Convert type to ref-to-type
868 * A reference type is similar to a pointer type except that the
869 * resolver is not able to entirely know what it is pointing to.
870 * The reference type is a superclass, but the actual type is
871 * stored in the run-time structure.
874 TypeToRefType(Type *otype)
878 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
879 if (type->ty_Op == TY_REFTO)
882 type = AllocType(&otype->ty_QList, TY_REFTO);
883 type->ty_RefType.et_Type = otype;
888 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
893 * XXX handle constant expression optimization for QList
894 * XXX handle qualifiers
896 type = AllocType(&otype->ty_QList, TY_ARYOF);
897 type->ty_AryType.et_ArySize = exp;
898 type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
899 type->ty_AryType.et_SemGroup = sg;
900 type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
907 TypeToRunTimeAryType(Type *otype, int count)
910 Type *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
912 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
913 if (type->ty_Op == TY_ARYOF &&
914 type->ty_AryType.et_Type == t2 &&
915 type->ty_AryType.et_Count == count &&
917 (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
922 type = AllocType(&otype->ty_QList, TY_ARYOF);
923 type->ty_AryType.et_Count = count;
924 type->ty_AryType.et_Type = t2;
925 type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
932 TypeToVarType(Type *otype, SemGroup *sg)
936 dassert(sg->sg_Flags & SGF_RESOLVED);
937 dassert(otype->ty_Flags & TF_RESOLVED);
939 RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
940 if (type->ty_Op == TY_VAR &&
941 type->ty_VarType.et_Type == otype &&
942 type->ty_VarType.et_SemGroup == sg
944 puts("SG2"); /* YYY */
948 type = AllocType(&otype->ty_QList, TY_VAR);
949 type->ty_VarType.et_Type = otype;
950 type->ty_VarType.et_SemGroup = sg;
952 /* XXX doesn't work for var-args */
953 if (sg->sg_Flags & SGF_RESOLVED) {
954 type->ty_Flags |= TF_RESOLVED;
955 type->ty_Bytes = sg->sg_Bytes;
956 type->ty_AlignMask = sg->sg_AlignMask;
963 * ChangeType() - given pointer, C pointer, or array of something,
964 * return 'op' of something instead.
967 ChangeType(Type *type, int op)
969 switch(type->ty_Op) {
973 type = TypeToCPtrType(type->ty_PtrType.et_Type);
976 type = TypeToAryType(type->ty_PtrType.et_Type,
986 type = TypeToPtrType(type->ty_CPtrType.et_Type);
989 type = TypeToAryType(type->ty_CPtrType.et_Type,
999 type = TypeToPtrType(type->ty_AryType.et_Type);
1002 type = TypeToCPtrType(type->ty_AryType.et_Type);
1015 * BaseType() - return base type
1017 * Traverse the type to locate the base type. Store the base type
1018 * in *ptype and return the SemGroup, or return NULL if the base type
1019 * does not have a SemGroup.
1022 BaseType(Type **ptype)
1024 Type *type = *ptype;
1027 switch(type->ty_Op) {
1029 type = type->ty_CPtrType.et_Type;
1032 type = type->ty_PtrType.et_Type;
1035 type = type->ty_RefType.et_Type;
1038 type = type->ty_AryType.et_Type;
1046 switch(type->ty_Op) {
1048 return(type->ty_ClassType.et_SemGroup);
1050 return(type->ty_CompType.et_SemGroup);
1052 return(type->ty_ArgsType.et_SemGroup);
1060 dassert_type(type, 0);
1061 return(NULL); /* avoid compiler complaints */
1066 * DupType() - create a duplicate of a type, possibly in a new SemGroup.
1068 * This code is used when duplicating procedures and other elements
1069 * when merging a superclass into a subclass.
1071 * If sg is NULL, stype is simply returned. The case is used when we
1072 * try to duplciate an expression with DupExp()... in that case we
1073 * want to dup the expression tree but use the same types.
1076 DupType(SemGroup *sg, Type *stype)
1084 * XXX type may be resolved if it is part of a varargs dup
1088 (stype->ty_Flags & (TF_RESOLVED|TF_RESOLVING)) == 0);
1091 switch(stype->ty_Op) {
1094 * This only occurs because the resolver has resolved an
1095 * unresolved type on the original SemGroup. We duplicate
1096 * that on the new SemGroup.
1098 type = AllocClassType(&sg->sg_ClassList,
1099 stype->ty_ClassType.et_Super,
1100 stype->ty_ClassType.et_SemGroup,
1101 stype->ty_Visibility);
1108 type = TypeToCPtrType(DupType(sg, stype->ty_CPtrType.et_Type));
1111 type = TypeToPtrType(DupType(sg, stype->ty_PtrType.et_Type));
1114 type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1117 type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1118 SetDupExp(sg, stype->ty_AryType.et_ArySize),
1119 stype->ty_AryType.et_SemGroup);
1122 type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1123 DupSemGroup(sg, NULL,
1124 stype->ty_VarType.et_SemGroup, 1));
1127 type = AllocCompoundType(
1128 DupSemGroup(sg, NULL,
1129 stype->ty_CompType.et_SemGroup, 1));
1133 * At the moment we always formally duplicate the arguments
1134 * so we can modify them for methods below.
1136 type = AllocArgsType(
1137 DupSemGroup(sg, NULL,
1138 stype->ty_CompType.et_SemGroup, 1));
1141 type = DupType(sg, stype->ty_ProcType.et_RetType);
1142 type = TypeToProcType(type,
1144 stype->ty_ProcType.et_ArgsType));
1147 * If this is a method procedure, we have to change the
1148 * first argument to point at our new subclass. It was
1149 * previously pointing at our superclass. XXX the
1150 * programmer can override the argument. If it isn't a
1151 * reference we have to assert.
1153 if (stype->ty_SQFlags & SF_METHOD) {
1154 SemGroup *asg = type->ty_ProcType.et_ArgsType->ty_ArgsType.et_SemGroup;
1155 Declaration *d = RUNE_FIRST(&asg->sg_DeclList);
1156 Type *thisType = d->d_StorDecl.ed_Type;
1158 dassert_decl(d, d->d_Id == String_This &&
1159 d->d_Op == DOP_ARGS_STORAGE);
1160 dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1161 if (thisType->ty_Op == TY_CLASS) {
1162 /* XXX sg_ClassList? right sg? */
1163 /* XXX correct visibility? */
1164 if (d->d_Search == NULL) {
1165 d->d_Search = d->d_StorDecl.ed_Type->
1166 ty_ClassType.et_SemGroup;
1168 d->d_StorDecl.ed_Type =
1169 AllocClassType(&sg->sg_ClassList,
1170 sg->sg_Stmt->st_ClassStmt.es_Super,
1171 sg->sg_Stmt->st_MyGroup,
1174 dassert_decl(d, thisType->ty_Op == TY_REFTO);
1176 } else if (stype->ty_SQFlags & SF_GMETHOD) {
1180 asg = type->ty_ProcType.et_ArgsType->
1181 ty_ArgsType.et_SemGroup;
1182 d = RUNE_FIRST(&asg->sg_DeclList);
1184 dassert_decl(d, d->d_Id == String_This &&
1185 d->d_Op == DOP_TYPEDEF);
1186 dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1187 dassert_decl(d, d->d_TypedefDecl.ed_Type->ty_Op ==
1189 /* XXX sg_ClassList? right sg? */
1190 /* XXX correct visibility? */
1191 if (d->d_Search == NULL) {
1192 d->d_Search = d->d_TypedefDecl.ed_Type->
1193 ty_ClassType.et_SemGroup;
1195 d->d_TypedefDecl.ed_Type =
1196 AllocClassType(&sg->sg_ClassList,
1197 sg->sg_Stmt->st_ClassStmt.es_Super,
1198 sg->sg_Stmt->st_MyGroup,
1207 * e.g. so elements in a superclass will see refined elements
1208 * in the subclass. Note that the original import semgroup
1209 * is left intact so the semantic search mechanism uses it
1210 * when the base sg (typically a subclass) fails.
1212 type = AllocUnresolvedType(
1213 stype->ty_UnresType.et_ImportSemGroup,
1215 stype->ty_UnresType.et_DottedId,
1219 dassert_type(stype, 0);
1222 if (type != stype) {
1223 type->ty_Flags = stype->ty_Flags & ~TF_ISINTERNAL;
1224 type->ty_Bytes = stype->ty_Bytes;
1225 type->ty_AlignMask = stype->ty_AlignMask;
1226 type->ty_Visibility = stype->ty_Visibility;
1228 if (stype->ty_AssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1229 type = TypeToQualType(type, NULL,
1231 SetDupExp(sg, stype->ty_AssExp));
1238 typedef RUNE_HEAD(typereglist, TypeRegNode) typereglist_t;
1240 typedef struct TypeRegNode {
1241 RUNE_ENTRY(TypeRegNode) tr_Node;
1246 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1249 InternalRegisterType(const char *str, Type *type)
1251 static int Special = SPECIALF_REGISTERED|SPECIALF_INTERNAL|1;
1254 dassert(Special & SPECIALF_MASK);
1255 tr = zalloc(sizeof(TypeRegNode));
1256 tr->tr_Id = StrTableAlloc(str, strlen(str), Special++);
1258 RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1262 InternalRegisteredTypeLookup(string_t id)
1266 RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1267 if (tr->tr_Id == id)
1268 return(tr->tr_Type);