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
This commit is contained in:
David Blaikie 2013-08-17 00:06:55 +00:00
parent 59ed08b238
commit 7d5d7c7e90
4 changed files with 37 additions and 130 deletions

View File

@ -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<VarDecl>(*I))
elements.push_back(getOrCreateStaticDataMemberDeclaration(V, RecordTy));
elements.push_back(CreateRecordStaticField(V, RecordTy));
else if (FieldDecl *field = dyn_cast<FieldDecl>(*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<CXXMethodDecl>(D)) {
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::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<CXXMethodDecl>(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<CXXRecordDecl>(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<CXXRecordDecl>(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<Decl>(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<llvm::Value *, 16> 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<const FunctionDecl *, llvm::WeakVH>::iterator
MI = SPCache.find(FD->getCanonicalDecl());
if (MI == SPCache.end()) {
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD->getCanonicalDecl())) {
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(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<const Decl *, llvm::WeakVH>::iterator MI =
StaticDataMemberCache.find(D->getCanonicalDecl());
if (MI != StaticDataMemberCache.end()) {
assert(MI->second && "Static data member declaration should still exist");
return llvm::DIDerivedType(cast<llvm::MDNode>(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<const Decl *, llvm::WeakVH>::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<llvm::MDNode>(V));
}
llvm::DICompositeType Ctxt(
getContextDescriptor(cast<Decl>(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<const Decl *, llvm::WeakVH>::iterator MI =
StaticDataMemberCache.find(D->getCanonicalDecl());
if (MI != StaticDataMemberCache.end()) {
assert(MI->second && "Static data member declaration should still exist");
return llvm::DIDerivedType(cast<llvm::MDNode>(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<Decl>(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<VarDecl>(VD)));
getStaticDataMemberDeclaration(cast<VarDecl>(VD)));
DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV)));
}

View File

@ -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

View File

@ -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);

View File

@ -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,