diff options
author | Reid Kleckner <rnk@google.com> | 2019-11-06 15:04:52 -0800 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2019-11-07 13:58:01 -0800 |
commit | d91ed80e97ac9bfcfb02440874ed8b9a51c9491e (patch) | |
tree | 1bde59eb5403487367706c59f443b866e5ed301f /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
parent | 01b10bc7b14963902405d202ac78cd88d44adbc5 (diff) | |
download | bcm5719-llvm-d91ed80e97ac9bfcfb02440874ed8b9a51c9491e.tar.gz bcm5719-llvm-d91ed80e97ac9bfcfb02440874ed8b9a51c9491e.zip |
[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
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 36 |
1 files changed, 22 insertions, 14 deletions
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<StringRef> &QualifiedNameComponents) { const DISubprogram *ClosestSubprogram = nullptr; while (Scope != nullptr) { if (ClosestSubprogram == nullptr) ClosestSubprogram = dyn_cast<DISubprogram>(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<DIType>(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<StringRef> QualifiedNameComponents, - StringRef TypeName) { +std::string +CodeViewDebug::formatNestedName(ArrayRef<StringRef> QualifiedNameComponents, + StringRef TypeName) { std::string FullyQualifiedName; for (StringRef QualifiedNameComponent : llvm::reverse(QualifiedNameComponents)) { @@ -329,10 +337,15 @@ static std::string getQualifiedName(ArrayRef<StringRef> QualifiedNameComponents, return FullyQualifiedName; } -static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name) { +std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Scope, StringRef Name) { SmallVector<StringRef, 5> 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<DIFile>(Scope)) @@ -1468,12 +1476,12 @@ void CodeViewDebug::addToUDTs(const DIType *Ty) { if (!shouldEmitUdt(Ty)) return; - SmallVector<StringRef, 5> QualifiedNameComponents; + SmallVector<StringRef, 5> 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); |