diff options
author | Adrian Prantl <aprantl@apple.com> | 2017-07-24 23:48:51 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2017-07-24 23:48:51 +0000 |
commit | 05401222b8a75806c855ac4872701058db42a6dd (patch) | |
tree | 0d93746b0f649f47a1e3d000a37542bb9253d2c5 /lib/CodeGen/CGDebugInfo.cpp | |
parent | 0ea90f4421eaefb84b520b768386b41250b6e4a3 (diff) |
Debug Info: Avoid completing class types when a definition is in a module.
This patch adds an early exit to CGDebugInfo::completeClassData() when
compiling with -gmodules and the to-be-completed type is available in
a clang module.
rdar://problem/23599990
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@308938 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index c9c450c32e..b78ba0d201 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/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) { |