[cfe-commits] r74993 - in /cfe/trunk: lib/Sema/SemaLookup.cpp test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp test/SemaCXX/basic_lookup_argdep.cpp www/cxx_status.html

Douglas Gregor dgregor at apple.com
Wed Jul 8 00:52:10 PDT 2009


Author: dgregor
Date: Wed Jul  8 02:51:57 2009
New Revision: 74993

URL: http://llvm.org/viewvc/llvm-project?rev=74993&view=rev
Log:
Improve argument-dependent lookup to find associated classes and
namespaces based on the template arguments of a class template
specialization type.

Added:
    cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp   (with props)
    cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
      - copied unchanged from r74992, cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp
Removed:
    cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp
Modified:
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=74993&r1=74992&r2=74993&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Jul  8 02:51:57 2009
@@ -1241,6 +1241,74 @@
   return true;
 }
 
+static void 
+addAssociatedClassesAndNamespaces(QualType T, 
+                                  ASTContext &Context,
+                          Sema::AssociatedNamespaceSet &AssociatedNamespaces,
+                                  Sema::AssociatedClassSet &AssociatedClasses,
+                                  bool &GlobalScope);
+
+// \brief Add the associated classes and namespaces for argument-dependent 
+// lookup that involves a template argument (C++ [basic.lookup.koenig]p2).
+static void 
+addAssociatedClassesAndNamespaces(const TemplateArgument &Arg, 
+                                  ASTContext &Context,
+                           Sema::AssociatedNamespaceSet &AssociatedNamespaces,
+                                  Sema::AssociatedClassSet &AssociatedClasses,
+                                  bool &GlobalScope) {
+  // C++ [basic.lookup.koenig]p2, last bullet:
+  //   -- [...] ;  
+  switch (Arg.getKind()) {
+    case TemplateArgument::Null:
+      break;
+    
+    case TemplateArgument::Type:
+      // [...] the namespaces and classes associated with the types of the
+      // template arguments provided for template type parameters (excluding
+      // template template parameters)
+      addAssociatedClassesAndNamespaces(Arg.getAsType(), Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses,
+                                        GlobalScope);
+      break;
+      
+    case TemplateArgument::Declaration:
+      // [...] the namespaces in which any template template arguments are 
+      // defined; and the classes in which any member templates used as 
+      // template template arguments are defined.
+      if (ClassTemplateDecl *ClassTemplate 
+            = dyn_cast<ClassTemplateDecl>(Arg.getAsDecl())) {
+        DeclContext *Ctx = ClassTemplate->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;
+      }
+      break;
+      
+    case TemplateArgument::Integral:
+    case TemplateArgument::Expression:
+      // [Note: non-type template arguments do not contribute to the set of 
+      //  associated namespaces. ]
+      break;
+      
+    case TemplateArgument::Pack:
+      for (TemplateArgument::pack_iterator P = Arg.pack_begin(),
+                                        PEnd = Arg.pack_end();
+           P != PEnd; ++P)
+        addAssociatedClassesAndNamespaces(*P, Context,
+                                          AssociatedNamespaces,
+                                          AssociatedClasses,
+                                          GlobalScope);
+      break;
+  }
+}
+
 // \brief Add the associated classes and namespaces for
 // argument-dependent lookup with an argument of class type 
 // (C++ [basic.lookup.koenig]p2). 
@@ -1275,8 +1343,36 @@
   if (!AssociatedClasses.insert(Class))
     return;
 
