[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