Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 90e5523

Browse files
committed
Revert "Revert "Revert "DebugInfo: Omit debug info for dynamic classes in TUs that do not have the vtable for that class"""
This reverts commit r188642. This change is causing LTO builds to cause our 16 GB machines to swap and OOM all weekend. I am going to work with Dave Blaikie to resolve the issue. Sorry Dave =(. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188687 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 783344c commit 90e5523

File tree

4 files changed

+44
-163
lines changed

4 files changed

+44
-163
lines changed

lib/CodeGen/CGDebugInfo.cpp

+30-85
Original file line numberDiff line numberDiff line change
@@ -644,24 +644,8 @@ llvm::DIDescriptor CGDebugInfo::createContextChain(const Decl *Context) {
644644

645645
if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) {
646646
if (!RD->isDependentType()) {
647-
llvm::DICompositeType T(getTypeOrNull(CGM.getContext().getRecordType(RD)));
648-
llvm::DICompositeType Ty(getOrCreateLimitedType(
649-
CGM.getContext().getRecordType(RD)->castAs<RecordType>(),
650-
getOrCreateMainFile()));
651-
if (!Ty.getTypeArray().getNumElements()) {
652-
if (T) {
653-
llvm::DIArray PrevMem = T.getTypeArray();
654-
unsigned NumElements = PrevMem.getNumElements();
655-
if (NumElements == 1 && !PrevMem.getElement(0))
656-
NumElements = 0;
657-
SmallVector<llvm::Value *, 16> EltTys;
658-
EltTys.reserve(NumElements);
659-
for (unsigned i = 0; i != NumElements; ++i)
660-
EltTys.push_back(PrevMem.getElement(i));
661-
llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
662-
Ty.setTypeArray(Elements);
663-
}
664-
}
647+
llvm::DIType Ty = getOrCreateLimitedType(
648+
CGM.getContext().getRecordType(RD)->castAs<RecordType>(), getOrCreateMainFile());
665649
return llvm::DIDescriptor(Ty);
666650
}
667651
}
@@ -881,7 +865,7 @@ CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,
881865
}
882866
}
883867

884-
/// Helper for CollectRecordFields.
868+
/// CollectRecordStaticField - Helper for CollectRecordFields.
885869
llvm::DIDerivedType
886870
CGDebugInfo::CreateRecordStaticField(const VarDecl *Var,
887871
llvm::DIType RecordTy) {
@@ -964,7 +948,7 @@ void CGDebugInfo::CollectRecordFields(const RecordDecl *record,
964948
for (RecordDecl::decl_iterator I = record->decls_begin(),
965949
E = record->decls_end(); I != E; ++I)
966950
if (const VarDecl *V = dyn_cast<VarDecl>(*I))
967-
elements.push_back(getOrCreateStaticDataMemberDeclaration(V, RecordTy));
951+
elements.push_back(CreateRecordStaticField(V, RecordTy));
968952
else if (FieldDecl *field = dyn_cast<FieldDecl>(*I)) {
969953
CollectRecordNormalField(field, layout.getFieldOffset(fieldNo),
970954
tunit, elements, RecordTy);
@@ -1139,14 +1123,8 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,
11391123
if (D->isImplicit())
11401124
continue;
11411125

1142-
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
1143-
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI =
1144-
SPCache.find(Method->getCanonicalDecl());
1145-
if (MI == SPCache.end())
1146-
EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
1147-
else
1148-
EltTys.push_back(MI->second);
1149-
}
1126+
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
1127+
EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
11501128
}
11511129
}
11521130

@@ -1430,18 +1408,10 @@ void CGDebugInfo::completeType(const RecordDecl *RD) {
14301408
}
14311409

