From 7d5d7c7e907a3db447435cb67585c8666410a5f6 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Sat, 17 Aug 2013 00:06:55 +0000 Subject: [PATCH] Revert "DebugInfo: Omit debug info for dynamic classes in TUs that do not have the vtable for that class" This reverts commit r188576. Reverting while I investigate a selfhosting buildbot failure on Darwin. llvm-svn: 188600 --- clang/lib/CodeGen/CGDebugInfo.cpp | 101 ++++++--------------- clang/lib/CodeGen/CGDebugInfo.h | 13 +-- clang/lib/CodeGen/CGVTables.cpp | 3 - clang/test/CodeGenCXX/debug-info-class.cpp | 50 +--------- 4 files changed, 37 insertions(+), 130 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9965dbacac75..74b4662171e1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -865,7 +865,7 @@ CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl, } } -/// Helper for CollectRecordFields. +/// CollectRecordStaticField - Helper for CollectRecordFields. llvm::DIDerivedType CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType RecordTy) { @@ -951,7 +951,7 @@ void CGDebugInfo::CollectRecordFields(const RecordDecl *record, for (RecordDecl::decl_iterator I = record->decls_begin(), E = record->decls_end(); I != E; ++I) if (const VarDecl *V = dyn_cast(*I)) - elements.push_back(getOrCreateStaticDataMemberDeclaration(V, RecordTy)); + elements.push_back(CreateRecordStaticField(V, RecordTy)); else if (FieldDecl *field = dyn_cast(*I)) { CollectRecordNormalField(field, layout.getFieldOffset(fieldNo), tunit, elements, RecordTy); @@ -1122,14 +1122,8 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit, if (D->isImplicit()) continue; - if (const CXXMethodDecl *Method = dyn_cast(D)) { - llvm::DenseMap::iterator MI = - SPCache.find(Method->getCanonicalDecl()); - if (MI == SPCache.end()) - EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy)); - else - EltTys.push_back(MI->second); - } + if (const CXXMethodDecl *Method = dyn_cast(D)) + EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy)); } } @@ -1414,18 +1408,10 @@ void CGDebugInfo::completeType(const RecordDecl *RD) { } void CGDebugInfo::completeRequiredType(const RecordDecl *RD) { - if (const CXXRecordDecl *CXXDecl = dyn_cast(RD)) - if (CXXDecl->isDynamicClass()) - return; - QualType Ty = CGM.getContext().getRecordType(RD); llvm::DIType T = getTypeOrNull(Ty); - if (T && T.isForwardDecl()) - completeClassData(RD); -} - -void CGDebugInfo::completeClassData(const RecordDecl *RD) { - QualType Ty = CGM.getContext().getRecordType(RD); + if (!T || !T.isForwardDecl()) + return; void* TyPtr = Ty.getAsOpaquePtr(); if (CompletedTypeCache.count(TyPtr)) return; @@ -1438,23 +1424,14 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) { /// CreateType - get structure or union type. llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) { RecordDecl *RD = Ty->getDecl(); - const CXXRecordDecl *CXXDecl = dyn_cast(RD); // Limited debug info should only remove struct definitions that can // safely be replaced by a forward declaration in the source code. - if ((DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration && - !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) || - (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())) { + if (DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration && + !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) { llvm::DIDescriptor FDContext = getContextDescriptor(cast(RD->getDeclContext())); llvm::DIType RetTy = getOrCreateRecordFwdDecl(RD, FDContext); - // FIXME: This is conservatively correct. If we return a non-forward decl - // that's not a full definition (such as those created by - // createContextChain) then getOrCreateType will record is as a complete - // type and we'll never record all its members. But this means we're - // emitting full debug info in TUs where GCC successfully emits a partial - // definition of the type. - if (RetTy.isForwardDecl()) - return RetTy; + return RetTy; } return CreateTypeDefinition(Ty); @@ -1489,13 +1466,6 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { // Convert all the elements. SmallVector EltTys; - llvm::DIArray PrevMem = FwdDecl.getTypeArray(); - unsigned NumElements = PrevMem.getNumElements(); - if (NumElements == 1 && !PrevMem.getElement(0)) - NumElements = 0; - EltTys.reserve(NumElements); - for (unsigned i = 0; i != NumElements; ++i) - EltTys.push_back(PrevMem.getElement(i)); // Note: The split of CXXDecl information here is intentional, the // gdb tests will depend on a certain ordering at printout. The debug @@ -2321,7 +2291,7 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { llvm::DenseMap::iterator MI = SPCache.find(FD->getCanonicalDecl()); if (MI == SPCache.end()) { - if (const CXXMethodDecl *MD = dyn_cast(FD->getCanonicalDecl())) { + if (const CXXMethodDecl *MD = dyn_cast(FD)) { llvm::DICompositeType T(S); llvm::DISubprogram SP = CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), T); T.addMember(SP); @@ -3027,35 +2997,19 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, DbgDecl->setDebugLoc(llvm::DebugLoc::get(line, column, scope)); } -/// If D is an out-of-class definition of a static data member of a class, find -/// its corresponding in-class declaration. -llvm::DIDerivedType -CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) { - if (!D->isStaticDataMember()) - return llvm::DIDerivedType(); - llvm::DenseMap::iterator MI = - StaticDataMemberCache.find(D->getCanonicalDecl()); - if (MI != StaticDataMemberCache.end()) { - assert(MI->second && "Static data member declaration should still exist"); - return llvm::DIDerivedType(cast(MI->second)); +/// getStaticDataMemberDeclaration - If D is an out-of-class definition of +/// a static data member of a class, find its corresponding in-class +/// declaration. +llvm::DIDerivedType CGDebugInfo::getStaticDataMemberDeclaration(const VarDecl *D) { + if (D->isStaticDataMember()) { + llvm::DenseMap::iterator + MI = StaticDataMemberCache.find(D->getCanonicalDecl()); + if (MI != StaticDataMemberCache.end()) + // Verify the info still exists. + if (llvm::Value *V = MI->second) + return llvm::DIDerivedType(cast(V)); } - llvm::DICompositeType Ctxt( - getContextDescriptor(cast(D->getDeclContext()))); - llvm::DIDerivedType T = CreateRecordStaticField(D, Ctxt); - Ctxt.addMember(T); - return T; -} - -llvm::DIDerivedType -CGDebugInfo::getOrCreateStaticDataMemberDeclaration(const VarDecl *D, - llvm::DICompositeType Ctxt) { - llvm::DenseMap::iterator MI = - StaticDataMemberCache.find(D->getCanonicalDecl()); - if (MI != StaticDataMemberCache.end()) { - assert(MI->second && "Static data member declaration should still exist"); - return llvm::DIDerivedType(cast(MI->second)); - } - return CreateRecordStaticField(D, Ctxt); + return llvm::DIDerivedType(); } /// EmitGlobalVariable - Emit information about a global variable. @@ -3087,10 +3041,11 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, LinkageName = StringRef(); llvm::DIDescriptor DContext = getContextDescriptor(dyn_cast(D->getDeclContext())); - llvm::DIGlobalVariable GV = DBuilder.createStaticVariable( - DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), - Var->hasInternalLinkage(), Var, - getOrCreateStaticDataMemberDeclarationOrNull(D)); + llvm::DIGlobalVariable GV = + DBuilder.createStaticVariable(DContext, DeclName, LinkageName, Unit, + LineNo, getOrCreateType(T, Unit), + Var->hasInternalLinkage(), Var, + getStaticDataMemberDeclaration(D)); DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV))); } @@ -3138,7 +3093,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, return; llvm::DIGlobalVariable GV = DBuilder.createStaticVariable( Unit, Name, Name, Unit, getLineNumber(VD->getLocation()), Ty, true, Init, - getOrCreateStaticDataMemberDeclarationOrNull(cast(VD))); + getStaticDataMemberDeclaration(cast(VD))); DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV))); } diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 51a937bfced4..39436e18a72d 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -290,7 +290,7 @@ public: void completeType(const RecordDecl *RD); void completeRequiredType(const RecordDecl *RD); - void completeClassData(const RecordDecl *RD); + private: /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration. @@ -353,13 +353,10 @@ private: /// declaration for the given method definition. llvm::DISubprogram getFunctionDeclaration(const Decl *D); - /// Return debug info descriptor to describe in-class static data member - /// declaration for the given out-of-class definition. - llvm::DIDerivedType - getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D); - llvm::DIDerivedType - getOrCreateStaticDataMemberDeclaration(const VarDecl *D, - llvm::DICompositeType Ctxt); + /// getStaticDataMemberDeclaration - Return debug info descriptor to + /// describe in-class static data member declaration for the given + /// out-of-class definition. + llvm::DIDerivedType getStaticDataMemberDeclaration(const VarDecl *D); /// getFunctionName - Get function name for the given FunctionDecl. If the /// name is constructred on demand (e.g. C++ destructor) then the name diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 6649578fc09c..c7bb54e06996 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -828,9 +828,6 @@ CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) { VFTContext->getVFPtrOffsets(RD); } - if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) - DI->completeClassData(RD); - // First off, check whether we've already emitted the v-table and // associated stuff. llvm::GlobalVariable *VTable = GetAddrOfVTable(RD); diff --git a/clang/test/CodeGenCXX/debug-info-class.cpp b/clang/test/CodeGenCXX/debug-info-class.cpp index 76cc1e3e27c2..df2492603e36 100644 --- a/clang/test/CodeGenCXX/debug-info-class.cpp +++ b/clang/test/CodeGenCXX/debug-info-class.cpp @@ -12,32 +12,6 @@ class B { public: virtual ~B(); }; - -B::~B() { -} - -struct C { - static int s; - virtual ~C(); -}; - -C::~C() { -} - -struct D { - D(); - virtual ~D(); - void func() { - } -}; - -struct E { - E(); - virtual ~E(); - virtual void func() { - } -}; - struct A { int one; static const int HdrSize = 52; @@ -47,11 +21,6 @@ struct A { } }; -void f1() { - D x; - x.func(); - E y; -} int main(int argc, char **argv) { B b; @@ -71,20 +40,9 @@ int main(int argc, char **argv) { // CHECK: DW_TAG_structure_type ] [foo] // CHECK: DW_TAG_class_type ] [bar] // CHECK: DW_TAG_union_type ] [baz] +// CHECK: DW_TAG_structure_type ] [A] +// CHECK: HdrSize // CHECK: DW_TAG_class_type ] [B] // CHECK: metadata !"_vptr$B", {{.*}}, i32 64, metadata !{{.*}}} ; [ DW_TAG_member ] - -// CHECK: [[C:![0-9]*]] = {{.*}} metadata [[C_MEM:![0-9]*]], i32 0, metadata [[C]], null} ; [ DW_TAG_structure_type ] [C] {{.*}} [def] -// CHECK: [[C_MEM]] = metadata !{metadata [[C_VPTR:![0-9]*]], metadata [[C_S:![0-9]*]], metadata [[C_DTOR:![0-9]*]]} -// CHECK: [[C_VPTR]] = {{.*}} ; [ DW_TAG_member ] [_vptr$C] {{.*}} [artificial] -// CHECK: [[C_S]] = {{.*}} ; [ DW_TAG_member ] [s] {{.*}} [static] [from int] -// CHECK: [[C_DTOR]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [~C] - -// CHECK: ; [ DW_TAG_structure_type ] [A] -// CHECK: HdrSize -// CHECK: metadata [[D_MEM:![0-9]*]], i32 0, null} ; [ DW_TAG_structure_type ] [D] {{.*}} [decl] -// CHECK: [[D_MEM]] = metadata !{metadata [[D_FUNC:![0-9]*]]} -// CHECK: [[D_FUNC]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [func] -// CHECK: null, i32 0, null} ; [ DW_TAG_structure_type ] [E] {{.*}} [decl] -// CHECK: ![[EXCEPTLOC]] = metadata !{i32 62, -// CHECK: ![[RETLOC]] = metadata !{i32 61, +// CHECK: ![[EXCEPTLOC]] = metadata !{i32 31, +// CHECK: ![[RETLOC]] = metadata !{i32 30,