DebugInfo: Don't emit vbase 'containing types' for context chain limited types

Possible minor reduction in debug info & avoid some cases where creating
a context chain could lead to the type the context chain is being
created for, being created. (this is still possible with template
parameters - tests/fixes/improvements to follow)

llvm-svn: 188639
This commit is contained in:
David Blaikie
2013-08-18 16:55:33 +00:00
parent c96c699a16
commit adfbf993d6
3 changed files with 49 additions and 27 deletions

View File

@@ -1453,6 +1453,9 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
if (FwdDecl.isForwardDecl())
return FwdDecl;
if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
CollectContainingType(CXXDecl, FwdDecl);
// Push the struct on region stack.
LexicalBlockStack.push_back(&*FwdDecl);
RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
@@ -2207,34 +2210,37 @@ llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl;
if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
// A class's primary base or the class itself contains the vtable.
llvm::DICompositeType ContainingType;
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
// Seek non virtual primary base root.
while (1) {
const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
const CXXRecordDecl *PBT = BRL.getPrimaryBase();
if (PBT && !BRL.isPrimaryBaseVirtual())
PBase = PBT;
else
break;
}
ContainingType = llvm::DICompositeType(
getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit));
} else if (CXXDecl->isDynamicClass())
ContainingType = RealDecl;
RealDecl.setContainingType(ContainingType);
if (const ClassTemplateSpecializationDecl *TSpecial =
dyn_cast<ClassTemplateSpecializationDecl>(CXXDecl))
RealDecl.setTypeArray(llvm::DIArray(),
CollectCXXTemplateParams(TSpecial, DefUnit));
}
if (const ClassTemplateSpecializationDecl *TSpecial =
dyn_cast<ClassTemplateSpecializationDecl>(RD))
RealDecl.setTypeArray(llvm::DIArray(),
CollectCXXTemplateParams(TSpecial, DefUnit));
return RealDecl;
}
void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,
llvm::DICompositeType RealDecl) {
// A class's primary base or the class itself contains the vtable.
llvm::DICompositeType ContainingType;
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
// Seek non virtual primary base root.
while (1) {
const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
const CXXRecordDecl *PBT = BRL.getPrimaryBase();
if (PBT && !BRL.isPrimaryBaseVirtual())
PBase = PBT;
else
break;
}
ContainingType = llvm::DICompositeType(
getOrCreateType(QualType(PBase->getTypeForDecl(), 0),
getOrCreateFile(RD->getLocation())));
} else if (RD->isDynamicClass())
ContainingType = RealDecl;
RealDecl.setContainingType(ContainingType);
}
/// CreateMemberType - Create new member and increase Offset by FType's size.
llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,
StringRef Name,

View File

@@ -117,6 +117,7 @@ class CGDebugInfo {
llvm::DIType CreateType(const RecordType *Ty, bool Declaration);
llvm::DIType CreateTypeDefinition(const RecordType *Ty);
llvm::DIType CreateLimitedType(const RecordType *Ty);
void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT);
llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);

View File

@@ -12,6 +12,14 @@ class B {
public:
virtual ~B();
};
struct C {
virtual void func();
struct inner {
int j;
};
};
struct A {
int one;
static const int HdrSize = 52;
@@ -24,6 +32,7 @@ struct A {
int main(int argc, char **argv) {
B b;
C::inner c_i;
if (argc) {
A a;
}
@@ -44,5 +53,11 @@ int main(int argc, char **argv) {
// CHECK: HdrSize
// CHECK: DW_TAG_class_type ] [B]
// CHECK: metadata !"_vptr$B", {{.*}}, i32 64, metadata !{{.*}}} ; [ DW_TAG_member ]
// CHECK: ![[EXCEPTLOC]] = metadata !{i32 31,
// CHECK: ![[RETLOC]] = metadata !{i32 30,
// CHECK: metadata [[C_INNER_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [inner] {{.*}} [def]
// Context chains (in Clang -flimit-debug-info and in GCC generally) contain
// definitions without members (& without a vbase 'containing type'):
// CHECK: null, i32 0, null, null} ; [ DW_TAG_structure_type ] [C] {{.*}} [def]
// CHECK: [[C_INNER_MEM]] = metadata !{metadata [[C_INNER_I:![0-9]*]]}
// CHECK: [[C_INNER_I]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int]
// CHECK: ![[EXCEPTLOC]] = metadata !{i32 40,
// CHECK: ![[RETLOC]] = metadata !{i32 39,