14321410
void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
1433-
if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
1434-
if (CXXDecl->isDynamicClass())
1435-
return;
1436-
14371411
QualType Ty = CGM.getContext().getRecordType(RD);
14381412
llvm::DIType T = getTypeOrNull(Ty);
1439-
if (T && T.isForwardDecl())
1440-
completeClassData(RD);
1441-
}
1442-
1443-
void CGDebugInfo::completeClassData(const RecordDecl *RD) {
1444-
QualType Ty = CGM.getContext().getRecordType(RD);
1413+
if (!T || !T.isForwardDecl())
1414+
return;
14451415
void* TyPtr = Ty.getAsOpaquePtr();
14461416
if (CompletedTypeCache.count(TyPtr))
14471417
return;
@@ -1454,23 +1424,14 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) {
14541424
/// CreateType - get structure or union type.
14551425
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) {
14561426
RecordDecl *RD = Ty->getDecl();
1457-
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
14581427
// Limited debug info should only remove struct definitions that can
14591428
// safely be replaced by a forward declaration in the source code.
1460-
if ((DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration &&
1461-
!RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) ||
1462-
(CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())) {
1429+
if (DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration &&
1430+
!RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) {
14631431
llvm::DIDescriptor FDContext =
14641432
getContextDescriptor(cast<Decl>(RD->getDeclContext()));
14651433
llvm::DIType RetTy = getOrCreateRecordFwdDecl(RD, FDContext);
1466-
// FIXME: This is conservatively correct. If we return a non-forward decl
1467-
// that's not a full definition (such as those created by
1468-
// createContextChain) then getOrCreateType will record is as a complete
1469-
// type and we'll never record all its members. But this means we're
1470-
// emitting full debug info in TUs where GCC successfully emits a partial
1471-
// definition of the type.
1472-
if (RetTy.isForwardDecl())
1473-
return RetTy;
1434+
return RetTy;
14741435
}
14751436

14761437
return CreateTypeDefinition(Ty);
@@ -1508,7 +1469,6 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
15081469

15091470
// Convert all the elements.
15101471
SmallVector<llvm::Value *, 16> EltTys;
1511-
// what about nested types?
15121472

15131473
// Note: The split of CXXDecl information here is intentional, the
15141474
// gdb tests will depend on a certain ordering at printout. The debug
@@ -2350,7 +2310,7 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {
23502310
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
23512311
MI = SPCache.find(FD->getCanonicalDecl());
23522312
if (MI == SPCache.end()) {
2353-
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD->getCanonicalDecl())) {
2313+
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
23542314
llvm::DICompositeType T(S);
23552315
llvm::DISubprogram SP = CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), T);
23562316
T.addMember(SP);
@@ -3065,35 +3025,19 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
30653025
DbgDecl->setDebugLoc(llvm::DebugLoc::get(line, column, scope));
30663026
}
30673027

3068-
/// If D is an out-of-class definition of a static data member of a class, find
3069-
/// its corresponding in-class declaration.
3070-
llvm::DIDerivedType
3071-
CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) {
3072-
if (!D->isStaticDataMember())
3073-
return llvm::DIDerivedType();
3074-
llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI =
3075-
StaticDataMemberCache.find(D->getCanonicalDecl());
3076-
if (MI != StaticDataMemberCache.end()) {
3077-
assert(MI->second && "Static data member declaration should still exist");
3078-
return llvm::DIDerivedType(cast<llvm::MDNode>(MI->second));
3079-
}
3080-
llvm::DICompositeType Ctxt(
3081-
getContextDescriptor(cast<Decl>(D->getDeclContext())));
3082-
llvm::DIDerivedType T = CreateRecordStaticField(D, Ctxt);
3083-
Ctxt.addMember(T);
3084-
return T;
3085-
}
3086-
3087-
llvm::DIDerivedType
3088-
CGDebugInfo::getOrCreateStaticDataMemberDeclaration(const VarDecl *D,
3089-
llvm::DICompositeType Ctxt) {
3090-
llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI =
3091-
StaticDataMemberCache.find(D->getCanonicalDecl());
3092-
if (MI != StaticDataMemberCache.end()) {
3093-
assert(MI->second && "Static data member declaration should still exist");
3094-
return llvm::DIDerivedType(cast<llvm::MDNode>(MI->second));
3028+
/// getStaticDataMemberDeclaration - If D is an out-of-class definition of
3029+
/// a static data member of a class, find its corresponding in-class
3030+
/// declaration.
3031+
llvm::DIDerivedType CGDebugInfo::getStaticDataMemberDeclaration(const VarDecl *D) {
3032+
if (D->isStaticDataMember()) {
3033+
llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
3034+
MI = StaticDataMemberCache.find(D->getCanonicalDecl());
3035+
if (MI != StaticDataMemberCache.end())
3036+
// Verify the info still exists.
3037+
if (llvm::Value *V = MI->second)
3038+
return llvm::DIDerivedType(cast<llvm::MDNode>(V));
30953039
}
3096-
return CreateRecordStaticField(D, Ctxt);
3040+
return llvm::DIDerivedType();
30973041
}
30983042

30993043
/// EmitGlobalVariable - Emit information about a global variable.
@@ -3125,10 +3069,11 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
31253069
LinkageName = StringRef();
31263070
llvm::DIDescriptor DContext =
31273071
getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()));
3128-
llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(
3129-
DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
3130-
Var->hasInternalLinkage(), Var,
3131-
getOrCreateStaticDataMemberDeclarationOrNull(D));
3072+
llvm::DIGlobalVariable GV =
3073+
DBuilder.createStaticVariable(DContext, DeclName, LinkageName, Unit,
3074+
LineNo, getOrCreateType(T, Unit),
3075+
Var->hasInternalLinkage(), Var,
3076+
getStaticDataMemberDeclaration(D));
31323077
DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV)));
31333078
}
31343079

