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 type as
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) {
51 * Relaxed storage qualifiers. We are effectively casting to
52 * 'super'. We can remove SF_CONST from super but not from type.
54 * NOTE: Actual casts may do more stringent tests.
56 if (super->ty_SQFlags != type->ty_SQFlags) {
58 (type->ty_SQFlags & ~SF_IGNORE_MASK) !=
59 (super->ty_SQFlags & ~SF_RELAXING_MASK)) {
65 switch (super->ty_Op) {
68 * type can be a subclass of super
70 if (type->ty_ClassType.et_SemGroup ==
71 super->ty_ClassType.et_SemGroup) {
74 r = type->ty_ClassType.et_SemGroup->sg_Compat;
76 if (r < SG_COMPAT_PART)
79 while ((type = type->ty_ClassType.et_Super) != NULL) {
80 if (type->ty_ClassType.et_SemGroup ==
81 super->ty_ClassType.et_SemGroup) {
84 if (r < type->ty_ClassType.et_SemGroup->sg_Compat)
85 r = type->ty_ClassType.et_SemGroup->sg_Compat;
87 if (type == NULL) /* not even a subclass */
92 * type can be a subclass of super
98 type = type->ty_RawPtrType.et_Type;
99 super = super->ty_RawPtrType.et_Type;
102 type = type->ty_RefType.et_Type;
103 super = super->ty_RefType.et_Type;
106 type = type->ty_AryType.et_Type;
107 super = super->ty_AryType.et_Type;
111 sg1 = super->ty_CompType.et_SemGroup;
112 sg2 = type->ty_CompType.et_SemGroup;
115 sg1 = super->ty_ArgsType.et_SemGroup;
116 sg2 = type->ty_ArgsType.et_SemGroup;
119 r = MatchType(super->ty_VarType.et_Type,
120 type->ty_VarType.et_Type);
126 r = MatchType(super->ty_ProcType.et_ArgsType,
127 type->ty_ProcType.et_ArgsType);
128 v = MatchType(super->ty_ProcType.et_RetType,
129 type->ty_ProcType.et_RetType);
137 if (type->ty_StorType.et_Bytes !=
138 super->ty_StorType.et_Bytes) {
139 r = SG_COMPAT_SUBCLASS;
144 dassert_type(super, 0); /* can't happen */
148 Declaration *sd = RUNE_FIRST(&sg1->sg_DeclList);
149 Declaration *rd = RUNE_FIRST(&sg2->sg_DeclList);
151 int v = MatchDeclTypes(sd, rd);
154 if (r == SG_COMPAT_FAIL)
156 sd = RUNE_NEXT(sd, d_Node);
157 rd = RUNE_NEXT(rd, d_Node);
168 * SameType() - return 1 if the types are exactly the same, 0 if they are
171 * The sqFlags for t2 may be overriden. If you do not wish to override the
172 * sqFlags for t2, pass -1. The override only applies to the top level of
175 * Types can be aliased - for example, two different type structures may
176 * point to the same class data.
178 * XXX this needs a lot of work. We really need to guarentee some level of
179 * uniqueness for non-qualified type elements.
182 SameType(Type *t1, Type *t2, int sqFlags2)
187 if (t1->ty_Op != t2->ty_Op)
190 sqFlags2 = t2->ty_SQFlags;
191 if (t1->ty_SQFlags != sqFlags2)
195 if (t1->ty_ImportType.et_SemGroup == t2->ty_ImportType.et_SemGroup)
199 if (t1->ty_ClassType.et_SemGroup == t2->ty_ClassType.et_SemGroup &&
200 SameType(t1->ty_ClassType.et_Super,
201 t2->ty_ClassType.et_Super, -1))
207 t1 = t1->ty_RawPtrType.et_Type;
208 t2 = t2->ty_RawPtrType.et_Type;
211 t1 = t1->ty_RefType.et_Type;
212 t2 = t2->ty_RefType.et_Type;
230 sqFlags2 = t2->ty_SQFlags;
236 * SimilarType() - like SameType(), but ignores storage qualifiers (except
237 * SF_CONST) and if t2 is varargs, compares the original version.
239 * Used when casting t2 (rhs) to t1 (lhs).
242 SimilarType(Type *t1, Type *t2)
247 if (t2->ty_Op == TY_VAR)
248 t2 = t2->ty_VarType.et_Type;
255 * Check for an incompatible constant conversion if we loop through a
256 * pointer or ref. Allow compatibility for e.g. rvalues (const int)1
260 (t2->ty_SQFlags & SF_CONST) &&
261 (t1->ty_SQFlags & SF_CONST) == 0) {
264 if (t2->ty_Op != t1->ty_Op)
268 if (t1->ty_ImportType.et_SemGroup ==
269 t2->ty_ImportType.et_SemGroup) {
274 if (t1->ty_ClassType.et_SemGroup ==
275 t2->ty_ClassType.et_SemGroup &&
276 SameType(t1->ty_ClassType.et_Super,
277 t2->ty_ClassType.et_Super, -1)) {
282 t1 = t1->ty_RawPtrType.et_Type;
283 t2 = t2->ty_RawPtrType.et_Type;
287 * Reference types are similar if the lhs is a superclass of the
288 * rhs and partially compatible (only method call changes and
291 t1 = t1->ty_RefType.et_Type;
292 t2 = t2->ty_RefType.et_Type;
293 if (MatchType(t1, t2) <= SG_COMPAT_PART) {
300 * Compare the elements making up the compound type. XXX
302 return (SimilarSemGroup(t1->ty_CompType.et_SemGroup,
303 t2->ty_CompType.et_SemGroup));
326 * SimilarSemGroup() - check to see if the storage underlying the two
327 * semantic groups is compatible.
330 SimilarSemGroup(SemGroup *s1, SemGroup *s2)
335 if (s1->sg_Bytes != s2->sg_Bytes)
337 d1 = RUNE_FIRST(&s1->sg_DeclList);
338 d2 = RUNE_FIRST(&s2->sg_DeclList);
341 ((d1->d_Op & DOPF_STORAGE) == 0 ||
342 d1->d_Op == DOP_GLOBAL_STORAGE)
344 d1 = RUNE_NEXT(d1, d_Node);
347 ((d2->d_Op & DOPF_STORAGE) == 0 ||
348 d2->d_Op == DOP_GLOBAL_STORAGE)
350 d2 = RUNE_NEXT(d2, d_Node);
352 if (d1 == NULL || d2 == NULL)
354 if (SimilarType(d1->d_StorDecl.ed_Type,
355 d2->d_StorDecl.ed_Type) == 0) {
358 d1 = RUNE_NEXT(d1, d_Node);
359 d2 = RUNE_NEXT(d2, d_Node);
362 return (0); /* compare bad */
363 return (1); /* compare good */
366 static char *SaveStr[8];
367 static int SaveIndex;
371 typeToStr(Type *type, char **pstr, int simple)
373 char buf[RUNE_IDTOSTR_LEN];
384 safe_asprintf(&str, "(null)");
386 switch (type->ty_Op) {
388 st = type->ty_ClassType.et_SemGroup->sg_Stmt;
390 dassert(st->st_Op == ST_Class);
392 safe_asprintf(&str, "%s",
393 runeid_text(st->st_ClassStmt.es_Decl->d_Id, buf));
395 LexPrintRef(&st->st_LexRef, 0);
396 safe_asprintf(&str, "%s(",
397 runeid_text(st->st_ClassStmt.es_Decl->d_Id, buf));
398 if (type->ty_Flags & (TF_ISINTEGER | TF_ISFLOAT |
405 while (st && st->st_Op != ST_Import)
409 safe_replacef(&str, "%s%s%s",
412 /* st->st_ImportStmt.es_Path, */
413 st->st_ImportStmt.es_File);
417 safe_replacef(&str, "%s)", str);
420 safe_asprintf(&str, "(class_sg=%p)",
421 type->ty_ClassType.et_SemGroup);
425 st = type->ty_ImportType.et_SemGroup->sg_Stmt;
427 dassert(st->st_Op == ST_Module);
428 safe_asprintf(&str, "IMPORT(%s)",
429 st->st_LexRef.lr_Lex->l_Path);
431 safe_asprintf(&str, "IMPORT(sg=%p)",
432 type->ty_ImportType.et_SemGroup);
436 typeToStr(type->ty_RawPtrType.et_Type, &s1, simple);
437 safe_replacef(&str, "*%s", s1);
440 typeToStr(type->ty_RefType.et_Type, &s1, simple);
441 safe_replacef(&str, "@%s", s1);
444 typeToStr(type->ty_AryType.et_Type, &s1, simple);
445 safe_replacef(&str, "%s[%jd]",
446 s1, (intmax_t) type->ty_AryType.et_Count);
449 sg = type->ty_CompType.et_SemGroup;
450 safe_asprintf(&str, "COMP(");
453 RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
454 if (d->d_Op & DOPF_STORAGE) {
455 Type *dtype = d->d_StorDecl.ed_Type;
456 typeToStr(dtype, &s1, 1);
458 safe_replacef(&str, "%s,%s",
461 safe_replacef(&str, "%s%s",
467 safe_replacef(&str, "%s)", str);
470 safe_replacef(&str, "VAR");
473 sg = type->ty_ArgsType.et_SemGroup;
474 safe_asprintf(&str, "ARGS(");
476 RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
477 if (d->d_Op & DOPF_STORAGE) {
478 Type *dtype = d->d_StorDecl.ed_Type;
479 typeToStr(dtype, &s1, 1);
481 safe_replacef(&str, "%s,%s",
484 safe_replacef(&str, "%s%s",
490 safe_replacef(&str, "%s)", str);
494 Type *rtype = type->ty_ProcType.et_RetType;
495 Type *atype = type->ty_ProcType.et_ArgsType;
496 typeToStr(rtype, &s1, 1);
497 typeToStr(atype, &s2, 1);
498 safe_asprintf(&str, "%s %s", s1, s2);
502 safe_asprintf(&str, "STORAGE(%d)",
503 type->ty_StorType.et_Bytes);
506 safe_asprintf(&str, "DYNAMIC");
509 safe_asprintf(&str, "UNRES(");
510 for (count = 0; type->ty_UnresType.et_DottedId[count]; ++count) {
513 id = type->ty_UnresType.et_DottedId[count];
516 safe_replacef(&str, "%s.%s", str, runeid_text(id, buf));
518 safe_replacef(&str, "%s%s", str, runeid_text(id, buf));
521 safe_replacef(&str, "%s)", str);
524 safe_asprintf(&str, "?");
527 flags = type->ty_SQFlags;
532 if (flags & SF_CONST) {
535 } else if (flags & SF_VOLATILE) {
537 flags &= ~SF_VOLATILE;
538 } else if (flags & SF_VARARGS) {
540 flags &= ~SF_VARARGS;
541 } else if (flags & SF_LVALUE) {
544 } else if (flags & SF_NOZERO) {
547 } else if (flags & SF_METHOD) {
550 } else if (flags & SF_GMETHOD) {
552 flags &= ~SF_GMETHOD;
553 } else if (flags & SF_STRUCT) {
554 sqflag = "structure";
556 } else if (flags & SF_INTERNAL) {
558 flags &= ~SF_INTERNAL;
563 safe_replacef(&str, "%s%s%s",
574 safe_free(&SaveStr[SaveIndex]);
575 SaveStr[SaveIndex] = str;
576 SaveIndex = (SaveIndex + 1) % arysize(SaveStr);
582 TypeToStr(Type *type, char **pstr)
587 res = typeToStr(type, pstr, 0);
588 safe_asprintf(&str, "<TYPE_%p %s>", type, res);
593 safe_free(&SaveStr[SaveIndex]);
594 SaveStr[SaveIndex] = str;
595 SaveIndex = (SaveIndex + 1) % arysize(SaveStr);
601 TypePrintRef(Type *type, int t __unused)
604 fprintf(stderr, "for type: %s\n", TypeToStr(type, NULL));