-  // FIXME: Handle class template specializations
-
+  // -- If T is a template-id, its associated namespaces and classes are 
+  //    the namespace in which the template is defined; for member 
+  //    templates, the member template’s class; the namespaces and classes
+  //    associated with the types of the template arguments provided for 
+  //    template type parameters (excluding template template parameters); the
+  //    namespaces in which any template template arguments are defined; and 
+  //    the classes in which any member templates used as template template 
+  //    arguments are defined. [Note: non-type template arguments do not 
+  //    contribute to the set of associated namespaces. ]
+  if (ClassTemplateSpecializationDecl *Spec 
+        = dyn_cast<ClassTemplateSpecializationDecl>(Class)) {
+    DeclContext *Ctx = Spec->getSpecializedTemplate()->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;
+    
+    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+    for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+      addAssociatedClassesAndNamespaces(TemplateArgs[I], Context,
+                                        AssociatedNamespaces,
+                                        AssociatedClasses,
+                                        GlobalScope);
+  }
+  
   // Add direct and indirect base classes along with their associated
   // namespaces.
   llvm::SmallVector<CXXRecordDecl *, 32> Bases;
@@ -1297,7 +1393,8 @@
         DeclContext *BaseCtx = BaseDecl->getDeclContext();
         while (BaseCtx->isRecord())
           BaseCtx = BaseCtx->getParent();
-        if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(BaseCtx))
+        if (NamespaceDecl *EnclosingNamespace 
+              = dyn_cast<NamespaceDecl>(BaseCtx))
           AssociatedNamespaces.insert(EnclosingNamespace);
         else if (BaseCtx->isTranslationUnit())
           GlobalScope = true;
@@ -1490,6 +1587,8 @@
     if (!DRE)
       continue;
 
+    // FIXME: The declaration might be a FunctionTemplateDecl (by itself)
+    // or might be buried in a TemplateIdRefExpr.
     OverloadedFunctionDecl *Ovl 
       = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl());
     if (!Ovl)

Added: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp?rev=74993&view=auto

==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp (added)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp Wed Jul  8 02:51:57 2009
@@ -0,0 +1,16 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+namespace N1 {
+  struct X { };
+  int& f(void*);
+}
+
+namespace N2 {
+  template<typename T> struct Y { };
+}
+
+namespace N3 {
+  void test() {
+    int &ir = f((N2::Y<N1::X>*)0);
+  }
+}

Propchange: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Removed: cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp?rev=74992&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp (original)
+++ cfe/trunk/test/SemaCXX/basic_lookup_argdep.cpp (removed)
@@ -1,73 +0,0 @@
-// RUN: clang-cc -fsyntax-only -verify %s
-
-namespace N {
-  struct X { };
-  
-  X operator+(X, X);
-
-  void f(X);
-  void g(X); // expected-note{{candidate function}}
-
-  void test_multiadd(X x) {
-    (void)(x + x);
-  }
-}
-
-namespace M {
-  struct Y : N::X { };
-}
-
-void f();
-
-void test_operator_adl(N::X x, M::Y y) {
-  (void)(x + x);
-  (void)(y + y);
-}
-
-void test_func_adl(N::X x, M::Y y) {
-  f(x);
-  f(y);
-  (f)(x); // expected-error{{too many arguments to function call}}
-  ::f(x); // expected-error{{too many arguments to function call}}
-}
-
-namespace N {
-  void test_multiadd2(X x) {
-    (void)(x + x);
-  }
-}
-
-
-void test_func_adl_only(N::X x) {
-  g(x);
-}
-
-namespace M {
-  int g(N::X); // expected-note{{candidate function}}
-
-  void test(N::X x) {
-    g(x); // expected-error{{call to 'g' is ambiguous; candidates are:}}
-    int i = (g)(x);
-
-    int g(N::X);
-    g(x); // okay; calls locally-declared function, no ADL
-  }
-}
-
-
-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);
-    }
-  }
-}
-

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=74993&r1=74992&r2=74993&view=diff

==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Wed Jul  8 02:51:57 2009
@@ -353,7 +353,7 @@
   <td class="advanced" align="center"></td>
   <td class="advanced" align="center"></td>
   <td class="na">N/A</td>
-  <td>Missing support for templates, friend functions.</td>
+  <td>Missing support for friend functions.</td>
 </tr>
 <tr>
   <td>    3.4.3 [basic.lookup.qual]</td>





More information about the cfe-commits mailing list