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