Rune - Objectification of references work part 2 (build broken)
[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,
348                        itype->ty_SQFlags | SF_CONST, NULL);
349     }
350
351     return (t);
352 }
353
354 /*
355  * This is mostly deprecated except for official type aliases such as
356  * intptr_t.
357  */
358 int
359 InternalTypeAttach(Parse *p, int t, Declaration *d)
360 {
361     Type   *itype;
362
363     dassert_decl(d, d->d_Op == DOP_TYPEDEF);
364
365     switch(d->d_Id) {
366     case RUNEID_VOID:
367         itype = &VoidType;
368         break;
369     case RUNEID_BOOL:
370         itype = &BoolType;
371         break;
372     case RUNEID_INT8:
373         itype = &Int8Type;
374         break;
375     case RUNEID_UINT8:
376         itype = &UInt8Type;
377         break;
378     case RUNEID_INT16:
379         itype = &Int16Type;
380         break;
381     case RUNEID_UINT16:
382         itype = &UInt16Type;
383         break;
384     case RUNEID_INT32:
385         itype = &Int32Type;
386         break;
387     case RUNEID_UINT32:
388         itype = &UInt32Type;
389         break;
390     case RUNEID_INT64:
391         itype = &Int64Type;
392         break;
393     case RUNEID_UINT64:
394         itype = &UInt64Type;
395         break;
396
397     case RUNEID_FLOAT32:
398         itype = &Float32Type;
399         break;
400     case RUNEID_FLOAT64:
401         itype = &Float64Type;
402         break;
403     case RUNEID_FLOAT128:
404         itype = &Float128Type;
405         break;
406
407     case RUNEID_INTPTR:
408         itype = &IntPtrType;
409         break;
410     case RUNEID_UINTPTR:
411         itype = &UIntPtrType;
412         break;
413     case RUNEID_OFF:
414         itype = &OffType;
415         break;
416     case RUNEID_USIZE:
417         itype = &USizeType;
418         break;
419     case RUNEID_SSIZE:
420         itype = &SSizeType;
421         break;
422     case RUNEID_POINTER:
423         itype = &PointerType;
424         break;
425     case RUNEID_REFERENCE:
426         itype = &ReferenceType;
427         break;
428     case RUNEID_NUMERIC:
429         itype = &NumericType;
430         break;
431     case RUNEID_INTEGRAL:
432         itype = &IntegralType;
433         break;
434     case RUNEID_SINTEGER:
435         itype = &SIntegerType;
436         break;
437     case RUNEID_UINTEGER:
438         itype = &UIntegerType;
439         break;
440     default:
441         itype = InternalRegisteredTypeLookup(d->d_Id);
442         if (itype == NULL)
443             dpanic("Unknown internal type: %s", d->d_Id);
444         break;
445     }
446
447     if (itype) {
448         if (itype->ty_Op != TY_UNRESOLVED) {
449             t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
450         } else {
451             Type   *ntype = d->d_TypedefDecl.ed_Type;
452
453             TypeToQualType(ntype, itype, ntype->ty_SQFlags, NULL);
454         }
455     } else {
456         t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
457     }
458     return (t);
459 }
460
461 Type *
462 AllocType(typelist_t *list, int op)
463 {
464     Type   *type = zalloc(sizeof(Type));
465
466     initType(type, list, op);
467     return (type);
468 }
469
470 /*
471  * May be used to generate a varargs compound type, in which case the
472  * semgroup may already be resolved.
473  *
474  * We do no matching/caching at this time and callers assume that (for making
475  * adjustments) to the underlying sg at parse-time via TypeToProcType()
476  */
477 Type *
478 AllocCompoundType(SemGroup *sg)
479 {
480     Type   *type;
481
482     type = AllocType(&CompoundTypeList, TY_COMPOUND);
483     type->ty_CompType.et_SemGroup = sg;
484     dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
485     return (type);
486 }
487
488 /*
489  * XXX match the compound type(s)
490  */
491 Type *
492 AllocArgsType(SemGroup *sg)
493 {
494     Type   *type;
495
496     type = AllocType(&ArgsTypeList, TY_ARGS);
497     type->ty_ArgsType.et_SemGroup = sg;
498     return (type);
499 }
500
501 Type *
502 AllocStorageType(urunesize_t bytes)
503 {
504     Type   *type;
505
506     RUNE_FOREACH(type, &StorageTypeList, ty_Node) {
507         if (type->ty_Op == TY_STORAGE &&
508             type->ty_StorType.et_Bytes == bytes
509             ) {
510             return (type);
511         }
512     }
513     type = AllocType(&StorageTypeList, TY_STORAGE);
514     type->ty_StorType.et_Bytes = bytes;
515     return (type);
516 }
517
518 Type *
519 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, runeid_t *ary, int eatAry)
520 {
521     Type   *type = NULL;
522
523     dassert_semgrp(sg, ary != NULL);
524
525     RUNE_FOREACH(type, &sg->sg_ClassList, ty_Node) {
526         int     i;
527
528         if (type->ty_Op != TY_UNRESOLVED)
529             continue;
530         if (type->ty_UnresType.et_ImportSemGroup != isg)
531             continue;
532
533         for (i = 0; ary[i]; ++i) {
534             if (ary[i] != type->ty_UnresType.et_DottedId[i])
535                 break;
536         }
537         if (ary[i] == 0 && type->ty_UnresType.et_DottedId[i] == 0) {
538             if (eatAry)
539                 FreeDotIdAry(ary);
540             return (type);
541         }
542     }
543     type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
544     type->ty_UnresType.et_DottedId = ary;
545     type->ty_UnresType.et_SemGroup = sg;        /* may be NULL */
546     type->ty_UnresType.et_ImportSemGroup = isg; /* may be NULL */
547     return (type);
548 }
549
550 /*
551  * AllocClassType() - Allocate a class representing a the semgroup which in
552  *                    turn represents (typically) a class.
553  */
554 Type *
555 AllocClassType(typelist_t *list, Type *super, SemGroup *sg, int visibility)
556 {
557     Type   *type;
558
559     dassert(sg != NULL);
560     list = &sg->sg_ClassList;
561
562     RUNE_FOREACH(type, list, ty_Node) {
563         if (type->ty_Op == TY_CLASS &&
564             type->ty_ClassType.et_SemGroup == sg &&
565             type->ty_ClassType.et_Super == super &&
566             type->ty_Visibility == visibility)
567         {
568             return (type);
569         }
570     }
571     if (sg)
572         dassert(&sg->sg_ClassList == list);
573     type = AllocType(list, TY_CLASS);
574     type->ty_ClassType.et_SemGroup = sg;
575     type->ty_ClassType.et_Super = super;
576     type->ty_Visibility = visibility;
577     return (type);
578 }
579
580 static
581 void
582 initInternalClassType(Type *type, Declaration *d)
583 {
584     SemGroup *sg = d->d_ClassDecl.ed_SemGroup;
585
586     initType(type, &sg->sg_ClassList, TY_CLASS);
587     RUNE_REMOVE(&sg->sg_ClassList, type, ty_Node);
588     RUNE_INSERT_HEAD(&sg->sg_ClassList, type, ty_Node);
589     type->ty_ClassType.et_SemGroup = d->d_ClassDecl.ed_SemGroup;
590     type->ty_ClassType.et_Super = d->d_ClassDecl.ed_Super;
591     type->ty_Visibility = d->d_ScopeFlags & SCOPE_ALL_VISIBLE;
592     type->ty_Flags |= TF_ISINTERNAL;
593 }
594
595 Type *
596 AllocImportType(typelist_t *list, SemGroup *sg, int visibility)
597 {
598     Type   *type = AllocType(list, TY_IMPORT);
599
600     type->ty_ImportType.et_SemGroup = sg;
601     type->ty_Visibility = visibility;
602     return (type);
603 }
604
605 /*
606  * adjtype must be moved to type's QList because type is being modified such
607  * that that is where it is expected to be.
608  */
609 Type *
610 TypeAdjustQList(Type *type, Type *adjtype)
611 {
612     if (adjtype) {
613         if (adjtype->ty_SQList)
614             RUNE_REMOVE(adjtype->ty_SQList, adjtype, ty_Node);
615         adjtype->ty_SQList = &type->ty_QList;
616         RUNE_INSERT_TAIL(adjtype->ty_SQList, adjtype, ty_Node);
617     }
618     return type;
619 }
620
621 /*
622  * Compound types inherit locking modes if not specifically overridden.
623  */
624 Type *
625 TypeFixupInheritedFlags(Type *type, int rqflags)
626 {
627     SemGroup *sg;
628     Declaration *d;
629
630     if (type->ty_Op != TY_COMPOUND)
631         return type;
632
633     /*
634      * Assume no matching collapse yet
635      */
636     sg = type->ty_CompType.et_SemGroup;
637     RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
638         if (d->d_Op != DOP_GROUP_STORAGE)
639             continue;
640         if ((d->d_ScopeFlags & SCOPE_LOCKING_MASK) == 0) {
641             if (rqflags & SF_UNTRACKED)
642                 d->d_ScopeFlags |= SCOPE_UNTRACKED;
643             if (rqflags & SF_UNLOCKED)
644                 d->d_ScopeFlags |= SCOPE_UNLOCKED;
645             if (rqflags & SF_SOFT)
646                 d->d_ScopeFlags |= SCOPE_SOFT;
647             if (rqflags & SF_HARD)
648                 d->d_ScopeFlags |= SCOPE_HARD;
649         }
650     }
651     return type;
652 }
653
654 /*
655  * Convert type to qualified type
656  *
657  * NOTE: exp is applied to ty_OrigAssExp, meaning that the new type
658  *       must then be resolved.
659  */
660 Type *
661 TypeToQualType(Type *otype, Type *ntype, int sqFlags, Exp *exp)
662 {
663     SemGroup *sg;
664
665     /*
666      * Combine with existing qualifiers, Shortcut if no changes made.
667      */
668     if (ntype == NULL && sqFlags == otype->ty_SQFlags &&
669         (exp == NULL || exp == otype->ty_OrigAssExp))
670     {
671         return (otype);
672     }
673
674     /*
675      * See if we already have a matching qualified type (only if storage for
676      * the new type is not being provided).  Note: the provided storage has
677      * already been initType()d
678      */
679     if (ntype == NULL) {
680         RUNE_FOREACH(ntype, otype->ty_SQList, ty_Node) {
681             if (ntype->ty_Op == otype->ty_Op &&
682                 ntype->ty_SQFlags == sqFlags &&
683                 (exp == NULL || ntype->ty_OrigAssExp == exp))
684             {
685                 if (SameType(ntype, otype, sqFlags))
686                     return (ntype);
687             }
688         }
689     }
690
691     /*
692      * Build a new qualified type and set its qualifiers, then duplicate
693      * appropriate sections of the old type.
694      *
695      * Default to the same SQList as otype.
696      */
697     if (ntype == NULL) {
698         ntype = AllocType(otype->ty_SQList, otype->ty_Op);
699     } else {
700         if (ntype->ty_SQList)
701             RUNE_REMOVE(ntype->ty_SQList, ntype, ty_Node);
702         ntype->ty_SQList = otype->ty_SQList;
703         RUNE_INSERT_TAIL(ntype->ty_SQList, ntype, ty_Node);
704     }
705
706     /*
707      * Set the op and the expression.  Unlike SQFlags, if exp is passed as
708      * NULL we inherit the old type's default.
709      *
710      * The DupExp() call here is special, see DupExp()'s handling of ex_Decl.
711      *
712      * Normally DupExp() is called during resolution prior to ex_Decl being
713      * set.  This is the one case where it may be called with ex_Decl already
714      * set.
715      *
716      * WARNING! We do not try to resolve the type here.  Various resolve
717      * related flags in ty_Flags will be resolved later.  This includes
718      * TF_ISUNSIGNED and other TF_* flags.
719      */
720     ntype->ty_Op = otype->ty_Op;
721     if (exp)
722         ntype->ty_OrigAssExp = exp;
723     else if (otype->ty_OrigAssExp)
724         ntype->ty_OrigAssExp = otype->ty_OrigAssExp;
725     ntype->ty_SQFlags = sqFlags;
726     ntype->ty_Visibility = otype->ty_Visibility;
727
728     switch (otype->ty_Op) {
729     case TY_CLASS:
730         /*
731          * When updating the class, alternative forms are collapsed into it's
732          * SemGroup->sg_ClassList and not into some potentially long
733          * recursive chain based on ty_QList.
734          */
735         sg = otype->ty_ClassType.et_SemGroup;
736
737         dassert(ntype->ty_SQList == &sg->sg_ClassList);
738         if (ntype->ty_ClassType.et_SemGroup != sg) {
739             ntype->ty_ClassType.et_SemGroup = sg;
740         }
741         ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
742         break;
743     case TY_IMPORT:
744         ntype->ty_Visibility = otype->ty_Visibility;
745         ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
746         break;
747     case TY_PTRTO:
748         ntype->ty_RawPtrType.et_Type = otype->ty_RawPtrType.et_Type;
749         break;
750     case TY_REFTO:
751         ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
752         break;
753     case TY_ARYOF:
754         /*
755          * note: multiple type structures may share the same array size
756          * expression in simple qualified-type cases.  YYY XXX bad bad.
757          */
758         ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
759         ntype->ty_AryType.et_OrigArySize = otype->ty_AryType.et_OrigArySize;
760         ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
761         ntype->ty_AryType.et_Count = otype->ty_AryType.et_Count;
762         break;
763     case TY_COMPOUND:
764         ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
765         break;
766     case TY_VAR:
767         ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
768         ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
769         break;
770     case TY_ARGS:
771         ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
772         break;
773     case TY_PROC:
774         ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
775         ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
776         ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
777         dassert(ntype->ty_SQList ==
778                 &otype->ty_ProcType.et_RetType->ty_QList);
779         break;
780     case TY_STORAGE:
781         ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
782         break;
783     case TY_DYNAMIC:
784         /*
785          * It is not legal to qualify a dynamic type other then to add or
786          * remove SF_LVALUE.
787          */
788         dpanic("Dynamic type cannot be qualified");
789         break;
790     case TY_UNRESOLVED:
791         ntype->ty_UnresType.et_DottedId =
792             otype->ty_UnresType.et_DottedId;
793         ntype->ty_UnresType.et_SemGroup =
794             otype->ty_UnresType.et_SemGroup;
795         ntype->ty_UnresType.et_ImportSemGroup =
796             otype->ty_UnresType.et_ImportSemGroup;
797         break;
798     default:
799         dassert_type(otype, 0);
800     }
801     return (ntype);
802 }
803
804 /*
805  * Convert a return-type + argument-type into a procedure type.  If adjret is
806  * non-zero the return-type is converted to locked storage (which is
807  * generally what we want).
808  *
809  * Match the procedure type(s) (after adjustment?)
810  */
811 Type *
812 TypeToProcType(Type *rtype, Type *atype, int adjret)
813 {
814     urunesize_t count = 0;
815     Declaration *d;
816     SemGroup *sg;
817     Type   *type;
818
819     dassert_type(atype, atype->ty_Op == TY_ARGS);
820
821     if (adjret)
822         rtype = TypeFixupInheritedFlags(rtype, rtype->ty_SQFlags);
823
824     sg = atype->ty_CompType.et_SemGroup;
825
826     RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
827         ++count;
828     }
829     RUNE_FOREACH(type, &rtype->ty_QList, ty_Node) {
830         if (type->ty_Op == TY_PROC) {
831             if (type->ty_ProcType.et_ArgsType == atype &&
832                 type->ty_ProcType.et_RetType == rtype &&
833                 type->ty_ProcType.et_ArgCount == count
834                 ) {
835                 return (type);
836             }
837         }
838     }
839     type = AllocType(&rtype->ty_QList, TY_PROC);
840     type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
841     type->ty_ProcType.et_RetType = rtype;
842     type->ty_ProcType.et_ArgCount = count;
843     return (type);
844 }
845
846 /*
847  * Convert type to pointer-to-type
848  */
849 Type *
850 TypeToRawPtrType(Type *otype)
851 {
852     Type   *type;
853
854     RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
855         if (type->ty_Op == TY_PTRTO)
856             return (type);
857     }
858     type = AllocType(&otype->ty_QList, TY_PTRTO);
859     type->ty_RawPtrType.et_Type = otype;
860
861     return (type);
862 }
863
864 /*
865  * Convert type to ref-to-type
866  *
867  * A reference type is similar to a pointer type except that the resolver is
868  * not able to entirely know what it is pointing to. The reference type is a
869  * superclass, but the actual type is stored in the run-time structure.
870  */
871 Type *
872 TypeToRefType(Type *otype)
873 {
874     Type   *type;
875
876     RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
877         if (type->ty_Op == TY_REFTO)
878             return (type);
879     }
880     type = AllocType(&otype->ty_QList, TY_REFTO);
881     type->ty_RefType.et_Type = otype;
882     return (type);
883 }
884
885 Type *
886 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
887 {
888     Type   *type;
889
890     /*
891      * XXX handle constant expression optimization for QList XXX handle
892      * qualifiers
893      */
894     type = AllocType(&otype->ty_QList, TY_ARYOF);
895     type->ty_AryType.et_OrigArySize = exp;
896     type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
897     type->ty_AryType.et_SemGroup = sg;
898     type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
899
900     return (type);
901 }
902
903 #if 0
904
905 Type *
906 TypeToRunTimeAryType(Type *otype, int count)
907 {
908     Type   *type;
909     Type   *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
910
911     RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
912         if (type->ty_Op == TY_ARYOF &&
913             type->ty_AryType.et_Type == t2 &&
914             type->ty_AryType.et_Count == count &&
915             type->ty_SQFlags ==
916             (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
917             ) {
918             return (type);
919         }
920     }
921     type = AllocType(&otype->ty_QList, TY_ARYOF);
922     type->ty_AryType.et_Count = count;
923     type->ty_AryType.et_Type = t2;
924     type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
925     return (type);
926 }
927
928 #endif
929
930 Type *
931 TypeToVarType(Type *otype, SemGroup *sg)
932 {
933     Type   *type;
934
935     /* dassert(sg->sg_Flags & SGF_RESOLVED); */
936     /* dassert(otype->ty_Flags & TF_RESOLVED); */
937
938     RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
939         if (type->ty_Op == TY_VAR &&
940             type->ty_VarType.et_Type == otype &&
941             type->ty_VarType.et_SemGroup == sg
942             ) {
943             puts("SG2");        /* YYY */
944             return (type);
945         }
946     }
947     type = AllocType(&otype->ty_QList, TY_VAR);
948     type->ty_VarType.et_Type = otype;
949     type->ty_VarType.et_SemGroup = sg;
950 #if 0
951     /* XXX doesn't work for var-args */
952     if (sg->sg_Flags & SGF_RESOLVED) {
953         type->ty_Flags |= TF_RESOLVED;
954         type->ty_Bytes = sg->sg_Bytes;
955         type->ty_AlignMask = sg->sg_AlignMask;
956     }
957 #endif
958     return (type);
959 }
960
961 /*
962  * ChangeType() - given pointer, C pointer, or array of something, return
963  * 'op' of something instead.
964  */
965 Type *
966 ChangeType(Type *type, int op)
967 {
968     switch (type->ty_Op) {
969     case TY_PTRTO:
970         switch (op) {
971         case TY_ARYOF:
972             type = TypeToAryType(type->ty_RawPtrType.et_Type,
973                                  NULL, NULL);
974             break;
975         default:
976             dpanic("Illegal type convesion (B)");
977         }
978         break;
979     case TY_ARYOF:
980         switch (op) {
981         case TY_PTRTO:
982             type = TypeToRawPtrType(type->ty_AryType.et_Type);
983             break;
984         default:
985             dpanic("Illegal type convesion (C)");
986         }
987         break;
988     default:
989         dpanic("Illegal type convesion (D)");
990     }
991     return (type);
992 }
993
994 /*
995  * BaseType() - return base type
996  *
997  * Traverse the type to locate the base type.  Store the base type in *ptype
998  * and return the SemGroup, or return NULL if the base type does not have a
999  * SemGroup.
1000  */
1001 SemGroup *
1002 BaseType(Type **ptype)
1003 {
1004     Type   *type = *ptype;
1005
1006     for (;;) {
1007         switch (type->ty_Op) {
1008         case TY_PTRTO:
1009             type = type->ty_RawPtrType.et_Type;
1010             continue;
1011         case TY_REFTO:
1012             type = type->ty_RefType.et_Type;
1013             continue;
1014         case TY_ARYOF:
1015             type = type->ty_AryType.et_Type;
1016             continue;
1017         }
1018         break;
1019     }
1020
1021     *ptype = type;
1022
1023     switch (type->ty_Op) {
1024     case TY_CLASS:
1025         return (type->ty_ClassType.et_SemGroup);
1026     case TY_COMPOUND:
1027         return (type->ty_CompType.et_SemGroup);
1028     case TY_ARGS:
1029         return (type->ty_ArgsType.et_SemGroup);
1030     case TY_PROC:
1031     case TY_VAR:
1032     case TY_DYNAMIC:
1033     case TY_STORAGE:
1034         return (NULL);
1035     case TY_UNRESOLVED:
1036     default:
1037         dassert_type(type, 0);
1038         return (NULL);          /* avoid compiler complaints */
1039     }
1040 }
1041
1042 /*
1043  * DupType()     - create a duplicate of a type, possibly in a new SemGroup.
1044  *
1045  * This code is used when duplicating procedures and other elements when
1046  * merging a superclass into a subclass.
1047  *
1048  * If sg is NULL, stype is simply returned.  The case is used when we try to
1049  * duplciate an expression with DupExp()... in that case we want to dup the
1050  * expression tree but use the same types.
1051  */
1052 Type *
1053 DupType(SemGroup *sg, Type *stype)
1054 {
1055     Type   *type = NULL;
1056
1057     if (sg == NULL)
1058         return (stype);
1059
1060     /*
1061      * XXX type may be resolved if it is part of a varargs dup
1062      */
1063 #if 0
1064     dassert_type(stype,
1065                  (stype->ty_Flags & (TF_RESOLVED | TF_RESOLVING)) == 0);
1066 #endif
1067
1068     switch (stype->ty_Op) {
1069     case TY_CLASS:
1070         /*
1071          * This only occurs because the resolver has resolved an unresolved
1072          * type on the original SemGroup.  We duplicate that on the new
1073          * SemGroup.
1074          */
1075         type = AllocClassType(&sg->sg_ClassList,
1076                               stype->ty_ClassType.et_Super,
1077                               stype->ty_ClassType.et_SemGroup,
1078                               stype->ty_Visibility);
1079         break;
1080     case TY_IMPORT:
1081     case TY_DYNAMIC:
1082         /*
1083          * For TY_IMPORT, leave et_SemGroup alone?
1084          */
1085         type = stype;
1086         break;
1087     case TY_PTRTO:
1088         type = TypeToRawPtrType(DupType(sg, stype->ty_RawPtrType.et_Type));
1089         break;
1090     case TY_REFTO:
1091         type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1092         break;
1093     case TY_ARYOF:
1094         /*
1095          * When redeclaring an array, the semantic context if the
1096          * [exp] needs to be able to see refined elements in subclasses,
1097          * even if the array declaration itself has not been refined.
1098          *
1099          * XXX however, this may make other elements in the subclass
1100          * visible to the [exp] that we did not refine (? TEST)
1101          */
1102 #if 1
1103         dassert(sg);
1104         type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1105                              stype->ty_AryType.et_OrigArySize,
1106                              sg);
1107 #else
1108         type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1109                              stype->ty_AryType.et_OrigArySize,
1110                              stype->ty_AryType.et_SemGroup);
1111 #endif
1112         type->ty_AryType.et_Count = stype->ty_AryType.et_Count;
1113         break;
1114     case TY_VAR:
1115         /*
1116          * varargs (whole thing), requires duplicating the semantic group
1117          * they are contained in too.
1118          */
1119         type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1120                     DupSemGroup(sg, NULL, stype->ty_VarType.et_SemGroup, 1));
1121         break;
1122     case TY_COMPOUND:
1123         type = AllocCompoundType(DupSemGroup(sg, NULL,
1124                                         stype->ty_CompType.et_SemGroup, 1));
1125         break;
1126     case TY_ARGS:
1127         /*
1128          * Arguments (whole thing), requires duplicating the semantic
1129          * group they are contained in too.
1130          *
1131          * At the moment we always formally duplicate the arguments so we can
1132          * modify them for methods below.
1133          */
1134         type = AllocArgsType(DupSemGroup(sg, NULL,
1135                                          stype->ty_CompType.et_SemGroup, 1));
1136         break;
1137     case TY_PROC:
1138         /*
1139          * Procedural type.
1140          */
1141         type = DupType(sg, stype->ty_ProcType.et_RetType);
1142         type = TypeToProcType(type,
1143                               DupType(sg, stype->ty_ProcType.et_ArgsType),
1144                               1);
1145         break;
1146     case TY_STORAGE:
1147         type = stype;
1148         break;
1149     case TY_UNRESOLVED:
1150         /*
1151          * e.g. so elements in a superclass will see refined elements in the
1152          * subclass.  Note that the original import semgroup is left intact
1153          * so the semantic search mechanism uses it when the base sg
1154          * (typically a subclass) fails.
1155          */
1156         type = AllocUnresolvedType(
1157                                    stype->ty_UnresType.et_ImportSemGroup,
1158                                    sg,
1159                                    stype->ty_UnresType.et_DottedId,
1160                                    0);
1161         break;
1162     default:
1163         dassert_type(stype, 0);
1164     }
1165
1166     if (type != stype) {
1167         type->ty_Flags = stype->ty_Flags &
1168             ~(TF_ISINTERNAL | TF_RESOLVING | TF_RESOLVED |
1169               TF_ALIGNRESOLVED | TF_TMPRESOLVED);
1170         type->ty_Bytes = stype->ty_Bytes;
1171         type->ty_AlignMask = stype->ty_AlignMask;
1172         type->ty_Visibility = stype->ty_Visibility;
1173         type->ty_DynamicVector = stype->ty_DynamicVector;
1174     }
1175     if (stype->ty_OrigAssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1176         type = TypeToQualType(type, NULL,
1177                               stype->ty_SQFlags, stype->ty_OrigAssExp);
1178     }
1179
1180     return (type);
1181 }
1182
1183 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1184
1185 void
1186 InternalRegisterType(const char *str, const char *linkname, Type *type)
1187 {
1188     TypeRegNode *tr;
1189
1190     tr = zalloc(sizeof(TypeRegNode));
1191     tr->tr_Id = runeid_hash(str, strlen(str));
1192     tr->tr_Type = type;
1193     tr->tr_LinkName = linkname;
1194     RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1195 }
1196
1197 Type *
1198 InternalRegisteredTypeLookup(runeid_t id)
1199 {
1200     TypeRegNode *tr;
1201
1202     RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1203         if (tr->tr_Id == id)
1204             return (tr->tr_Type);
1205     }
1206     return (NULL);
1207 }