@@ -3176,7 +3121,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD,
31763121
return;
31773122
llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(
31783123
Unit, Name, Name, Unit, getLineNumber(VD->getLocation()), Ty, true, Init,
3179-
getOrCreateStaticDataMemberDeclarationOrNull(cast<VarDecl>(VD)));
3124+
getStaticDataMemberDeclaration(cast<VarDecl>(VD)));
31803125
DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV)));
31813126
}
31823127

lib/CodeGen/CGDebugInfo.h

+5-8
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class CGDebugInfo {
291291

292292
void completeType(const RecordDecl *RD);
293293
void completeRequiredType(const RecordDecl *RD);
294-
void completeClassData(const RecordDecl *RD);
294+
295295

296296
private:
297297
/// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
@@ -354,13 +354,10 @@ class CGDebugInfo {
354354
/// declaration for the given method definition.
355355
llvm::DISubprogram getFunctionDeclaration(const Decl *D);
356356

357-
/// Return debug info descriptor to describe in-class static data member
358-
/// declaration for the given out-of-class definition.
359-
llvm::DIDerivedType
360-
getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);
361-
llvm::DIDerivedType
362-
getOrCreateStaticDataMemberDeclaration(const VarDecl *D,
363-
llvm::DICompositeType Ctxt);
357+
/// getStaticDataMemberDeclaration - Return debug info descriptor to
358+
/// describe in-class static data member declaration for the given
359+
/// out-of-class definition.
360+
llvm::DIDerivedType getStaticDataMemberDeclaration(const VarDecl *D);
364361

365362
/// getFunctionName - Get function name for the given FunctionDecl. If the
366363
/// name is constructred on demand (e.g. C++ destructor) then the name

lib/CodeGen/CGVTables.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -828,9 +828,6 @@ CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
828828
VFTContext->getVFPtrOffsets(RD);
829829
}
830830

831-
if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
832-
DI->completeClassData(RD);
833-
834831
// First off, check whether we've already emitted the v-table and
835832
// associated stuff.
836833
llvm::GlobalVariable *VTable = GetAddrOfVTable(RD);

test/CodeGenCXX/debug-info-class.cpp

+9-67
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,7 @@ class B {
1313
virtual ~B();
1414
};
1515

