diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2281,22 +2281,18 @@ } 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. + // Constructor homing can be used for classes that don't have any implicit, + // trivial default constructors or constexpr constructors. + // In other words, the class cannot be constructed without emitting code for + // one of its constructors. + // // Skip this optimization if the class or any of its methods are marked // dllimport. - if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() || - isClassOrMethodDLLImport(RD)) + if (RD->isLambda() || 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; + return !RD->isAggregate() && !RD->hasTrivialDefaultConstructor() && + !RD->hasConstexprNonCopyMoveConstructor(); } static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind, diff --git a/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp --- a/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp +++ b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp @@ -20,14 +20,37 @@ }; D::D() {} +// Test for constexpr constructor. // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "E"{{.*}}DIFlagTypePassByValue struct E { constexpr E(){}; } TestE; +// Tests for trivial constructors. // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "F"{{.*}}DIFlagTypePassByValue struct F { F() = default; F(int) {} int i; } TestF; + +// CHECK-DAG: ![[G:.*]] ={{.*}}!DICompositeType({{.*}}name: "G"{{.*}}DIFlagTypePassByValue +// CHECK-DAG: !DICompositeType({{.*}}scope: ![[G]], {{.*}}DIFlagTypePassByValue +struct G { + G() : g_(0) {} + struct { + int g_; + }; +} TestG; + +// CHECK-DAG: !DICompositeType({{.*}}name: "H",{{.*}}DIFlagTypePassByValue +struct H { + B b; +}; +void f(H h) {} + +// CHECK-DAG: !DICompositeType({{.*}}name: "I",{{.*}}DIFlagTypePassByValue +struct I { + B b; +}; +void f(decltype(I()) i) {}