[cfe-commits] r98123 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp lib/CodeGen/CGVtable.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/Sema/SemaDeclCXX.cpp test/CodeGenCXX/virtual-base-destructor-call.cpp test/SemaTemplate/virtual-member-functions.cpp

Rafael Espindola rafael.espindola at gmail.com
Tue Mar 9 18:19:29 PST 2010


Author: rafael
Date: Tue Mar  9 20:19:29 2010
New Revision: 98123

URL: http://llvm.org/viewvc/llvm-project?rev=98123&view=rev
Log:
Delay codegen of vtables when handling implicit instantiations.

This fixes PR6474.


Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/lib/CodeGen/CGVtable.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp
    cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=98123&r1=98122&r2=98123&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Tue Mar  9 20:19:29 2010
@@ -3405,7 +3405,22 @@
   Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
                           /*IsVirtual=*/false,
                           AddressPoints);
-  GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);  
+  GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+
+  for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+	 e = RD->method_end(); i != e; ++i) {
+    if (!(*i)->isVirtual())
+      continue;
+    if(!(*i)->hasInlineBody() && !(*i)->isImplicit())
+      continue;
+
+    if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
+      CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
+      CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
+    } else {
+      CGM.BuildThunksForVirtual(GlobalDecl(*i));
+    }
+  }
 }
 
 llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
@@ -3438,19 +3453,12 @@
       return;
   }
 
-  // Emit the data.
-  GenerateClassData(CGM.getVtableLinkage(RD), RD);
+  if (Vtables.count(RD))
+    return;
 
-  for (CXXRecordDecl::method_iterator i = RD->method_begin(),
-       e = RD->method_end(); i != e; ++i) {
-    if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) {
-      if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
-        CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
-        CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
-      } else {
-        CGM.BuildThunksForVirtual(GlobalDecl(*i));
-      }
-    }
-  }
+  TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
+  if (kind == TSK_ImplicitInstantiation)
+    CGM.DeferredVtables.push_back(RD);
+  else
+    GenerateClassData(CGM.getVtableLinkage(RD), RD);
 }
-

Modified: cfe/trunk/lib/CodeGen/CGVtable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.h?rev=98123&r1=98122&r2=98123&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.h (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.h Tue Mar  9 20:19:29 2010
@@ -173,15 +173,7 @@
   uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
   
   void ComputeMethodVtableIndices(const CXXRecordDecl *RD);
-  
-  /// GenerateClassData - Generate all the class data requires to be generated
-  /// upon definition of a KeyFunction.  This includes the vtable, the
-  /// rtti data structure and the VTT.
-  /// 
-  /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
-  void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
-                         const CXXRecordDecl *RD);
- 
+   
   llvm::GlobalVariable *
   GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
                  bool GenerateDefinition, const CXXRecordDecl *LayoutClass, 
@@ -245,6 +237,14 @@
   llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
   
   void MaybeEmitVtable(GlobalDecl GD);
+
+  /// GenerateClassData - Generate all the class data requires to be generated
+  /// upon definition of a KeyFunction.  This includes the vtable, the
+  /// rtti data structure and the VTT.
+  ///
+  /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
+  void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                         const CXXRecordDecl *RD);
 };
 
 } // end namespace CodeGen

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=98123&r1=98122&r2=98123&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Mar  9 20:19:29 2010
@@ -488,7 +488,15 @@
   // Emit code for any potentially referenced deferred decls.  Since a
   // previously unused static decl may become used during the generation of code
   // for a static function, iterate until no  changes are made.
-  while (!DeferredDeclsToEmit.empty()) {
+
+  while (!DeferredDeclsToEmit.empty() || !DeferredVtables.empty()) {
+    if (!DeferredVtables.empty()) {
+      const CXXRecordDecl *RD = DeferredVtables.back();
+      DeferredVtables.pop_back();
+      getVtableInfo().GenerateClassData(getVtableLinkage(RD), RD);
+      continue;
+    }
+
     GlobalDecl D = DeferredDeclsToEmit.back();
     DeferredDeclsToEmit.pop_back();
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=98123&r1=98122&r2=98123&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Mar  9 20:19:29 2010
@@ -451,7 +451,9 @@
   /// GetTargetTypeStoreSize - Return the store size, in character units, of
   /// the given LLVM type.
   CharUnits GetTargetTypeStoreSize(const llvm::Type *Ty) const;
-  
+
+  std::vector<const CXXRecordDecl*> DeferredVtables;
+
 private:
   /// UniqueMangledName - Unique a name by (if necessary) inserting it into the
   /// MangledNames string map.

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=98123&r1=98122&r2=98123&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar  9 20:19:29 2010
@@ -5902,10 +5902,13 @@
 
   // We will need to mark all of the virtual members as referenced to build the
   // vtable.
-  // We actually call MarkVirtualMembersReferenced instead of adding to
-  // ClassesWithUnmarkedVirtualMembers because this marking is needed by
-  // codegen that will happend before we finish parsing the file.
-  if (needsVtable(MD, Context))
+  if (!needsVtable(MD, Context))
+    return;
+
+  TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
+  if (kind == TSK_ImplicitInstantiation)
+    ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(RD, Loc));
+  else
     MarkVirtualMembersReferenced(Loc, RD);
 }
 

Modified: cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp?rev=98123&r1=98122&r2=98123&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp Tue Mar  9 20:19:29 2010
@@ -22,6 +22,11 @@
 //  CHECK: call void @_ZN14basic_iostreamIcED2Ev
 //  CHECK: call void @_ZN9basic_iosD2Ev
 
+// basic_iostream's base dtor calls its non-virtual base dtor.
+//  CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev
+//  CHECK: call void @_ZN13basic_istreamIcED2Ev
+//  CHECK: }
+
 // basic_iostream's deleting dtor calls its complete dtor, then
 // operator delete().
 //  CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
@@ -40,11 +45,6 @@
 //  CHECK: call void @_ZN13basic_istreamIcED1Ev
 //  CHECK: call void @_ZdlPv
 
-// basic_iostream's base dtor calls its non-virtual base dtor.
-//  CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev
-//  CHECK: call void @_ZN13basic_istreamIcED2Ev
-//  CHECK: }
-
 // basic_istream's base dtor is a no-op.
 //  CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
 //  CHECK-NOT: call

Modified: cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp?rev=98123&r1=98122&r2=98123&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp (original)
+++ cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp Tue Mar  9 20:19:29 2010
@@ -14,7 +14,7 @@
 }
 
 void f(A<int> x) {
-  x.anchor(); // expected-note{{in instantiation of member function 'PR5557::A<int>::anchor' requested here}}
+  x.anchor();
 }
 
 template<typename T>
@@ -52,4 +52,4 @@
   return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
 }
 
-HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
+HasOutOfLineKey<int> out_of_line;





More information about the cfe-commits mailing list