diff options
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 17 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/debug-info-limited-ctor.cpp | 30 |
2 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 3672490fafd..cbd524eda9d 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1648,6 +1648,12 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( 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<CXXConstructorDecl>(Method)) + completeClass(CD->getParent()); + llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit); llvm::DISubprogram *SP = DBuilder.createMethod( RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine, @@ -2211,6 +2217,17 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind, !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<ClassTemplateSpecializationDecl>(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 index 00000000000..321f1736391 --- /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() {} |