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