[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