in structrual_comptypes. */
extern int comparing_specializations;
+/* Nonzero if we are inside eq_specializations, which affects
+ resolving of typenames in structural_comptypes. */
+extern int comparing_typenames;
+
/* In parser.c. */
/* Nonzero if we are parsing an unevaluated operand: an operand to
return spec;
}
-/* Returns true iff two spec_entry nodes are equivalent. */
-
+/* Restricts tree and type comparisons. */
int comparing_specializations;
+int comparing_typenames;
+
+/* Returns true iff two spec_entry nodes are equivalent. */
bool
spec_hasher::equal (spec_entry *e1, spec_entry *e2)
int equal;
++comparing_specializations;
+ ++comparing_typenames;
equal = (e1->tmpl == e2->tmpl
&& comp_template_args (e1->args, e2->args));
if (equal && flag_concepts
equal = equivalent_constraints (c1, c2);
}
--comparing_specializations;
+ --comparing_typenames;
return equal;
}
gcc_assert (TYPE_P (t1) && TYPE_P (t2));
- if (!comparing_specializations)
- {
- /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
- current instantiation. */
- if (TREE_CODE (t1) == TYPENAME_TYPE)
- t1 = resolve_typename_type (t1, /*only_current_p=*/true);
-
- if (TREE_CODE (t2) == TYPENAME_TYPE)
- t2 = resolve_typename_type (t2, /*only_current_p=*/true);
- }
+ /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
+ current instantiation, and we don't care about typename
+ structural equality. The comparing_typenames check is after the
+ code check, in order to early-out the common case. */
+ if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames)
+ t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+
+ if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames)
+ t2 = resolve_typename_type (t2, /*only_current_p=*/true);
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);