[cfe-commits] r99665 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiateDecl.cpp test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp

John McCall rjmccall at apple.com
Fri Mar 26 16:10:15 PDT 2010


Author: rjmccall
Date: Fri Mar 26 18:10:15 2010
New Revision: 99665

URL: http://llvm.org/viewvc/llvm-project?rev=99665&view=rev
Log:
Put function templates instantiated from friend declarations in the correct
lexical context.  This is required for ADL to work properly;  fixes PR6716.


Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=99665&r1=99664&r2=99665&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Mar 26 18:10:15 2010
@@ -840,16 +840,18 @@
   assert(InstTemplate && 
          "VisitFunctionDecl/CXXMethodDecl didn't create a template!");
 
+  bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None);
+
   // Link the instantiation back to the pattern *unless* this is a
   // non-definition friend declaration.
   if (!InstTemplate->getInstantiatedFromMemberTemplate() &&
-      !(InstTemplate->getFriendObjectKind() &&
-        !D->getTemplatedDecl()->isThisDeclarationADefinition()))
+      !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition()))
     InstTemplate->setInstantiatedFromMemberTemplate(D);
   
-  // Add non-friends into the owner.
-  if (!InstTemplate->getFriendObjectKind())
+  // Make declarations visible in the appropriate context.
+  if (!isFriend)
     Owner->addDecl(InstTemplate);
+
   return InstTemplate;
 }
 
@@ -973,7 +975,13 @@
   if (Qualifier)
     Function->setQualifierInfo(Qualifier, D->getQualifierRange());
 
-  Function->setLexicalDeclContext(Owner);
+  DeclContext *LexicalDC = Owner;
+  if (!isFriend && D->isOutOfLine()) {
+    assert(D->getDeclContext()->isFileContext());
+    LexicalDC = D->getDeclContext();
+  }
+
+  Function->setLexicalDeclContext(LexicalDC);
 
   // Attach the parameters
   for (unsigned P = 0; P < Params.size(); ++P)
@@ -1000,7 +1008,8 @@
                                                     Function->getDeclName(),
                                                     TemplateParams, Function);
     Function->setDescribedFunctionTemplate(FunctionTemplate);
-    FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
+
+    FunctionTemplate->setLexicalDeclContext(LexicalDC);
 
     if (isFriend && D->isThisDeclarationADefinition()) {
       // TODO: should we remember this connection regardless of whether

Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp?rev=99665&r1=99664&r2=99665&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp Fri Mar 26 18:10:15 2010
@@ -40,3 +40,15 @@
     D::D() + D::D(); // expected-error {{ invalid operands to binary expression ('D::D' and 'D::D') }}
   }
 }
+
+// PR6716
+namespace test1 {
+  template <class T> class A {
+    template <class U> friend void foo(A &, U); // expected-note {{not viable: 1st argument ('A<int> const') would lose const qualifier}}
+  };
+
+  void test() {
+    const A<int> a;
+    foo(a, 10); // expected-error {{no matching function for call to 'foo'}}
+  }
+}





More information about the cfe-commits mailing list