DebugInfo: Omit class definitions even in the presence of available_externally vtables
To ensure optimization level doesn't pessimize the -fstandalone-debug vtable debug info optimization (where class definitions are only emitted where the vtable is emitted - reducing redundant debug info) ensure the debug info class definition is still omitted when an available_externally vtable definition is emitted for optimization purposes. llvm-svn: 292768
This commit is contained in:
parent
0218ce1080
commit
b06bcde1ab
|
@ -1714,7 +1714,26 @@ void CGDebugInfo::completeType(const RecordDecl *RD) {
|
|||
completeRequiredType(RD);
|
||||
}
|
||||
|
||||
/// Return true if the class or any of its methods are marked dllimport.
|
||||
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD) {
|
||||
if (RD->hasAttr<DLLImportAttr>())
|
||||
return true;
|
||||
for (const CXXMethodDecl *MD : RD->methods())
|
||||
if (MD->hasAttr<DLLImportAttr>())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGDebugInfo::completeClassData(const RecordDecl *RD) {
|
||||
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
|
||||
if (CGM.getVTableLinkage(CXXRD) ==
|
||||
llvm::GlobalValue::AvailableExternallyLinkage &&
|
||||
!isClassOrMethodDLLImport(CXXRD))
|
||||
return;
|
||||
completeClass(RD);
|
||||
}
|
||||
|
||||
void CGDebugInfo::completeClass(const RecordDecl *RD) {
|
||||
if (DebugKind <= codegenoptions::DebugLineTablesOnly)
|
||||
return;
|
||||
QualType Ty = CGM.getContext().getRecordType(RD);
|
||||
|
@ -1760,16 +1779,6 @@ static bool isDefinedInClangModule(const RecordDecl *RD) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Return true if the class or any of its methods are marked dllimport.
|
||||
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD) {
|
||||
if (RD->hasAttr<DLLImportAttr>())
|
||||
return true;
|
||||
for (const CXXMethodDecl *MD : RD->methods())
|
||||
if (MD->hasAttr<DLLImportAttr>())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
|
||||
bool DebugTypeExtRefs, const RecordDecl *RD,
|
||||
const LangOptions &LangOpts) {
|
||||
|
|
|
@ -409,6 +409,7 @@ public:
|
|||
void completeType(const RecordDecl *RD);
|
||||
void completeRequiredType(const RecordDecl *RD);
|
||||
void completeClassData(const RecordDecl *RD);
|
||||
void completeClass(const RecordDecl *RD);
|
||||
|
||||
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
|
||||
|
||||
|
|
|
@ -744,9 +744,10 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
|
|||
switch (keyFunction->getTemplateSpecializationKind()) {
|
||||
case TSK_Undeclared:
|
||||
case TSK_ExplicitSpecialization:
|
||||
assert((def || CodeGenOpts.OptimizationLevel > 0) &&
|
||||
"Shouldn't query vtable linkage without key function or "
|
||||
"optimizations");
|
||||
assert((def || CodeGenOpts.OptimizationLevel > 0 ||
|
||||
CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) &&
|
||||
"Shouldn't query vtable linkage without key function, "
|
||||
"optimizations, or debug info");
|
||||
if (!def && CodeGenOpts.OptimizationLevel > 0)
|
||||
return llvm::GlobalVariable::AvailableExternallyLinkage;
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited %s -O1 -o - | FileCheck %s
|
||||
|
||||
// Ensure class definitions are not emitted to debug info just because the
|
||||
// vtable is emitted for optimization purposes (as available_externally). The
|
||||
// class definition debug info should only go where the vtable is actually
|
||||
// emitted into the object file.
|
||||
|
||||
// CHECK: @_ZTV3foo = available_externally
|
||||
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
|
||||
// CHECK-SAME: DIFlagFwdDecl
|
||||
|
||||
struct foo {
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
foo f;
|
Loading…
Reference in New Issue