diff options
author | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2020-05-15 10:36:27 -0400 |
---|---|---|
committer | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2020-05-15 10:37:09 -0400 |
commit | 76c5f277f25e334404aa44ea0aafd674a627ab74 (patch) | |
tree | dfd884583fd401b988335a106fbb0c732f3ab13d /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
parent | 436c5750cf36697afb17468908cbb7303b229e1f (diff) | |
download | llvm-76c5f277f25e334404aa44ea0aafd674a627ab74.zip llvm-76c5f277f25e334404aa44ea0aafd674a627ab74.tar.gz llvm-76c5f277f25e334404aa44ea0aafd674a627ab74.tar.bz2 |
Re-land [Debug][CodeView] Emit fully qualified names for globals
Before this patch, S_[L|G][THREAD32|DATA32] records were emitted with a simple name, not the fully qualified name (namespace + class scope).
Differential Revision: https://reviews.llvm.org/D79447
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index f167cea..6f75dbd 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -343,18 +343,6 @@ static std::string formatNestedName(ArrayRef<StringRef> QualifiedNameComponents, return FullyQualifiedName; } -std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Scope, - StringRef Name) { - SmallVector<StringRef, 5> QualifiedNameComponents; - 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 { TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; } ~TypeLoweringScope() { @@ -367,6 +355,22 @@ struct CodeViewDebug::TypeLoweringScope { CodeViewDebug &CVD; }; +std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Scope, + StringRef Name) { + // Ensure types in the scope chain are emitted as soon as possible. + // This can create otherwise a situation where S_UDTs are emitted while + // looping in emitDebugInfoForUDTs. + TypeLoweringScope S(*this); + SmallVector<StringRef, 5> QualifiedNameComponents; + collectParentScopeNames(Scope, QualifiedNameComponents); + return formatNestedName(QualifiedNameComponents, Name); +} + +std::string CodeViewDebug::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)) @@ -2981,10 +2985,16 @@ void CodeViewDebug::emitEndSymbolRecord(SymbolKind EndKind) { } void CodeViewDebug::emitDebugInfoForUDTs( - ArrayRef<std::pair<std::string, const DIType *>> UDTs) { + const std::vector<std::pair<std::string, const DIType *>> &UDTs) { +#ifndef NDEBUG + size_t OriginalSize = UDTs.size(); +#endif for (const auto &UDT : UDTs) { const DIType *T = UDT.second; assert(shouldEmitUdt(T)); + // Ensure no new types are discovered when executing the code below. + // See discussion in https://reviews.llvm.org/D79512 + assert(OriginalSize == UDTs.size()); MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT); OS.AddComment("Type"); @@ -3092,6 +3102,14 @@ void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) { void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) { const DIGlobalVariable *DIGV = CVGV.DIGV; + + const DIScope *Scope = DIGV->getScope(); + // For static data members, get the scope from the declaration. + if (const auto *MemberDecl = dyn_cast_or_null<DIDerivedType>( + DIGV->getRawStaticDataMemberDeclaration())) + Scope = MemberDecl->getScope(); + std::string QualifiedName = getFullyQualifiedName(Scope, DIGV->getName()); + if (const GlobalVariable *GV = CVGV.GVInfo.dyn_cast<const GlobalVariable *>()) { // DataSym record, see SymbolRecord.h for more info. Thread local data @@ -3111,13 +3129,9 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) { OS.EmitCOFFSectionIndex(GVSym); OS.AddComment("Name"); const unsigned LengthOfDataRecord = 12; - emitNullTerminatedSymbolName( - OS, getFullyQualifiedName(DIGV->getScope(), DIGV->getName()), - LengthOfDataRecord); + emitNullTerminatedSymbolName(OS, QualifiedName, LengthOfDataRecord); endSymbolRecord(DataEnd); } else { - // FIXME: Currently this only emits the global variables in the IR metadata. - // This should also emit enums and static data members. const DIExpression *DIE = CVGV.GVInfo.get<const DIExpression *>(); assert(DIE->isConstant() && "Global constant variables must contain a constant expression."); @@ -3137,13 +3151,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) { OS.emitBinaryData(SRef); OS.AddComment("Name"); - const DIScope *Scope = DIGV->getScope(); - // For static data members, get the scope from the declaration. - if (const auto *MemberDecl = dyn_cast_or_null<DIDerivedType>( - DIGV->getRawStaticDataMemberDeclaration())) - Scope = MemberDecl->getScope(); - emitNullTerminatedSymbolName(OS, - getFullyQualifiedName(Scope, DIGV->getName())); + emitNullTerminatedSymbolName(OS, QualifiedName); endSymbolRecord(SConstantEnd); } } |