From d91ed80e97ac9bfcfb02440874ed8b9a51c9491e Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 6 Nov 2019 15:04:52 -0800 Subject: [codeview] Reference types in type parent scopes Without this change, when a nested tag type of any kind (enum, class, struct, union) is used as a variable type, it is emitted without emitting the parent type. In CodeView, parent types point to their inner types, and inner types do not point back to their parents. We already walk over all of the parent scopes to build the fully qualified name. This change simply requests their type indices as we go along to enusre they are all emitted. Fixes PR43905 Reviewers: akhuang, amccarth Differential Revision: https://reviews.llvm.org/D69924 --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 36 ++++++++++++++++----------- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h | 13 ++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) (limited to 'llvm/lib/CodeGen/AsmPrinter') diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 62ad356e7f8..3829dd4eff1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -303,12 +303,19 @@ static StringRef getPrettyScopeName(const DIScope *Scope) { return StringRef(); } -static const DISubprogram *getQualifiedNameComponents( +const DISubprogram *CodeViewDebug::collectParentScopeNames( const DIScope *Scope, SmallVectorImpl &QualifiedNameComponents) { const DISubprogram *ClosestSubprogram = nullptr; while (Scope != nullptr) { if (ClosestSubprogram == nullptr) ClosestSubprogram = dyn_cast(Scope); + + // If a type appears in a scope chain, make sure it gets emitted. The + // frontend will be responsible for deciding if this should be a forward + // declaration or a complete type. + if (const auto *Ty = dyn_cast(Scope)) + (void)getTypeIndex(Ty); + StringRef ScopeName = getPrettyScopeName(Scope); if (!ScopeName.empty()) QualifiedNameComponents.push_back(ScopeName); @@ -317,8 +324,9 @@ static const DISubprogram *getQualifiedNameComponents( return ClosestSubprogram; } -static std::string getQualifiedName(ArrayRef QualifiedNameComponents, - StringRef TypeName) { +std::string +CodeViewDebug::formatNestedName(ArrayRef QualifiedNameComponents, + StringRef TypeName) { std::string FullyQualifiedName; for (StringRef QualifiedNameComponent : llvm::reverse(QualifiedNameComponents)) { @@ -329,10 +337,15 @@ static std::string getQualifiedName(ArrayRef QualifiedNameComponents, return FullyQualifiedName; } -static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name) { +std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Scope, StringRef Name) { SmallVector QualifiedNameComponents; - getQualifiedNameComponents(Scope, QualifiedNameComponents); - return getQualifiedName(QualifiedNameComponents, Name); + collectParentScopeNames(Scope, QualifiedNameComponents); + return formatNestedName(QualifiedNameComponents, Name); +} + +std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Ty) { + const DIScope *Scope = Ty->getScope(); + return getFullyQualifiedName(Scope, getPrettyScopeName(Ty)); } struct CodeViewDebug::TypeLoweringScope { @@ -347,11 +360,6 @@ struct CodeViewDebug::TypeLoweringScope { CodeViewDebug &CVD; }; -static std::string getFullyQualifiedName(const DIScope *Ty) { - const DIScope *Scope = Ty->getScope(); - return getFullyQualifiedName(Scope, getPrettyScopeName(Ty)); -} - TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) { // No scope means global scope and that uses the zero index. if (!Scope || isa(Scope)) @@ -1468,12 +1476,12 @@ void CodeViewDebug::addToUDTs(const DIType *Ty) { if (!shouldEmitUdt(Ty)) return; - SmallVector QualifiedNameComponents; + SmallVector ParentScopeNames; const DISubprogram *ClosestSubprogram = - getQualifiedNameComponents(Ty->getScope(), QualifiedNameComponents); + collectParentScopeNames(Ty->getScope(), ParentScopeNames); std::string FullyQualifiedName = - getQualifiedName(QualifiedNameComponents, getPrettyScopeName(Ty)); + formatNestedName(ParentScopeNames, getPrettyScopeName(Ty)); if (ClosestSubprogram == nullptr) { GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty); diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index b56b9047e1a..e32d6267430 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -443,6 +443,19 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { codeview::TypeIndex TI, const DIType *ClassTy = nullptr); + /// Collect the names of parent scopes, innermost to outermost. Return the + /// innermost subprogram scope if present. Ensure that parent type scopes are + /// inserted into the type table. + const DISubprogram * + collectParentScopeNames(const DIScope *Scope, + SmallVectorImpl &ParentScopeNames); + + std::string formatNestedName(ArrayRef ParentScopeNames, + StringRef TypeName); + + std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name); + std::string getFullyQualifiedName(const DIScope *Scope); + unsigned getPointerSizeInBytes(); protected: -- cgit v1.2.3