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:
parent
59ed08b238
commit
7d5d7c7e90
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue