[DebugInfo] Move constructor homing case in shouldOmitDefinition.

For some reason the ctor homing case was before the template
specialization case, and could have returned false too early.
I moved the code out into a separate function to avoid this.

Also added a run line to the template specialization test. I guess
all the -debug-info-kind=limited tests should still pass with =constructor,
but it's probably unnecessary to test for all of those.

Differential Revision: https://reviews.llvm.org/D86491
This commit is contained in:
Amy Huang 2020-08-24 20:17:59 -07:00
parent 1f04678f87
commit 589ce5f705
2 changed files with 29 additions and 18 deletions

View File

@ -2260,6 +2260,25 @@ static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I,
return false; return false;
} }
static bool canUseCtorHoming(const CXXRecordDecl *RD) {
// Constructor homing can be used for classes that have at least one
// constructor and have no trivial or constexpr constructors.
// Skip this optimization if the class or any of its methods are marked
// dllimport.
if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() ||
isClassOrMethodDLLImport(RD))
return false;
if (RD->ctors().empty())
return false;
for (const auto *Ctor : RD->ctors())
if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
return false;
return true;
}
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind, static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
bool DebugTypeExtRefs, const RecordDecl *RD, bool DebugTypeExtRefs, const RecordDecl *RD,
const LangOptions &LangOpts) { const LangOptions &LangOpts) {
@ -2294,23 +2313,6 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
!isClassOrMethodDLLImport(CXXDecl)) !isClassOrMethodDLLImport(CXXDecl))
return true; return true;
// In constructor debug mode, only emit debug info for a class when its
// constructor is emitted. Skip this optimization if the class or any of
// its methods are marked dllimport.
//
// This applies to classes that don't have any trivial constructors and have
// at least one constructor.
if (DebugKind == codegenoptions::DebugInfoConstructor &&
!CXXDecl->isLambda() && !CXXDecl->hasConstexprNonCopyMoveConstructor() &&
!isClassOrMethodDLLImport(CXXDecl)) {
if (CXXDecl->ctors().empty())
return false;
for (const auto *Ctor : CXXDecl->ctors())
if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
return false;
return true;
}
TemplateSpecializationKind Spec = TSK_Undeclared; TemplateSpecializationKind Spec = TSK_Undeclared;
if (const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) if (const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
Spec = SD->getSpecializationKind(); Spec = SD->getSpecializationKind();
@ -2320,6 +2322,12 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
CXXDecl->method_end())) CXXDecl->method_end()))
return true; return true;
// In constructor homing mode, only emit complete debug info for a class
// when its constructor is emitted.
if ((DebugKind != codegenoptions::DebugInfoConstructor) &&
canUseCtorHoming(CXXDecl))
return true;
return false; return false;
} }

View File

@ -1,4 +1,7 @@
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=limited %s -o - | FileCheck %s // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=limited %s -o - | FileCheck %
// Make sure this still works with constructor homing.
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=constructor %s -o - | FileCheck %s
// Run again with -gline-tables-only or -gline-directives-only and verify we don't crash. We won't output // Run again with -gline-tables-only or -gline-directives-only and verify we don't crash. We won't output
// type info at all. // type info at all.