diff options
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 50 | ||||
-rw-r--r-- | clang/test/Modules/ExtDebugInfo.cpp | 9 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/DebugCXX.h | 6 | ||||
-rw-r--r-- | clang/test/Modules/ModuleDebugInfo.cpp | 11 |
4 files changed, 47 insertions, 29 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c9c450c32e3..b78ba0d201e 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1766,6 +1766,29 @@ static bool isClassOrMethodDLLImport(const CXXRecordDecl *RD) { return false; } +/// Does a type definition exist in an imported clang module? +static bool isDefinedInClangModule(const RecordDecl *RD) { + // Only definitions that where imported from an AST file come from a module. + if (!RD || !RD->isFromASTFile()) + return false; + // Anonymous entities cannot be addressed. Treat them as not from module. + if (!RD->isExternallyVisible() && RD->getName().empty()) + return false; + if (auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) { + if (!CXXDecl->isCompleteDefinition()) + return false; + auto TemplateKind = CXXDecl->getTemplateSpecializationKind(); + if (TemplateKind != TSK_Undeclared) { + // This is a template, check the origin of the first member. + if (CXXDecl->field_begin() == CXXDecl->field_end()) + return TemplateKind == TSK_ExplicitInstantiationDeclaration; + if (!CXXDecl->field_begin()->isFromASTFile()) + return false; + } + } + return true; +} + void CGDebugInfo::completeClassData(const RecordDecl *RD) { if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) if (CXXRD->isDynamicClass() && @@ -1773,6 +1796,10 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) { llvm::GlobalValue::AvailableExternallyLinkage && !isClassOrMethodDLLImport(CXXRD)) return; + + if (DebugTypeExtRefs && isDefinedInClangModule(RD->getDefinition())) + return; + completeClass(RD); } @@ -1799,29 +1826,6 @@ static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, return false; } -/// Does a type definition exist in an imported clang module? -static bool isDefinedInClangModule(const RecordDecl *RD) { - // Only definitions that where imported from an AST file come from a module. - if (!RD || !RD->isFromASTFile()) - return false; - // Anonymous entities cannot be addressed. Treat them as not from module. - if (!RD->isExternallyVisible() && RD->getName().empty()) - return false; - if (auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) { - if (!CXXDecl->isCompleteDefinition()) - return false; - auto TemplateKind = CXXDecl->getTemplateSpecializationKind(); - if (TemplateKind != TSK_Undeclared) { - // This is a template, check the origin of the first member. - if (CXXDecl->field_begin() == CXXDecl->field_end()) - return TemplateKind == TSK_ExplicitInstantiationDeclaration; - if (!CXXDecl->field_begin()->isFromASTFile()) - return false; - } - } - return true; -} - static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind, bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts) { diff --git a/clang/test/Modules/ExtDebugInfo.cpp b/clang/test/Modules/ExtDebugInfo.cpp index ed9d1e859d8..97386bc4d00 100644 --- a/clang/test/Modules/ExtDebugInfo.cpp +++ b/clang/test/Modules/ExtDebugInfo.cpp @@ -69,6 +69,8 @@ WithSpecializedBase<int> definedLocally4; void foo() { anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum; + A a; + Virtual virt; } // CHECK: ![[CPP:.*]] = !DIFile(filename: {{.*}}ExtDebugInfo.cpp" @@ -210,3 +212,10 @@ void foo() { // CHECK-SAME: dwoId: // CHECK-PCH: !DICompileUnit({{.*}}splitDebugFilename: // CHECK-PCH: dwoId: 18446744073709551614 + +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A", +// CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS1A") + +// There is a full definition of the type available in the module. +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", +// CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS7Virtual") diff --git a/clang/test/Modules/Inputs/DebugCXX.h b/clang/test/Modules/Inputs/DebugCXX.h index c9cd68f30c4..1ccf8d302f1 100644 --- a/clang/test/Modules/Inputs/DebugCXX.h +++ b/clang/test/Modules/Inputs/DebugCXX.h @@ -54,9 +54,9 @@ namespace DebugCXX { } // Virtual class with a forward declaration. -class FwdVirtual; -class FwdVirtual { - virtual ~FwdVirtual() {} +struct Virtual; +struct Virtual { + virtual ~Virtual() {} }; struct PureForwardDecl; diff --git a/clang/test/Modules/ModuleDebugInfo.cpp b/clang/test/Modules/ModuleDebugInfo.cpp index 71b05e5aeb8..008b3e4f2ba 100644 --- a/clang/test/Modules/ModuleDebugInfo.cpp +++ b/clang/test/Modules/ModuleDebugInfo.cpp @@ -86,10 +86,10 @@ // CHECK-SAME: flags: DIFlagFwdDecl // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE") -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdVirtual" +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual" // CHECK-SAME: elements: -// CHECK-SAME: identifier: "_ZTS10FwdVirtual") -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$FwdVirtual" +// CHECK-SAME: identifier: "_ZTS7Virtual") +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Virtual" // CHECK: !DICompositeType(tag: DW_TAG_union_type, // CHECK-NOT: name: @@ -111,6 +111,11 @@ // CHECK-SAME: name: "InAnonymousNamespace", // CHECK-SAME: elements: !{{[0-9]+}}) +// CHECK: ![[A:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "A", +// CHECK-SAME: elements: +// CHECK-SAME: vtableHolder: ![[A]], +// CHECK-SAME: identifier: "_ZTS1A") + // CHECK: ![[DERIVED:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "Derived", // CHECK-SAME: identifier: "_ZTS7Derived") // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B", scope: ![[DERIVED]], |