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

Commit 64edc01

Browse files
committed
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@292768 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 916645c commit 64edc01

File tree

4 files changed

+40
-13
lines changed

4 files changed

+40
-13
lines changed

lib/CodeGen/CGDebugInfo.cpp

+19-10
Original file line numberDiff line numberDiff line change
@@ -1714,7 +1714,26 @@ void CGDebugInfo::completeType(const RecordDecl *RD) {
17141714
completeRequiredType(RD);
17151715
}
17161716

1717+
/// Return true if the class or any of its methods are marked dllimport.
1718+
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD) {
1719+
if (RD->hasAttr<DLLImportAttr>())
1720+
return true;
1721+
for (const CXXMethodDecl *MD : RD->methods())
1722+
if (MD->hasAttr<DLLImportAttr>())
1723+
return true;
1724+
return false;
1725+
}
1726+
17171727
void CGDebugInfo::completeClassData(const RecordDecl *RD) {
1728+
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1729+
if (CGM.getVTableLinkage(CXXRD) ==
1730+
llvm::GlobalValue::AvailableExternallyLinkage &&
1731+
!isClassOrMethodDLLImport(CXXRD))
1732+
return;
1733+
completeClass(RD);
1734+
}
1735+
1736+
void CGDebugInfo::completeClass(const RecordDecl *RD) {
17181737
if (DebugKind <= codegenoptions::DebugLineTablesOnly)
17191738
return;
17201739
QualType Ty = CGM.getContext().getRecordType(RD);
@@ -1760,16 +1779,6 @@ static bool isDefinedInClangModule(const RecordDecl *RD) {
17601779
return true;
17611780
}
17621781

1763-
/// Return true if the class or any of its methods are marked dllimport.
1764-
static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD) {
1765-
if (RD->hasAttr<DLLImportAttr>())
1766-
return true;
1767-
for (const CXXMethodDecl *MD : RD->methods())
1768-
if (MD->hasAttr<DLLImportAttr>())
1769-
return true;
1770-
return false;
1771-
}
1772-
17731782
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
17741783
bool DebugTypeExtRefs, const RecordDecl *RD,
17751784
const LangOptions &LangOpts) {

lib/CodeGen/CGDebugInfo.h

+1
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ class CGDebugInfo {
409409
void completeType(const RecordDecl *RD);
410410
void completeRequiredType(const RecordDecl *RD);
411411
void completeClassData(const RecordDecl *RD);
412+
void completeClass(const RecordDecl *RD);
412413

413414
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
414415

lib/CodeGen/CGVTables.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,10 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
744744
switch (keyFunction->getTemplateSpecializationKind()) {
745745
case TSK_Undeclared:
746746
case TSK_ExplicitSpecialization:
747-
assert((def || CodeGenOpts.OptimizationLevel > 0) &&
748-
"Shouldn't query vtable linkage without key function or "
749-
"optimizations");
747+
assert((def || CodeGenOpts.OptimizationLevel > 0 ||
748+
CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) &&
749+
"Shouldn't query vtable linkage without key function, "
750+
"optimizations, or debug info");
750751
if (!def && CodeGenOpts.OptimizationLevel > 0)
751752
return llvm::GlobalVariable::AvailableExternallyLinkage;
752753

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited %s -O1 -o - | FileCheck %s
2+
3+
// Ensure class definitions are not emitted to debug info just because the
4+
// vtable is emitted for optimization purposes (as available_externally). The
5+
// class definition debug info should only go where the vtable is actually
6+
// emitted into the object file.
7+
8+
// CHECK: @_ZTV3foo = available_externally
9+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
10+
// CHECK-SAME: DIFlagFwdDecl
11+
12+
struct foo {
13+
virtual void f();
14+
};
15+
16+
foo f;

0 commit comments

Comments
 (0)