riccibruno created this revision.
riccibruno added reviewers: Quuxplusone, rsmith, rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.
riccibruno added a parent revision: D60573: [Sema] ADL: Associated namespaces
for class types and enumeration types (CWG 1691).
CWG 997 added the following wording at the end of `[basic.lookup.argdep]p2`
> [...] Additionally, if the aforementioned set of overloaded functions is
> named with a template-id, its associated classes and namespaces are those of
> its type template-arguments and its template template-arguments.
This resolve CWG 1015 and part of CWG 997 (I will mark it as done when the rest
of it is implemented).
Repository:
rC Clang
https://reviews.llvm.org/D60665
Files:
lib/Sema/SemaLookup.cpp
test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
test/CXX/drs/dr10xx.cpp
Index: test/CXX/drs/dr10xx.cpp
===================================================================
--- test/CXX/drs/dr10xx.cpp
+++ test/CXX/drs/dr10xx.cpp
@@ -35,6 +35,19 @@
Third<A<int> > t; // expected-note {{in instantiation of default argument}}
}
+namespace dr1015 { // dr1015: 9
+ namespace N {
+ struct S {};
+ void f(void (*)(S));
+ }
+
+ template<typename T> void g(T);
+
+ void h() {
+ f(g<N::S>); // ok, N::f
+ }
+}
+
namespace dr1048 { // dr1048: 3.6
struct A {};
const A f();
Index: test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
===================================================================
--- test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
+++ test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
@@ -315,7 +315,7 @@
namespace N {
struct S {};
constexpr int f(int (*g)()) { return g(); }
- // expected-note@-1 2{{'N::f' declared here}}
+ // expected-note@-1 {{'N::f' declared here}}
template <typename T> struct Q;
}
@@ -328,11 +328,13 @@
constexpr int g3() { return 4; }
template <typename T> constexpr int g3(T, N::Q<T>) { return 5; }
+ template <template <typename> class Z> constexpr int g4() { return 6; }
+
void test() {
- static_assert(f(g1) == 1, ""); // Well-formed from the union rule above
- static_assert(f(g2<N::S>) == 3, ""); // FIXME: Well-formed from the template-id rule above.
- // expected-error@-1 {{use of undeclared}}
+ static_assert(f(g1) == 1, ""); // Well-formed from the union rule.
+ static_assert(f(g2<N::S>) == 3, ""); // Well-formed from the template-id rule.
static_assert(f(g3) == 4, ""); // FIXME: Also well-formed from the union rule.
// expected-error@-1 {{use of undeclared}}
+ static_assert(f(g4<N::Q>) == 6, ""); // Well-formed from the template-id rule.
}
}
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -2625,12 +2625,11 @@
}
}
-// Add the associated classes and namespaces for
-// argument-dependent lookup with an argument of type T
-// (C++ [basic.lookup.koenig]p2).
+// Add the associated classes and namespaces for argument-dependent
+// lookup with an argument of type T (C++ [basic.lookup.argdep]p2).
static void
addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
- // C++ [basic.lookup.koenig]p2:
+ // C++ [basic.lookup.argdep]p2:
//
// For each argument type T in the function call, there is a set
// of zero or more associated namespaces and a set of zero or more
@@ -2806,7 +2805,7 @@
AssociatedLookup Result(*this, InstantiationLoc,
AssociatedNamespaces, AssociatedClasses);
- // C++ [basic.lookup.koenig]p2:
+ // C++ [basic.lookup.argdep]p2:
// For each argument type T in the function call, there is a set
// of zero or more associated namespaces and a set of zero or more
// associated classes to be considered. The sets of namespaces and
@@ -2821,15 +2820,16 @@
continue;
}
- // [...] In addition, if the argument is the name or address of a
- // set of overloaded functions and/or function templates, its
- // associated classes and namespaces are the union of those
- // associated with each of the members of the set: the namespace
- // in which the function or function template is defined and the
- // classes and namespaces associated with its (non-dependent)
- // parameter types and return type.
OverloadExpr *OE = OverloadExpr::find(Arg).Expression;
+ // C++ [basic.lookup.argdep] end of p2:
+ // [...] In addition, if the argument is the name or address of a set of
+ // overloaded functions and/or function templates, its associated classes
+ // and namespaces are the union of those associated with each of the
+ // members of the set, i.e., the classes and namespaces associated with
+ // its parameter types and return type.
+ //
+ // TODO: CWG 997 removed the restriction on non-dependent types.
for (const NamedDecl *D : OE->decls()) {
// Look through any using declarations to find the underlying function.
const FunctionDecl *FDecl = D->getUnderlyingDecl()->getAsFunction();
@@ -2838,6 +2838,17 @@
// types and return type of this function.
addAssociatedClassesAndNamespaces(Result, FDecl->getType());
}
+
+ // [...] Additionally, if the aforementioned set of overloaded functions
+ // is named with a template-id, its associated classes and namespaces also
+ // include those of its type template-arguments and its template
+ // template-arguments.
+ //
+ // Added by CWG 997.
+ for (const TemplateArgumentLoc &TemplateArgLoc : OE->template_arguments()) {
+ const TemplateArgument &TemplateArg = TemplateArgLoc.getArgument();
+ addAssociatedClassesAndNamespaces(Result, TemplateArg);
+ }
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits