[cfe-commits] r137934 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiateDecl.cpp test/CodeGenCXX/template-instantiation.cpp

Chandler Carruth chandlerc at gmail.com
Thu Aug 18 02:09:59 PDT 2011


Author: chandlerc
Date: Thu Aug 18 04:09:59 2011
New Revision: 137934

URL: http://llvm.org/viewvc/llvm-project?rev=137934&view=rev
Log:
Always mark friend function declarations in class templates as
implicitly instantiable, even if we don't see a body on the friend
function declaration. The body may simply have not yet been attached.
This fixes PR10666.

There may be an alternate, preferred implementation strategy, see my
FIXME. Review would definitely be appreciated Doug. =D

Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/CodeGenCXX/template-instantiation.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=137934&r1=137933&r2=137934&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Aug 18 04:09:59 2011
@@ -1153,9 +1153,13 @@
                                                              Innermost.first,
                                                              Innermost.second),
                                                 InsertPos);
-  } else if (isFriend && D->isThisDeclarationADefinition()) {
-    // TODO: should we remember this connection regardless of whether
-    // the friend declaration provided a body?
+  } else if (isFriend) {
+    // Note, we need this connection even if the friend doesn't have a body.
+    // Its body may exist but not have been attached yet due to deferred
+    // parsing.
+    // FIXME: It might be cleaner to set this when attaching the body to the
+    // friend function declaration, however that would require finding all the
+    // instantiations and modifying them.
     Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
     

Modified: cfe/trunk/test/CodeGenCXX/template-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/template-instantiation.cpp?rev=137934&r1=137933&r2=137934&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/template-instantiation.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/template-instantiation.cpp Thu Aug 18 04:09:59 2011
@@ -17,6 +17,19 @@
 // CHECK: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
 // CHECK: define available_externally void @_ZN5test21CIiE6zedbarEd(
 
+// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi1EEE()
+// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi2EEE()
+// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi3EEE()
+// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi1EEE()
+// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi2EEE()
+// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi3EEE()
+// CHECK: declare void @_ZN7PR106662h1ENS_1SILi1EEE()
+// CHECK: declare void @_ZN7PR106662h1ENS_1SILi2EEE()
+// CHECK: declare void @_ZN7PR106662h1ENS_1SILi3EEE()
+// CHECK: declare void @_ZN7PR106662h2ENS_1SILi1EEE()
+// CHECK: declare void @_ZN7PR106662h2ENS_1SILi2EEE()
+// CHECK: declare void @_ZN7PR106662h2ENS_1SILi3EEE()
+
 namespace test0 {
   struct  basic_streambuf   {
     virtual       ~basic_streambuf();
@@ -152,3 +165,26 @@
 
   int x = S<int>::f();
 }
+
+// Ensure that definitions are emitted for all friend functions defined within
+// class templates. Order of declaration is extremely important here. Different
+// instantiations of the class happen at different points during the deferred
+// method body parsing and afterward. Those different points of instantiation
+// change the exact form the class template appears to have.
+namespace PR10666 {
+  template <int N> struct S {
+    void f1() { S<1> s; }
+    friend void g1(S s) {}
+    friend void h1(S s);
+    void f2() { S<2> s; }
+    friend void g2(S s) {}
+    friend void h2(S s);
+    void f3() { S<3> s; }
+  };
+  void test(S<1> s1, S<2> s2, S<3> s3) {
+    g1(s1); g1(s2); g1(s3);
+    g2(s1); g2(s2); g2(s3);
+    h1(s1); h1(s2); h1(s3);
+    h2(s1); h2(s2); h2(s3);
+  }
+}





More information about the cfe-commits mailing list