Rune - Objectification of references work part 4 (interp test/gfx* working)
[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    USizeType;
35 Type    SSizeType;
36
37 Type    FloatType;              /* generic float placeholder */
38 Type    Float32Type;
39 Type    Float64Type;
40 Type    Float128Type;
41
42 Type    PointerType;            /* generic pointer placeholder */
43 Type    ReferenceType;          /* generic pointer placeholder */
44 Type    CCharType;              /* const uchar          */
45 Type    StrType;                /* const uchar *        */
46 Type    UCharPtrType;           /* uchar *              */
47 Type    UCharPtrPtrType;        /* uchar **             */
48 Type    CUCharPtrPtrType;       /* const uchar **       */
49 Type    VoidPtrType;            /* void *               */
50 Type    VoidRefType;            /* void @               */
51 Type    CVoidPtrType;           /* const void *         */
52 Type    LVoidPtrType;           /* lvalue void *        */
53
54 Type    LexRefType;             /* run-time access class tie-ins */
55 Type    ScopeType;
56 Type    DeclarationType;
57 Type    SemGroupType;
58 Type    ObjectInfoType;
59 Type    RuneLockType;
60 Type    TypeType;
61 Type    FILLERTypeType;
62 Type    FILLERDeclType;
63
64 typelist_t DynamicTypeList = RUNE_HEAD_INITIALIZER(DynamicTypeList);
65 typelist_t CompoundTypeList = RUNE_HEAD_INITIALIZER(CompoundTypeList);
66 typelist_t ArgsTypeList = RUNE_HEAD_INITIALIZER(ArgsTypeList);
67 typelist_t StorageTypeList = RUNE_HEAD_INITIALIZER(StorageTypeList);
68
69 static void initInternalClassType(Type *type, Declaration *d);
70
71 Type   *BaseTypeAry[] = {
72     &DynamicLValueType, &DynamicRValueType, &NumericType,
73     &IntegralType, &SIntegerType, &UIntegerType,
74     &VoidType, &BoolType, &Int8Type, &UInt8Type,
75     &Int16Type, &UInt16Type, &Int32Type, &UInt32Type,
76     &Int64Type, &UInt64Type, &Int128Type, &UInt128Type,
77
78     &IntPtrType, &UIntPtrType, &OffType, &USizeType, &SSizeType,
79
80     &FloatType, &Float32Type, &Float64Type, &Float128Type,
81
82     &PointerType, &ReferenceType,
83
84     &CCharType, &StrType, &UCharPtrType,
85     &UCharPtrPtrType, &CUCharPtrPtrType,
86     &VoidPtrType, &VoidRefType, &CVoidPtrType,
87     &LVoidPtrType,
88
89     &LexRefType, &ScopeType, &DeclarationType, &SemGroupType,
90     &ObjectInfoType, &RuneLockType, &TypeType,
91     &FILLERTypeType, &FILLERDeclType,
92     NULL
93 };
94
95 void
96 initType(Type *type, typelist_t *list, int op)
97 {
98     type->ty_Op = op;
99     RUNE_INIT(&type->ty_QList);
100     if (list)
101         RUNE_INSERT_TAIL(list, type, ty_Node);
102     type->ty_SQList = list;
103 }
104
105 void
106 initQualType(Type *type, typelist_t *list, int op, int sqflags)
107 {
108     initType(type, list, op);
109     type->ty_SQFlags = sqflags;
110 }
111
112 void
113 initRawPtrType(Type *type, Type *ptrto, int sqflags)
114 {
115     initQualType(type, &ptrto->ty_QList, TY_PTRTO, sqflags);
116     type->ty_RawPtrType.et_Type = ptrto;
117     /* type->ty_Bytes = sizeof(void *); */
118     type->ty_AlignMask = sizeof(void *) - 1;
119 }
120
121 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_Bytes = sizeof(ReferenceStor); */
127     type->ty_AlignMask = REFERENCESTOR_ALIGNMASK;
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     initType(&ReferenceType, NULL, TY_UNRESOLVED);
145     PointerType.ty_AlignMask = RAWPTR_ALIGN;
146     ReferenceType.ty_AlignMask = REFERENCESTOR_ALIGNMASK;
147
148     initType(&VoidType, NULL, TY_UNRESOLVED);
149     initType(&BoolType, NULL, TY_UNRESOLVED);
150     initType(&Int8Type, NULL, TY_UNRESOLVED);
151     initType(&UInt8Type, NULL, TY_UNRESOLVED);
152     initType(&Int16Type, NULL, TY_UNRESOLVED);
153     initType(&UInt16Type, NULL, TY_UNRESOLVED);
154     initType(&Int32Type, NULL, TY_UNRESOLVED);
155     initType(&UInt32Type, NULL, TY_UNRESOLVED);
156     initType(&Int64Type, NULL, TY_UNRESOLVED);
157     initType(&UInt64Type, NULL, TY_UNRESOLVED);
158
159     initType(&IntPtrType, NULL, TY_UNRESOLVED);
160     initType(&UIntPtrType, NULL, TY_UNRESOLVED);
161     initType(&OffType, NULL, TY_UNRESOLVED);
162     initType(&USizeType, NULL, TY_UNRESOLVED);
163     initType(&SSizeType, NULL, TY_UNRESOLVED);
164
165     initType(&Float32Type, NULL, TY_UNRESOLVED);
166     initType(&Float64Type, NULL, TY_UNRESOLVED);
167     initType(&Float128Type, NULL, TY_UNRESOLVED);
168
169     initQualType(&CCharType, NULL, TY_UNRESOLVED, SF_CONST);
170     initRawPtrType(&StrType, &CCharType, 0);
171     initRawPtrType(&UCharPtrType, &UInt8Type, 0);
172     initRawPtrType(&UCharPtrPtrType, &UCharPtrType, 0);
173     initRawPtrType(&CUCharPtrPtrType, &StrType, 0);
174     initRawPtrType(&VoidPtrType, &VoidType, 0);
175     initRefType(&VoidRefType, &VoidType, 0);
176     initRawPtrType(&CVoidPtrType, &VoidType, SF_CONST);
177     initRawPtrType(&LVoidPtrType, &VoidType, SF_LVALUE);
178
179     /*
180      * Mark internal types (not all are bound to classes so it is easiest to
181      * just do it here).  This will prevent the collapse code from trying to
182      * collapse our base types.
183      */
184     for (i = 0; BaseTypeAry[i]; ++i)
185         BaseTypeAry[i]->ty_Flags |= TF_ISINTERNAL;
186 }
187
188 /*
189  * Attach an internal class, creating a global summary type for it that
190  * allows our interpreter and code generator to make various assumptions.
191  */
192 int
193 InternalClassAttach(Parse *p __unused, int t, Declaration *d)
194 {
195     Type   *itype;
196
197     dassert_decl(d, d->d_Op == DOP_CLASS);
198
199     switch(d->d_Id) {
200     case RUNEID_VOID:
201         itype = &VoidType;
202         break;
203     case RUNEID_BOOL:
204         /*
205          * Special flag helper (resolver sets TF_ISBOOL in in the type)
206          */
207         itype = &BoolType;
208         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISBOOL;
209         break;
210     case RUNEID_INT8:
211         itype = &Int8Type;
212         break;
213     case RUNEID_UINT8:
214         itype = &UInt8Type;
215         break;
216     case RUNEID_INT16:
217         itype = &Int16Type;
218         break;
219     case RUNEID_UINT16:
220         itype = &UInt16Type;
221         break;
222     case RUNEID_INT32:
223         itype = &Int32Type;
224         break;
225     case RUNEID_UINT32:
226         itype = &UInt32Type;
227         break;
228     case RUNEID_INT64:
229         itype = &Int64Type;
230         break;
231     case RUNEID_UINT64:
232         itype = &UInt64Type;
233         break;
234     case RUNEID_INT128:
235         itype = &Int128Type;
236         break;
237     case RUNEID_UINT128:
238         itype = &UInt128Type;
239         break;
240
241     case RUNEID_FLOAT:
242         /*
243          * Special flag helper (resolver sets TF_ISFLOATING in in the
244          * type)
245          */
246         itype = &FloatType;
247         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISFLOATING;
248         break;
249     case RUNEID_FLOAT32:
250         itype = &Float32Type;
251         break;
252     case RUNEID_FLOAT64:
253         itype = &Float64Type;
254         break;
255     case RUNEID_FLOAT128:
256         itype = &Float128Type;
257         break;
258
259     case RUNEID_INTPTR:
260         itype = &IntPtrType;
261         break;
262     case RUNEID_UINTPTR:
263         itype = &UIntPtrType;
264         break;
265     case RUNEID_OFF:
266         itype = &OffType;
267         break;
268     case RUNEID_USIZE:
269         itype = &USizeType;
270         break;
271     case RUNEID_SSIZE:
272         itype = &SSizeType;
273         break;
274     case RUNEID_POINTER:
275         itype = &PointerType;
276         break;
277     case RUNEID_REFERENCE:
278         itype = &ReferenceType;
279         break;
280     case RUNEID_NUMERIC:
281         itype = &NumericType;
282         break;
283     case RUNEID_INTEGRAL:
284         itype = &IntegralType;
285         break;
286     case RUNEID_SINTEGER:
287         /*
288          * Special flag helper (resolver sets TF_ISINTEGER in in the
289          * type)
290          */
291         itype = &SIntegerType;
292         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
293         break;
294     case RUNEID_UINTEGER:
295         /*
296          * Special flag helper (resolver sets TF_ISINTEGER and
297          * TF_ISUNSIGNED in the type)
298          */
299         itype = &UIntegerType;
300         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISUNSIGNED;
301         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
302         break;
303     case RUNEID_LEXREF:
304         itype = &LexRefType;
305         break;
306     case RUNEID_SCOPE:
307         itype = &ScopeType;
308         break;
309     case RUNEID_DECLARATION:
310         itype = &DeclarationType;
311         break;
312     case RUNEID_SEMGROUP:
313         itype = &SemGroupType;
314         break;
315     case RUNEID_OBJECTINFO:
316         itype = &ObjectInfoType;
317         break;
318     case RUNEID_RUNELOCK:
319         itype = &RuneLockType;
320         break;
321     case RUNEID_TYPE:
322         itype = &TypeType;
323         break;
324     case RUNEID_FILLERTYPE:
325         itype = &FILLERTypeType;
326         break;
327     case RUNEID_FILLERDECL:
328         itype = &FILLERDeclType;
329         break;
330     default:
331         {
332             char buf[RUNE_IDTOSTR_LEN];
333
334             dpanic("Unknown internal class: %s", runeid_text(d->d_Id, buf));
335         }
336         itype = NULL;
337         break;
338     }
339     initInternalClassType(itype, d);
340
341     /*
342      * Fixup for const int8 pointers... we did not have a QList to put
343      * CCharType on until now.  It will wind up on the SemGroup's
344      * sg_ClassList.
345      */
346     if (itype == &UInt8Type) {
347         TypeToQualType(itype, &CCharType, NULL,
348                        itype->ty_SQFlags | SF_CONST,
349                        itype->ty_Visibility);
350     }
351
352     return (t);
353 }
354
355 /*
356  * This is mostly deprecated except for official type aliases such as
357  * intptr_t.
358  */
359 int
360 InternalTypeAttach(Parse *p, int t, Declaration *d)
361 {
362     Type   *itype;
363
364     dassert_decl(d, d->d_Op == DOP_TYPEDEF);
365
366     switch(d->d_Id) {
367     case RUNEID_VOID:
368         itype = &VoidType;
369         break;
370     case RUNEID_BOOL:
371         itype = &BoolType;
372         break;
373     case RUNEID_INT8:
374         itype = &Int8Type;
375         break;
376     case RUNEID_UINT8:
377         itype = &UInt8Type;
378         break;
379     case RUNEID_INT16:
380         itype = &Int16Type;
381         break;
382     case RUNEID_UINT16:
383         itype = &UInt16Type;
384         break;
385     case RUNEID_INT32:
386         itype = &Int32Type;
387         break;
388     case RUNEID_UINT32:
389         itype = &UInt32Type;
390         break;
391     case RUNEID_INT64:
392         itype = &Int64Type;
393         break;
394     case RUNEID_UINT64:
395         itype = &UInt64Type;
396         break;
397
398     case RUNEID_FLOAT32:
399         itype = &Float32Type;
400         break;
401     case RUNEID_FLOAT64:
402         itype = &Float64Type;
403         break;
404     case RUNEID_FLOAT128:
405         itype = &Float128Type;
406         break;
407
408     case RUNEID_INTPTR:
409         itype = &IntPtrType;
410         break;
411     case RUNEID_UINTPTR:
412         itype = &UIntPtrType;
413         break;
414     case RUNEID_OFF:
415         itype = &OffType;
416         break;
417     case RUNEID_USIZE:
418         itype = &USizeType;
419         break;
420     case RUNEID_SSIZE:
421         itype = &SSizeType;
422         break;
423     case RUNEID_POINTER:
424         itype = &PointerType;
425         break;
426     case RUNEID_REFERENCE:
427         itype = &ReferenceType;
428         break;
429     case RUNEID_NUMERIC:
430         itype = &NumericType;
431         break;
432     case RUNEID_INTEGRAL:
433         itype = &IntegralType;
434         break;
435     case RUNEID_SINTEGER:
436         itype = &SIntegerType;
437         break;
438     case RUNEID_UINTEGER:
439         itype = &UIntegerType;
440         break;
441     default:
442         itype = InternalRegisteredTypeLookup(d->d_Id);
443         if (itype == NULL)
444             dpanic("Unknown internal type: %s", d->d_Id);
445         break;
446     }
447
448     if (itype) {
449         if (itype->ty_Op != TY_UNRESOLVED) {
450             t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
451         } else {
452             Type   *ntype = d->d_TypedefDecl.ed_Type;
453
454             TypeToQualType(ntype, itype, NULL,
455                            ntype->ty_SQFlags,
456                            ntype->ty_Visibility);
457         }
458     } else {
459         t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
460     }
461     return (t);
462 }
463
464 Type *
465 AllocType(typelist_t *list, int op)
466 {
467     Type   *type = zalloc(sizeof(Type));
468
469     initType(type, list, op);
470     return (type);
471 }
472
473 /*
474  * May be used to generate a varargs compound type, in which case the
475  * semgroup may already be resolved.
476  *
477  * We do no matching/caching at this time and callers assume that (for making
478  * adjustments) to the underlying sg at parse-time via TypeToProcType()
479  */
480 Type *
481 AllocCompoundType(SemGroup *sg)
482 {
483     Type   *type;
484
485     type = AllocType(&CompoundTypeList, TY_COMPOUND);
486     type->ty_CompType.et_SemGroup = sg;
487     dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
488     return (type);
489 }
490
491 /*
492  * XXX match the compound type(s)
493  */
494 Type *
495 AllocArgsType(SemGroup *sg)
496 {
497     Type   *type;
498
499     type = AllocType(&ArgsTypeList, TY_ARGS);
500     type->ty_ArgsType.et_SemGroup = sg;
501     return (type);
502 }
503
504 Type *
505 AllocStorageType(urunesize_t bytes)
506 {
507     Type   *type;
508
509     RUNE_FOREACH(type, &StorageTypeList, ty_Node) {
510         if (type->ty_Op == TY_STORAGE &&
511             type->ty_StorType.et_Bytes == bytes
512             ) {
513             return (type);
514         }
515     }
516     type = AllocType(&StorageTypeList, TY_STORAGE);
517     type->ty_StorType.et_Bytes = bytes;
518     return (type);
519 }
520
521 Type *
522 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, runeid_t *ary, int eatAry)
523 {
524     Type   *type = NULL;
525
526     dassert_sg(sg, ary != NULL);
527
528     RUNE_FOREACH(type, &sg->sg_ClassList, ty_Node) {
529         int     i;
530
531         if (type->ty_Op != TY_UNRESOLVED)
532             continue;
533         if (type->ty_UnresType.et_ImportSemGroup != isg)
534             continue;
535
536         for (i = 0; ary[i]; ++i) {
537             if (ary[i] != type->ty_UnresType.et_DottedId[i])
538                 break;
539         }
540         if (ary[i] == 0 && type->ty_UnresType.et_DottedId[i] == 0) {
541             if (eatAry)
542                 FreeDotIdAry(ary);
543             return (type);
544         }
545     }
546     type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
547     type->ty_UnresType.et_DottedId = ary;
548     type->ty_UnresType.et_SemGroup = sg;        /* may be NULL */
549     type->ty_UnresType.et_ImportSemGroup = isg; /* may be NULL */
550     return (type);
551 }
552
553 /*
554  * AllocClassType() - Allocate a class representing a the semgroup which in
555  *                    turn represents (typically) a class.
556  *
557  * (This function is only used by parse1.c when parsing class statements)
558  */
559 Type *
560 AllocClassType(typelist_t *list, Type *super, SemGroup *sg, int visibility)
561 {
562     Type   *type;
563
564     dassert(sg != NULL);
565     list = &sg->sg_ClassList;
566
567     RUNE_FOREACH(type, list, ty_Node) {
568         if (type->ty_Op == TY_CLASS &&
569             type->ty_ClassType.et_SemGroup == sg &&
570             type->ty_ClassType.et_Super == super &&
571             type->ty_Visibility == visibility)
572         {
573             return (type);
574         }
575     }
576     if (sg)
577         dassert(&sg->sg_ClassList == list);
578     type = AllocType(list, TY_CLASS);
579     type->ty_ClassType.et_SemGroup = sg;
580     type->ty_ClassType.et_Super = super;
581     type->ty_Visibility = visibility;
582     return (type);
583 }
584
585 static
586 void
587 initInternalClassType(Type *type, Declaration *d)
588 {
589     SemGroup *sg = d->d_ClassDecl.ed_SemGroup;
590
591     dassert(d->d_Op == DOP_CLASS);
592
593     initType(type, &sg->sg_ClassList, TY_CLASS);
594     RUNE_REMOVE(&sg->sg_ClassList, type, ty_Node);
595     RUNE_INSERT_HEAD(&sg->sg_ClassList, type, ty_Node);
596     type->ty_ClassType.et_SemGroup = sg;
597     type->ty_ClassType.et_Super = d->d_ClassDecl.ed_Super;
598     if (sg->sg_ClassType)
599         type->ty_SQFlags = sg->sg_ClassType->ty_SQFlags;
600     type->ty_Visibility = d->d_ScopeFlags & SCOPE_ALL_VISIBLE;
601     type->ty_Flags |= TF_ISINTERNAL;
602 }
603
604 Type *
605 AllocImportType(typelist_t *list, SemGroup *sg, int visibility)
606 {
607     Type   *type = AllocType(list, TY_IMPORT);
608
609     type->ty_ImportType.et_SemGroup = sg;
610     type->ty_Visibility = visibility;
611     return (type);
612 }
613
614 /*
615  * adjtype must be moved to type's QList because type is being modified such
616  * that that is where it is expected to be.
617  */
618 Type *
619 TypeAdjustQList(Type *type, Type *adjtype)
620 {
621     if (adjtype) {
622         if (adjtype->ty_SQList)
623             RUNE_REMOVE(adjtype->ty_SQList, adjtype, ty_Node);
624         adjtype->ty_SQList = &type->ty_QList;
625         RUNE_INSERT_TAIL(adjtype->ty_SQList, adjtype, ty_Node);
626     }
627     return type;
628 }
629
630 /*
631  * Compound types inherit locking modes if not specifically overridden.
632  */
633 Type *
634 TypeFixupInheritedFlags(Type *type, int rqflags)
635 {
636     SemGroup *sg;
637     Declaration *d;
638
639     if (type->ty_Op != TY_COMPOUND)
640         return type;
641
642     /*
643      * Assume no matching collapse yet
644      */
645     sg = type->ty_CompType.et_SemGroup;
646     RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
647         if (d->d_Op != DOP_GROUP_STORAGE)
648             continue;
649         if ((d->d_ScopeFlags & SCOPE_LOCKING_MASK) == 0) {
650             if (rqflags & SF_UNTRACKED)
651                 d->d_ScopeFlags |= SCOPE_UNTRACKED;
652             if (rqflags & SF_UNLOCKED)
653                 d->d_ScopeFlags |= SCOPE_UNLOCKED;
654             if (rqflags & SF_SOFT)
655                 d->d_ScopeFlags |= SCOPE_SOFT;
656             if (rqflags & SF_HARD)
657                 d->d_ScopeFlags |= SCOPE_HARD;
658         }
659     }
660     return type;
661 }
662
663 /*
664  * Convert type to qualified type
665  *
666  * NOTE: exp is applied to ty_OrigAssExp, meaning that the new type
667  *       must then be resolved.
668  */
669 Type *
670 TypeToQualType(Type *otype, Type *ntype, Exp *exp,
671                int sqflags, int visibility)
672 {
673     SemGroup *sg;
674
675     /*
676      * Combine with existing qualifiers, Shortcut if no changes made.
677      */
678     if (ntype == NULL && sqflags == otype->ty_SQFlags &&
679         (exp == NULL || exp == otype->ty_OrigAssExp))
680     {
681         return (otype);
682     }
683
684     /*
685      * See if we already have a matching qualified type (only if storage for
686      * the new type is not being provided).  Note: the provided storage has
687      * already been initType()d
688      */
689     if (ntype == NULL) {
690         RUNE_FOREACH(ntype, otype->ty_SQList, ty_Node) {
691             if (ntype->ty_Op == otype->ty_Op &&
692                 ntype->ty_SQFlags == sqflags &&
693                 ntype->ty_Visibility == visibility &&
694                 (exp == NULL || ntype->ty_OrigAssExp == exp))
695             {
696                 if (SameType(ntype, otype, sqflags))
697                     return (ntype);
698             }
699         }
700     }
701
702     /*
703      * Build a new qualified type and set its qualifiers, then duplicate
704      * appropriate sections of the old type.
705      *
706      * Default to the same SQList as otype.
707      */
708     if (ntype == NULL) {
709         ntype = AllocType(otype->ty_SQList, otype->ty_Op);
710     } else {
711         if (ntype->ty_SQList)
712             RUNE_REMOVE(ntype->ty_SQList, ntype, ty_Node);
713         ntype->ty_SQList = otype->ty_SQList;
714         RUNE_INSERT_TAIL(ntype->ty_SQList, ntype, ty_Node);
715     }
716
717     /*
718      * Set the op and the expression.  Unlike SQFlags, if exp is passed as
719      * NULL we inherit the old type's default.
720      *
721      * The DupExp() call here is special, see DupExp()'s handling of ex_Decl.
722      *
723      * Normally DupExp() is called during resolution prior to ex_Decl being
724      * set.  This is the one case where it may be called with ex_Decl already
725      * set.
726      *
727      * WARNING! We do not try to resolve the type here.  Various resolve
728      * related flags in ty_Flags will be resolved later.  This includes
729      * TF_ISUNSIGNED and other TF_* flags.
730      */
731     ntype->ty_Op = otype->ty_Op;
732     if (exp)
733         ntype->ty_OrigAssExp = exp;
734     else if (otype->ty_OrigAssExp)
735         ntype->ty_OrigAssExp = otype->ty_OrigAssExp;
736     ntype->ty_SQFlags = sqflags;
737     ntype->ty_Visibility = visibility;
738
739     switch (otype->ty_Op) {
740     case TY_CLASS:
741         /*
742          * When updating the class, alternative forms are collapsed into it's
743          * SemGroup->sg_ClassList and not into some potentially long
744          * recursive chain based on ty_QList.
745          */
746         sg = otype->ty_ClassType.et_SemGroup;
747
748         dassert(ntype->ty_SQList == &sg->sg_ClassList);
749         if (ntype->ty_ClassType.et_SemGroup != sg) {
750             ntype->ty_ClassType.et_SemGroup = sg;
751         }
752         ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
753         break;
754     case TY_IMPORT:
755         ntype->ty_Visibility = otype->ty_Visibility;
756         ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
757         break;
758     case TY_PTRTO:
759         ntype->ty_RawPtrType.et_Type = otype->ty_RawPtrType.et_Type;
760         break;
761     case TY_REFTO:
762         ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
763         break;
764     case TY_ARYOF:
765         /*
766          * note: multiple type structures may share the same array size
767          * expression in simple qualified-type cases.  YYY XXX bad bad.
768          */
769         ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
770         ntype->ty_AryType.et_OrigArySize = otype->ty_AryType.et_OrigArySize;
771         ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
772         ntype->ty_AryType.et_Count = otype->ty_AryType.et_Count;
773         break;
774     case TY_COMPOUND:
775         ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
776         break;
777     case TY_VAR:
778         ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
779         ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
780         break;
781     case TY_ARGS:
782         ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
783         break;
784     case TY_PROC:
785         ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
786         ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
787         ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
788         dassert(ntype->ty_SQList ==
789                 &otype->ty_ProcType.et_RetType->ty_QList);
790         break;
791     case TY_STORAGE:
792         ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
793         break;
794     case TY_DYNAMIC:
795         /*
796          * It is not legal to qualify a dynamic type other then to add or
797          * remove SF_LVALUE.
798          */
799         dpanic("Dynamic type cannot be qualified");
800         break;
801     case TY_UNRESOLVED:
802         ntype->ty_UnresType.et_DottedId =
803             otype->ty_UnresType.et_DottedId;
804         ntype->ty_UnresType.et_SemGroup =
805             otype->ty_UnresType.et_SemGroup;
806         ntype->ty_UnresType.et_ImportSemGroup =
807             otype->ty_UnresType.et_ImportSemGroup;
808         break;
809     default:
810         dassert_type(otype, 0);
811     }
812     return (ntype);
813 }
814
815 Type *
816 TypeToVisibilityType(Type *type, int visibility)
817 {
818     if (type->ty_Visibility != visibility) {
819         type = TypeToQualType(type, NULL, type->ty_OrigAssExp,
820                               type->ty_SQFlags, visibility);
821     }
822     return type;
823 }
824
825 /*
826  * Convert a return-type + argument-type into a procedure type.  If adjret is
827  * non-zero the return-type is converted to locked storage (which is
828  * 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     urunesize_t count = 0;
836     Declaration *d;
837     SemGroup *sg;
838     Type   *type;
839
840     dassert_type(atype, atype->ty_Op == TY_ARGS);
841
842     if (adjret)
843         rtype = TypeFixupInheritedFlags(rtype, rtype->ty_SQFlags);
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 TypeToRawPtrType(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_RawPtrType.et_Type = otype;
881
882     return (type);
883 }
884
885 /*
886  * Convert type to ref-to-type
887  *
888  * A reference type is similar to a pointer type except that the resolver is
889  * not able to entirely know what it is pointing to. The reference type is a
890  * superclass, but the actual type is stored in the run-time structure.
891  */
892 Type *
893 TypeToRefType(Type *otype)
894 {
895     Type   *type;
896
897     RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
898         if (type->ty_Op == TY_REFTO)
899             return (type);
900     }
901     type = AllocType(&otype->ty_QList, TY_REFTO);
902     type->ty_RefType.et_Type = otype;
903     return (type);
904 }
905
906 Type *
907 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
908 {
909     Type   *type;
910
911     /*
912      * XXX handle constant expression optimization for QList XXX handle
913      * qualifiers
914      */
915     type = AllocType(&otype->ty_QList, TY_ARYOF);
916     type->ty_AryType.et_OrigArySize = exp;
917     type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
918     type->ty_AryType.et_SemGroup = sg;
919     type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
920
921     return (type);
922 }
923
924 #if 0
925
926 Type *
927 TypeToRunTimeAryType(Type *otype, int count)
928 {
929     Type   *type;
930     Type   *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
931
932     RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
933         if (type->ty_Op == TY_ARYOF &&
934             type->ty_AryType.et_Type == t2 &&
935             type->ty_AryType.et_Count == count &&
936             type->ty_SQFlags ==
937             (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
938             ) {
939             return (type);
940         }
941     }
942     type = AllocType(&otype->ty_QList, TY_ARYOF);
943     type->ty_AryType.et_Count = count;
944     type->ty_AryType.et_Type = t2;
945     type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
946     return (type);
947 }
948
949 #endif
950
951 Type *
952 TypeToVarType(Type *otype, SemGroup *sg)
953 {
954     Type   *type;
955
956     /* dassert(sg->sg_Flags & SGF_RESOLVED); */
957     /* dassert(otype->ty_Flags & TF_RESOLVED); */
958
959     RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
960         if (type->ty_Op == TY_VAR &&
961             type->ty_VarType.et_Type == otype &&
962             type->ty_VarType.et_SemGroup == sg
963             ) {
964             puts("SG2");        /* YYY */
965             return (type);
966         }
967     }
968     type = AllocType(&otype->ty_QList, TY_VAR);
969     type->ty_VarType.et_Type = otype;
970     type->ty_VarType.et_SemGroup = sg;
971 #if 0
972     /* XXX doesn't work for var-args */
973     if (sg->sg_Flags & SGF_RESOLVED) {
974         type->ty_Flags |= TF_RESOLVED;
975         type->ty_Bytes = sg->sg_Bytes;
976         type->ty_AlignMask = sg->sg_AlignMask;
977     }
978 #endif
979     return (type);
980 }
981
982 /*
983  * ChangeType() - given pointer, C pointer, or array of something, return
984  * 'op' of something instead.
985  */
986 Type *
987 ChangeType(Type *type, int op)
988 {
989     switch (type->ty_Op) {
990     case TY_PTRTO:
991         switch (op) {
992         case TY_ARYOF:
993             type = TypeToAryType(type->ty_RawPtrType.et_Type,
994                                  NULL, NULL);
995             break;
996         default:
997             dpanic("Illegal type convesion (B)");
998         }
999         break;
1000     case TY_ARYOF:
1001         switch (op) {
1002         case TY_PTRTO:
1003             type = TypeToRawPtrType(type->ty_AryType.et_Type);
1004             break;
1005         default:
1006             dpanic("Illegal type convesion (C)");
1007         }
1008         break;
1009     default:
1010         dpanic("Illegal type convesion (D)");
1011     }
1012     return (type);
1013 }
1014
1015 /*
1016  * BaseType() - return base type
1017  *
1018  * Traverse the type to locate the base type.  Store the base type in *ptype
1019  * and return the SemGroup, or return NULL if the base type does not have a
1020  * SemGroup.
1021  */
1022 SemGroup *
1023 BaseType(Type **ptype)
1024 {
1025     Type   *type = *ptype;
1026
1027     for (;;) {
1028         switch (type->ty_Op) {
1029         case TY_PTRTO:
1030             type = type->ty_RawPtrType.et_Type;
1031             continue;
1032         case TY_REFTO:
1033             type = type->ty_RefType.et_Type;
1034             continue;
1035         case TY_ARYOF:
1036             type = type->ty_AryType.et_Type;
1037             continue;
1038         }
1039         break;
1040     }
1041
1042     *ptype = type;
1043
1044     switch (type->ty_Op) {
1045     case TY_CLASS:
1046         return (type->ty_ClassType.et_SemGroup);
1047     case TY_COMPOUND:
1048         return (type->ty_CompType.et_SemGroup);
1049     case TY_ARGS:
1050         return (type->ty_ArgsType.et_SemGroup);
1051     case TY_PROC:
1052     case TY_VAR:
1053     case TY_DYNAMIC:
1054     case TY_STORAGE:
1055         return (NULL);
1056     case TY_UNRESOLVED:
1057     default:
1058         dassert_type(type, 0);
1059         return (NULL);          /* avoid compiler complaints */
1060     }
1061 }
1062
1063 /*
1064  * DupType()     - create a duplicate of a type, possibly in a new SemGroup.
1065  *
1066  * This code is used when duplicating procedures and other elements when
1067  * merging a superclass into a subclass.
1068  *
1069  * If sg is NULL, stype is simply returned.  The case is used when we try to
1070  * duplciate an expression with DupExp()... in that case we want to dup the
1071  * expression tree but use the same types.
1072  */
1073 Type *
1074 DupType(SemGroup *sg, Type *stype)
1075 {
1076     Type   *type = NULL;
1077
1078     if (sg == NULL)
1079         return (stype);
1080
1081     /*
1082      * XXX type may be resolved if it is part of a varargs dup
1083      */
1084 #if 0
1085     dassert_type(stype,
1086                  (stype->ty_Flags & (TF_RESOLVED | TF_RESOLVING)) == 0);
1087 #endif
1088
1089     switch (stype->ty_Op) {
1090     case TY_CLASS:
1091         /*
1092          * This only occurs because the resolver has resolved an unresolved
1093          * type on the original SemGroup.  We duplicate that on the new
1094          * SemGroup.  XXX remove
1095          */
1096 #if 0
1097         type = AllocClassType(&sg->sg_ClassList,
1098                               stype->ty_ClassType.et_Super,
1099                               stype->ty_ClassType.et_SemGroup,
1100                               stype->ty_Visibility);
1101 #endif
1102 #if 0
1103         type = TypeToQualType(sg->sg_ClassType, NULL, stype->ty_OrigAssExp,
1104                               stype->ty_SQFlags,
1105                               stype->ty_Visibility);
1106 #endif
1107         return stype;
1108         break;
1109     case TY_IMPORT:
1110     case TY_DYNAMIC:
1111         /*
1112          * For TY_IMPORT, leave et_SemGroup alone?
1113          */
1114         type = stype;
1115         break;
1116     case TY_PTRTO:
1117         type = TypeToRawPtrType(DupType(sg, stype->ty_RawPtrType.et_Type));
1118         break;
1119     case TY_REFTO:
1120         type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1121         break;
1122     case TY_ARYOF:
1123         /*
1124          * When redeclaring an array, the semantic context if the
1125          * [exp] needs to be able to see refined elements in subclasses,
1126          * even if the array declaration itself has not been refined.
1127          *
1128          * XXX however, this may make other elements in the subclass
1129          * visible to the [exp] that we did not refine (? TEST)
1130          */
1131 #if 1
1132         dassert(sg);
1133         type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1134                              stype->ty_AryType.et_OrigArySize,
1135                              sg);
1136 #else
1137         type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1138                              stype->ty_AryType.et_OrigArySize,
1139                              stype->ty_AryType.et_SemGroup);
1140 #endif
1141         type->ty_AryType.et_Count = stype->ty_AryType.et_Count;
1142         break;
1143     case TY_VAR:
1144         /*
1145          * varargs (whole thing), requires duplicating the semantic group
1146          * they are contained in too.
1147          */
1148         type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1149                     DupSemGroup(sg, NULL, stype->ty_VarType.et_SemGroup, 1));
1150         break;
1151     case TY_COMPOUND:
1152         type = AllocCompoundType(DupSemGroup(sg, NULL,
1153                                         stype->ty_CompType.et_SemGroup, 1));
1154         break;
1155     case TY_ARGS:
1156         /*
1157          * Arguments (whole thing), requires duplicating the semantic
1158          * group they are contained in too.
1159          *
1160          * At the moment we always formally duplicate the arguments so we can
1161          * modify them for methods below.
1162          */
1163         type = AllocArgsType(DupSemGroup(sg, NULL,
1164                                          stype->ty_CompType.et_SemGroup, 1));
1165         break;
1166     case TY_PROC:
1167         /*
1168          * Procedural type.
1169          */
1170         type = DupType(sg, stype->ty_ProcType.et_RetType);
1171         type = TypeToProcType(type,
1172                               DupType(sg, stype->ty_ProcType.et_ArgsType),
1173                               1);
1174         break;
1175     case TY_STORAGE:
1176         type = stype;
1177         break;
1178     case TY_UNRESOLVED:
1179         /*
1180          * e.g. so elements in a superclass will see refined elements in the
1181          * subclass.  Note that the original import semgroup is left intact
1182          * so the semantic search mechanism uses it when the base sg
1183          * (typically a subclass) fails.
1184          */
1185         type = AllocUnresolvedType(stype->ty_UnresType.et_ImportSemGroup,
1186                                    sg,
1187                                    stype->ty_UnresType.et_DottedId,
1188                                    0);
1189         break;
1190     default:
1191         dassert_type(stype, 0);
1192     }
1193
1194     if (type != stype) {
1195         type->ty_Flags = stype->ty_Flags &
1196             ~(TF_ISINTERNAL | TF_RESOLVING | TF_RESOLVED |
1197               TF_ALIGNRESOLVED | TF_TMPRESOLVED);
1198         type->ty_Bytes = stype->ty_Bytes;
1199         type->ty_AlignMask = stype->ty_AlignMask;
1200         type->ty_Visibility = stype->ty_Visibility;
1201         type->ty_DynamicVector = stype->ty_DynamicVector;
1202     }
1203     if (stype->ty_OrigAssExp ||
1204         stype->ty_SQFlags != type->ty_SQFlags ||
1205         stype->ty_Visibility != type->ty_Visibility)
1206     {
1207         type = TypeToQualType(type, NULL, stype->ty_OrigAssExp,
1208                               stype->ty_SQFlags, stype->ty_Visibility);
1209     }
1210
1211     return (type);
1212 }
1213
1214 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1215
1216 void
1217 InternalRegisterType(const char *str, const char *linkname, Type *type)
1218 {
1219     TypeRegNode *tr;
1220
1221     tr = zalloc(sizeof(TypeRegNode));
1222     tr->tr_Id = runeid_hash(str, strlen(str));
1223     tr->tr_Type = type;
1224     tr->tr_LinkName = linkname;
1225     RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1226 }
1227
1228 Type *
1229 InternalRegisteredTypeLookup(runeid_t id)
1230 {
1231     TypeRegNode *tr;
1232
1233     RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1234         if (tr->tr_Id == id)
1235             return (tr->tr_Type);
1236     }
1237     return (NULL);
1238 }