summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2009-12-29 06:17:27 +0000
committerChandler Carruth <chandlerc@gmail.com>2009-12-29 06:17:27 +0000
commitc25c6ee3dbf28ebbe1d918db8a55d498a4266d81 (patch)
tree60baf8bbff749cfa7b0d2bf8b7d8c774bad60b28
parent015215ca86c8a33ce7f887c877da7323001a6691 (diff)
downloadbcm5719-llvm-c25c6ee3dbf28ebbe1d918db8a55d498a4266d81.tar.gz
bcm5719-llvm-c25c6ee3dbf28ebbe1d918db8a55d498a4266d81.zip
Handle using declarations in overloaded and template functions during ADL and
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. llvm-svn: 92245
-rw-r--r--clang/lib/Sema/SemaLookup.cpp13
-rw-r--r--clang/lib/Sema/SemaOverload.cpp9
-rw-r--r--clang/test/SemaCXX/using-decl-1.cpp18
3 files changed, 29 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index aac3ffe6dd8..289c81da7a3 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 9f175f962b8..72a85cc968d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -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,
diff --git a/clang/test/SemaCXX/using-decl-1.cpp b/clang/test/SemaCXX/using-decl-1.cpp
index fe4d167fe27..e8a7d70976e 100644
--- a/clang/test/SemaCXX/using-decl-1.cpp
+++ b/clang/test/SemaCXX/using-decl-1.cpp
@@ -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);
+ }
+}
OpenPOWER on IntegriCloud