16-
B::~B() {
17-
}
18-
1916
struct C {
20-
static int s;
21-
virtual ~C();
22-
};
23-
24-
C::~C() {
25-
}
26-
27-
struct D {
28-
D();
29-
virtual ~D();
30-
void func() {
31-
}
32-
};
33-
34-
struct E {
35-
E();
36-
virtual ~E();
37-
virtual void func() {
38-
}
39-
};
40-
41-
struct F {
42-
struct inner {
43-
};
44-
static const int i = 2;
45-
virtual ~F();
46-
};
47-
48-
struct G {
4917
virtual void func();
5018
struct inner {
5119
int j;
@@ -61,17 +29,10 @@ struct A {
6129
}
6230
};
6331

64-
void f1() {
65-
D x;
66-
x.func();
67-
E y;
68-
int i = F::i;
69-
F::inner z;
70-
}
7132

7233
int main(int argc, char **argv) {
7334
B b;
74-
G::inner c_i;
35+
C::inner c_i;
7536
if (argc) {
7637
A a;
7738
}
@@ -88,34 +49,15 @@ int main(int argc, char **argv) {
8849
// CHECK: DW_TAG_structure_type ] [foo]
8950
// CHECK: DW_TAG_class_type ] [bar]
9051
// CHECK: DW_TAG_union_type ] [baz]
52+
// CHECK: DW_TAG_structure_type ] [A]
53+
// CHECK: HdrSize
9154
// CHECK: DW_TAG_class_type ] [B]
9255
// CHECK: metadata !"_vptr$B", {{.*}}, i32 64, metadata !{{.*}}} ; [ DW_TAG_member ]
93-
94-
// CHECK: [[C:![0-9]*]] = {{.*}} metadata [[C_MEM:![0-9]*]], i32 0, metadata [[C]], null} ; [ DW_TAG_structure_type ] [C] {{.*}} [def]
95-
// CHECK: [[C_MEM]] = metadata !{metadata [[C_VPTR:![0-9]*]], metadata [[C_S:![0-9]*]], metadata [[C_DTOR:![0-9]*]]}
96-
// CHECK: [[C_VPTR]] = {{.*}} ; [ DW_TAG_member ] [_vptr$C] {{.*}} [artificial]
97-
// CHECK: [[C_S]] = {{.*}} ; [ DW_TAG_member ] [s] {{.*}} [static] [from int]
98-
// CHECK: [[C_DTOR]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [~C]
99-
100-
// CHECK: ; [ DW_TAG_structure_type ] [A]
101-
// CHECK: HdrSize
102-
// CHECK: metadata [[D_MEM:![0-9]*]], i32 0, null} ; [ DW_TAG_structure_type ] [D] {{.*}} [decl]
103-
// CHECK: [[D_MEM]] = metadata !{metadata [[D_FUNC:![0-9]*]]}
104-
// CHECK: [[D_FUNC]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [func]
105-
106-
// CHECK: [[F_I_DEF:![0-9]*]] = {{.*}}, metadata [[F_I:![0-9]*]]} ; [ DW_TAG_variable ] [i]
107-
// CHECK: [[F_I]] = {{.*}} ; [ DW_TAG_member ] [i]
108-
// CHECK: [[F:![0-9]*]] = {{.*}} metadata [[F_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [F] {{.*}} [def]
109-
// CHECK: [[F_MEM]] = metadata !{metadata [[F_I]]}
110-
111-
// CHECK: null, i32 0, null} ; [ DW_TAG_structure_type ] [E] {{.*}} [decl]
112-
113-
// CHECK: metadata [[G_INNER_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [inner] [line 50, {{.*}} [def]
56+
// CHECK: metadata [[C_INNER_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [inner] {{.*}} [def]
11457
// Context chains (in Clang -flimit-debug-info and in GCC generally) contain
11558
// definitions without members (& without a vbase 'containing type'):
116-
// CHECK: null, i32 0, null, null} ; [ DW_TAG_structure_type ] [G] {{.*}} [def]
117-
// CHECK: [[G_INNER_MEM]] = metadata !{metadata [[G_INNER_I:![0-9]*]]}
118-
// CHECK: [[G_INNER_I]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int]
119-
120-
// CHECK: ![[EXCEPTLOC]] = metadata !{i32 79,
121-
// CHECK: ![[RETLOC]] = metadata !{i32 78,
59+
// CHECK: null, i32 0, null, null} ; [ DW_TAG_structure_type ] [C] {{.*}} [def]
60+
// CHECK: [[C_INNER_MEM]] = metadata !{metadata [[C_INNER_I:![0-9]*]]}
61+
// CHECK: [[C_INNER_I]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int]
62+
// CHECK: ![[EXCEPTLOC]] = metadata !{i32 40,
63+
// CHECK: ![[RETLOC]] = metadata !{i32 39,

0 commit comments

Comments
 (0)