mirror of
https://github.com/intel/llvm.git
synced 2026-02-08 17:28:30 +08:00
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:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user