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 @@ -1648,6 +1648,12 @@ if (CGM.getLangOpts().Optimize) SPFlags |= llvm::DISubprogram::SPFlagOptimized; + // In this debug mode, emit type info for a class when its constructor type + // info is emitted. + if (DebugKind == codegenoptions::DebugInfoConstructor) + if (const CXXConstructorDecl *CD = dyn_cast(Method)) + completeClass(CD->getParent()); + llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit); llvm::DISubprogram *SP = DBuilder.createMethod( RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine, @@ -2211,6 +2217,17 @@ !isClassOrMethodDLLImport(CXXDecl)) 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. + if (DebugKind == codegenoptions::DebugInfoConstructor && + !CXXDecl->isLambda() && !isClassOrMethodDLLImport(CXXDecl)) { + for (const auto *Ctor : CXXDecl->ctors()) { + if (Ctor->isUserProvided()) + return true; + } + } + TemplateSpecializationKind Spec = TSK_Undeclared; if (const auto *SD = dyn_cast(RD)) Spec = SD->getSpecializationKind(); diff --git a/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp @@ -0,0 +1,30 @@ +// RUN: %clang -cc1 -debug-info-kind=constructor -emit-llvm %s -o - | FileCheck %s + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} +struct A {}; +void TestA() { A a; } + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B" +// CHECK-SAME: flags: DIFlagFwdDecl +struct B { + B(); +}; +void TestB() { B b; } + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "C" +// CHECK-NOT: flags: DIFlagFwdDecl +// CHECK-SAME: ){{$}} +struct C { + C() {} +}; +void TestC() { C c; } + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "D" +// CHECK-NOT: flags: DIFlagFwdDecl +// CHECK-SAME: ){{$}} +struct D { + D(); +}; +D::D() {}