4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
7 * WARNING: This needs to be almost standalone because it is also compiled
14 * MatchType() - Match two types
16 * Match two types as if we wanted to cast type to super or use
19 * SG_COMPAT_FULL Type is a subclass, methods and storage are
20 * compatible (storage may be extended).
22 * SG_COMPAT_PART Type is a subclass, methods are compatible
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).
29 * SG_COMPAT_FAIL Type is not even a subclass
31 * XXX we are skipping qualifiers
34 MatchType(Type *super, Type *type)
36 int r = SG_COMPAT_FULL;
39 while (super && type) {
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);
58 * Relaxed storage qualifiers. We are effectively casting
59 * to 'super'. We can remove SF_CONST from super but not from
62 * NOTE: Actual casts may do more stringent tests.
64 if (super->ty_SQFlags != type->ty_SQFlags) {
66 (type->ty_SQFlags & ~SF_IGNORE_MASK) !=
67 (super->ty_SQFlags & ~SF_RELAXING_MASK)) {
73 switch(super->ty_Op) {
76 * type can be a subclass of super
78 if (type->ty_ClassType.et_SemGroup ==
79 super->ty_ClassType.et_SemGroup) {
82 r = type->ty_ClassType.et_SemGroup->sg_Compat;
84 if (r < SG_COMPAT_PART)
87 while ((type = type->ty_ClassType.et_Super) != NULL) {
88 if (type->ty_ClassType.et_SemGroup ==
89 super->ty_ClassType.et_SemGroup) {
92 if (r < type->ty_ClassType.et_SemGroup->sg_Compat)
93 r = type->ty_ClassType.et_SemGroup->sg_Compat;
95 if (type == NULL) /* not even a subclass */
100 * type can be a subclass of super
106 type = type->ty_CPtrType.et_Type;
107 super = super->ty_CPtrType.et_Type;
110 type = type->ty_PtrType.et_Type;
111 super = super->ty_PtrType.et_Type;
114 type = type->ty_RefType.et_Type;
115 super = super->ty_RefType.et_Type;
118 type = type->ty_AryType.et_Type;
119 super = super->ty_AryType.et_Type;
123 sg1 = super->ty_CompType.et_SemGroup;
124 sg2 = type->ty_CompType.et_SemGroup;
127 sg1 = super->ty_ArgsType.et_SemGroup;
128 sg2 = type->ty_ArgsType.et_SemGroup;
131 r = MatchType(super->ty_VarType.et_Type,
132 type->ty_VarType.et_Type);
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);
149 if (type->ty_StorType.et_Bytes !=
150 super->ty_StorType.et_Bytes) {
151 r = SG_COMPAT_SUBCLASS;
156 dassert_type(super, 0); /* can't happen */
160 Declaration *sd = RUNE_FIRST(&sg1->sg_DeclList);
161 Declaration *rd = RUNE_FIRST(&sg2->sg_DeclList);
163 int v = MatchDeclTypes(sd, rd);
166 if (r == SG_COMPAT_FAIL)
168 sd = RUNE_NEXT(sd, d_Node);
169 rd = RUNE_NEXT(rd, d_Node);
180 * SameType() - return 1 if the types are exactly the same, 0 if they are not.
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.
186 * Types can be aliased - for example, two different type structures
187 * may point to the same class data.
189 * XXX this needs a lot of work. We really need to guarentee
190 * some level of uniqueness for non-qualified type elements.
193 SameType(Type *t1, Type *t2, int sqFlags2)
198 if (t1->ty_Op != t2->ty_Op)
200 if (t1->ty_SQFlags != sqFlags2)
204 if (t1->ty_ImportType.et_SemGroup ==
205 t2->ty_ImportType.et_SemGroup)
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))
220 t1 = t1->ty_CPtrType.et_Type;
221 t2 = t2->ty_CPtrType.et_Type;
224 t1 = t1->ty_PtrType.et_Type;
225 t2 = t2->ty_PtrType.et_Type;
228 t1 = t1->ty_RefType.et_Type;
229 t2 = t2->ty_RefType.et_Type;
247 sqFlags2 = t2->ty_SQFlags;
253 * SimilarType() - like SameType(), but ignores storage qualifiers (except
254 * SF_CONST) and if t2 is varargs, compares the original
257 * Used when casting t2 (rhs) to t1 (lhs).
260 SimilarType(Type *t1, Type *t2)
265 if (t2->ty_Op == TY_VAR)
266 t2 = t2->ty_VarType.et_Type;
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
278 (t2->ty_SQFlags & SF_CONST) &&
279 (t1->ty_SQFlags & SF_CONST) == 0) {
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.
289 if (t2->ty_Op != t1->ty_Op) {
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) {
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) {
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) {
326 if (t2->ty_Op != t1->ty_Op)
330 if (t1->ty_ImportType.et_SemGroup ==
331 t2->ty_ImportType.et_SemGroup) {
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))
345 t1 = t1->ty_CPtrType.et_Type;
346 t2 = t2->ty_CPtrType.et_Type;
349 t1 = t1->ty_PtrType.et_Type;
350 t2 = t2->ty_PtrType.et_Type;
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).
358 t1 = t1->ty_RefType.et_Type;
359 t2 = t2->ty_RefType.et_Type;
360 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
367 * Compare the elements making up the compound type.
370 return(SimilarSemGroup(t1->ty_CompType.et_SemGroup,
371 t2->ty_CompType.et_SemGroup));
394 * SimilarSemGroup() - check to see if the storage underlying the two
395 * semantic groups is compatible.
398 SimilarSemGroup(SemGroup *s1, SemGroup *s2)
403 if (s1->sg_Bytes != s2->sg_Bytes)
405 d1 = RUNE_FIRST(&s1->sg_DeclList);
406 d2 = RUNE_FIRST(&s2->sg_DeclList);
409 ((d1->d_Op & DOPF_STORAGE) == 0 ||
410 d1->d_Op == DOP_GLOBAL_STORAGE)
412 d1 = RUNE_NEXT(d1, d_Node);
415 ((d2->d_Op & DOPF_STORAGE) == 0 ||
416 d2->d_Op == DOP_GLOBAL_STORAGE)
418 d2 = RUNE_NEXT(d2, d_Node);
420 if (d1 == NULL || d2 == NULL)
422 if (SimilarType(d1->d_StorDecl.ed_Type,
423 d2->d_StorDecl.ed_Type) == 0) {
426 d1 = RUNE_NEXT(d1, d_Node);
427 d2 = RUNE_NEXT(d2, d_Node);
430 return(0); /* compare bad */
431 return(1); /* compare good */
434 static char *SaveStr[8];
435 static int SaveIndex;
439 typeToStr(Type *type, char **pstr, int simple)
451 safe_asprintf(&str, "(null)");
453 switch(type->ty_Op) {
455 st = type->ty_ClassType.et_SemGroup->sg_Stmt;
457 dassert(st->st_Op == ST_Class);
459 safe_asprintf(&str, "%s",
460 st->st_ClassStmt.es_Decl->d_Id);
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 |
472 while (st && st->st_Op != ST_Import)
476 safe_replacef(&str, "%s%s%s",
479 /* st->st_ImportStmt.es_Path, */
480 st->st_ImportStmt.es_File);
484 safe_replacef(&str, "%s)", str);
487 safe_asprintf(&str, "(class_sg=%p)",
488 type->ty_ClassType.et_SemGroup);
492 st = type->ty_ImportType.et_SemGroup->sg_Stmt;
494 dassert(st->st_Op == ST_Module);
495 safe_asprintf(&str, "IMPORT(%s)",
496 st->st_LexRef.lr_Lex->l_Path);
498 safe_asprintf(&str, "IMPORT(sg=%p)",
499 type->ty_ImportType.et_SemGroup);
503 typeToStr(type->ty_CPtrType.et_Type, &s1, simple);
504 safe_replacef(&str, "(CLANG)*%s", s1);
507 typeToStr(type->ty_PtrType.et_Type, &s1, simple);
508 safe_replacef(&str, "*%s", s1);
511 typeToStr(type->ty_RefType.et_Type, &s1, simple);
512 safe_replacef(&str, "@%s", s1);
515 typeToStr(type->ty_AryType.et_Type, &s1, simple);
516 safe_replacef(&str, "%s[%jd]",
517 s1, (intmax_t)type->ty_AryType.et_Count);
520 sg = type->ty_CompType.et_SemGroup;
521 safe_asprintf(&str, "COMP(");
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);
529 safe_replacef(&str, "%s,%s",
532 safe_replacef(&str, "%s%s",
538 safe_replacef(&str, "%s)", str);
541 safe_replacef(&str, "VAR");
544 sg = type->ty_ArgsType.et_SemGroup;
545 safe_asprintf(&str, "ARGS(");
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);
552 safe_replacef(&str, "%s,%s",
555 safe_replacef(&str, "%s%s",
561 safe_replacef(&str, "%s)", str);
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);
573 safe_asprintf(&str, "STORAGE(%d)",
574 type->ty_StorType.et_Bytes);
577 safe_asprintf(&str, "DYNAMIC");
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]);
585 safe_replacef(&str, "%s,%s",
586 str, type->ty_UnresType.et_DottedId[count]);
589 safe_replacef(&str, "%s)", str);
592 safe_asprintf(&str, "?");
595 flags = type->ty_SQFlags;
600 if (flags & SF_CONST) {
603 } else if (flags & SF_VOLATILE) {
605 flags &= ~SF_VOLATILE;
606 } else if (flags & SF_VARARGS) {
608 flags &= ~SF_VARARGS;
609 } else if (flags & SF_LVALUE) {
612 } else if (flags & SF_NOZERO) {
615 } else if (flags & SF_METHOD) {
618 } else if (flags & SF_GMETHOD) {
620 flags &= ~SF_GMETHOD;
625 safe_replacef(&str, "%s%s%s",
636 safe_free(&SaveStr[SaveIndex]);
637 SaveStr[SaveIndex] = str;
638 SaveIndex = (SaveIndex + 1) % arysize(SaveStr);
644 TypeToStr(Type *type, char **pstr)
649 res = typeToStr(type, pstr, 0);
650 safe_asprintf(&str, "<TYPE_%p %s>", type, res);
655 safe_free(&SaveStr[SaveIndex]);
656 SaveStr[SaveIndex] = str;
657 SaveIndex = (SaveIndex + 1) % arysize(SaveStr);