lookup will stop when we hit a dependent base. */
if (!dependent_scope_p (context))
{
- bool want_type = (complain & tf_qualifying_scope);
+ /* We generally don't ignore non-types during TYPENAME_TYPE lookup
+ (as per [temp.res.general]/3), unless
+ - the tag corresponds to a class-key or 'enum' so
+ [basic.lookup.elab] applies, or
+ - the tag corresponds to scope_type or tf_qualifying_scope is
+ set so [basic.lookup.qual]/1 applies.
+ TODO: If we'd set/track the scope_type tag thoroughly on all
+ TYPENAME_TYPEs that are followed by :: then we wouldn't need the
+ tf_qualifying_scope flag. */
+ bool want_type = (tag_type != none_type && tag_type != typename_type)
+ || (complain & tf_qualifying_scope);
t = lookup_member (context, name, /*protect=*/2, want_type, complain);
}
else
return error_mark_node;
}
+ /* FIXME: TYPENAME_IS_CLASS_P conflates 'class' vs 'struct' vs 'union'
+ tags. TYPENAME_TYPE should probably remember the exact tag that
+ was written. */
+ enum tag_types tag_type
+ = TYPENAME_IS_CLASS_P (t) ? class_type
+ : TYPENAME_IS_ENUM_P (t) ? enum_type
+ : typename_type;
tsubst_flags_t tcomplain = complain | tf_keep_type_decl;
tcomplain |= tst_ok_flag | qualifying_scope_flag;
- f = make_typename_type (ctx, f, typename_type, tcomplain);
+ f = make_typename_type (ctx, f, tag_type, tcomplain);
if (f == error_mark_node)
return f;
if (TREE_CODE (f) == TYPE_DECL)
--- /dev/null
+// PR c++/109420
+
+struct A {
+ struct X { };
+ int X;
+};
+
+struct B {
+ enum E { };
+ enum F { E };
+};
+
+template<class T, class U>
+void f() {
+ struct T::X x; // OK, lookup ignores the data member 'int A::X'
+ enum U::E e; // OK, lookup ignores the enumerator 'B::F::E'
+}
+
+template void f<A, B>();