Rune - Add 'mpsafe'
[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  * Adjust the type to be locked storage.  Assumes that compound types
662  * have not been cached/collapsed (parse-time only).
663  */
664 Type *
665 TypeAdjustLockedStorage(Type *type)
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                 d->d_ScopeFlags &= ~(SCOPE_UNLOCKED | SCOPE_MPSAFE);
681         }
682         return type;
683 }
684
685 Type *
686 TypeToQualType(Type *otype, Type *ntype, int sqFlags, Exp *exp)
687 {
688         SemGroup *sg;
689
690         /*
691          * Combine with existing qualifiers, Shortcut if no changes made.
692          */
693         if (ntype == NULL && 
694             sqFlags == otype->ty_SQFlags &&
695             (exp == NULL || exp == otype->ty_AssExp)
696         ) {
697                 return(otype);
698         }
699
700         /*
701          * See if we already have a matching qualified type (only if storage
702          * for the new type is not being provided).  Note: the provided storage
703          * has already been initType()d
704          */
705         if (ntype == NULL) {
706                 RUNE_FOREACH(ntype, otype->ty_SQList, ty_Node) {
707                         if (ntype->ty_Op == otype->ty_Op && 
708                             ntype->ty_SQFlags == sqFlags &&
709                             (exp == NULL || ntype->ty_AssExp == exp)
710                         ) {
711                                 if (SameType(ntype, otype, sqFlags))
712                                         return(ntype);
713                         }
714                 }
715         }
716
717         /*
718          * Build a new qualified type and set its qualifiers, then duplicate
719          * appropriate sections of the old type.
720          *
721          * Default to the same SQList as otype.
722          */
723         if (ntype == NULL) {
724                 ntype = AllocType(otype->ty_SQList, otype->ty_Op);
725         } else {
726                 if (ntype->ty_SQList)
727                         RUNE_REMOVE(ntype->ty_SQList, ntype, ty_Node);
728                 ntype->ty_SQList = otype->ty_SQList;
729                 RUNE_INSERT_TAIL(ntype->ty_SQList, ntype, ty_Node);
730         }
731
732         /*
733          * Set the op and the expression.  Unlike SQFlags, if exp is passed as
734          * NULL we inherit the old type's default.
735          *
736          * The DupExp() call here is special, see DupExp()'s handling of
737          * ex_Decl.
738          *
739          * Normally DupExp() is called during resolution prior to ex_Decl
740          * being set.  This is the one case where it may be called with
741          * ex_Decl already set.
742          *
743          * WARNING! We do not try to resolve the type here.  Various resolve
744          *          related flags in ty_Flags will be resolved later.  This
745          *          includes TF_ISUNSIGNED and other TF_* flags.
746          */
747         ntype->ty_Op = otype->ty_Op;
748         if (exp)
749                 ntype->ty_AssExp = exp;
750         else if (otype->ty_AssExp)
751                 ntype->ty_AssExp = SetDupExp(NULL, otype->ty_AssExp);
752         ntype->ty_SQFlags = sqFlags;
753         ntype->ty_Visibility = otype->ty_Visibility;
754
755         switch(otype->ty_Op) {
756         case TY_CLASS:
757                 /*
758                  * When updating the class, alternative forms are collapsed
759                  * into it's SemGroup->sg_ClassList and not into some
760                  * potentially long recursive chain based on ty_QList.
761                  */
762                 sg = otype->ty_ClassType.et_SemGroup;
763
764                 dassert(ntype->ty_SQList == &sg->sg_ClassList);
765                 if (ntype->ty_ClassType.et_SemGroup != sg) {
766                         ntype->ty_ClassType.et_SemGroup = sg;
767                 }
768                 ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
769                 break;
770         case TY_IMPORT:
771                 ntype->ty_Visibility = otype->ty_Visibility;
772                 ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
773                 break;
774         case TY_CPTRTO:
775                 ntype->ty_CPtrType.et_Type = otype->ty_CPtrType.et_Type;
776                 break;
777         case TY_PTRTO:
778                 ntype->ty_PtrType.et_Type = otype->ty_PtrType.et_Type;
779                 break;
780         case TY_REFTO:
781                 ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
782                 break;
783         case TY_ARYOF:
784                 /*
785                  * note: multiple type structures may share the same array size
786                  * expression in simple qualified-type cases.  YYY XXX bad bad.
787                  */
788                 ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
789                 ntype->ty_AryType.et_ArySize = otype->ty_AryType.et_ArySize;
790                 ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
791                 ntype->ty_AryType.et_Count = otype->ty_AryType.et_Count;
792                 break;
793         case TY_COMPOUND:
794                 ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
795                 break;
796         case TY_VAR:
797                 ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
798                 ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
799                 break;
800         case TY_ARGS:
801                 ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
802                 break;
803         case TY_PROC:
804                 ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
805                 ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
806                 ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
807                 dassert(ntype->ty_SQList ==
808                         &otype->ty_ProcType.et_RetType->ty_QList);
809                 break;
810         case TY_STORAGE:
811                 ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
812                 break;
813         case TY_DYNAMIC:
814                 /*
815                  * It is not legal to qualify a dynamic type other then to
816                  * add or remove SF_LVALUE.
817                  */
818                 dpanic("Dynamic type cannot be qualified");
819                 break;
820         case TY_UNRESOLVED:
821                 ntype->ty_UnresType.et_DottedId =
822                         otype->ty_UnresType.et_DottedId;
823                 ntype->ty_UnresType.et_SemGroup =
824                         otype->ty_UnresType.et_SemGroup;
825                 ntype->ty_UnresType.et_ImportSemGroup =
826                         otype->ty_UnresType.et_ImportSemGroup;
827                 break;
828         default:
829                 dassert_type(otype, 0);
830         }
831         return(ntype);
832 }
833
834 /*
835  * Convert a return-type + argument-type into a procedure type.  If
836  * adjret is non-zero the return-type is converted to locked storage
837  * (which is generally what we want).
838  *
839  * Match the procedure type(s) (after adjustment?)
840  */
841 Type *
842 TypeToProcType(Type *rtype, Type *atype, int adjret)
843 {
844         Type *type;
845         runesize_t count = 0;
846         Declaration *d;
847         SemGroup *sg;
848
849         dassert_type(atype, atype->ty_Op == TY_ARGS);
850
851         if (adjret)
852                 rtype = TypeAdjustLockedStorage(rtype);
853
854         sg = atype->ty_CompType.et_SemGroup;
855
856         RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
857                 ++count;
858         }
859         RUNE_FOREACH(type, &rtype->ty_QList, ty_Node) {
860                 if (type->ty_Op == TY_PROC) {
861                         if (type->ty_ProcType.et_ArgsType == atype &&
862                             type->ty_ProcType.et_RetType == rtype &&
863                             type->ty_ProcType.et_ArgCount == count
864                         ) {
865                                 return(type);
866                         }
867                 }
868         }
869         type = AllocType(&rtype->ty_QList, TY_PROC);
870         type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
871         type->ty_ProcType.et_RetType = rtype;
872         type->ty_ProcType.et_ArgCount = count;
873         return(type);
874 }
875
876 /*
877  * Convert type to pointer-to-type
878  */
879 Type *
880 TypeToPtrType(Type *otype)
881 {
882         Type *type;
883
884         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
885                 if (type->ty_Op == TY_PTRTO)
886                         return(type);
887         }
888         type = AllocType(&otype->ty_QList, TY_PTRTO);
889         type->ty_PtrType.et_Type = otype;
890         return(type);
891 }
892
893 /*
894  * Convert type to pointer-to-type
895  */
896 Type *
897 TypeToCPtrType(Type *otype)
898 {
899         Type *type;
900
901         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
902                 if (type->ty_Op == TY_CPTRTO)
903                         return(type);
904         }
905         type = AllocType(&otype->ty_QList, TY_CPTRTO);
906         type->ty_CPtrType.et_Type = otype;
907         return(type);
908 }
909
910 /*
911  * Convert type to ref-to-type
912  *
913  *      A reference type is similar to a pointer type except that the
914  *      resolver is not able to entirely know what it is pointing to.
915  *      The reference type is a superclass, but the actual type is 
916  *      stored in the run-time structure.
917  */
918 Type *
919 TypeToRefType(Type *otype)
920 {
921         Type *type;
922
923         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
924                 if (type->ty_Op == TY_REFTO)
925                         return(type);
926         }
927         type = AllocType(&otype->ty_QList, TY_REFTO);
928         type->ty_RefType.et_Type = otype;
929         return(type);
930 }
931
932 Type *
933 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
934 {
935         Type *type;
936
937         /*
938          * XXX handle constant expression optimization for QList
939          * XXX handle qualifiers
940          */
941         type = AllocType(&otype->ty_QList, TY_ARYOF);
942         type->ty_AryType.et_ArySize = exp;
943         type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
944         type->ty_AryType.et_SemGroup = sg;
945         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
946         return(type);
947 }
948
949 #if 0
950
951 Type *
952 TypeToRunTimeAryType(Type *otype, int count)
953 {
954         Type *type;
955         Type *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
956
957         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
958                 if (type->ty_Op == TY_ARYOF &&
959                         type->ty_AryType.et_Type == t2 &&
960                         type->ty_AryType.et_Count == count &&
961                         type->ty_SQFlags ==
962                          (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
963                 ) {
964                         return(type);
965                 }
966         }
967         type = AllocType(&otype->ty_QList, TY_ARYOF);
968         type->ty_AryType.et_Count = count;
969         type->ty_AryType.et_Type = t2;
970         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
971         return(type);
972 }
973
974 #endif
975
976 Type *
977 TypeToVarType(Type *otype, SemGroup *sg)
978 {
979         Type *type;
980
981         /*dassert(sg->sg_Flags & SGF_RESOLVED);*/
982         /*dassert(otype->ty_Flags & TF_RESOLVED);*/
983
984         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
985                 if (type->ty_Op == TY_VAR &&
986                     type->ty_VarType.et_Type == otype &&
987                     type->ty_VarType.et_SemGroup == sg
988                 ) {
989                         puts("SG2"); /* YYY */
990                         return(type);
991                 }
992         }
993         type = AllocType(&otype->ty_QList, TY_VAR);
994         type->ty_VarType.et_Type = otype;
995         type->ty_VarType.et_SemGroup = sg;
996 #if 0
997         /* XXX doesn't work for var-args */
998         if (sg->sg_Flags & SGF_RESOLVED) {
999                 type->ty_Flags |= TF_RESOLVED;
1000                 type->ty_Bytes = sg->sg_Bytes;
1001                 type->ty_AlignMask = sg->sg_AlignMask;
1002         }
1003 #endif
1004         return(type);
1005 }
1006
1007 /*
1008  * ChangeType() - given pointer, C pointer, or array of something,
1009  *                return 'op' of something instead.
1010  */
1011 Type *
1012 ChangeType(Type *type, int op)
1013 {
1014         switch(type->ty_Op) {
1015         case TY_PTRTO:
1016                 switch(op) {
1017                 case TY_CPTRTO:
1018                         type = TypeToCPtrType(type->ty_PtrType.et_Type);
1019                         break;
1020                 case TY_ARYOF:
1021                         type = TypeToAryType(type->ty_PtrType.et_Type,
1022                                              NULL, NULL);
1023                         break;
1024                 default:
1025                         dpanic("Illegal type convesion (A)");
1026                 }
1027                 break;
1028         case TY_CPTRTO:
1029                 switch(op) {
1030                 case TY_PTRTO:
1031                         type = TypeToPtrType(type->ty_CPtrType.et_Type);
1032                         break;
1033                 case TY_ARYOF:
1034                         type = TypeToAryType(type->ty_CPtrType.et_Type,
1035                                              NULL, NULL);
1036                         break;
1037                 default:
1038                         dpanic("Illegal type convesion (B)");
1039                 }
1040                 break;
1041         case TY_ARYOF:
1042                 switch(op) {
1043                 case TY_PTRTO:
1044                         type = TypeToPtrType(type->ty_AryType.et_Type);
1045                         break;
1046                 case TY_CPTRTO:
1047                         type = TypeToCPtrType(type->ty_AryType.et_Type);
1048                         break;
1049                 default:
1050                         dpanic("Illegal type convesion (C)");
1051                 }
1052                 break;
1053         default:
1054                 dpanic("Illegal type convesion (D)");
1055         }
1056         return(type);
1057 }
1058
1059 /*
1060  * BaseType() - return base type
1061  *
1062  *      Traverse the type to locate the base type.  Store the base type
1063  *      in *ptype and return the SemGroup, or return NULL if the base type
1064  *      does not have a SemGroup.
1065  */
1066 SemGroup *
1067 BaseType(Type **ptype)
1068 {
1069         Type *type = *ptype;
1070
1071         for (;;) {
1072                 switch(type->ty_Op) {
1073                 case TY_CPTRTO:
1074                         type = type->ty_CPtrType.et_Type;
1075                         continue;
1076                 case TY_PTRTO:
1077                         type = type->ty_PtrType.et_Type;
1078                         continue;
1079                 case TY_REFTO:
1080                         type = type->ty_RefType.et_Type;
1081                         continue;
1082                 case TY_ARYOF:
1083                         type = type->ty_AryType.et_Type;
1084                         continue;
1085                 }
1086                 break;
1087         }
1088
1089         *ptype = type;
1090
1091         switch(type->ty_Op) {
1092         case TY_CLASS:
1093                 return(type->ty_ClassType.et_SemGroup);
1094         case TY_COMPOUND:
1095                 return(type->ty_CompType.et_SemGroup);
1096         case TY_ARGS:
1097                 return(type->ty_ArgsType.et_SemGroup);
1098         case TY_PROC:
1099         case TY_VAR:
1100         case TY_DYNAMIC:
1101         case TY_STORAGE:
1102                 return(NULL);
1103         case TY_UNRESOLVED:
1104         default:
1105                 dassert_type(type, 0);
1106                 return(NULL);   /* avoid compiler complaints */
1107         }
1108 }
1109
1110 /*
1111  * DupType()     - create a duplicate of a type, possibly in a new SemGroup.
1112  *
1113  *      This code is used when duplicating procedures and other elements
1114  *      when merging a superclass into a subclass.
1115  *
1116  *      If sg is NULL, stype is simply returned.  The case is used when we
1117  *      try to duplciate an expression with DupExp()... in that case we
1118  *      want to dup the expression tree but use the same types.
1119  */
1120 Type *
1121 DupType(SemGroup *sg, Type *stype)
1122 {
1123         Type *type = NULL;
1124
1125         if (sg == NULL)
1126                 return(stype);
1127
1128         /*
1129          * XXX type may be resolved if it is part of a varargs dup
1130          */
1131 #if 0
1132         dassert_type(stype,
1133                      (stype->ty_Flags & (TF_RESOLVED|TF_RESOLVING)) == 0);
1134 #endif
1135
1136         switch(stype->ty_Op) {
1137         case TY_CLASS:
1138                 /*
1139                  * This only occurs because the resolver has resolved an
1140                  * unresolved type on the original SemGroup.  We duplicate
1141                  * that on the new SemGroup.
1142                  */
1143                 type = AllocClassType(&sg->sg_ClassList,
1144                                       stype->ty_ClassType.et_Super,
1145                                       stype->ty_ClassType.et_SemGroup,
1146                                       stype->ty_Visibility);
1147                 break;
1148         case TY_IMPORT:
1149         case TY_DYNAMIC:
1150                 type = stype;
1151                 break;
1152         case TY_CPTRTO:
1153                 type = TypeToCPtrType(DupType(sg, stype->ty_CPtrType.et_Type));
1154                 break;
1155         case TY_PTRTO:
1156                 type = TypeToPtrType(DupType(sg, stype->ty_PtrType.et_Type));
1157                 break;
1158         case TY_REFTO:
1159                 type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1160                 break;
1161         case TY_ARYOF:
1162                 type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1163                                 SetDupExp(sg, stype->ty_AryType.et_ArySize),
1164                                 stype->ty_AryType.et_SemGroup);
1165                 type->ty_AryType.et_Count = stype->ty_AryType.et_Count;
1166                 break;
1167         case TY_VAR:
1168                 type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1169                                 DupSemGroup(sg, NULL,
1170                                             stype->ty_VarType.et_SemGroup, 1));
1171                 break;
1172         case TY_COMPOUND:
1173                 type = AllocCompoundType(
1174                                 DupSemGroup(sg, NULL,
1175                                             stype->ty_CompType.et_SemGroup, 1));
1176                 break;
1177         case TY_ARGS:
1178                 /*
1179                  * At the moment we always formally duplicate the arguments
1180                  * so we can modify them for methods below.
1181                  */
1182                 type = AllocArgsType(
1183                                 DupSemGroup(sg, NULL,
1184                                             stype->ty_CompType.et_SemGroup, 1));
1185                 break;
1186         case TY_PROC:
1187                 type = DupType(sg, stype->ty_ProcType.et_RetType);
1188                 type = TypeToProcType(type,
1189                                   DupType(sg, stype->ty_ProcType.et_ArgsType),
1190                                       1);
1191
1192                 /*
1193                  * If this is a method procedure, we have to change the
1194                  * first argument to point at our new subclass.  It was
1195                  * previously pointing at our superclass.   XXX the
1196                  * programmer can override the argument.  If it isn't a
1197                  * reference we have to assert.
1198                  */
1199                 if (sg->sg_Stmt->st_Op != ST_Class) {
1200                         /*
1201                          * XXX probably an inlined procedure, the type is
1202                          *     already correct.  Need an assertrion here.
1203                          */
1204                 } else if (stype->ty_SQFlags & SF_METHOD) {
1205                         SemGroup *asg = type->ty_ProcType.et_ArgsType->ty_ArgsType.et_SemGroup;
1206                         Declaration *d = RUNE_FIRST(&asg->sg_DeclList);
1207                         Type *thisType = d->d_StorDecl.ed_Type;
1208
1209                         dassert_decl(d, d->d_Id == String_This &&
1210                                         d->d_Op == DOP_ARGS_STORAGE);
1211                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1212                         if (thisType->ty_Op == TY_CLASS) {
1213                                 /* XXX sg_ClassList? right sg? */
1214                                 /* XXX correct visibility? */
1215                                 if (d->d_Search == NULL) {
1216                                         d->d_Search = d->d_StorDecl.ed_Type->
1217                                                       ty_ClassType.et_SemGroup;
1218                                 }
1219                                 d->d_StorDecl.ed_Type =
1220                                         AllocClassType(&sg->sg_ClassList,
1221                                                        sg->sg_Stmt->st_ClassStmt.es_Super,
1222                                                        sg->sg_Stmt->st_MyGroup,
1223                                                        SCOPE_ALL_VISIBLE);
1224                         } else {
1225                                 dassert_decl(d, thisType->ty_Op == TY_REFTO);
1226                         }
1227                 } else if (stype->ty_SQFlags & SF_GMETHOD) {
1228                         SemGroup *asg;
1229                         Declaration *d;
1230
1231                         asg = type->ty_ProcType.et_ArgsType->
1232                                 ty_ArgsType.et_SemGroup;
1233                         d = RUNE_FIRST(&asg->sg_DeclList);
1234
1235                         dassert_decl(d, d->d_Id == String_This &&
1236                                      d->d_Op == DOP_TYPEDEF);
1237                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1238                         dassert_decl(d, d->d_TypedefDecl.ed_Type->ty_Op ==
1239                                         TY_CLASS);
1240                         /* XXX sg_ClassList? right sg? */
1241                         /* XXX correct visibility? */
1242                         if (d->d_Search == NULL) {
1243                                 d->d_Search = d->d_TypedefDecl.ed_Type->
1244                                                ty_ClassType.et_SemGroup;
1245                         }
1246                         d->d_TypedefDecl.ed_Type =
1247                                 AllocClassType(&sg->sg_ClassList,
1248                                                sg->sg_Stmt->st_ClassStmt.es_Super,
1249                                                sg->sg_Stmt->st_MyGroup,
1250                                                SCOPE_ALL_VISIBLE);
1251                 }
1252                 break;
1253         case TY_STORAGE:
1254                 type = stype;
1255                 break;
1256         case TY_UNRESOLVED:
1257                 /*
1258                  * e.g. so elements in a superclass will see refined elements
1259                  * in the subclass.  Note that the original import semgroup
1260                  * is left intact so the semantic search mechanism uses it
1261                  * when the base sg (typically a subclass) fails.
1262                  */
1263                 type = AllocUnresolvedType(
1264                                 stype->ty_UnresType.et_ImportSemGroup,
1265                                 sg,
1266                                 stype->ty_UnresType.et_DottedId,
1267                                 0);
1268                 break;
1269         default:
1270                 dassert_type(stype, 0);
1271         }
1272
1273         if (type != stype) {
1274                 type->ty_Flags = stype->ty_Flags &
1275                                  ~(TF_ISINTERNAL | TF_RESOLVING | TF_RESOLVED |
1276                                    TF_ALIGNRESOLVED | TF_TMPRESOLVED);
1277                 type->ty_Bytes = stype->ty_Bytes;
1278                 type->ty_AlignMask = stype->ty_AlignMask;
1279                 type->ty_Visibility = stype->ty_Visibility;
1280                 type->ty_DynamicVector = stype->ty_DynamicVector;
1281         }
1282         if (stype->ty_AssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1283                 type = TypeToQualType(type, NULL,
1284                                       stype->ty_SQFlags,
1285                                       SetDupExp(sg, stype->ty_AssExp));
1286         }
1287
1288         return(type);
1289 }
1290
1291 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1292
1293 void
1294 InternalRegisterType(const char *str, const char *linkname, Type *type)
1295 {
1296         static int Special = SPECIALF_REGISTERED|SPECIALF_INTERNAL|1;
1297         TypeRegNode *tr;
1298
1299         dassert(Special & SPECIALF_MASK);
1300         tr = zalloc(sizeof(TypeRegNode));
1301         tr->tr_Id = StrTableAlloc(str, strlen(str), Special++);
1302         tr->tr_Type = type;
1303         tr->tr_LinkName = linkname;
1304         RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1305 }
1306
1307 Type *
1308 InternalRegisteredTypeLookup(string_t id)
1309 {
1310         TypeRegNode *tr;
1311
1312         RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1313                 if (tr->tr_Id == id)
1314                         return(tr->tr_Type);
1315         }
1316         return(NULL);
1317 }