Rune - Change regsave burden for syscalls
[rune.git] / librune / typeq.c
1 /*
2  * TYPEQ.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  * WARNING: This needs to be almost standalone because it is also compiled
8  *          into libruntime.
9  */
10
11 #include "defs.h"
12
13 /*
14  * MatchType() -        Match two types
15  *
16  *      Match two types as if we wanted to cast type to super or use
17  *      type as super.
18  *
19  *      SG_COMPAT_FULL          Type is a subclass, methods and storage are
20  *                              compatible (storage may be extended).
21  *
22  *      SG_COMPAT_PART          Type is a subclass, methods are compatible
23  *                              but storage is not.
24  *
25  *      SG_COMPAT_SUBCLASS      Type is a subclass, but the methods are
26  *                              not directly compatible (the methods that
27  *                              propogate down must be regenerated).
28  *
29  *      SG_COMPAT_FAIL          Type is not even a subclass
30  *
31  *      XXX we are skipping qualifiers
32  */
33 int
34 MatchType(Type *super, Type *type)
35 {
36         int r = SG_COMPAT_FULL;
37         int loop = 0;
38
39         while (super && type) {
40                 SemGroup *sg1 = NULL;
41                 SemGroup *sg2 = NULL;
42
43                 ++loop;
44
45                 if (type->ty_Op != super->ty_Op) {
46                         if (super->ty_Op == TY_REFTO &&
47                             type->ty_Op == TY_PTRTO) {
48                                 super = super->ty_RefType.et_Type;
49                                 type = type->ty_PtrType.et_Type;
50                                 r = MatchType(super, type);
51                         } else {
52                                 r = SG_COMPAT_FAIL;
53                         }
54                         break;
55                 }
56
57                 /*
58                  * Relaxed storage qualifiers.  We are effectively casting
59                  * to 'super'.  We can remove SF_CONST from super but not from
60                  * type.
61                  *
62                  * NOTE: Actual casts may do more stringent tests.
63                  */
64                 if (super->ty_SQFlags != type->ty_SQFlags) {
65                         if (loop > 1 &&
66                             (type->ty_SQFlags & ~SF_IGNORE_MASK) !=
67                             (super->ty_SQFlags & ~SF_RELAXING_MASK)) {
68                                 r = SG_COMPAT_FAIL;
69                                 break;
70                         }
71                 }
72
73                 switch(super->ty_Op) {
74                 case TY_CLASS:
75                         /*
76                          * type can be a subclass of super
77                          */
78                         if (type->ty_ClassType.et_SemGroup ==
79                             super->ty_ClassType.et_SemGroup) {
80                                 return(r);
81                         }
82                         r = type->ty_ClassType.et_SemGroup->sg_Compat;
83 #if 0
84                         if (r < SG_COMPAT_PART)
85                                 r = SG_COMPAT_PART;
86 #endif
87                         while ((type = type->ty_ClassType.et_Super) != NULL) {
88                                 if (type->ty_ClassType.et_SemGroup ==
89                                     super->ty_ClassType.et_SemGroup) {
90                                         break;
91                                 }
92                                 if (r < type->ty_ClassType.et_SemGroup->sg_Compat)
93                                         r = type->ty_ClassType.et_SemGroup->sg_Compat;
94                         }
95                         if (type == NULL)       /* not even a subclass */
96                                 r = SG_COMPAT_FAIL;
97                         break;
98                 case TY_IMPORT:
99                         /*
100                          * type can be a subclass of super
101                          */
102                         if (type != super)
103                                 r = SG_COMPAT_FAIL;
104                         break;
105                 case TY_CPTRTO:
106                         type = type->ty_CPtrType.et_Type;
107                         super = super->ty_CPtrType.et_Type;
108                         continue;
109                 case TY_PTRTO:
110                         type = type->ty_PtrType.et_Type;
111                         super = super->ty_PtrType.et_Type;
112                         continue;
113                 case TY_REFTO:
114                         type = type->ty_RefType.et_Type;
115                         super = super->ty_RefType.et_Type;
116                         continue;
117                 case TY_ARYOF:
118                         type = type->ty_AryType.et_Type;
119                         super = super->ty_AryType.et_Type;
120                         /* XXX */
121                         continue;
122                 case TY_COMPOUND:
123                         sg1 = super->ty_CompType.et_SemGroup;
124                         sg2 = type->ty_CompType.et_SemGroup;
125                         break;
126                 case TY_ARGS:
127                         sg1 = super->ty_ArgsType.et_SemGroup;
128                         sg2 = type->ty_ArgsType.et_SemGroup;
129                         break;
130                 case TY_VAR:
131                         r = MatchType(super->ty_VarType.et_Type,
132                                       type->ty_VarType.et_Type);
133                         break;
134                 case TY_PROC:
135                         {
136                                 int v;
137
138                                 r = MatchType(super->ty_ProcType.et_ArgsType, 
139                                               type->ty_ProcType.et_ArgsType);
140                                 v = MatchType(super->ty_ProcType.et_RetType,
141                                               type->ty_ProcType.et_RetType);
142                                 if (r < v)
143                                         r = v;
144                         }
145                         break;
146                 case TY_DYNAMIC:
147                         break;
148                 case TY_STORAGE:
149                         if (type->ty_StorType.et_Bytes !=
150                             super->ty_StorType.et_Bytes) {
151                                 r = SG_COMPAT_SUBCLASS;
152                         }
153                         break;
154                 case TY_UNRESOLVED:
155                 default:
156                         dassert_type(super, 0); /* can't happen */
157                         break;
158                 }
159                 if (sg1) {
160                         Declaration *sd = RUNE_FIRST(&sg1->sg_DeclList);
161                         Declaration *rd = RUNE_FIRST(&sg2->sg_DeclList);
162                         while (sd && rd) {
163                                 int v = MatchDeclTypes(sd, rd);
164                                 if (r < v)
165                                         r = v;
166                                 if (r == SG_COMPAT_FAIL)
167                                         break;
168                                 sd = RUNE_NEXT(sd, d_Node);
169                                 rd = RUNE_NEXT(rd, d_Node);
170                         }
171                         if (sd || rd)
172                                 r = SG_COMPAT_FAIL;
173                 }
174                 break;
175         }
176         return(r);
177 }
178
179 /*
180  * SameType() - return 1 if the types are exactly the same, 0 if they are not.
181  *
182  *      The sqFlags for t2 may be overriden.  If you do not wish to override
183  *      the sqFlags for t2, pass t2->ty_SQFlags for sqFlags.  The override
184  *      only applies to the top level of the type.
185  *
186  *      Types can be aliased - for example, two different type structures
187  *      may point to the same class data.
188  *
189  *      XXX this needs a lot of work.  We really need to guarentee
190  *      some level of uniqueness for non-qualified type elements.
191  */
192 int
193 SameType(Type *t1, Type *t2, int sqFlags2)
194 {
195         for (;;) {
196                 if (t1 == t2)
197                         return(1);
198                 if (t1->ty_Op != t2->ty_Op)
199                         break;
200                 if (t1->ty_SQFlags != sqFlags2)
201                         break;
202                 switch(t1->ty_Op) {
203                 case TY_IMPORT:
204                         if (t1->ty_ImportType.et_SemGroup ==
205                             t2->ty_ImportType.et_SemGroup)
206                         {
207                                 return(1);
208                         }
209                         return(0);
210                 case TY_CLASS:
211                         if (t1->ty_ClassType.et_SemGroup ==
212                              t2->ty_ClassType.et_SemGroup &&
213                             SameType(t1->ty_ClassType.et_Super,
214                                      t2->ty_ClassType.et_Super, 0))
215                         {
216                                 return(1);
217                         }
218                         return(0);
219                 case TY_CPTRTO:
220                         t1 = t1->ty_CPtrType.et_Type;
221                         t2 = t2->ty_CPtrType.et_Type;
222                         break;
223                 case TY_PTRTO:
224                         t1 = t1->ty_PtrType.et_Type;
225                         t2 = t2->ty_PtrType.et_Type;
226                         break;
227                 case TY_REFTO:
228                         t1 = t1->ty_RefType.et_Type;
229                         t2 = t2->ty_RefType.et_Type;
230                         break;
231                 case TY_ARYOF:
232                 case TY_VAR:
233                 case TY_COMPOUND:
234                 case TY_PROC:
235                         /* XXX */
236                         return(0);
237                 case TY_STORAGE:
238                 case TY_ARGS:
239                 case TY_UNRESOLVED:
240                 case TY_DYNAMIC:
241                         /* XXX */
242                         return(0);
243                 default:
244                         dassert_type(t1, 0);
245                         return(0);
246                 }
247                 sqFlags2 = t2->ty_SQFlags;
248         }
249         return(0);
250 }
251
252 /*
253  * SimilarType() - like SameType(), but ignores storage qualifiers (except
254  *                 SF_CONST) and if t2 is varargs, compares the original
255  *                 version.
256  *
257  * Used when casting t2 (rhs) to t1 (lhs).
258  */
259 int
260 SimilarType(Type *t1, Type *t2)
261 {
262         int check_const = 0;
263
264
265         if (t2->ty_Op == TY_VAR)
266                 t2 = t2->ty_VarType.et_Type;
267
268         for (;;) {
269                 if (t1 == t2)
270                         return(1);
271
272                 /*
273                  * Check for an incompatible constant conversion if we loop
274                  * through a pointer or ref.  Allow compatibility for e.g.
275                  * rvalues (const int)1 == (int)1
276                  */
277                 if (check_const &&
278                     (t2->ty_SQFlags & SF_CONST) &&
279                     (t1->ty_SQFlags & SF_CONST) == 0) {
280                         return(0);
281                 }
282 #if 0
283                 /*
284                  * Normally we fail if the ops do not match, but it is legal to
285                  * cast a pointer (t2) to a reference type (t1) if the ref type
286                  * is its superclass.  It is also legal to cast an array to a
287                  * pointer or C pointer.
288                  */
289                 if (t2->ty_Op != t1->ty_Op) {
290                         /*
291                          * pointer->ref
292                          */
293                         if (t2->ty_Op == TY_PTRTO && t1->ty_Op == TY_REFTO) {
294                                 t1 = t1->ty_RefType.et_Type;
295                                 t2 = t2->ty_PtrType.et_Type;
296                                 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
297                                         return(1);
298                                 }
299                                 return(0);
300                         }
301                         /*
302                          * array->pointer
303                          */
304                         if (t2->ty_Op == TY_ARYOF && t1->ty_Op == TY_PTRTO) {
305                                 t1 = t1->ty_PtrType.et_Type;
306                                 t2 = t2->ty_AryType.et_Type;
307                                 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
308                                         return(1);
309                                 }
310                                 return(0);
311                         }
312                         /*
313                          * array->cpointer
314                          */
315                         if (t2->ty_Op == TY_ARYOF && t1->ty_Op == TY_CPTRTO) {
316                                 t1 = t1->ty_PtrType.et_Type;
317                                 t2 = t2->ty_AryType.et_Type;
318                                 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
319                                         return(1);
320                                 }
321                                 return(0);
322                         }
323                         break;
324                 }
325 #endif
326                 if (t2->ty_Op != t1->ty_Op)
327                         break;
328                 switch(t1->ty_Op) {
329                 case TY_IMPORT:
330                         if (t1->ty_ImportType.et_SemGroup ==
331                             t2->ty_ImportType.et_SemGroup) {
332                                 return(1);
333                         }
334                         return(0);
335                 case TY_CLASS:
336                         if (t1->ty_ClassType.et_SemGroup ==
337                              t2->ty_ClassType.et_SemGroup &&
338                             SameType(t1->ty_ClassType.et_Super,
339                                      t2->ty_ClassType.et_Super, 0))
340                         {
341                                 return(1);
342                         }
343                         return(0);
344                 case TY_CPTRTO:
345                         t1 = t1->ty_CPtrType.et_Type;
346                         t2 = t2->ty_CPtrType.et_Type;
347                         break;
348                 case TY_PTRTO:
349                         t1 = t1->ty_PtrType.et_Type;
350                         t2 = t2->ty_PtrType.et_Type;
351                         break;
352                 case TY_REFTO:
353                         /*
354                          * Reference types are similar if the lhs is a
355                          * superclass of the rhs and partially compatible
356                          * (only method call changes and extensions).
357                          */
358                         t1 = t1->ty_RefType.et_Type;
359                         t2 = t2->ty_RefType.et_Type;
360                         if (MatchType(t1, t2) <= SG_COMPAT_PART) {
361                                 return(1);
362                         }
363                         return(0);
364                         break;
365                 case TY_COMPOUND:
366                         /*
367                          * Compare the elements making up the compound type.
368                          * XXX
369                          */
370                         return(SimilarSemGroup(t1->ty_CompType.et_SemGroup,
371                                                t2->ty_CompType.et_SemGroup));
372                         break;
373                 case TY_ARYOF:
374                 case TY_VAR:
375                 case TY_PROC:
376                         /* XXX */
377                         return(0);
378                 case TY_STORAGE:
379                 case TY_ARGS:
380                 case TY_UNRESOLVED:
381                 case TY_DYNAMIC:
382                         /* XXX */
383                         return(0);
384                 default:
385                         dassert_type(t1, 0);
386                         return(0);
387                 }
388                 check_const = 1;
389         }
390         return(0);
391 }
392
393 /*
394  * SimilarSemGroup() - check to see if the storage underlying the two
395  *                      semantic groups is compatible.
396  */
397 int
398 SimilarSemGroup(SemGroup *s1, SemGroup *s2)
399 {
400         Declaration *d1;
401         Declaration *d2;
402
403         if (s1->sg_Bytes != s2->sg_Bytes)
404                 return(0);
405         d1 = RUNE_FIRST(&s1->sg_DeclList);
406         d2 = RUNE_FIRST(&s2->sg_DeclList);
407         for (;;) {
408                 while (d1 && 
409                        ((d1->d_Op & DOPF_STORAGE) == 0 ||
410                          d1->d_Op == DOP_GLOBAL_STORAGE)
411                 ) {
412                         d1 = RUNE_NEXT(d1, d_Node);
413                 }
414                 while (d2 && 
415                        ((d2->d_Op & DOPF_STORAGE) == 0 ||
416                          d2->d_Op == DOP_GLOBAL_STORAGE)
417                 ) {
418                         d2 = RUNE_NEXT(d2, d_Node);
419                 }
420                 if (d1 == NULL || d2 == NULL)
421                         break;
422                 if (SimilarType(d1->d_StorDecl.ed_Type,
423                                 d2->d_StorDecl.ed_Type) == 0) {
424                         break;
425                 }
426                 d1 = RUNE_NEXT(d1, d_Node);
427                 d2 = RUNE_NEXT(d2, d_Node);
428         }
429         if (d1 || d2)
430                 return(0);      /* compare bad */
431         return(1);              /* compare good */
432 }
433
434 static char *SaveStr[8];
435 static int SaveIndex;
436
437 static
438 char *
439 typeToStr(Type *type, char **pstr, int simple)
440 {
441         char *str = NULL;
442         char *s1 = NULL;
443         char *s2 = NULL;
444         Stmt *st;
445         SemGroup *sg;
446         Declaration *d;
447         int count;
448         int flags;
449
450         if (type == NULL) {
451                 safe_asprintf(&str, "(null)");
452         } else {
453                 switch(type->ty_Op) {
454                 case TY_CLASS:
455                         st = type->ty_ClassType.et_SemGroup->sg_Stmt;
456                         if (st) {
457                                 dassert(st->st_Op == ST_Class);
458 #if 1
459                                 safe_asprintf(&str, "%s",
460                                               st->st_ClassStmt.es_Decl->d_Id);
461 #else
462                                 LexPrintRef(&st->st_LexRef, 0);
463                                 safe_asprintf(&str, "%s(",
464                                               st->st_ClassStmt.es_Decl->d_Id);
465                                 if (type->ty_Flags & (TF_ISINTEGER | TF_ISFLOAT |
466                                                       TF_ISBOOL)) {
467                                         break;
468                                 }
469
470                                 count = 0;
471                                 for (;;) {
472                                         while (st && st->st_Op != ST_Import)
473                                                 st = st->st_Parent;
474                                         if (st == NULL)
475                                                 break;
476                                         safe_replacef(&str, "%s%s%s",
477                                                       str,
478                                                       (count ? "," : ""),
479                                                       /* st->st_ImportStmt.es_Path, */
480                                                       st->st_ImportStmt.es_File);
481                                         st = st->st_Parent;
482                                         ++count;
483                                 }
484                                 safe_replacef(&str, "%s)", str);
485 #endif
486                         } else {
487                                 safe_asprintf(&str, "(class_sg=%p)",
488                                               type->ty_ClassType.et_SemGroup);
489                         }
490                         break;
491                 case TY_IMPORT:
492                         st = type->ty_ImportType.et_SemGroup->sg_Stmt;
493                         if (st) {
494                                 dassert(st->st_Op == ST_Module);
495                                 safe_asprintf(&str, "IMPORT(%s)",
496                                               st->st_LexRef.lr_Lex->l_Path);
497                         } else {
498                                 safe_asprintf(&str, "IMPORT(sg=%p)",
499                                               type->ty_ImportType.et_SemGroup);
500                         }
501                         break;
502                 case TY_CPTRTO:
503                         typeToStr(type->ty_CPtrType.et_Type, &s1, simple);
504                         safe_replacef(&str, "(CLANG)*%s", s1);
505                         break;
506                 case TY_PTRTO:
507                         typeToStr(type->ty_PtrType.et_Type, &s1, simple);
508                         safe_replacef(&str, "*%s", s1);
509                         break;
510                 case TY_REFTO:
511                         typeToStr(type->ty_RefType.et_Type, &s1, simple);
512                         safe_replacef(&str, "@%s", s1);
513                         break;
514                 case TY_ARYOF:
515                         typeToStr(type->ty_AryType.et_Type, &s1, simple);
516                         safe_replacef(&str, "%s[%jd]",
517                                       s1, (intmax_t)type->ty_AryType.et_Count);
518                         break;
519                 case TY_COMPOUND:
520                         sg = type->ty_CompType.et_SemGroup;
521                         safe_asprintf(&str, "COMP(");
522                         count = 0;
523
524                         RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
525                                 if (d->d_Op & DOPF_STORAGE) {
526                                         Type *dtype = d->d_StorDecl.ed_Type;
527                                         typeToStr(dtype, &s1, 1);
528                                         if (count)
529                                                 safe_replacef(&str, "%s,%s",
530                                                               str, s1);
531                                         else
532                                                 safe_replacef(&str, "%s%s",
533                                                               str, s1);
534                                         ++count;
535                                         safe_free(&s1);
536                                 }
537                         }
538                         safe_replacef(&str, "%s)", str);
539                         break;
540                 case TY_VAR:
541                         safe_replacef(&str, "VAR");
542                         break;
543                 case TY_ARGS:
544                         sg = type->ty_ArgsType.et_SemGroup;
545                         safe_asprintf(&str, "ARGS(");
546                         count = 0;
547                         RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
548                                 if (d->d_Op & DOPF_STORAGE) {
549                                         Type *dtype = d->d_StorDecl.ed_Type;
550                                         typeToStr(dtype, &s1, 1);
551                                         if (count)
552                                                 safe_replacef(&str, "%s,%s",
553                                                               str, s1);
554                                         else
555                                                 safe_replacef(&str, "%s%s",
556                                                               str, s1);
557                                         safe_free(&s1);
558                                         ++count;
559                                 }
560                         }
561                         safe_replacef(&str, "%s)", str);
562                         break;
563                 case TY_PROC:
564                         {
565                                 Type *rtype = type->ty_ProcType.et_RetType;
566                                 Type *atype = type->ty_ProcType.et_ArgsType;
567                                 typeToStr(rtype, &s1, 1);
568                                 typeToStr(atype, &s2, 1);
569                                 safe_asprintf(&str, "%s %s", s1, s2);
570                         }
571                         break;
572                 case TY_STORAGE:
573                         safe_asprintf(&str, "STORAGE(%d)",
574                                       type->ty_StorType.et_Bytes);
575                         break;
576                 case TY_DYNAMIC:
577                         safe_asprintf(&str, "DYNAMIC");
578                         break;
579                 case TY_UNRESOLVED:
580                         safe_asprintf(&str, "UNRES(");
581                         for (count = 0; type->ty_UnresType.et_DottedId[count]; ++count) {
582                                 safe_replacef(&str, "%s%s",
583                                               str, type->ty_UnresType.et_DottedId[count]);
584                                 if (count) {
585                                         safe_replacef(&str, "%s,%s",
586                                                       str, type->ty_UnresType.et_DottedId[count]);
587                                 }
588                         }
589                         safe_replacef(&str, "%s)", str);
590                         break;
591                 default:
592                         safe_asprintf(&str, "?");
593                         break;
594                 }
595                 flags = type->ty_SQFlags;
596                 count = 0;
597                 while (flags) {
598                         const char *sqflag;
599
600                         if (flags & SF_CONST) {
601                                 sqflag = "const";
602                                 flags &= ~SF_CONST;
603                         } else if (flags & SF_VOLATILE) {
604                                 sqflag = "volatile";
605                                 flags &= ~SF_VOLATILE;
606                         } else if (flags & SF_VARARGS) {
607                                 sqflag = "varargs";
608                                 flags &= ~SF_VARARGS;
609                         } else if (flags & SF_LVALUE) {
610                                 sqflag = "lvalue";
611                                 flags &= ~SF_LVALUE;
612                         } else if (flags & SF_NOZERO) {
613                                 sqflag = "__nozero";
614                                 flags &= ~SF_NOZERO;
615                         } else if (flags & SF_METHOD) {
616                                 sqflag = "method";
617                                 flags &= ~SF_METHOD;
618                         } else if (flags & SF_GMETHOD) {
619                                 sqflag = "gmethod";
620                                 flags &= ~SF_GMETHOD;
621                         } else {
622                                 sqflag = "bad";
623                                 flags = 0;
624                         }
625                         safe_replacef(&str, "%s%s%s",
626                                       sqflag, " ", str);
627                         ++count;
628                 }
629         }
630         safe_free(&s1);
631         safe_free(&s2);
632         if (pstr) {
633                 safe_free(pstr);
634                 *pstr = str;
635         } else {
636                 safe_free(&SaveStr[SaveIndex]);
637                 SaveStr[SaveIndex] = str;
638                 SaveIndex = (SaveIndex + 1) % arysize(SaveStr);
639         }
640         return(str);
641 }
642
643 char *
644 TypeToStr(Type *type, char **pstr)
645 {
646         char *str = NULL;
647         char *res;
648
649         res = typeToStr(type, pstr, 0);
650         safe_asprintf(&str, "<TYPE_%p %s>", type, res);
651         if (pstr) {
652                 safe_free(pstr);
653                 *pstr = str;
654         } else {
655                 safe_free(&SaveStr[SaveIndex]);
656                 SaveStr[SaveIndex] = str;
657                 SaveIndex = (SaveIndex + 1) % arysize(SaveStr);
658         }
659         return(str);
660 }