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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits