Arrays - Slight unhacking of array[] expressions
[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;
14 Type IntegerType;
15 Type VoidType;
16 Type BoolType;
17 Type Int8Type;
18 Type UInt8Type;
19 Type Int16Type;
20 Type UInt16Type;
21 Type Int32Type;
22 Type UInt32Type;
23 Type Int64Type;
24 Type UInt64Type;
25
26 Type Float32Type;
27 Type Float64Type;
28 Type Float128Type;
29
30 Type CCharType;         /* const char           */
31 Type StrType;           /* const char *         */
32 Type CharPtrType;       /* char *               */
33 Type CharPtrPtrType;    /* char **              */
34 Type VoidPtrType;       /* void *               */
35 Type VoidRefType;       /* void @               */
36 Type CVoidPtrType;      /* const void *         */
37 Type LVoidPtrType;      /* lvalue void *        */
38
39 Type PointerType;       /* generic pointer placeholder */
40 Type IntPtrType;        /* not int * ... intptr_t */
41 Type UIntPtrType;       /* not int * ... intptr_t */
42
43 static List DynamicTypeList = INITLIST(DynamicTypeList);
44 static List CompoundTypeList = INITLIST(CompoundTypeList);
45 static List ArgsTypeList = INITLIST(ArgsTypeList);
46 static List StorageTypeList = INITLIST(StorageTypeList);
47
48 void
49 initType(Type *type, List *list, int op)
50 {
51         type->ty_Op = op;
52         initList(&type->ty_QList);
53         if (list)
54                 addTail(list, &type->ty_Node);
55         type->ty_SQList = list;
56 }
57
58 void
59 initQualType(Type *type, List *list, int op, int sqflags)
60 {
61         initType(type, list, op);
62         type->ty_SQFlags = sqflags;
63 }
64
65 void
66 initPtrType(Type *type, Type *ptrto, int sqflags)
67 {
68         initQualType(type, &ptrto->ty_QList, TY_PTRTO, sqflags);
69         type->ty_PtrType.et_Type = ptrto;
70         type->ty_PtrType.et_RefNull.rs_Type = ptrto;
71         type->ty_PtrType.et_RefNull.rs_Refs = 1;
72 }
73
74 static void
75 initRefType(Type *type, Type *refto, int sqflags)
76 {
77         initQualType(type, &refto->ty_QList, TY_REFTO, sqflags);
78         type->ty_RefType.et_Type = refto;
79         type->ty_RefType.et_RefNull.rs_Type = refto;
80         type->ty_RefType.et_RefNull.rs_Refs = 1;
81 }
82
83 void
84 TypeInit(void)
85 {
86         initQualType(&DynamicLValueType, &DynamicTypeList,
87                      TY_DYNAMIC, SF_LVALUE);
88         initType(&DynamicRValueType, &DynamicTypeList, TY_DYNAMIC);
89         initType(&NumericType, NULL, TY_UNRESOLVED);
90         initType(&IntegerType, NULL, TY_UNRESOLVED);
91         initType(&VoidType, NULL, TY_UNRESOLVED);
92         initType(&BoolType, NULL, TY_UNRESOLVED);
93         initType(&Int8Type, NULL, TY_UNRESOLVED);
94         initType(&UInt8Type, NULL, TY_UNRESOLVED);
95         initType(&Int16Type, NULL, TY_UNRESOLVED);
96         initType(&UInt16Type, NULL, TY_UNRESOLVED);
97         initType(&Int32Type, NULL, TY_UNRESOLVED);
98         initType(&UInt32Type, NULL, TY_UNRESOLVED);
99         initType(&Int64Type, NULL, TY_UNRESOLVED);
100         initType(&UInt64Type, NULL, TY_UNRESOLVED);
101
102         initType(&Float32Type, NULL, TY_UNRESOLVED);
103         initType(&Float64Type, NULL, TY_UNRESOLVED);
104         initType(&Float128Type, NULL, TY_UNRESOLVED);
105
106         initQualType(&CCharType, NULL, TY_UNRESOLVED, SF_CONST);
107         initPtrType(&StrType, &CCharType, 0);
108         initPtrType(&CharPtrType, &UInt8Type, 0);
109         initPtrType(&CharPtrPtrType, &CharPtrType, 0);
110         initPtrType(&VoidPtrType, &VoidType, 0);
111         initRefType(&VoidRefType, &VoidType, 0);
112         initPtrType(&CVoidPtrType, &VoidType, SF_CONST);
113         initPtrType(&LVoidPtrType, &VoidType, SF_LVALUE);
114
115         initType(&PointerType, NULL, TY_UNRESOLVED);
116         initType(&IntPtrType, NULL, TY_UNRESOLVED);
117         initType(&UIntPtrType, NULL, TY_UNRESOLVED);
118
119         StrTableAlloc("__internal_void", 15, SPECIAL_INTERNAL_VOID);
120         StrTableAlloc("__internal_bool", 15, SPECIAL_INTERNAL_BOOL);
121         StrTableAlloc("__internal_int8", 15, SPECIAL_INTERNAL_INT8);
122         StrTableAlloc("__internal_uint8", 16, SPECIAL_INTERNAL_UINT8);
123         StrTableAlloc("__internal_int16", 16, SPECIAL_INTERNAL_INT16);
124         StrTableAlloc("__internal_uint16", 17, SPECIAL_INTERNAL_UINT16);
125         StrTableAlloc("__internal_int32", 16, SPECIAL_INTERNAL_INT32);
126         StrTableAlloc("__internal_uint32", 17, SPECIAL_INTERNAL_UINT32);
127         StrTableAlloc("__internal_int64", 16, SPECIAL_INTERNAL_INT64);
128         StrTableAlloc("__internal_uint64", 17, SPECIAL_INTERNAL_UINT64);
129
130         StrTableAlloc("__internal_float32", 18, SPECIAL_INTERNAL_FLOAT32);
131         StrTableAlloc("__internal_float64", 18, SPECIAL_INTERNAL_FLOAT64);
132         StrTableAlloc("__internal_float128", 19, SPECIAL_INTERNAL_FLOAT128);
133
134         StrTableAlloc("__internal_pointer", 18, SPECIAL_INTERNAL_POINTER);
135         StrTableAlloc("__internal_intptr", 17, SPECIAL_INTERNAL_INTPTR);
136         StrTableAlloc("__internal_uintptr", 18, SPECIAL_INTERNAL_UINTPTR);
137
138         StrTableAlloc("__internal_numeric", 18, SPECIAL_INTERNAL_NUMERIC);
139         StrTableAlloc("__internal_integer", 18, SPECIAL_INTERNAL_INTEGER);
140
141         StrTableAlloc("__count",        7,      SPECIAL_COUNT);
142         StrTableAlloc("__data",         6,      SPECIAL_DATA);
143         StrTableAlloc("__varcount",     10,     SPECIAL_VAR_COUNT);
144         StrTableAlloc("__vardata",      9,      SPECIAL_VAR_DATA);
145         StrTableAlloc("__typeid",       8,      SPECIAL_TYPEID);
146         StrTableAlloc("__typestr",      9,      SPECIAL_TYPESTR);
147         StrTableAlloc("NULL",           4,      SPECIAL_NULL);
148 }
149
150 int
151 InternalTypeAttach(Parse *p, int t, Declaration *d)
152 {
153         Type *itype = NULL;
154         int s;
155
156         dassert_decl(d, d->d_Op == DOP_TYPEDEF);
157
158         if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
159                 switch(s) {
160                 case SPECIAL_INTERNAL_VOID:
161                         itype = &VoidType;
162                         break;
163                 case SPECIAL_INTERNAL_BOOL:
164                         itype = &BoolType;
165                         break;
166                 case SPECIAL_INTERNAL_INT8:
167                         itype = &Int8Type;
168                         break;
169                 case SPECIAL_INTERNAL_UINT8:
170                         itype = &UInt8Type;
171                         break;
172                 case SPECIAL_INTERNAL_INT16:
173                         itype = &Int16Type;
174                         break;
175                 case SPECIAL_INTERNAL_UINT16:
176                         itype = &UInt16Type;
177                         break;
178                 case SPECIAL_INTERNAL_INT32:
179                         itype = &Int32Type;
180                         break;
181                 case SPECIAL_INTERNAL_UINT32:
182                         itype = &UInt32Type;
183                         break;
184                 case SPECIAL_INTERNAL_INT64:
185                         itype = &Int64Type;
186                         break;
187                 case SPECIAL_INTERNAL_UINT64:
188                         itype = &UInt64Type;
189                         break;
190                 case SPECIAL_INTERNAL_FLOAT32:
191                         itype = &Float32Type;
192                         break;
193                 case SPECIAL_INTERNAL_FLOAT64:
194                         itype = &Float64Type;
195                         break;
196                 case SPECIAL_INTERNAL_FLOAT128:
197                         itype = &Float128Type;
198                         break;
199                 case SPECIAL_INTERNAL_POINTER:
200                         itype = &PointerType;
201                         break;
202                 case SPECIAL_INTERNAL_INTPTR:
203                         itype = &IntPtrType;
204                         break;
205                 case SPECIAL_INTERNAL_UINTPTR:
206                         itype = &UIntPtrType;
207                         break;
208                 case SPECIAL_INTERNAL_NUMERIC:
209                         itype = &NumericType;
210                         break;
211                 case SPECIAL_INTERNAL_INTEGER:
212                         itype = &IntegerType;
213                         break;
214                 default:
215                         itype = InternalRegisteredTypeLookup(d->d_Id);
216                         if (itype == NULL)
217                                 dassert(0);
218                         break;
219                 }
220         }
221         if (itype) {
222                 if (itype->ty_Op != TY_UNRESOLVED) {
223                         t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
224                 } else {
225                         Type *ntype = d->d_TypedefDecl.ed_Type;
226
227                         TypeToQualType(ntype, itype, ntype->ty_SQFlags, NULL);
228
229                         /*
230                          * fixup for const int8 pointers... we did not have
231                          * a QList to put CCharType on until now.  It will
232                          * wind up on the SemGroup's sg_ClassList.
233                          */
234                         if (itype == &UInt8Type) {
235                                 TypeToQualType(ntype, &CCharType,
236                                         ntype->ty_SQFlags | SF_CONST, NULL);
237                         } 
238                 }
239         } else {
240                 t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
241         }
242         return(t);
243 }
244
245 Type *
246 AllocType(List *list, int op)
247 {
248         Type *type = zalloc(sizeof(Type));
249
250         initType(type, list, op);
251         return(type);
252 }
253
254 /*
255  * XXX match the compound type(s)
256  *
257  * May be used to generate a varargs compound type, in which case the
258  * semgroup may already be resolved.
259  */
260 Type *
261 AllocCompoundType(SemGroup *sg)
262 {
263         Type *type;
264
265         type = AllocType(&CompoundTypeList, TY_COMPOUND);
266         type->ty_CompType.et_SemGroup = sg;
267         dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
268         return(type);
269 }
270
271 /*
272  * XXX match the compound type(s)
273  */
274 Type *
275 AllocArgsType(SemGroup *sg)
276 {
277         Type *type;
278
279         type = AllocType(&ArgsTypeList, TY_ARGS);
280         type->ty_ArgsType.et_SemGroup = sg;
281         return(type);
282 }
283
284 Type *
285 AllocStorageType(int bytes)
286 {
287         Type *type;
288
289         for (
290                 type = getHead(&StorageTypeList); 
291                 type; 
292                 type = getSucc(&StorageTypeList, &type->ty_Node)
293         ) {
294                 if (type->ty_Op == TY_STORAGE &&
295                         type->ty_StorType.et_Bytes == bytes
296                 ) {
297                         return(type);
298                 }
299         }
300         type = AllocType(&StorageTypeList, TY_STORAGE);
301         type->ty_StorType.et_Bytes = bytes;
302         return(type);
303 }
304
305 Type *
306 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, string_t *ary, int eatAry)
307 {
308         Type *type = NULL;
309
310         dassert_semgrp(sg, ary != NULL);
311
312         for (
313                 type = getHead(&sg->sg_ClassList);
314                 type;
315                 type = getSucc(&sg->sg_ClassList, &type->ty_Node)
316         ) {
317                 int i;
318
319                 if (type->ty_Op != TY_UNRESOLVED)
320                         continue;
321                 if (type->ty_UnresType.et_ImportSemGroup != isg)
322                         continue;
323
324                 for (i = 0; ary[i]; ++i) {
325                         if (ary[i] != type->ty_UnresType.et_DottedId[i])
326                                 break;
327                 }
328                 if (ary[i] == NULL &&
329                     type->ty_UnresType.et_DottedId[i] == NULL) {
330                         if (eatAry)
331                                 FreeDotIdAry(ary);
332                         return(type);
333                 }
334         }
335         type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
336         type->ty_UnresType.et_DottedId = ary;
337         type->ty_UnresType.et_SemGroup = sg;            /* may be NULL */
338         type->ty_UnresType.et_ImportSemGroup = isg;     /* may be NULL */
339         return(type);
340 }
341
342 /*
343  * AllocClassType() - allocate a type representing a the semgroup which
344  *                      in turn represents (typically) a class.
345  */
346 Type *
347 AllocClassType(List *list, Type *super, SemGroup *sg, int visibility)
348 {
349         Type *type;
350
351         for (type = getHead(list); type; type = getSucc(list, &type->ty_Node)) {
352                 if (type->ty_Op == TY_CLASS &&
353                     type->ty_ClassType.et_SemGroup == sg &&
354                     type->ty_ClassType.et_Super == super &&
355                     type->ty_Visibility == visibility
356                 ) {
357                         return(type);
358                 }
359         }
360         type = AllocType(list, TY_CLASS);
361         type->ty_ClassType.et_SemGroup = sg;
362         type->ty_ClassType.et_Super = super;
363         type->ty_Visibility = visibility;
364         return(type);
365 }
366
367 Type *
368 AllocImportType(List *list, SemGroup *sg, int visibility)
369 {
370         Type *type = AllocType(list, TY_IMPORT);
371
372         type->ty_ImportType.et_SemGroup = sg;
373         type->ty_Visibility = visibility;
374         return(type);
375 }
376
377 Type *
378 TypeToQualType(Type *otype, Type *ntype, int sqFlags, Exp *exp)
379 {
380         /*
381          * Combine with existing qualifiers, Shortcut if no changes made.
382          */
383         if (ntype == NULL && 
384             sqFlags == otype->ty_SQFlags &&
385             (exp == NULL || exp == otype->ty_AssExp)
386         ) {
387                 return(otype);
388         }
389
390         /*
391          * See if we already have a matching qualified type (only if storage
392          * for the new type is not being provided).  Note: the provided storage
393          * has already been initType()d
394          */
395         if (ntype == NULL) {
396                 for (ntype = getHead(otype->ty_SQList);
397                      ntype;
398                      ntype = getSucc(otype->ty_SQList, &ntype->ty_Node)
399                 ) {
400                         if (ntype->ty_Op == otype->ty_Op && 
401                             ntype->ty_SQFlags == sqFlags &&
402                             (exp == NULL || ntype->ty_AssExp == exp)
403                         ) {
404                                 if (SameType(ntype, otype, sqFlags))
405                                         return(ntype);
406                         }
407                 }
408         }
409
410         /*
411          * Build a new qualified type and set its qualifiers, then duplicate
412          * appropriate sections of the old type.
413          */
414         if (ntype == NULL) {
415                 ntype = AllocType(otype->ty_SQList, otype->ty_Op);
416         } else if (ntype->ty_SQList == NULL) {
417                 ntype->ty_SQList = otype->ty_SQList;
418                 addTail(ntype->ty_SQList, &ntype->ty_Node);
419         }
420
421         /*
422          * Set the op and the expression.  Unlike SQFlags, if exp is passed as
423          * NULL we inherit the old type's default.
424          *
425          * The DupExp() call here is special, see DupExp()'s handling of
426          * ex_Decl.
427          *
428          * Normally DupExp() is called during resolution prior to ex_Decl
429          * being set.  This is the one case where it may be called with
430          * ex_Decl already set.
431          */
432         ntype->ty_Op = otype->ty_Op;
433         if (exp)
434                 ntype->ty_AssExp = exp;
435         else if (otype->ty_AssExp)
436                 ntype->ty_AssExp = SetDupExp(NULL, otype->ty_AssExp);
437         ntype->ty_SQFlags = sqFlags;
438         ntype->ty_Visibility = otype->ty_Visibility;
439
440         switch(otype->ty_Op) {
441         case TY_CLASS:
442                 ntype->ty_ClassType.et_SemGroup =
443                         otype->ty_ClassType.et_SemGroup;
444                 ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
445                 break;
446         case TY_IMPORT:
447                 ntype->ty_Visibility = otype->ty_Visibility;
448                 ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
449                 break;
450         case TY_CPTRTO:
451                 ntype->ty_CPtrType.et_Type = otype->ty_CPtrType.et_Type;
452                 ntype->ty_CPtrType.et_RefNull.rs_Type =
453                         ntype->ty_CPtrType.et_Type;
454                 ntype->ty_CPtrType.et_RefNull.rs_Refs = 1;
455                 break;
456         case TY_PTRTO:
457                 ntype->ty_PtrType.et_Type = otype->ty_PtrType.et_Type;
458                 ntype->ty_PtrType.et_RefNull.rs_Type =
459                         ntype->ty_PtrType.et_Type;
460                 ntype->ty_PtrType.et_RefNull.rs_Refs = 1;
461                 break;
462         case TY_REFTO:
463                 ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
464                 ntype->ty_RefType.et_RefNull.rs_Type =
465                         ntype->ty_RefType.et_Type;
466                 ntype->ty_RefType.et_RefNull.rs_Refs = 1;
467                 break;
468         case TY_ARYOF:
469                 /*
470                  * note: multiple type structures may share the same array size
471                  * expression in simple qualified-type cases.  YYY XXX bad bad.
472                  */
473                 ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
474                 ntype->ty_AryType.et_ArySize = otype->ty_AryType.et_ArySize;
475                 ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
476                 break;
477         case TY_COMPOUND:
478                 ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
479                 break;
480         case TY_VAR:
481                 ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
482                 ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
483                 break;
484         case TY_ARGS:
485                 ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
486                 break;
487         case TY_PROC:
488                 ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
489                 ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
490                 ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
491                 break;
492         case TY_STORAGE:
493                 ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
494                 break;
495         case TY_DYNAMIC:
496                 /*
497                  * It is not legal to qualify a dynamic type other then to
498                  * add or remove SF_LVALUE.
499                  */
500                 dassert(0);
501                 break;
502         case TY_UNRESOLVED:
503                 ntype->ty_UnresType.et_DottedId =
504                         otype->ty_UnresType.et_DottedId;
505                 ntype->ty_UnresType.et_SemGroup =
506                         otype->ty_UnresType.et_SemGroup;
507                 break;
508         default:
509                 dassert_type(otype, 0);
510         }
511         return(ntype);
512 }
513
514 /*
515  * XXX match the procedure type(s)
516  */
517 Type *
518 TypeToProcType(Type *rtype, Type *atype)
519 {
520         Type *type;
521         int count = 0;
522         Declaration *d;
523         SemGroup *sg;
524
525         dassert_type(atype, atype->ty_Op == TY_ARGS);
526         sg = atype->ty_CompType.et_SemGroup;
527
528         for (
529                 d = getHead(&sg->sg_DeclList);
530                 d;
531                 d = getSucc(&sg->sg_DeclList, &d->d_Node)
532         ) {
533                 ++count;
534         }
535         for (
536                 type = getHead(&rtype->ty_QList);
537                 type;
538                 type = getSucc(&rtype->ty_QList, &type->ty_Node)
539         ) {
540                 if (type->ty_Op == TY_PROC) {
541                         if (type->ty_ProcType.et_ArgsType == atype &&
542                             type->ty_ProcType.et_RetType == rtype &&
543                             type->ty_ProcType.et_ArgCount == count
544                         ) {
545                                 puts("SG1"); /* YYY */
546                                 return(type);
547                         }
548                 }
549         }
550         type = AllocType(&rtype->ty_QList, TY_PROC);
551         type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
552         type->ty_ProcType.et_RetType = rtype;
553         type->ty_ProcType.et_ArgCount = count;
554         return(type);
555 }
556
557 /*
558  * Convert type to pointer-to-type
559  */
560 Type *
561 TypeToPtrType(Type *otype)
562 {
563         Type *type;
564
565         for (type = getHead(&otype->ty_QList);
566              type;
567              type = getSucc(&otype->ty_QList, &type->ty_Node)
568         ) {
569                 if (type->ty_Op == TY_PTRTO)
570                         return(type);
571         }
572         type = AllocType(&otype->ty_QList, TY_PTRTO);
573         type->ty_PtrType.et_Type = otype;
574         type->ty_PtrType.et_RefNull.rs_Type = otype;
575         type->ty_PtrType.et_RefNull.rs_Refs = 1;
576         return(type);
577 }
578
579 /*
580  * Convert type to pointer-to-type
581  */
582 Type *
583 TypeToCPtrType(Type *otype)
584 {
585         Type *type;
586
587         for (type = getHead(&otype->ty_QList);
588              type;
589              type = getSucc(&otype->ty_QList, &type->ty_Node)
590         ) {
591                 if (type->ty_Op == TY_CPTRTO)
592                         return(type);
593         }
594         type = AllocType(&otype->ty_QList, TY_CPTRTO);
595         type->ty_CPtrType.et_Type = otype;
596         type->ty_CPtrType.et_RefNull.rs_Type = otype;
597         type->ty_CPtrType.et_RefNull.rs_Refs = 1;
598         return(type);
599 }
600
601 /*
602  * Convert type to ref-to-type
603  *
604  *      A reference type is similar to a pointer type except that the
605  *      resolver is not able to entirely know what it is pointing to.
606  *      The reference type is a superclass, but the actual type is 
607  *      stored in the run-time structure.
608  */
609 Type *
610 TypeToRefType(Type *otype)
611 {
612         Type *type;
613
614         for (type = getHead(&otype->ty_QList);
615              type;
616              type = getSucc(&otype->ty_QList, &type->ty_Node)
617         ) {
618                 if (type->ty_Op == TY_REFTO)
619                         return(type);
620         }
621         type = AllocType(&otype->ty_QList, TY_REFTO);
622         type->ty_RefType.et_Type = otype;
623         type->ty_RefType.et_RefNull.rs_Type = otype;
624         type->ty_RefType.et_RefNull.rs_Refs = 1;
625         return(type);
626 }
627
628 Type *
629 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
630 {
631         Type *type;
632
633         /*
634          * XXX handle constant expression optimization for QList
635          * XXX handle qualifiers
636          */
637         type = AllocType(&otype->ty_QList, TY_ARYOF);
638         type->ty_AryType.et_ArySize = exp;
639         type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
640         type->ty_AryType.et_SemGroup = sg;
641         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
642         return(type);
643 }
644
645 #if 0
646
647 Type *
648 TypeToRunTimeAryType(Type *otype, int count)
649 {
650         Type *type;
651         Type *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
652
653         for (type = getHead(&otype->ty_QList);
654              type;
655              type = getSucc(&otype->ty_QList, &type->ty_Node)
656         ) {
657                 if (type->ty_Op == TY_ARYOF &&
658                         type->ty_AryType.et_Type == t2 &&
659                         type->ty_AryType.et_Count == count &&
660                         type->ty_SQFlags ==
661                          (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
662                 ) {
663                         return(type);
664                 }
665         }
666         type = AllocType(&otype->ty_QList, TY_ARYOF);
667         type->ty_AryType.et_Count = count;
668         type->ty_AryType.et_Type = t2;
669         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
670         return(type);
671 }
672
673 #endif
674
675 Type *
676 TypeToVarType(Type *otype, SemGroup *sg)
677 {
678         Type *type;
679
680         dassert(sg->sg_Flags & SGF_RESOLVED);
681         dassert(otype->ty_Flags & TF_RESOLVED);
682
683         for (type = getHead(&otype->ty_QList);
684              type;
685              type = getSucc(&otype->ty_QList, &type->ty_Node)
686         ) {
687                 if (type->ty_Op == TY_VAR &&
688                     type->ty_VarType.et_Type == otype &&
689                     type->ty_VarType.et_SemGroup == sg
690                 ) {
691                         puts("SG2"); /* YYY */
692                         return(type);
693                 }
694         }
695         type = AllocType(&otype->ty_QList, TY_VAR);
696         type->ty_VarType.et_Type = otype;
697         type->ty_VarType.et_SemGroup = sg;
698         if (sg->sg_Flags & SGF_RESOLVED) {
699                 type->ty_Flags |= TF_RESOLVED;
700                 type->ty_Bytes = sg->sg_Bytes;
701                 type->ty_AlignMask = sg->sg_AlignMask;
702         }
703         return(type);
704 }
705
706 /*
707  * ChangeType() - given pointer, C pointer, or array of something,
708  *                return 'op' of something instead.
709  */
710 Type *
711 ChangeType(Type *type, int op)
712 {
713         switch(type->ty_Op) {
714         case TY_PTRTO:
715                 switch(op) {
716                 case TY_CPTRTO:
717                         type = TypeToCPtrType(type->ty_PtrType.et_Type);
718                         break;
719                 case TY_ARYOF:
720                         type = TypeToAryType(type->ty_PtrType.et_Type,
721                                              NULL, NULL);
722                         break;
723                 default:
724                         dassert(0);
725                 }
726                 break;
727         case TY_CPTRTO:
728                 switch(op) {
729                 case TY_PTRTO:
730                         type = TypeToPtrType(type->ty_CPtrType.et_Type);
731                         break;
732                 case TY_ARYOF:
733                         type = TypeToAryType(type->ty_CPtrType.et_Type,
734                                              NULL, NULL);
735                         break;
736                 default:
737                         dassert(0);
738                 }
739                 break;
740         case TY_ARYOF:
741                 switch(op) {
742                 case TY_PTRTO:
743                         type = TypeToPtrType(type->ty_AryType.et_Type);
744                         break;
745                 case TY_CPTRTO:
746                         type = TypeToCPtrType(type->ty_AryType.et_Type);
747                         break;
748                 default:
749                         dassert(0);
750                 }
751                 break;
752         default:
753                 dassert(0);
754         }
755         return(type);
756 }
757
758 /*
759  * BaseType() - return base type
760  *
761  *      Traverse the type to locate the base type.  Store the base type
762  *      in *ptype and return the SemGroup, or return NULL if the base type
763  *      does not have a SemGroup.
764  */
765 SemGroup *
766 BaseType(Type **ptype)
767 {
768         Type *type = *ptype;
769
770         for (;;) {
771                 switch(type->ty_Op) {
772                 case TY_CPTRTO:
773                         type = type->ty_CPtrType.et_Type;
774                         continue;
775                 case TY_PTRTO:
776                         type = type->ty_PtrType.et_Type;
777                         continue;
778                 case TY_REFTO:
779                         type = type->ty_RefType.et_Type;
780                         continue;
781                 case TY_ARYOF:
782                         type = type->ty_AryType.et_Type;
783                         continue;
784                 }
785                 break;
786         }
787
788         *ptype = type;
789
790         switch(type->ty_Op) {
791         case TY_CLASS:
792                 return(type->ty_ClassType.et_SemGroup);
793         case TY_COMPOUND:
794                 return(type->ty_CompType.et_SemGroup);
795         case TY_ARGS:
796                 return(type->ty_ArgsType.et_SemGroup);
797         case TY_PROC:
798         case TY_VAR:
799         case TY_DYNAMIC:
800         case TY_STORAGE:
801                 return(NULL);
802         case TY_UNRESOLVED:
803         default:
804                 dassert_type(type, 0);
805                 return(NULL);   /* avoid compiler complaints */
806         }
807 }
808
809 /*
810  * MatchType() -        Match two types
811  *
812  *      Match two types as if we wanted to cast type to super or use
813  *      type as super.
814  *
815  *      SG_COMPAT_FULL          Type is a subclass, methods and storage are
816  *                              compatible (storage may be extended).
817  *
818  *      SG_COMPAT_PART          Type is a subclass, methods are compatible
819  *                              but storage is not.
820  *
821  *      SG_COMPAT_SUBCLASS      Type is a subclass, but the methods are
822  *                              not directly compatible (the methods that
823  *                              propogate down must be regenerated).
824  *      SG_COMPAT_FAIL          Type is not even a subclass
825  *
826  *      XXX we are skipping qualifiers
827  */
828 int
829 MatchType(Type *super, Type *type)
830 {
831         int r = SG_COMPAT_FULL;
832
833         while (super && type) {
834                 SemGroup *sg1 = NULL;
835                 SemGroup *sg2 = NULL;
836
837                 if (type->ty_Op != super->ty_Op) {
838                         if (super->ty_Op == TY_REFTO &&
839                             type->ty_Op == TY_PTRTO) {
840                                 super = super->ty_RefType.et_Type;
841                                 type = type->ty_PtrType.et_Type;
842                                 r = MatchType(super, type);
843                         } else {
844                                 r = SG_COMPAT_FAIL;
845                         }
846                         break;
847                 }
848                 switch(super->ty_Op) {
849                 case TY_CLASS:
850                         /*
851                          * type can be a subclass of super
852                          */
853                         if (type->ty_ClassType.et_SemGroup ==
854                             super->ty_ClassType.et_SemGroup) {
855                                 return(r);
856                         }
857                         r = type->ty_ClassType.et_SemGroup->sg_Compat;
858 #if 0
859                         if (r < SG_COMPAT_PART)
860                                 r = SG_COMPAT_PART;
861 #endif
862                         while ((type = type->ty_ClassType.et_Super) != NULL) {
863                                 if (type->ty_ClassType.et_SemGroup ==
864                                     super->ty_ClassType.et_SemGroup) {
865                                         break;
866                                 }
867                                 if (r < type->ty_ClassType.et_SemGroup->sg_Compat)
868                                         r = type->ty_ClassType.et_SemGroup->sg_Compat;
869                         }
870                         if (type == NULL)       /* not even a subclass */
871                                 r = SG_COMPAT_FAIL;
872                         break;
873                 case TY_IMPORT:
874                         /*
875                          * type can be a subclass of super
876                          */
877                         if (type != super)
878                                 r = SG_COMPAT_FAIL;
879                         break;
880                 case TY_CPTRTO:
881                         type = type->ty_CPtrType.et_Type;
882                         super = super->ty_CPtrType.et_Type;
883                         continue;
884                 case TY_PTRTO:
885                         type = type->ty_PtrType.et_Type;
886                         super = super->ty_PtrType.et_Type;
887                         continue;
888                 case TY_REFTO:
889                         type = type->ty_RefType.et_Type;
890                         super = super->ty_RefType.et_Type;
891                         continue;
892                 case TY_ARYOF:
893                         type = type->ty_AryType.et_Type;
894                         super = super->ty_AryType.et_Type;
895                         /* XXX */
896                         continue;
897                 case TY_COMPOUND:
898                         sg1 = super->ty_CompType.et_SemGroup;
899                         sg2 = type->ty_CompType.et_SemGroup;
900                         break;
901                 case TY_ARGS:
902                         sg1 = super->ty_ArgsType.et_SemGroup;
903                         sg2 = type->ty_ArgsType.et_SemGroup;
904                         break;
905                 case TY_VAR:
906                         r = MatchType(super->ty_VarType.et_Type,
907                                       type->ty_VarType.et_Type);
908                         break;
909                 case TY_PROC:
910                         {
911                                 int v;
912
913                                 r = MatchType(super->ty_ProcType.et_ArgsType, 
914                                               type->ty_ProcType.et_ArgsType);
915                                 v = MatchType(super->ty_ProcType.et_RetType,
916                                               type->ty_ProcType.et_RetType);
917                                 if (r < v)
918                                         r = v;
919                         }
920                         break;
921                 case TY_DYNAMIC:
922                         break;
923                 case TY_STORAGE:
924                         if (type->ty_StorType.et_Bytes !=
925                             super->ty_StorType.et_Bytes) {
926                                 r = SG_COMPAT_SUBCLASS;
927                         }
928                         break;
929                 case TY_UNRESOLVED:
930                 default:
931                         dassert_type(super, 0); /* can't happen */
932                         break;
933                 }
934                 if (sg1) {
935                         Declaration *sd = getHead(&sg1->sg_DeclList);
936                         Declaration *rd = getHead(&sg2->sg_DeclList);
937                         while (sd && rd) {
938                                 int v = MatchDeclTypes(sd, rd);
939                                 if (r < v)
940                                         r = v;
941                                 if (r == SG_COMPAT_FAIL)
942                                         break;
943                                 sd = getSucc(&sg1->sg_DeclList, &sd->d_Node);
944                                 rd = getSucc(&sg2->sg_DeclList, &rd->d_Node);
945                         }
946                         if (sd || rd)
947                                 r = SG_COMPAT_FAIL;
948                 }
949                 break;
950         }
951         return(r);
952 }
953
954 /*
955  * DupType()     - create a duplicate of a type, possibly in a new SemGroup.
956  *
957  *      This code is used when duplicating procedures and other elements
958  *      when merging a superclass into a subclass.
959  *
960  *      If sg is NULL, stype is simply returned.  The case is used when we
961  *      try to duplciate an expression with DupExp()... in that case we
962  *      want to dup the expression tree but use the same types.
963  */
964 Type *
965 DupType(SemGroup *sg, Type *stype)
966 {
967         Type *type = NULL;
968
969         if (sg == NULL)
970                 return(stype);
971
972         /*
973          * XXX type may be resolved if it is part of a varargs dup
974          */
975 #if 0
976         dassert_type(stype,
977                      (stype->ty_Flags & (TF_RESOLVED|TF_RESOLVING)) == 0);
978 #endif
979
980         switch(stype->ty_Op) {
981         case TY_CLASS:
982                 /*
983                  * This only occurs because the resolver has resolved an
984                  * unresolved type on the original SemGroup.  We duplicate
985                  * that on the new SemGroup.
986                  */
987                 type = AllocClassType(&sg->sg_ClassList,
988                                       stype->ty_ClassType.et_Super,
989                                       stype->ty_ClassType.et_SemGroup,
990                                       stype->ty_Visibility);
991                 break;
992         case TY_IMPORT:
993         case TY_DYNAMIC:
994                 type = stype;
995                 break;
996         case TY_CPTRTO:
997                 type = TypeToCPtrType(DupType(sg, stype->ty_CPtrType.et_Type));
998                 break;
999         case TY_PTRTO:
1000                 type = TypeToPtrType(DupType(sg, stype->ty_PtrType.et_Type));
1001                 break;
1002         case TY_REFTO:
1003                 type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1004                 break;
1005         case TY_ARYOF:
1006                 type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1007                                 SetDupExp(sg, stype->ty_AryType.et_ArySize),
1008                                 stype->ty_AryType.et_SemGroup);
1009                 break;
1010         case TY_VAR:
1011                 type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1012                                 DupSemGroup(sg, NULL,
1013                                             stype->ty_VarType.et_SemGroup, 1));
1014                 break;
1015         case TY_COMPOUND:
1016                 type = AllocCompoundType(
1017                                 DupSemGroup(sg, NULL,
1018                                             stype->ty_CompType.et_SemGroup, 1));
1019                 break;
1020         case TY_ARGS:
1021                 /*
1022                  * At the moment we always formally duplicate the arguments
1023                  * so we can modify them for methods below.
1024                  */
1025                 type = AllocArgsType(
1026                                 DupSemGroup(sg, NULL,
1027                                             stype->ty_CompType.et_SemGroup, 1));
1028                 break;
1029         case TY_PROC:
1030                 type = DupType(sg, stype->ty_ProcType.et_RetType);
1031                 type = TypeToProcType(type,
1032                                       DupType(sg,
1033                                               stype->ty_ProcType.et_ArgsType));
1034
1035                 /*
1036                  * If this is a method procedure, we have to change the
1037                  * first argument to point at our new subclass.  It was
1038                  * previously pointing at our superclass.   XXX the
1039                  * programmer can override the argument.  If it isn't a
1040                  * reference we have to assert.
1041                  */
1042                 if (stype->ty_SQFlags & SF_METHOD) {
1043                         SemGroup *asg = type->ty_ProcType.et_ArgsType->ty_ArgsType.et_SemGroup;
1044                         Declaration *d = getHead(&asg->sg_DeclList);
1045                         Type *thisType = d->d_StorDecl.ed_Type;
1046
1047                         dassert_decl(d, d->d_Id == String_This &&
1048                                         d->d_Op == DOP_ARGS_STORAGE);
1049                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1050                         if (thisType->ty_Op == TY_CLASS) {
1051                                 /* XXX sg_ClassList? right sg? */
1052                                 /* XXX correct visibility? */
1053                                 if (d->d_Search == NULL) {
1054                                         d->d_Search = d->d_StorDecl.ed_Type->
1055                                                       ty_ClassType.et_SemGroup;
1056                                 }
1057                                 d->d_StorDecl.ed_Type =
1058                                         AllocClassType(&sg->sg_ClassList,
1059                                                        sg->sg_Stmt->st_ClassStmt.es_Super,
1060                                                        sg->sg_Stmt->st_MyGroup,
1061                                                        SCOPE_ALL_VISIBLE);
1062                         } else {
1063                                 dassert_decl(d, thisType->ty_Op == TY_REFTO);
1064                         }
1065                 } else if (stype->ty_SQFlags & SF_GMETHOD) {
1066                         SemGroup *asg;
1067                         Declaration *d;
1068
1069                         asg = type->ty_ProcType.et_ArgsType->
1070                                 ty_ArgsType.et_SemGroup;
1071                         d = getHead(&asg->sg_DeclList);
1072
1073                         dassert_decl(d, d->d_Id == String_This &&
1074                                      d->d_Op == DOP_TYPEDEF);
1075                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1076                         dassert_decl(d, d->d_TypedefDecl.ed_Type->ty_Op ==
1077                                         TY_CLASS);
1078                         /* XXX sg_ClassList? right sg? */
1079                         /* XXX correct visibility? */
1080                         if (d->d_Search == NULL) {
1081                                 d->d_Search = d->d_TypedefDecl.ed_Type->
1082                                                ty_ClassType.et_SemGroup;
1083                         }
1084                         d->d_TypedefDecl.ed_Type =
1085                                 AllocClassType(&sg->sg_ClassList,
1086                                                sg->sg_Stmt->st_ClassStmt.es_Super,
1087                                                sg->sg_Stmt->st_MyGroup,
1088                                                SCOPE_ALL_VISIBLE);
1089                 }
1090                 break;
1091         case TY_STORAGE:
1092                 type = stype;
1093                 break;
1094         case TY_UNRESOLVED:
1095                 /*
1096                  * e.g. so elements in a superclass will see refined elements
1097                  * in the subclass.  Note that the original import semgroup
1098                  * is left intact so the semantic search mechanism uses it
1099                  * when the base sg (typically a subclass) fails.
1100                  */
1101                 type = AllocUnresolvedType(
1102                                 stype->ty_UnresType.et_ImportSemGroup,
1103                                 sg,
1104                                 stype->ty_UnresType.et_DottedId,
1105                                 0);
1106                 break;
1107         default:
1108                 dassert_type(stype, 0);
1109         }
1110
1111         if (type != stype) {
1112                 type->ty_Flags = stype->ty_Flags;
1113                 type->ty_Bytes = stype->ty_Bytes;
1114                 type->ty_AlignMask = stype->ty_AlignMask;
1115                 type->ty_Visibility = stype->ty_Visibility;
1116         }
1117         if (stype->ty_AssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1118                 type = TypeToQualType(type, NULL,
1119                                       stype->ty_SQFlags,
1120                                       SetDupExp(sg, stype->ty_AssExp));
1121         }
1122
1123         return(type);
1124 }
1125
1126 /*
1127  * SameType() - return 1 if the types are equilvalent, 0 if they are not.
1128  *
1129  *      The sqFlags for t2 may be overriden.  If you do not wish to override
1130  *      the sqFlags for t2, pass t2->ty_SQFlags for sqFlags.  The override
1131  *      only applies to the top level of the type.
1132  *
1133  *      Types can be aliased - for example, two different type structures
1134  *      may point to the same class data.
1135  *
1136  *      XXX this needs a lot of work.  We really need to guarentee
1137  *      some level of uniqueness for non-qualified type elements.
1138  */
1139 int
1140 SameType(Type *t1, Type *t2, int sqFlags2)
1141 {
1142         for (;;) {
1143                 if (t1 == t2)
1144                         return(1);
1145                 if (t1->ty_Op != t2->ty_Op)
1146                         break;
1147                 if (t1->ty_SQFlags != sqFlags2)
1148                         break;
1149                 switch(t1->ty_Op) {
1150                 case TY_IMPORT:
1151                         if (t1->ty_ImportType.et_SemGroup ==
1152                             t2->ty_ImportType.et_SemGroup)
1153                         {
1154                                 return(1);
1155                         }
1156                         return(0);
1157                 case TY_CLASS:
1158                         if (t1->ty_ClassType.et_SemGroup ==
1159                              t2->ty_ClassType.et_SemGroup &&
1160                             t1->ty_ClassType.et_Super ==
1161                              t2->ty_ClassType.et_Super)
1162                         {
1163                                 return(1);
1164                         }
1165                         return(0);
1166                 case TY_CPTRTO:
1167                         t1 = t1->ty_CPtrType.et_Type;
1168                         t2 = t2->ty_CPtrType.et_Type;
1169                         break;
1170                 case TY_PTRTO:
1171                         t1 = t1->ty_PtrType.et_Type;
1172                         t2 = t2->ty_PtrType.et_Type;
1173                         break;
1174                 case TY_REFTO:
1175                         t1 = t1->ty_RefType.et_Type;
1176                         t2 = t2->ty_RefType.et_Type;
1177                         break;
1178                 case TY_ARYOF:
1179                 case TY_VAR:
1180                 case TY_COMPOUND:
1181                 case TY_PROC:
1182                         /* XXX */
1183                         return(0);
1184                 case TY_STORAGE:
1185                 case TY_ARGS:
1186                 case TY_UNRESOLVED:
1187                 case TY_DYNAMIC:
1188                         /* XXX */
1189                         return(0);
1190                 default:
1191                         dassert_type(t1, 0);
1192                         return(0);
1193                 }
1194                 sqFlags2 = t2->ty_SQFlags;
1195         }
1196         return(0);
1197 }
1198
1199 /*
1200  * SimilarType() - like SameType(), but ignores storage qualifiers and
1201  *                 if t2 is varargs, compares the original version.
1202  *
1203  *    Used when casting t2 (rhs) to t1 (lhs).
1204  */
1205 int
1206 SimilarType(Type *t1, Type *t2)
1207 {
1208         if (t2->ty_Op == TY_VAR)
1209                 t2 = t2->ty_VarType.et_Type;
1210         for (;;) {
1211                 if (t1 == t2)
1212                         return(1);
1213 #if 0
1214                 /*
1215                  * Normally we fail if the ops do not match, but it is legal to
1216                  * cast a pointer (t2) to a reference type (t1) if the ref type
1217                  * is its superclass.  It is also legal to cast an array to a
1218                  * pointer or C pointer.
1219                  */
1220                 if (t2->ty_Op != t1->ty_Op) {
1221                         /*
1222                          * pointer->ref
1223                          */
1224                         if (t2->ty_Op == TY_PTRTO && t1->ty_Op == TY_REFTO) {
1225                                 t1 = t1->ty_RefType.et_Type;
1226                                 t2 = t2->ty_PtrType.et_Type;
1227                                 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
1228                                         return(1);
1229                                 }
1230                                 return(0);
1231                         }
1232                         /*
1233                          * array->pointer
1234                          */
1235                         if (t2->ty_Op == TY_ARYOF && t1->ty_Op == TY_PTRTO) {
1236                                 t1 = t1->ty_PtrType.et_Type;
1237                                 t2 = t2->ty_AryType.et_Type;
1238                                 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
1239                                         return(1);
1240                                 }
1241                                 return(0);
1242                         }
1243                         /*
1244                          * array->cpointer
1245                          */
1246                         if (t2->ty_Op == TY_ARYOF && t1->ty_Op == TY_CPTRTO) {
1247                                 t1 = t1->ty_PtrType.et_Type;
1248                                 t2 = t2->ty_AryType.et_Type;
1249                                 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
1250                                         return(1);
1251                                 }
1252                                 return(0);
1253                         }
1254                         break;
1255                 }
1256 #endif
1257                 if (t2->ty_Op != t1->ty_Op)
1258                         break;
1259                 switch(t1->ty_Op) {
1260                 case TY_IMPORT:
1261                         if (t1->ty_ImportType.et_SemGroup ==
1262                             t2->ty_ImportType.et_SemGroup) {
1263                                 return(1);
1264                         }
1265                         return(0);
1266                 case TY_CLASS:
1267                         if (t1->ty_ClassType.et_SemGroup ==
1268                              t2->ty_ClassType.et_SemGroup &&
1269                             t1->ty_ClassType.et_Super ==
1270                              t2->ty_ClassType.et_Super)
1271                         {
1272                                 return(1);
1273                         }
1274                         return(0);
1275                 case TY_CPTRTO:
1276                         t1 = t1->ty_CPtrType.et_Type;
1277                         t2 = t2->ty_CPtrType.et_Type;
1278                         break;
1279                 case TY_PTRTO:
1280                         t1 = t1->ty_PtrType.et_Type;
1281                         t2 = t2->ty_PtrType.et_Type;
1282                         break;
1283                 case TY_REFTO:
1284                         /*
1285                          * Reference types are similar if the lhs is a
1286                          * superclass of the rhs and partially compatible
1287                          * (only method call changes and extensions).
1288                          */
1289                         t1 = t1->ty_RefType.et_Type;
1290                         t2 = t2->ty_RefType.et_Type;
1291                         if (MatchType(t1, t2) <= SG_COMPAT_PART) {
1292                                 return(1);
1293                         }
1294                         return(0);
1295                         break;
1296                 case TY_COMPOUND:
1297                         /*
1298                          * Compare the elements making up the compound type.
1299                          * XXX
1300                          */
1301                         return(SimilarSemGroup(t1->ty_CompType.et_SemGroup,
1302                                                t2->ty_CompType.et_SemGroup));
1303                         break;
1304                 case TY_ARYOF:
1305                 case TY_VAR:
1306                 case TY_PROC:
1307                         /* XXX */
1308                         return(0);
1309                 case TY_STORAGE:
1310                 case TY_ARGS:
1311                 case TY_UNRESOLVED:
1312                 case TY_DYNAMIC:
1313                         /* XXX */
1314                         return(0);
1315                 default:
1316                         dassert_type(t1, 0);
1317                         return(0);
1318                 }
1319         }
1320         return(0);
1321 }
1322
1323 /*
1324  * SimilarSemGroup() - check to see if the storage underlying the two
1325  *                      semantic groups is compatible.
1326  */
1327 int
1328 SimilarSemGroup(SemGroup *s1, SemGroup *s2)
1329 {
1330         Declaration *d1;
1331         Declaration *d2;
1332
1333         if (s1->sg_Bytes != s2->sg_Bytes)
1334                 return(0);
1335         d1 = getHead(&s1->sg_DeclList);
1336         d2 = getHead(&s2->sg_DeclList);
1337         for (;;) {
1338                 while (d1 && 
1339                        ((d1->d_Op & DOPF_STORAGE) == 0 ||
1340                          d1->d_Op == DOP_GLOBAL_STORAGE)
1341                 ) {
1342                         d1 = getSucc(&s1->sg_DeclList, &d1->d_Node);
1343                 }
1344                 while (d2 && 
1345                        ((d2->d_Op & DOPF_STORAGE) == 0 ||
1346                          d2->d_Op == DOP_GLOBAL_STORAGE)
1347                 ) {
1348                         d2 = getSucc(&s2->sg_DeclList, &d2->d_Node);
1349                 }
1350                 if (d1 == NULL || d2 == NULL)
1351                         break;
1352                 if (SimilarType(d1->d_StorDecl.ed_Type,
1353                                 d2->d_StorDecl.ed_Type) == 0) {
1354                         break;
1355                 }
1356                 d1 = getSucc(&s1->sg_DeclList, &d1->d_Node);
1357                 d2 = getSucc(&s2->sg_DeclList, &d2->d_Node);
1358         }
1359         if (d1 || d2)
1360                 return(0);      /* compare bad */
1361         return(1);              /* compare good */
1362 }
1363
1364 char *
1365 TypeToStr(Type *type, char **pstr)
1366 {
1367         char *str = NULL;
1368         char *s1 = NULL;
1369         char *s2 = NULL;
1370         Stmt *st;
1371         SemGroup *sg;
1372         Declaration *d;
1373         int count;
1374         static char *SaveStr[8];
1375         static int SaveIndex;
1376
1377         if (type == NULL) {
1378                 safe_asprintf(&str, "(null)");
1379         } else {
1380                 switch(type->ty_Op) {
1381                 case TY_CLASS:
1382                         st = type->ty_ClassType.et_SemGroup->sg_Stmt;
1383                         dassert(st->st_Op == ST_Class);
1384 #if 0
1385                         safe_asprintf(&str, "CLASS(%s",
1386                                       st->st_ClassStmt.es_Decl->d_Id);
1387 #else
1388                         LexPrintRef(&st->st_LexRef, 0);
1389                         safe_asprintf(&str, "PARSE(%p) CLASS(%s from",
1390                                       type->ty_ClassType.et_SemGroup->sg_Parse,
1391                                       st->st_ClassStmt.es_Decl->d_Id);
1392                         for (;;) {
1393                                 while (st && st->st_Op != ST_Import)
1394                                         st = st->st_Parent;
1395                                 if (st == NULL)
1396                                         break;
1397                                 safe_replacef(&str, "%s <%s%s>",
1398                                               str,
1399                                               st->st_ImportStmt.es_Path,
1400                                               st->st_ImportStmt.es_File);
1401                                 st = st->st_Parent;
1402                         }
1403 #endif
1404                         safe_replacef(&str, "%s)", str);
1405                         break;
1406                 case TY_IMPORT:
1407                         st = type->ty_ImportType.et_SemGroup->sg_Stmt;
1408                         dassert(st->st_Op == ST_Module);
1409                         safe_asprintf(&str, "IMPORT(%s)",
1410                                       st->st_LexRef.lr_Lex->l_Path);
1411                         break;
1412                 case TY_CPTRTO:
1413                         TypeToStr(type->ty_CPtrType.et_Type, &s1);
1414                         safe_replacef(&str, "(CLANG)*%s", s1);
1415                         break;
1416                 case TY_PTRTO:
1417                         TypeToStr(type->ty_PtrType.et_Type, &s1);
1418                         safe_replacef(&str, "*%s", s1);
1419                         break;
1420                 case TY_REFTO:
1421                         TypeToStr(type->ty_RefType.et_Type, &s1);
1422                         safe_replacef(&str, "@%s", s1);
1423                         break;
1424                 case TY_ARYOF:
1425                         TypeToStr(type->ty_AryType.et_Type, &s1);
1426                         safe_replacef(&str, "%s[]", s1);
1427                         break;
1428                 case TY_COMPOUND:
1429                         sg = type->ty_CompType.et_SemGroup;
1430                         safe_asprintf(&str, "COMPOUND(");
1431                         count = 0;
1432                         for (d = getHead(&sg->sg_DeclList);
1433                              d;
1434                              d = getSucc(&sg->sg_DeclList, &d->d_Node)) {
1435                                 if (d->d_Op & DOPF_STORAGE) {
1436                                         TypeToStr(d->d_StorDecl.ed_Type, &s1);
1437                                         if (count)
1438                                                 safe_replacef(&str, "%s,%s",
1439                                                               str, s1);
1440                                         else
1441                                                 safe_replacef(&str, "%s%s",
1442                                                               str, s1);
1443                                         ++count;
1444                                         safe_free(&s1);
1445                                 }
1446                         }
1447                         safe_replacef(&str, "%s)", str);
1448                         break;
1449                 case TY_VAR:
1450                         safe_replacef(&str, "VAR");
1451                         break;
1452                 case TY_ARGS:
1453                         sg = type->ty_ArgsType.et_SemGroup;
1454                         safe_asprintf(&str, "ARGS(");
1455                         count = 0;
1456                         for (d = getHead(&sg->sg_DeclList);
1457                              d;
1458                              d = getSucc(&sg->sg_DeclList, &d->d_Node)) {
1459                                 if (d->d_Op & DOPF_STORAGE) {
1460                                         TypeToStr(d->d_StorDecl.ed_Type, &s1);
1461                                         if (count)
1462                                                 safe_replacef(&str, "%s,%s",
1463                                                               str, s1);
1464                                         else
1465                                                 safe_replacef(&str, "%s%s",
1466                                                               str, s1);
1467                                         safe_free(&s1);
1468                                         ++count;
1469                                 }
1470                         }
1471                         safe_replacef(&str, "%s)", str);
1472                         break;
1473                 case TY_PROC:
1474                         {
1475                                 TypeToStr(type->ty_ProcType.et_RetType, &s1);
1476                                 TypeToStr(type->ty_ProcType.et_ArgsType, &s2);
1477                                 safe_asprintf(&str, "%s %s", s1, s2);
1478                         }
1479                         break;
1480                 case TY_STORAGE:
1481                         safe_asprintf(&str, "STORAGE(%d)",
1482                                       type->ty_StorType.et_Bytes);
1483                         break;
1484                 case TY_DYNAMIC:
1485                         safe_asprintf(&str, "DYNAMIC");
1486                         break;
1487                 case TY_UNRESOLVED:
1488                         safe_asprintf(&str, "UNRES(");
1489                         for (count = 0; type->ty_UnresType.et_DottedId[count]; ++count) {
1490                                 safe_replacef(&str, "%s%s",
1491                                               str, type->ty_UnresType.et_DottedId[count]);
1492                                 if (count) {
1493                                         safe_replacef(&str, "%s,%s",
1494                                                       str, type->ty_UnresType.et_DottedId[count]);
1495                                 }
1496                         }
1497                         safe_replacef(&str, "%s)", str);
1498                         break;
1499                 default:
1500                         safe_asprintf(&str, "?");
1501                         break;
1502                 }
1503         }
1504         safe_free(&s1);
1505         safe_free(&s2);
1506         if (pstr) {
1507                 safe_free(pstr);
1508                 *pstr = str;
1509         } else {
1510                 safe_free(&SaveStr[SaveIndex]);
1511                 SaveStr[SaveIndex] = str;
1512                 SaveIndex = (SaveIndex + 1) % arysize(SaveStr);
1513         }
1514         return(str);
1515 }
1516
1517 typedef struct TypeRegNode {
1518         Node    tr_Node;
1519         string_t        tr_Id;
1520         Type    *tr_Type;
1521 } TypeRegNode;
1522
1523 List TypeRegList = INITLIST(TypeRegList);
1524
1525 void
1526 InternalRegisterType(const char *str, Type *type)
1527 {
1528         static int Special = SPECIALF_REGISTERED|SPECIALF_INTERNAL|1;
1529         TypeRegNode *tr;
1530
1531         dassert(Special & SPECIALF_MASK);
1532         tr = zalloc(sizeof(TypeRegNode));
1533         tr->tr_Id = StrTableAlloc(str, strlen(str), Special++);
1534         tr->tr_Type = type;
1535         addTail(&TypeRegList, &tr->tr_Node);
1536 }
1537
1538 Type *
1539 InternalRegisteredTypeLookup(string_t id)
1540 {
1541         TypeRegNode *tr;
1542
1543         for (
1544                 tr = getHead(&TypeRegList);
1545                 tr;
1546                 tr = getSucc(&TypeRegList, &tr->tr_Node)
1547         ) {
1548                 if (tr->tr_Id == id)
1549                         return(tr->tr_Type);
1550         }
1551         return(NULL);
1552 }