diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-03-10 02:19:29 +0000 | 
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-03-10 02:19:29 +0000 | 
| commit | e7113ca907daa9f84992986f005e8ca6e6577481 (patch) | |
| tree | da4680799639f5060a4cbf70bcfcce709a1f870d /clang/lib | |
| parent | b7e0b87441a253be7973b1da9abc07a1c7fa68bd (diff) | |
| download | bcm5719-llvm-e7113ca907daa9f84992986f005e8ca6e6577481.tar.gz bcm5719-llvm-e7113ca907daa9f84992986f005e8ca6e6577481.zip  | |
Delay codegen of vtables when handling implicit instantiations.
This fixes PR6474.
llvm-svn: 98123
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 38 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.h | 18 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 11 | 
5 files changed, 51 insertions, 30 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 932bd079e93..a77a28ccdd8 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -3405,7 +3405,22 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,    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 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {        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);  } - diff --git a/clang/lib/CodeGen/CGVtable.h b/clang/lib/CodeGen/CGVtable.h index 6ccb011985f..57220d9d5af 100644 --- a/clang/lib/CodeGen/CGVtable.h +++ b/clang/lib/CodeGen/CGVtable.h @@ -173,15 +173,7 @@ private:    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 @@ public:    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 diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d6a56dad0ba..c67948d27f0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -488,7 +488,15 @@ void CodeGenModule::EmitDeferred() {    // 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(); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index c86f8b45bcd..40dc5638898 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -451,7 +451,9 @@ public:    /// 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. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index a89f355147f..79cab15e691 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5902,10 +5902,13 @@ void Sema::MaybeMarkVirtualMembersReferenced(SourceLocation Loc,    // 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);  }  | 

