]> granicus.if.org Git - clang/commitdiff
Handle using declarations in overloaded and template functions during ADL and
authorChandler Carruth <chandlerc@gmail.com>
Tue, 29 Dec 2009 06:17:27 +0000 (06:17 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Tue, 29 Dec 2009 06:17:27 +0000 (06:17 +0000)
address resolution. This fixes PR5751.

Also, while we're here, remove logic from ADL which mistakenly included the
definition namespaces of overloaded and/or templated functions whose name or
address is used as an argument.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92245 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaLookup.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/using-decl-1.cpp

index aac3ffe6dd83bffbbf6a1546a2bafcae47dc2444..289c81da7a339a8fb8d6237af07f582a9e01313c 100644 (file)
@@ -1528,15 +1528,12 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
 
     for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Functions.begin(),
            E = Functions.end(); I != E; ++I) {
-      FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I);
-      if (!FDecl)
-        FDecl = cast<FunctionTemplateDecl>(*I)->getTemplatedDecl();
+      // Look through any using declarations to find the underlying function.
+      NamedDecl *Fn = (*I)->getUnderlyingDecl();
 
-      // Add the namespace in which this function was defined. Note
-      // that, if this is a member function, we do *not* consider the
-      // enclosing namespace of its class.
-      DeclContext *Ctx = FDecl->getDeclContext();
-      CollectNamespace(AssociatedNamespaces, Ctx);
+      FunctionDecl *FDecl = dyn_cast<FunctionDecl>(Fn);
+      if (!FDecl)
+        FDecl = cast<FunctionTemplateDecl>(Fn)->getTemplatedDecl();
 
       // Add the classes and namespaces associated with the parameter
       // types and return type of this function.
index 9f175f962b8e729688521f23a04ff4ddd08cb2ab..72a85cc968d933a9d29fb2859386fbc610b476dc 100644 (file)
@@ -4465,6 +4465,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
   bool FoundNonTemplateFunction = false;
   for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(),
          E = Fns.end(); I != E; ++I) {
+    // Look through any using declarations to find the underlying function.
+    NamedDecl *Fn = (*I)->getUnderlyingDecl();
+
     // C++ [over.over]p3:
     //   Non-member functions and static member functions match
     //   targets of type "pointer-to-function" or "reference-to-function."
@@ -4473,7 +4476,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
     // Note that according to DR 247, the containing class does not matter.
 
     if (FunctionTemplateDecl *FunctionTemplate
-          = dyn_cast<FunctionTemplateDecl>(*I)) {
+          = dyn_cast<FunctionTemplateDecl>(Fn)) {
       if (CXXMethodDecl *Method
             = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) {
         // Skip non-static function templates when converting to pointer, and
@@ -4510,7 +4513,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
       continue;
     }
 
-    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) {
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
       // Skip non-static functions when converting to pointer, and static
       // when converting to member pointer.
       if (Method->isStatic() == IsMember)
@@ -4522,7 +4525,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
     } else if (IsMember)
       continue;
 
-    if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*I)) {
+    if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) {
       QualType ResultTy;
       if (Context.hasSameUnqualifiedType(FunctionType, FunDecl->getType()) ||
           IsNoReturnConversion(Context, FunDecl->getType(), FunctionType, 
index fe4d167fe27d9a538c309674c8b8e8c93e38b830..e8a7d70976eca4a66f2f5448c5feab34d63db987 100644 (file)
@@ -42,3 +42,21 @@ struct X1 : X0 {
 struct A { void f(); };
 struct B : A { };
 class C : B { using B::f; };
+
+// PR5751: Resolve overloaded functions through using decls.
+namespace O {
+  void f(int i);
+  void f(double d);
+}
+namespace P {
+  void f();
+  void g(void (*ptr)(int));
+  using O::f;
+  void test() {
+    f();
+    f(1);
+    void (*f_ptr1)(double) = f;
+    void (*f_ptr2)() = f;
+    g(f);
+  }
+}