[cfe-commits] r80418 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/CXX/temp/temp.decls/temp.friend/p1.cpp

John McCall rjmccall at apple.com
Fri Aug 28 20:16:09 PDT 2009


Author: rjmccall
Date: Fri Aug 28 22:16:09 2009
New Revision: 80418

URL: http://llvm.org/viewvc/llvm-project?rev=80418&view=rev
Log:
Ensure code generation for friend declarations in class templates.


Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p1.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri Aug 28 22:16:09 2009
@@ -37,7 +37,7 @@
   if (!Ctx)
     Ctx = D->getDeclContext();
   
-  for (; !Ctx->isFileContext(); Ctx = Ctx->getParent()) {
+  while (!Ctx->isFileContext()) {
     // Add template arguments from a class template instantiation.
     if (ClassTemplateSpecializationDecl *Spec 
           = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
@@ -46,18 +46,26 @@
         break;
       
       Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
-      continue;
     } 
     
     // Add template arguments from a function template specialization.
-    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
+    else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
       // FIXME: Check whether this is an explicit specialization.
       if (const TemplateArgumentList *TemplateArgs
             = Function->getTemplateSpecializationArgs())
         Result.addOuterTemplateArguments(TemplateArgs);
-      
-      continue;
+
+      // If this is a friend declaration and it declares an entity at
+      // namespace scope, take arguments from its lexical parent
+      // instead of its semantic parent.
+      if (Function->getFriendObjectKind() &&
+          Function->getDeclContext()->isFileContext()) {
+        Ctx = Function->getLexicalDeclContext();
+        continue;
+      }
     }
+
+    Ctx = Ctx->getParent();
   }
   
   return Result;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Aug 28 22:16:09 2009
@@ -498,6 +498,8 @@
     Function->setObjectOfFriendDecl(WasDeclared);
     if (!Owner->isDependentContext())
       DC->makeDeclVisibleInContext(Function);
+
+    Function->setInstantiationOfMemberFunction(D);
   }
   
   if (InitFunctionInstantiation(Function, D))

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p1.cpp?rev=80418&r1=80417&r2=80418&view=diff

==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p1.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p1.cpp Fri Aug 28 22:16:09 2009
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+// RUN: clang-cc %s
 
 template <typename T> struct Num {
   T value_;
@@ -38,7 +38,7 @@
 
 int calc2() {
   Num<int> x = 3;
-  Num<int>::Rep<char> n = 10;
+  Num<int>::Rep<char> n = (cast) 10;
   Num<int> result = x * n;
   return result.get();
 }





More information about the cfe-commits mailing list