[cfe-commits] r73992 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaLookup.cpp test/SemaCXX/basic_lookup_argdep.cpp
Douglas Gregor
dgregor at apple.com
Tue Jun 23 13:14:13 PDT 2009
Author: dgregor
Date: Tue Jun 23 15:14:09 2009
New Revision: 73992
URL: http://llvm.org/viewvc/llvm-project?rev=73992&view=rev
Log:
Make sure that argument-dependent lookup looks into the global scope
when it should.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73992&r1=73991&r2=73992&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jun 23 15:14:09 2009
@@ -1137,7 +1137,8 @@
void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses);
+ AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope);
bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
SourceLocation NameLoc,
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=73992&r1=73991&r2=73992&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Jun 23 15:14:09 2009
@@ -1239,7 +1239,8 @@
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 @@
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 @@
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 @@
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 @@
= dyn_cast<CXXRecordDecl>(ClassType->getDecl())) {
addAssociatedClassesAndNamespaces(ClassDecl, Context,
AssociatedNamespaces,
- AssociatedClasses);
+ AssociatedClasses,
+ GlobalScope);
return;
}
@@ -1366,6 +1372,8 @@
Ctx = Ctx->getParent();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
AssociatedNamespaces.insert(EnclosingNamespace);
+ else if (Ctx->isTranslationUnit())
+ GlobalScope = true;
return;
}
@@ -1377,7 +1385,8 @@
// Return type
addAssociatedClassesAndNamespaces(FunctionType->getResultType(),
Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FunctionType);
if (!Proto)
@@ -1388,7 +1397,8 @@
ArgEnd = Proto->arg_type_end();
Arg != ArgEnd; ++Arg)
addAssociatedClassesAndNamespaces(*Arg, Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
return;
}
@@ -1406,13 +1416,15 @@
// 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 @@
void
Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses) {
+ AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope) {
AssociatedNamespaces.clear();
AssociatedClasses.clear();
@@ -1447,7 +1460,8 @@
if (Arg->getType() != Context.OverloadTy) {
addAssociatedClassesAndNamespaces(Arg->getType(), Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
continue;
}
@@ -1483,11 +1497,14 @@
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 @@
// 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 @@
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);
+ }
+ }
}
Modified: cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp?rev=73992&r1=73991&r2=73992&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp (original)
+++ cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp Tue Jun 23 15:14:09 2009
@@ -58,3 +58,16 @@
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);
+ }
+ }
+}
+
More information about the cfe-commits
mailing list