aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-06-23 20:14:09 +0000
committerDouglas Gregor <dgregor@apple.com>2009-06-23 20:14:09 +0000
commit44bc2d53ebf1b7ad7439a0f73aba3d00a462d63a (patch)
treecbaba674bbf2f2c77bae4417b9e930095f52d885
parentbb7c96f290453104ec35ca17111a5165f68a4697 (diff)
Make sure that argument-dependent lookup looks into the global scope
when it should. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73992 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaLookup.cpp58
-rw-r--r--test/SemaCXX/basic_lookup_argdep.cpp13
3 files changed, 60 insertions, 14 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 8604fe56a2..3f96948c19 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1137,7 +1137,8 @@ public:
void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses);
+ AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope);
bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
SourceLocation NameLoc,
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 37e1df3a19..9bcf320771 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1239,7 +1239,8 @@ static void
addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
ASTContext &Context,
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
- Sema::AssociatedClassSet &AssociatedClasses) {
+ Sema::AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope) {
// C++ [basic.lookup.koenig]p2:
// [...]
// -- If T is a class type (including unions), its associated
@@ -1252,13 +1253,14 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
DeclContext *Ctx = Class->getDeclContext();
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
AssociatedClasses.insert(EnclosingClass);
-
// Add the associated namespace for this class.
while (Ctx->isRecord())
Ctx = Ctx->getParent();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
AssociatedNamespaces.insert(EnclosingNamespace);
-
+ else if (Ctx->isTranslationUnit())
+ GlobalScope = true;
+
// Add the class itself. If we've already seen this class, we don't
// need to visit base classes.
if (!AssociatedClasses.insert(Class))
@@ -1288,6 +1290,8 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
BaseCtx = BaseCtx->getParent();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(BaseCtx))
AssociatedNamespaces.insert(EnclosingNamespace);
+ else if (BaseCtx->isTranslationUnit())
+ GlobalScope = true;
// Make sure we visit the bases of this base class.
if (BaseDecl->bases_begin() != BaseDecl->bases_end())
@@ -1304,7 +1308,8 @@ static void
addAssociatedClassesAndNamespaces(QualType T,
ASTContext &Context,
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
- Sema::AssociatedClassSet &AssociatedClasses) {
+ Sema::AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope) {
// C++ [basic.lookup.koenig]p2:
//
// For each argument type T in the function call, there is a set
@@ -1346,7 +1351,8 @@ addAssociatedClassesAndNamespaces(QualType T,
= dyn_cast<CXXRecordDecl>(ClassType->getDecl())) {
addAssociatedClassesAndNamespaces(ClassDecl, Context,
AssociatedNamespaces,
- AssociatedClasses);
+ AssociatedClasses,
+ GlobalScope);
return;
}
@@ -1366,6 +1372,8 @@ addAssociatedClassesAndNamespaces(QualType T,
Ctx = Ctx->getParent();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
AssociatedNamespaces.insert(EnclosingNamespace);
+ else if (Ctx->isTranslationUnit())
+ GlobalScope = true;
return;
}
@@ -1377,7 +1385,8 @@ addAssociatedClassesAndNamespaces(QualType T,
// Return type
addAssociatedClassesAndNamespaces(FunctionType->getResultType(),
Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FunctionType);
if (!Proto)
@@ -1388,7 +1397,8 @@ addAssociatedClassesAndNamespaces(QualType T,
ArgEnd = Proto->arg_type_end();
Arg != ArgEnd; ++Arg)
addAssociatedClassesAndNamespaces(*Arg, Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
return;
}
@@ -1406,13 +1416,15 @@ addAssociatedClassesAndNamespaces(QualType T,
// Handle the type that the pointer to member points to.
addAssociatedClassesAndNamespaces(MemberPtr->getPointeeType(),
Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
// Handle the class type into which this points.
if (const RecordType *Class = MemberPtr->getClass()->getAsRecordType())
addAssociatedClassesAndNamespaces(cast<CXXRecordDecl>(Class->getDecl()),
Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
return;
}
@@ -1431,7 +1443,8 @@ addAssociatedClassesAndNamespaces(QualType T,
void
Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses) {
+ AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope) {
AssociatedNamespaces.clear();
AssociatedClasses.clear();
@@ -1447,7 +1460,8 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
if (Arg->getType() != Context.OverloadTy) {
addAssociatedClassesAndNamespaces(Arg->getType(), Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
continue;
}
@@ -1483,11 +1497,14 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
DeclContext *Ctx = FDecl->getDeclContext();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
AssociatedNamespaces.insert(EnclosingNamespace);
+ else if (Ctx->isTranslationUnit())
+ GlobalScope = true;
// Add the classes and namespaces associated with the parameter
// types and return type of this function.
addAssociatedClassesAndNamespaces(FDecl->getType(), Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
}
}
}
@@ -1589,8 +1606,10 @@ void Sema::ArgumentDependentLookup(DeclarationName Name,
// arguments we have.
AssociatedNamespaceSet AssociatedNamespaces;
AssociatedClassSet AssociatedClasses;
+ bool GlobalScope = false;
FindAssociatedClassesAndNamespaces(Args, NumArgs,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
// C++ [basic.lookup.argdep]p3:
// Let X be the lookup set produced by unqualified lookup (3.4.1)
@@ -1626,4 +1645,17 @@ void Sema::ArgumentDependentLookup(DeclarationName Name,
Functions.insert(Func);
}
}
+
+ if (GlobalScope) {
+ DeclContext::lookup_iterator I, E;
+ for (llvm::tie(I, E)
+ = Context.getTranslationUnitDecl()->lookup(Context, Name);
+ I != E; ++I) {
+ FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
+ if (!Func)
+ break;
+
+ Functions.insert(Func);
+ }
+ }
}
diff --git a/test/SemaCXX/basic_lookup_argdep.cpp b/test/SemaCXX/basic_lookup_argdep.cpp
index 486a688d94..677df8284a 100644
--- a/test/SemaCXX/basic_lookup_argdep.cpp
+++ b/test/SemaCXX/basic_lookup_argdep.cpp
@@ -58,3 +58,16 @@ namespace M {
void test_operator_name_adl(N::X x) {
(void)operator+(x, x);
}
+
+struct Z { };
+int& f(Z);
+
+namespace O {
+ char &f();
+ void test_global_scope_adl(Z z) {
+ {
+ int& ir = f(z);
+ }
+ }
+}
+