Rune - Change regsave burden for syscalls
[rune.git] / librune / type.c
1 /*
2  * TYPE.C
3  *
4  * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved.  See the  
5  *    COPYRIGHT file at the base of the distribution.
6  */
7
8 #include "defs.h"
9
10 Type DynamicLValueType;
11 Type DynamicRValueType;
12
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 */
17
18 Type VoidType;
19 Type BoolType;
20 Type Int8Type;
21 Type UInt8Type;
22 Type Int16Type;
23 Type UInt16Type;
24 Type Int32Type;
25 Type UInt32Type;
26 Type Int64Type;
27 Type UInt64Type;
28 Type Int128Type;
29 Type UInt128Type;
30
31 Type IntPtrType;
32 Type UIntPtrType;
33 Type OffType;
34 Type SizeType;
35
36 Type FloatType;         /* generic float placeholder */
37 Type Float32Type;
38 Type Float64Type;
39 Type Float128Type;
40
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 *        */
50
51 Type LexRefType;        /* run-time access class tie-ins */
52 Type ScopeType;
53 Type DeclarationType;
54 Type SemGroupType;
55 Type PointerInfoType;
56 Type TypeType;
57 Type FILLERTypeType;
58 Type FILLERDeclType;
59
60 typelist_t DynamicTypeList = RUNE_HEAD_INITIALIZER(DynamicTypeList);
61 typelist_t CompoundTypeList = RUNE_HEAD_INITIALIZER(CompoundTypeList);
62 typelist_t ArgsTypeList = RUNE_HEAD_INITIALIZER(ArgsTypeList);
63 typelist_t StorageTypeList = RUNE_HEAD_INITIALIZER(StorageTypeList);
64
65 static void initInternalClassType(Type *type, Declaration *d);
66
67 Type *BaseTypeAry[] = {
68                 &DynamicLValueType, &DynamicRValueType, &NumericType,
69                 &IntegralType, &SIntegerType, &UIntegerType,
70                 &VoidType, &BoolType, &Int8Type, &UInt8Type,
71                 &Int16Type, &UInt16Type, &Int32Type, &UInt32Type,
72                 &Int64Type, &UInt64Type, &Int128Type, &UInt128Type,
73
74                 &IntPtrType, &UIntPtrType, &OffType, &SizeType,
75
76                 &FloatType, &Float32Type, &Float64Type, &Float128Type,
77
78                 &PointerType, &CCharType, &StrType, &CharPtrType,
79                 &CharPtrPtrType, &VoidPtrType, &VoidRefType, &CVoidPtrType,
80                 &LVoidPtrType,
81
82                 &LexRefType, &ScopeType, &DeclarationType, &SemGroupType,
83                 &PointerInfoType, &TypeType,
84                 &FILLERTypeType, &FILLERDeclType,
85                 NULL
86 };
87
88 void
89 initType(Type *type, typelist_t *list, int op)
90 {
91         type->ty_Op = op;
92         RUNE_INIT(&type->ty_QList);
93         if (list)
94                 RUNE_INSERT_TAIL(list, type, ty_Node);
95         type->ty_SQList = list;
96         type->ty_Info.in_Type = type;
97         type->ty_Info.in_Refs = PINFO_STATIC;
98 }
99
100 void
101 initQualType(Type *type, typelist_t *list, int op, int sqflags)
102 {
103         initType(type, list, op);
104         type->ty_SQFlags = sqflags;
105 }
106
107 void
108 initPtrType(Type *type, Type *ptrto, int sqflags)
109 {
110         initQualType(type, &ptrto->ty_QList, TY_PTRTO, sqflags);
111         type->ty_PtrType.et_Type = ptrto;
112         /*type->ty_Bytes = sizeof(PointerStor);*/
113         type->ty_AlignMask = POINTERSTOR_ALIGN;
114 }
115
116 void
117 initCPtrType(Type *type, Type *ptrto, int sqflags)
118 {
119         initQualType(type, &ptrto->ty_QList, TY_CPTRTO, sqflags);
120         type->ty_PtrType.et_Type = ptrto;
121         /*type->ty_Bytes = sizeof(void *);*/
122         type->ty_AlignMask = sizeof(void *) - 1;
123 }
124
125 static void
126 initRefType(Type *type, Type *refto, int sqflags)
127 {
128         initQualType(type, &refto->ty_QList, TY_REFTO, sqflags);
129         type->ty_RefType.et_Type = refto;
130         /*type->ty_Bytes = sizeof(PointerStor);*/
131         type->ty_AlignMask = POINTERSTOR_ALIGN;
132 }
133
134 void
135 TypeInit(void)
136 {
137         int i;
138
139         initQualType(&DynamicLValueType, &DynamicTypeList,
140                      TY_DYNAMIC, SF_LVALUE);
141         initType(&DynamicRValueType, &DynamicTypeList, TY_DYNAMIC);
142         initType(&NumericType, NULL, TY_UNRESOLVED);
143         initType(&IntegralType, NULL, TY_UNRESOLVED);
144         initType(&SIntegerType, NULL, TY_UNRESOLVED);
145         initType(&UIntegerType, NULL, TY_UNRESOLVED);
146         initType(&FloatType, NULL, TY_UNRESOLVED);
147         initType(&PointerType, NULL, TY_UNRESOLVED);
148         PointerType.ty_AlignMask = POINTERSTOR_ALIGN;
149
150         initType(&VoidType, NULL, TY_UNRESOLVED);
151         initType(&BoolType, NULL, TY_UNRESOLVED);
152         initType(&Int8Type, NULL, TY_UNRESOLVED);
153         initType(&UInt8Type, NULL, TY_UNRESOLVED);
154         initType(&Int16Type, NULL, TY_UNRESOLVED);
155         initType(&UInt16Type, NULL, TY_UNRESOLVED);
156         initType(&Int32Type, NULL, TY_UNRESOLVED);
157         initType(&UInt32Type, NULL, TY_UNRESOLVED);
158         initType(&Int64Type, NULL, TY_UNRESOLVED);
159         initType(&UInt64Type, NULL, TY_UNRESOLVED);
160
161         initType(&IntPtrType, NULL, TY_UNRESOLVED);
162         initType(&UIntPtrType, NULL, TY_UNRESOLVED);
163         initType(&OffType, NULL, TY_UNRESOLVED);
164         initType(&SizeType, NULL, TY_UNRESOLVED);
165
166         initType(&Float32Type, NULL, TY_UNRESOLVED);
167         initType(&Float64Type, NULL, TY_UNRESOLVED);
168         initType(&Float128Type, NULL, TY_UNRESOLVED);
169
170         initQualType(&CCharType, NULL, TY_UNRESOLVED, SF_CONST);
171         initPtrType(&StrType, &CCharType, 0);
172         initPtrType(&CharPtrType, &UInt8Type, 0);
173         initPtrType(&CharPtrPtrType, &CharPtrType, 0);
174         initPtrType(&VoidPtrType, &VoidType, 0);
175         initRefType(&VoidRefType, &VoidType, 0);
176         initCPtrType(&CVoidPtrType, &VoidType, SF_CONST);
177         initPtrType(&LVoidPtrType, &VoidType, SF_LVALUE);
178
179         /*
180          * Mark internal types (not all are bound to classes so it is
181          * easiest to just do it here).  This will prevent the collapse
182          * code from trying to collapse our base types.
183          */
184         for (i = 0; BaseTypeAry[i]; ++i)
185                 BaseTypeAry[i]->ty_Flags |= TF_ISINTERNAL;
186
187         StrTableAlloc("void", 4, SPECIAL_INTERNAL_VOID);
188         StrTableAlloc("bool", 4, SPECIAL_INTERNAL_BOOL);
189         StrTableAlloc("int8_t", 6, SPECIAL_INTERNAL_INT8);
190         StrTableAlloc("uint8_t", 7, SPECIAL_INTERNAL_UINT8);
191         StrTableAlloc("int16_t", 7, SPECIAL_INTERNAL_INT16);
192         StrTableAlloc("uint16_t", 8, SPECIAL_INTERNAL_UINT16);
193         StrTableAlloc("int32_t", 7, SPECIAL_INTERNAL_INT32);
194         StrTableAlloc("uint32_t", 8, SPECIAL_INTERNAL_UINT32);
195         StrTableAlloc("int64_t", 7, SPECIAL_INTERNAL_INT64);
196         StrTableAlloc("uint64_t", 8, SPECIAL_INTERNAL_UINT64);
197         StrTableAlloc("int128_t", 8, SPECIAL_INTERNAL_INT128);
198         StrTableAlloc("uint128_t", 9, SPECIAL_INTERNAL_UINT128);
199
200         StrTableAlloc("float32_t", 9, SPECIAL_INTERNAL_FLOAT32);
201         StrTableAlloc("float64_t", 9, SPECIAL_INTERNAL_FLOAT64);
202         StrTableAlloc("float128_t", 10, SPECIAL_INTERNAL_FLOAT128);
203
204         StrTableAlloc("intptr_t", 8, SPECIAL_INTERNAL_INTPTR);
205         StrTableAlloc("uintptr_t", 9, SPECIAL_INTERNAL_UINTPTR);
206         StrTableAlloc("size_t", 6, SPECIAL_INTERNAL_SIZE);
207         StrTableAlloc("off_t", 5, SPECIAL_INTERNAL_OFF);
208
209         StrTableAlloc("Float", 5, SPECIAL_INTERNAL_FLOAT);
210         StrTableAlloc("Pointer", 7, SPECIAL_INTERNAL_POINTER);
211         StrTableAlloc("Numeric", 7, SPECIAL_INTERNAL_NUMERIC);
212         StrTableAlloc("Integral", 8, SPECIAL_INTERNAL_INTEGRAL);
213         StrTableAlloc("SInteger", 8, SPECIAL_INTERNAL_SINTEGER);
214         StrTableAlloc("UInteger", 8, SPECIAL_INTERNAL_UINTEGER);
215
216         StrTableAlloc("LexRef", 6, SPECIAL_INTERNAL_LEXREF);
217         StrTableAlloc("Scope", 5, SPECIAL_INTERNAL_SCOPE);
218         StrTableAlloc("Declaration", 11, SPECIAL_INTERNAL_DECLARATION);
219         StrTableAlloc("SemGroup", 8, SPECIAL_INTERNAL_SEMGROUP);
220         StrTableAlloc("PointerInfo", 11, SPECIAL_INTERNAL_POINTERINFO);
221         StrTableAlloc("Type", 4, SPECIAL_INTERNAL_TYPE);
222         StrTableAlloc("FILLERType", 10, SPECIAL_INTERNAL_FILLERTYPE);
223         StrTableAlloc("FILLERDecl", 10, SPECIAL_INTERNAL_FILLERDECL);
224
225         StrTableAlloc("__count",        7,      SPECIAL_COUNT);
226         StrTableAlloc("__data",         6,      SPECIAL_DATA);
227         StrTableAlloc("__varcount",     10,     SPECIAL_VAR_COUNT);
228         StrTableAlloc("__vardata",      9,      SPECIAL_VAR_DATA);
229         StrTableAlloc("__typeid",       8,      SPECIAL_TYPEID);
230         StrTableAlloc("__typestr",      9,      SPECIAL_TYPESTR);
231         StrTableAlloc("NULL",           4,      SPECIAL_NULL);
232 }
233
234 /*
235  * Attach an internal class, creating a global summary type for it that
236  * allows our interpreter and code generator to make various assumptions.
237  */
238 int
239 InternalClassAttach(Parse *p __unused, int t, Declaration *d)
240 {
241         Type *itype = NULL;
242         int s;
243
244         dassert_decl(d, d->d_Op == DOP_CLASS);
245
246         if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
247                 switch(s) {
248                 case SPECIAL_INTERNAL_VOID:
249                         itype = &VoidType;
250                         break;
251                 case SPECIAL_INTERNAL_BOOL:
252                         /*
253                          * Special flag helper (resolver sets TF_ISBOOL in
254                          * in the type)
255                          */
256                         itype = &BoolType;
257                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISBOOL;
258                         break;
259                 case SPECIAL_INTERNAL_INT8:
260                         itype = &Int8Type;
261                         break;
262                 case SPECIAL_INTERNAL_UINT8:
263                         itype = &UInt8Type;
264                         break;
265                 case SPECIAL_INTERNAL_INT16:
266                         itype = &Int16Type;
267                         break;
268                 case SPECIAL_INTERNAL_UINT16:
269                         itype = &UInt16Type;
270                         break;
271                 case SPECIAL_INTERNAL_INT32:
272                         itype = &Int32Type;
273                         break;
274                 case SPECIAL_INTERNAL_UINT32:
275                         itype = &UInt32Type;
276                         break;
277                 case SPECIAL_INTERNAL_INT64:
278                         itype = &Int64Type;
279                         break;
280                 case SPECIAL_INTERNAL_UINT64:
281                         itype = &UInt64Type;
282                         break;
283                 case SPECIAL_INTERNAL_INT128:
284                         itype = &Int128Type;
285                         break;
286                 case SPECIAL_INTERNAL_UINT128:
287                         itype = &UInt128Type;
288                         break;
289
290                 case SPECIAL_INTERNAL_FLOAT:
291                         /*
292                          * Special flag helper (resolver sets TF_ISFLOATING in
293                          * in the type)
294                          */
295                         itype = &FloatType;
296                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISFLOATING;
297                         break;
298                 case SPECIAL_INTERNAL_FLOAT32:
299                         itype = &Float32Type;
300                         break;
301                 case SPECIAL_INTERNAL_FLOAT64:
302                         itype = &Float64Type;
303                         break;
304                 case SPECIAL_INTERNAL_FLOAT128:
305                         itype = &Float128Type;
306                         break;
307
308                 case SPECIAL_INTERNAL_INTPTR:
309                         itype = &IntPtrType;
310                         break;
311                 case SPECIAL_INTERNAL_UINTPTR:
312                         itype = &UIntPtrType;
313                         break;
314                 case SPECIAL_INTERNAL_OFF:
315                         itype = &OffType;
316                         break;
317                 case SPECIAL_INTERNAL_SIZE:
318                         itype = &SizeType;
319                         break;
320                 /* NOTE: There is no ssize_t in rune. size_t is signed */
321
322                 case SPECIAL_INTERNAL_POINTER:
323                         itype = &PointerType;
324                         break;
325                 case SPECIAL_INTERNAL_NUMERIC:
326                         itype = &NumericType;
327                         break;
328                 case SPECIAL_INTERNAL_INTEGRAL:
329                         itype = &IntegralType;
330                         break;
331                 case SPECIAL_INTERNAL_SINTEGER:
332                         /*
333                          * Special flag helper (resolver sets TF_ISINTEGER in
334                          * in the type)
335                          */
336                         itype = &SIntegerType;
337                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
338                         break;
339                 case SPECIAL_INTERNAL_UINTEGER:
340                         /*
341                          * Special flag helper (resolver sets TF_ISINTEGER
342                          * and TF_ISUNSIGNED in the type)
343                          */
344                         itype = &UIntegerType;
345                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISUNSIGNED;
346                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
347                         break;
348
349                 case SPECIAL_INTERNAL_LEXREF:
350                         itype = &LexRefType;
351                         break;
352                 case SPECIAL_INTERNAL_SCOPE:
353                         itype = &ScopeType;
354                         break;
355                 case SPECIAL_INTERNAL_DECLARATION:
356                         itype = &DeclarationType;
357                         break;
358                 case SPECIAL_INTERNAL_SEMGROUP:
359                         itype = &SemGroupType;
360                         break;
361                 case SPECIAL_INTERNAL_POINTERINFO:
362                         itype = &PointerInfoType;
363                         break;
364                 case SPECIAL_INTERNAL_TYPE:
365                         itype = &TypeType;
366                         break;
367                 case SPECIAL_INTERNAL_FILLERTYPE:
368                         itype = &FILLERTypeType;
369                         break;
370                 case SPECIAL_INTERNAL_FILLERDECL:
371                         itype = &FILLERDeclType;
372                         break;
373                 default:
374                         dpanic("Unknown internal class: %s", d->d_Id);
375                         break;
376                 }
377         }
378         initInternalClassType(itype, d);
379
380         /*
381          * Fixup for const int8 pointers... we did not have
382          * a QList to put CCharType on until now.  It will
383          * wind up on the SemGroup's sg_ClassList.
384          */
385         if (itype == &UInt8Type) {
386                 TypeToQualType(itype, &CCharType,
387                                itype->ty_SQFlags | SF_CONST, NULL);
388         } 
389
390         return(t);
391 }
392
393 /*
394  * This is mostly deprecated except for official type aliases such as
395  * intptr_t.
396  */
397 int
398 InternalTypeAttach(Parse *p, int t, Declaration *d)
399 {
400         Type *itype = NULL;
401         int s;
402
403         dassert_decl(d, d->d_Op == DOP_TYPEDEF);
404
405         if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
406                 switch(s) {
407                 case SPECIAL_INTERNAL_VOID:
408                         itype = &VoidType;
409                         break;
410                 case SPECIAL_INTERNAL_BOOL:
411                         itype = &BoolType;
412                         break;
413                 case SPECIAL_INTERNAL_INT8:
414                         itype = &Int8Type;
415                         break;
416                 case SPECIAL_INTERNAL_UINT8:
417                         itype = &UInt8Type;
418                         break;
419                 case SPECIAL_INTERNAL_INT16:
420                         itype = &Int16Type;
421                         break;
422                 case SPECIAL_INTERNAL_UINT16:
423                         itype = &UInt16Type;
424                         break;
425                 case SPECIAL_INTERNAL_INT32:
426                         itype = &Int32Type;
427                         break;
428                 case SPECIAL_INTERNAL_UINT32:
429                         itype = &UInt32Type;
430                         break;
431                 case SPECIAL_INTERNAL_INT64:
432                         itype = &Int64Type;
433                         break;
434                 case SPECIAL_INTERNAL_UINT64:
435                         itype = &UInt64Type;
436                         break;
437
438                 case SPECIAL_INTERNAL_FLOAT32:
439                         itype = &Float32Type;
440                         break;
441                 case SPECIAL_INTERNAL_FLOAT64:
442                         itype = &Float64Type;
443                         break;
444                 case SPECIAL_INTERNAL_FLOAT128:
445                         itype = &Float128Type;
446                         break;
447
448                 case SPECIAL_INTERNAL_INTPTR:
449                         itype = &IntPtrType;
450                         break;
451                 case SPECIAL_INTERNAL_UINTPTR:
452                         itype = &UIntPtrType;
453                         break;
454                 case SPECIAL_INTERNAL_OFF:
455                         itype = &OffType;
456                         break;
457                 case SPECIAL_INTERNAL_SIZE:
458                         itype = &SizeType;
459                         break;
460                 /* NOTE: There is no ssize_t in rune. size_t is signed */
461
462                 case SPECIAL_INTERNAL_POINTER:
463                         itype = &PointerType;
464                         break;
465                 case SPECIAL_INTERNAL_NUMERIC:
466                         itype = &NumericType;
467                         break;
468                 case SPECIAL_INTERNAL_INTEGRAL:
469                         itype = &IntegralType;
470                         break;
471                 case SPECIAL_INTERNAL_SINTEGER:
472                         itype = &SIntegerType;
473                         break;
474                 case SPECIAL_INTERNAL_UINTEGER:
475                         itype = &UIntegerType;
476                         break;
477                 default:
478                         itype = InternalRegisteredTypeLookup(d->d_Id);
479                         if (itype == NULL)
480                                 dpanic("Unknown internal type: %s", d->d_Id);
481                         break;
482                 }
483         }
484         if (itype) {
485                 if (itype->ty_Op != TY_UNRESOLVED) {
486                         t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
487                 } else {
488                         Type *ntype = d->d_TypedefDecl.ed_Type;
489
490                         TypeToQualType(ntype, itype, ntype->ty_SQFlags, NULL);
491                 }
492         } else {
493                 t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
494         }
495         return(t);
496 }
497
498 Type *
499 AllocType(typelist_t *list, int op)
500 {
501         Type *type = zalloc(sizeof(Type));
502
503         initType(type, list, op);
504         return(type);
505 }
506
507 /*
508  * May be used to generate a varargs compound type, in which case the
509  * semgroup may already be resolved.
510  *
511  * We do no matching/caching at this time and callers assume that (for
512  * making adjustments) to the underlying sg at parse-time via
513  * TypeToProcType()
514  */
515 Type *
516 AllocCompoundType(SemGroup *sg)
517 {
518         Type *type;
519
520         type = AllocType(&CompoundTypeList, TY_COMPOUND);
521         type->ty_CompType.et_SemGroup = sg;
522         dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
523         return(type);
524 }
525
526 /*
527  * XXX match the compound type(s)
528  */
529 Type *
530 AllocArgsType(SemGroup *sg)
531 {
532         Type *type;
533
534         type = AllocType(&ArgsTypeList, TY_ARGS);
535         type->ty_ArgsType.et_SemGroup = sg;
536         return(type);
537 }
538
539 Type *
540 AllocStorageType(runesize_t bytes)
541 {
542         Type *type;
543
544         RUNE_FOREACH(type, &StorageTypeList, ty_Node) {
545                 if (type->ty_Op == TY_STORAGE &&
546                         type->ty_StorType.et_Bytes == bytes
547                 ) {
548                         return(type);
549                 }
550         }
551         type = AllocType(&StorageTypeList, TY_STORAGE);
552         type->ty_StorType.et_Bytes = bytes;
553         return(type);
554 }
555
556 Type *
557 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, string_t *ary, int eatAry)
558 {
559         Type *type = NULL;
560
561         dassert_semgrp(sg, ary != NULL);
562
563         RUNE_FOREACH(type, &sg->sg_ClassList, ty_Node) {
564                 int i;
565
566                 if (type->ty_Op != TY_UNRESOLVED)
567                         continue;
568                 if (type->ty_UnresType.et_ImportSemGroup != isg)
569                         continue;
570
571                 for (i = 0; ary[i]; ++i) {
572                         if (ary[i] != type->ty_UnresType.et_DottedId[i])
573                                 break;
574                 }
575                 if (ary[i] == NULL &&
576                     type->ty_UnresType.et_DottedId[i] == NULL) {
577                         if (eatAry)
578                                 FreeDotIdAry(ary);
579                         return(type);
580                 }
581         }
582         type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
583         type->ty_UnresType.et_DottedId = ary;
584         type->ty_UnresType.et_SemGroup = sg;            /* may be NULL */
585         type->ty_UnresType.et_ImportSemGroup = isg;     /* may be NULL */
586         return(type);
587 }
588
589 /*
590  * AllocClassType() - allocate a type representing a the semgroup which
591  *                      in turn represents (typically) a class.
592  */
593 Type *
594 AllocClassType(typelist_t *list, Type *super, SemGroup *sg, int visibility)
595 {
596         Type *type;
597
598         dassert(sg != NULL);
599         list = &sg->sg_ClassList;
600
601         RUNE_FOREACH(type, list, ty_Node) {
602                 if (type->ty_Op == TY_CLASS &&
603                     type->ty_ClassType.et_SemGroup == sg &&
604                     type->ty_ClassType.et_Super == super &&
605                     type->ty_Visibility == visibility
606                 ) {
607                         return(type);
608                 }
609         }
610         if (sg)
611                 dassert(&sg->sg_ClassList == list);
612         type = AllocType(list, TY_CLASS);
613         type->ty_ClassType.et_SemGroup = sg;
614         type->ty_ClassType.et_Super = super;
615         type->ty_Visibility = visibility;
616         return(type);
617 }
618
619 static
620 void
621 initInternalClassType(Type *type, Declaration *d)
622 {
623         SemGroup *sg = d->d_ClassDecl.ed_SemGroup;
624
625         initType(type, &sg->sg_ClassList, TY_CLASS);
626         RUNE_REMOVE(&sg->sg_ClassList, type, ty_Node);
627         RUNE_INSERT_HEAD(&sg->sg_ClassList, type, ty_Node);
628         type->ty_ClassType.et_SemGroup = d->d_ClassDecl.ed_SemGroup;
629         type->ty_ClassType.et_Super = d->d_ClassDecl.ed_Super;
630         type->ty_Visibility = d->d_ScopeFlags & SCOPE_ALL_VISIBLE;
631         type->ty_Flags |= TF_ISINTERNAL;
632 }
633
634 Type *
635 AllocImportType(typelist_t *list, SemGroup *sg, int visibility)
636 {
637         Type *type = AllocType(list, TY_IMPORT);
638
639         type->ty_ImportType.et_SemGroup = sg;
640         type->ty_Visibility = visibility;
641         return(type);
642 }
643
644 /*
645  * adjtype must be moved to type's QList because type is being modified
646  * such that that is where it is expected to be.
647  */
648 Type *
649 TypeAdjustQList(Type *type, Type *adjtype)
650 {
651         if (adjtype) {
652                 if (adjtype->ty_SQList)
653                         RUNE_REMOVE(adjtype->ty_SQList, adjtype, ty_Node);
654                 adjtype->ty_SQList = &type->ty_QList;
655                 RUNE_INSERT_TAIL(adjtype->ty_SQList, adjtype, ty_Node);
656         }
657         return type;
658 }
659
660 /*
661  * Compound types inherit locking modes if not specifically
662  * overridden.
663  */
664 Type *
665 TypeFixupInheritedFlags(Type *type, int rqflags)
666 {
667         SemGroup *sg;
668         Declaration *d;
669
670         if (type->ty_Op != TY_COMPOUND)
671                 return type;
672
673         /*
674          * Assume no matching collapse yet
675          */
676         sg = type->ty_CompType.et_SemGroup;
677         RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
678                 if (d->d_Op != DOP_GROUP_STORAGE)
679                         continue;
680                 if ((d->d_ScopeFlags & SCOPE_LOCKING_MASK) == 0) {
681                         if (rqflags & SF_UNTRACKED)
682                                 d->d_ScopeFlags |= SCOPE_UNTRACKED;
683                         if (rqflags & SF_UNLOCKED)
684                                 d->d_ScopeFlags |= SCOPE_UNLOCKED;
685                         if (rqflags & SF_SOFT)
686                                 d->d_ScopeFlags |= SCOPE_SOFT;
687                         if (rqflags & SF_HARD)
688                                 d->d_ScopeFlags |= SCOPE_HARD;
689                 }
690         }
691         return type;
692 }
693
694 Type *
695 TypeToQualType(Type *otype, Type *ntype, int sqFlags, Exp *exp)
696 {
697         SemGroup *sg;
698
699         /*
700          * Combine with existing qualifiers, Shortcut if no changes made.
701          */
702         if (ntype == NULL && 
703             sqFlags == otype->ty_SQFlags &&
704             (exp == NULL || exp == otype->ty_AssExp)
705         ) {
706                 return(otype);
707         }
708
709         /*
710          * See if we already have a matching qualified type (only if storage
711          * for the new type is not being provided).  Note: the provided storage
712          * has already been initType()d
713          */
714         if (ntype == NULL) {
715                 RUNE_FOREACH(ntype, otype->ty_SQList, ty_Node) {
716                         if (ntype->ty_Op == otype->ty_Op && 
717                             ntype->ty_SQFlags == sqFlags &&
718                             (exp == NULL || ntype->ty_AssExp == exp)
719                         ) {
720                                 if (SameType(ntype, otype, sqFlags))
721                                         return(ntype);
722                         }
723                 }
724         }
725
726         /*
727          * Build a new qualified type and set its qualifiers, then duplicate
728          * appropriate sections of the old type.
729          *
730          * Default to the same SQList as otype.
731          */
732         if (ntype == NULL) {
733                 ntype = AllocType(otype->ty_SQList, otype->ty_Op);
734         } else {
735                 if (ntype->ty_SQList)
736                         RUNE_REMOVE(ntype->ty_SQList, ntype, ty_Node);
737                 ntype->ty_SQList = otype->ty_SQList;
738                 RUNE_INSERT_TAIL(ntype->ty_SQList, ntype, ty_Node);
739         }
740
741         /*
742          * Set the op and the expression.  Unlike SQFlags, if exp is passed as
743          * NULL we inherit the old type's default.
744          *
745          * The DupExp() call here is special, see DupExp()'s handling of
746          * ex_Decl.
747          *
748          * Normally DupExp() is called during resolution prior to ex_Decl
749          * being set.  This is the one case where it may be called with
750          * ex_Decl already set.
751          *
752          * WARNING! We do not try to resolve the type here.  Various resolve
753          *          related flags in ty_Flags will be resolved later.  This
754          *          includes TF_ISUNSIGNED and other TF_* flags.
755          */
756         ntype->ty_Op = otype->ty_Op;
757         if (exp)
758                 ntype->ty_AssExp = exp;
759         else if (otype->ty_AssExp)
760                 ntype->ty_AssExp = SetDupExp(NULL, otype->ty_AssExp);
761         ntype->ty_SQFlags = sqFlags;
762         ntype->ty_Visibility = otype->ty_Visibility;
763
764         switch(otype->ty_Op) {
765         case TY_CLASS:
766                 /*
767                  * When updating the class, alternative forms are collapsed
768                  * into it's SemGroup->sg_ClassList and not into some
769                  * potentially long recursive chain based on ty_QList.
770                  */
771                 sg = otype->ty_ClassType.et_SemGroup;
772
773                 dassert(ntype->ty_SQList == &sg->sg_ClassList);
774                 if (ntype->ty_ClassType.et_SemGroup != sg) {
775                         ntype->ty_ClassType.et_SemGroup = sg;
776                 }
777                 ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
778                 break;
779         case TY_IMPORT:
780                 ntype->ty_Visibility = otype->ty_Visibility;
781                 ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
782                 break;
783         case TY_CPTRTO:
784                 ntype->ty_CPtrType.et_Type = otype->ty_CPtrType.et_Type;
785                 break;
786         case TY_PTRTO:
787                 ntype->ty_PtrType.et_Type = otype->ty_PtrType.et_Type;
788                 break;
789         case TY_REFTO:
790                 ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
791                 break;
792         case TY_ARYOF:
793                 /*
794                  * note: multiple type structures may share the same array size
795                  * expression in simple qualified-type cases.  YYY XXX bad bad.
796                  */
797                 ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
798                 ntype->ty_AryType.et_ArySize = otype->ty_AryType.et_ArySize;
799                 ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
800                 ntype->ty_AryType.et_Count = otype->ty_AryType.et_Count;
801                 break;
802         case TY_COMPOUND:
803                 ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
804                 break;
805         case TY_VAR:
806                 ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
807                 ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
808                 break;
809         case TY_ARGS:
810                 ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
811                 break;
812         case TY_PROC:
813                 ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
814                 ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
815                 ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
816                 dassert(ntype->ty_SQList ==
817                         &otype->ty_ProcType.et_RetType->ty_QList);
818                 break;
819         case TY_STORAGE:
820                 ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
821                 break;
822         case TY_DYNAMIC:
823                 /*
824                  * It is not legal to qualify a dynamic type other then to
825                  * add or remove SF_LVALUE.
826                  */
827                 dpanic("Dynamic type cannot be qualified");
828                 break;
829         case TY_UNRESOLVED:
830                 ntype->ty_UnresType.et_DottedId =
831                         otype->ty_UnresType.et_DottedId;
832                 ntype->ty_UnresType.et_SemGroup =
833                         otype->ty_UnresType.et_SemGroup;
834                 ntype->ty_UnresType.et_ImportSemGroup =
835                         otype->ty_UnresType.et_ImportSemGroup;
836                 break;
837         default:
838                 dassert_type(otype, 0);
839         }
840         return(ntype);
841 }
842
843 /*
844  * Convert a return-type + argument-type into a procedure type.  If
845  * adjret is non-zero the return-type is converted to locked storage
846  * (which is generally what we want).
847  *
848  * Match the procedure type(s) (after adjustment?)
849  */
850 Type *
851 TypeToProcType(Type *rtype, Type *atype, int adjret)
852 {
853         Type *type;
854         runesize_t count = 0;
855         Declaration *d;
856         SemGroup *sg;
857
858         dassert_type(atype, atype->ty_Op == TY_ARGS);
859
860         if (adjret)
861                 rtype = TypeFixupInheritedFlags(rtype, rtype->ty_SQFlags);
862
863         sg = atype->ty_CompType.et_SemGroup;
864
865         RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
866                 ++count;
867         }
868         RUNE_FOREACH(type, &rtype->ty_QList, ty_Node) {
869                 if (type->ty_Op == TY_PROC) {
870                         if (type->ty_ProcType.et_ArgsType == atype &&
871                             type->ty_ProcType.et_RetType == rtype &&
872                             type->ty_ProcType.et_ArgCount == count
873                         ) {
874                                 return(type);
875                         }
876                 }
877         }
878         type = AllocType(&rtype->ty_QList, TY_PROC);
879         type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
880         type->ty_ProcType.et_RetType = rtype;
881         type->ty_ProcType.et_ArgCount = count;
882         return(type);
883 }
884
885 /*
886  * Convert type to pointer-to-type
887  */
888 Type *
889 TypeToPtrType(Type *otype)
890 {
891         Type *type;
892
893         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
894                 if (type->ty_Op == TY_PTRTO)
895                         return(type);
896         }
897         type = AllocType(&otype->ty_QList, TY_PTRTO);
898         type->ty_PtrType.et_Type = otype;
899         return(type);
900 }
901
902 /*
903  * Convert type to pointer-to-type
904  */
905 Type *
906 TypeToCPtrType(Type *otype)
907 {
908         Type *type;
909
910         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
911                 if (type->ty_Op == TY_CPTRTO)
912                         return(type);
913         }
914         type = AllocType(&otype->ty_QList, TY_CPTRTO);
915         type->ty_CPtrType.et_Type = otype;
916         return(type);
917 }
918
919 /*
920  * Convert type to ref-to-type
921  *
922  *      A reference type is similar to a pointer type except that the
923  *      resolver is not able to entirely know what it is pointing to.
924  *      The reference type is a superclass, but the actual type is 
925  *      stored in the run-time structure.
926  */
927 Type *
928 TypeToRefType(Type *otype)
929 {
930         Type *type;
931
932         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
933                 if (type->ty_Op == TY_REFTO)
934                         return(type);
935         }
936         type = AllocType(&otype->ty_QList, TY_REFTO);
937         type->ty_RefType.et_Type = otype;
938         return(type);
939 }
940
941 Type *
942 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
943 {
944         Type *type;
945
946         /*
947          * XXX handle constant expression optimization for QList
948          * XXX handle qualifiers
949          */
950         type = AllocType(&otype->ty_QList, TY_ARYOF);
951         type->ty_AryType.et_ArySize = exp;
952         type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
953         type->ty_AryType.et_SemGroup = sg;
954         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
955         return(type);
956 }
957
958 #if 0
959
960 Type *
961 TypeToRunTimeAryType(Type *otype, int count)
962 {
963         Type *type;
964         Type *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
965
966         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
967                 if (type->ty_Op == TY_ARYOF &&
968                         type->ty_AryType.et_Type == t2 &&
969                         type->ty_AryType.et_Count == count &&
970                         type->ty_SQFlags ==
971                          (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
972                 ) {
973                         return(type);
974                 }
975         }
976         type = AllocType(&otype->ty_QList, TY_ARYOF);
977         type->ty_AryType.et_Count = count;
978         type->ty_AryType.et_Type = t2;
979         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
980         return(type);
981 }
982
983 #endif
984
985 Type *
986 TypeToVarType(Type *otype, SemGroup *sg)
987 {
988         Type *type;
989
990         /*dassert(sg->sg_Flags & SGF_RESOLVED);*/
991         /*dassert(otype->ty_Flags & TF_RESOLVED);*/
992
993         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
994                 if (type->ty_Op == TY_VAR &&
995                     type->ty_VarType.et_Type == otype &&
996                     type->ty_VarType.et_SemGroup == sg
997                 ) {
998                         puts("SG2"); /* YYY */
999                         return(type);
1000                 }
1001         }
1002         type = AllocType(&otype->ty_QList, TY_VAR);
1003         type->ty_VarType.et_Type = otype;
1004         type->ty_VarType.et_SemGroup = sg;
1005 #if 0
1006         /* XXX doesn't work for var-args */
1007         if (sg->sg_Flags & SGF_RESOLVED) {
1008                 type->ty_Flags |= TF_RESOLVED;
1009                 type->ty_Bytes = sg->sg_Bytes;
1010                 type->ty_AlignMask = sg->sg_AlignMask;
1011         }
1012 #endif
1013         return(type);
1014 }
1015
1016 /*
1017  * ChangeType() - given pointer, C pointer, or array of something,
1018  *                return 'op' of something instead.
1019  */
1020 Type *
1021 ChangeType(Type *type, int op)
1022 {
1023         switch(type->ty_Op) {
1024         case TY_PTRTO:
1025                 switch(op) {
1026                 case TY_CPTRTO:
1027                         type = TypeToCPtrType(type->ty_PtrType.et_Type);
1028                         break;
1029                 case TY_ARYOF:
1030                         type = TypeToAryType(type->ty_PtrType.et_Type,
1031                                              NULL, NULL);
1032                         break;
1033                 default:
1034                         dpanic("Illegal type convesion (A)");
1035                 }
1036                 break;
1037         case TY_CPTRTO:
1038                 switch(op) {
1039                 case TY_PTRTO:
1040                         type = TypeToPtrType(type->ty_CPtrType.et_Type);
1041                         break;
1042                 case TY_ARYOF:
1043                         type = TypeToAryType(type->ty_CPtrType.et_Type,
1044                                              NULL, NULL);
1045                         break;
1046                 default:
1047                         dpanic("Illegal type convesion (B)");
1048                 }
1049                 break;
1050         case TY_ARYOF:
1051                 switch(op) {
1052                 case TY_PTRTO:
1053                         type = TypeToPtrType(type->ty_AryType.et_Type);
1054                         break;
1055                 case TY_CPTRTO:
1056                         type = TypeToCPtrType(type->ty_AryType.et_Type);
1057                         break;
1058                 default:
1059                         dpanic("Illegal type convesion (C)");
1060                 }
1061                 break;
1062         default:
1063                 dpanic("Illegal type convesion (D)");
1064         }
1065         return(type);
1066 }
1067
1068 /*
1069  * BaseType() - return base type
1070  *
1071  *      Traverse the type to locate the base type.  Store the base type
1072  *      in *ptype and return the SemGroup, or return NULL if the base type
1073  *      does not have a SemGroup.
1074  */
1075 SemGroup *
1076 BaseType(Type **ptype)
1077 {
1078         Type *type = *ptype;
1079
1080         for (;;) {
1081                 switch(type->ty_Op) {
1082                 case TY_CPTRTO:
1083                         type = type->ty_CPtrType.et_Type;
1084                         continue;
1085                 case TY_PTRTO:
1086                         type = type->ty_PtrType.et_Type;
1087                         continue;
1088                 case TY_REFTO:
1089                         type = type->ty_RefType.et_Type;
1090                         continue;
1091                 case TY_ARYOF:
1092                         type = type->ty_AryType.et_Type;
1093                         continue;
1094                 }
1095                 break;
1096         }
1097
1098         *ptype = type;
1099
1100         switch(type->ty_Op) {
1101         case TY_CLASS:
1102                 return(type->ty_ClassType.et_SemGroup);
1103         case TY_COMPOUND:
1104                 return(type->ty_CompType.et_SemGroup);
1105         case TY_ARGS:
1106                 return(type->ty_ArgsType.et_SemGroup);
1107         case TY_PROC:
1108         case TY_VAR:
1109         case TY_DYNAMIC:
1110         case TY_STORAGE:
1111                 return(NULL);
1112         case TY_UNRESOLVED:
1113         default:
1114                 dassert_type(type, 0);
1115                 return(NULL);   /* avoid compiler complaints */
1116         }
1117 }
1118
1119 /*
1120  * DupType()     - create a duplicate of a type, possibly in a new SemGroup.
1121  *
1122  *      This code is used when duplicating procedures and other elements
1123  *      when merging a superclass into a subclass.
1124  *
1125  *      If sg is NULL, stype is simply returned.  The case is used when we
1126  *      try to duplciate an expression with DupExp()... in that case we
1127  *      want to dup the expression tree but use the same types.
1128  */
1129 Type *
1130 DupType(SemGroup *sg, Type *stype)
1131 {
1132         Type *type = NULL;
1133
1134         if (sg == NULL)
1135                 return(stype);
1136
1137         /*
1138          * XXX type may be resolved if it is part of a varargs dup
1139          */
1140 #if 0
1141         dassert_type(stype,
1142                      (stype->ty_Flags & (TF_RESOLVED|TF_RESOLVING)) == 0);
1143 #endif
1144
1145         switch(stype->ty_Op) {
1146         case TY_CLASS:
1147                 /*
1148                  * This only occurs because the resolver has resolved an
1149                  * unresolved type on the original SemGroup.  We duplicate
1150                  * that on the new SemGroup.
1151                  */
1152                 type = AllocClassType(&sg->sg_ClassList,
1153                                       stype->ty_ClassType.et_Super,
1154                                       stype->ty_ClassType.et_SemGroup,
1155                                       stype->ty_Visibility);
1156                 break;
1157         case TY_IMPORT:
1158         case TY_DYNAMIC:
1159                 type = stype;
1160                 break;
1161         case TY_CPTRTO:
1162                 type = TypeToCPtrType(DupType(sg, stype->ty_CPtrType.et_Type));
1163                 break;
1164         case TY_PTRTO:
1165                 type = TypeToPtrType(DupType(sg, stype->ty_PtrType.et_Type));
1166                 break;
1167         case TY_REFTO:
1168                 type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1169                 break;
1170         case TY_ARYOF:
1171                 type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1172                                 SetDupExp(sg, stype->ty_AryType.et_ArySize),
1173                                 stype->ty_AryType.et_SemGroup);
1174                 type->ty_AryType.et_Count = stype->ty_AryType.et_Count;
1175                 break;
1176         case TY_VAR:
1177                 type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1178                                 DupSemGroup(sg, NULL,
1179                                             stype->ty_VarType.et_SemGroup, 1));
1180                 break;
1181         case TY_COMPOUND:
1182                 type = AllocCompoundType(
1183                                 DupSemGroup(sg, NULL,
1184                                             stype->ty_CompType.et_SemGroup, 1));
1185                 break;
1186         case TY_ARGS:
1187                 /*
1188                  * At the moment we always formally duplicate the arguments
1189                  * so we can modify them for methods below.
1190                  */
1191                 type = AllocArgsType(
1192                                 DupSemGroup(sg, NULL,
1193                                             stype->ty_CompType.et_SemGroup, 1));
1194                 break;
1195         case TY_PROC:
1196                 type = DupType(sg, stype->ty_ProcType.et_RetType);
1197                 type = TypeToProcType(type,
1198                                   DupType(sg, stype->ty_ProcType.et_ArgsType),
1199                                       1);
1200
1201                 /*
1202                  * If this is a method procedure, we have to change the
1203                  * first argument to point at our new subclass.  It was
1204                  * previously pointing at our superclass.   XXX the
1205                  * programmer can override the argument.  If it isn't a
1206                  * reference we have to assert.
1207                  */
1208                 if (sg->sg_Stmt->st_Op != ST_Class) {
1209                         /*
1210                          * XXX probably an inlined procedure, the type is
1211                          *     already correct.  Need an assertrion here.
1212                          */
1213                 } else if (stype->ty_SQFlags & SF_METHOD) {
1214                         SemGroup *asg = type->ty_ProcType.et_ArgsType->ty_ArgsType.et_SemGroup;
1215                         Declaration *d = RUNE_FIRST(&asg->sg_DeclList);
1216                         Type *thisType = d->d_StorDecl.ed_Type;
1217
1218                         dassert_decl(d, d->d_Id == String_This &&
1219                                         d->d_Op == DOP_ARGS_STORAGE);
1220                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1221                         if (thisType->ty_Op == TY_CLASS) {
1222                                 /* XXX sg_ClassList? right sg? */
1223                                 /* XXX correct visibility? */
1224                                 if (d->d_Search == NULL) {
1225                                         d->d_Search = d->d_StorDecl.ed_Type->
1226                                                       ty_ClassType.et_SemGroup;
1227                                 }
1228                                 d->d_StorDecl.ed_Type =
1229                                         AllocClassType(&sg->sg_ClassList,
1230                                                        sg->sg_Stmt->st_ClassStmt.es_Super,
1231                                                        sg->sg_Stmt->st_MyGroup,
1232                                                        SCOPE_ALL_VISIBLE);
1233                         } else {
1234                                 dassert_decl(d, thisType->ty_Op == TY_REFTO);
1235                         }
1236                 } else if (stype->ty_SQFlags & SF_GMETHOD) {
1237                         SemGroup *asg;
1238                         Declaration *d;
1239
1240                         asg = type->ty_ProcType.et_ArgsType->
1241                                 ty_ArgsType.et_SemGroup;
1242                         d = RUNE_FIRST(&asg->sg_DeclList);
1243
1244                         dassert_decl(d, d->d_Id == String_This &&
1245                                      d->d_Op == DOP_TYPEDEF);
1246                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1247                         dassert_decl(d, d->d_TypedefDecl.ed_Type->ty_Op ==
1248                                         TY_CLASS);
1249                         /* XXX sg_ClassList? right sg? */
1250                         /* XXX correct visibility? */
1251                         if (d->d_Search == NULL) {
1252                                 d->d_Search = d->d_TypedefDecl.ed_Type->
1253                                                ty_ClassType.et_SemGroup;
1254                         }
1255                         d->d_TypedefDecl.ed_Type =
1256                                 AllocClassType(&sg->sg_ClassList,
1257                                                sg->sg_Stmt->st_ClassStmt.es_Super,
1258                                                sg->sg_Stmt->st_MyGroup,
1259                                                SCOPE_ALL_VISIBLE);
1260                 }
1261                 break;
1262         case TY_STORAGE:
1263                 type = stype;
1264                 break;
1265         case TY_UNRESOLVED:
1266                 /*
1267                  * e.g. so elements in a superclass will see refined elements
1268                  * in the subclass.  Note that the original import semgroup
1269                  * is left intact so the semantic search mechanism uses it
1270                  * when the base sg (typically a subclass) fails.
1271                  */
1272                 type = AllocUnresolvedType(
1273                                 stype->ty_UnresType.et_ImportSemGroup,
1274                                 sg,
1275                                 stype->ty_UnresType.et_DottedId,
1276                                 0);
1277                 break;
1278         default:
1279                 dassert_type(stype, 0);
1280         }
1281
1282         if (type != stype) {
1283                 type->ty_Flags = stype->ty_Flags &
1284                                  ~(TF_ISINTERNAL | TF_RESOLVING | TF_RESOLVED |
1285                                    TF_ALIGNRESOLVED | TF_TMPRESOLVED);
1286                 type->ty_Bytes = stype->ty_Bytes;
1287                 type->ty_AlignMask = stype->ty_AlignMask;
1288                 type->ty_Visibility = stype->ty_Visibility;
1289                 type->ty_DynamicVector = stype->ty_DynamicVector;
1290         }
1291         if (stype->ty_AssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1292                 type = TypeToQualType(type, NULL,
1293                                       stype->ty_SQFlags,
1294                                       SetDupExp(sg, stype->ty_AssExp));
1295         }
1296
1297         return(type);
1298 }
1299
1300 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1301
1302 void
1303 InternalRegisterType(const char *str, const char *linkname, Type *type)
1304 {
1305         static int Special = SPECIALF_REGISTERED|SPECIALF_INTERNAL|1;
1306         TypeRegNode *tr;
1307
1308         dassert(Special & SPECIALF_MASK);
1309         tr = zalloc(sizeof(TypeRegNode));
1310         tr->tr_Id = StrTableAlloc(str, strlen(str), Special++);
1311         tr->tr_Type = type;
1312         tr->tr_LinkName = linkname;
1313         RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1314 }
1315
1316 Type *
1317 InternalRegisteredTypeLookup(string_t id)
1318 {
1319         TypeRegNode *tr;
1320
1321         RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1322                 if (tr->tr_Id == id)
1323                         return(tr->tr_Type);
1324         }
1325         return(NULL);
1326 }