diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-06-15 18:00:01 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-06-15 18:00:01 +0000 |
commit | 3128b10cdc5c83e79aad7fa3600445c494170498 (patch) | |
tree | f446ca9d3eb49f8ddefcb3dac5e77b0aafebafa1 /llvm/lib | |
parent | cc70da39ffec467a1fbc85070eec81ef68bdb303 (diff) | |
download | bcm5719-llvm-3128b10cdc5c83e79aad7fa3600445c494170498.tar.gz bcm5719-llvm-3128b10cdc5c83e79aad7fa3600445c494170498.zip |
[CodeView] Add support for emitting S_UDT for typedefs
Emit a S_UDT record for typedefs. We still need to do something for
class types.
Differential Revision: http://reviews.llvm.org/D21149
llvm-svn: 272813
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 87 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h | 17 |
2 files changed, 100 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 3b7815f3e0b..ff719b242c4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -253,12 +253,20 @@ void CodeViewDebug::endModule() { emitDebugInfoForFunction(P.first, P.second); // Emit global variable debug information. + setCurrentSubprogram(nullptr); emitDebugInfoForGlobals(); // Switch back to the generic .debug$S section after potentially processing // comdat symbol sections. switchToDebugSectionForSymbol(nullptr); + // Emit UDT records for any types used by global variables. + if (!GlobalUDTs.empty()) { + MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols); + emitDebugInfoForUDTs(GlobalUDTs); + endCVSubsection(SymbolsEnd); + } + // This subsection holds a file index to offset in string table table. OS.AddComment("File index to string table offset subsection"); OS.EmitCVFileChecksumsDirective(); @@ -457,7 +465,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, switchToDebugSectionForSymbol(Fn); StringRef FuncName; - if (auto *SP = GV->getSubprogram()) + auto *SP = GV->getSubprogram(); + setCurrentSubprogram(SP); + if (SP != nullptr) FuncName = SP->getDisplayName(); // If our DISubprogram name is empty, use the mangled name. @@ -519,6 +529,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, emitInlinedCallSite(FI, InlinedAt, I->second); } + if (SP != nullptr) + emitDebugInfoForUDTs(LocalUDTs); + // We're done with this function. OS.AddComment("Record length"); OS.EmitIntValue(0x0002, 2); @@ -755,15 +768,61 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty) { } } +static const DISubprogram *getQualifiedNameComponents( + const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) { + const DISubprogram *ClosestSubprogram = nullptr; + while (Scope != nullptr) { + if (ClosestSubprogram == nullptr) + ClosestSubprogram = dyn_cast<DISubprogram>(Scope); + StringRef ScopeName = Scope->getName(); + if (!ScopeName.empty()) + QualifiedNameComponents.push_back(ScopeName); + Scope = Scope->getScope().resolve(); + } + return ClosestSubprogram; +} + +static std::string getQualifiedName(ArrayRef<StringRef> QualifiedNameComponents, + StringRef TypeName) { + std::string FullyQualifiedName; + for (StringRef QualifiedNameComponent : reverse(QualifiedNameComponents)) { + FullyQualifiedName.append(QualifiedNameComponent); + FullyQualifiedName.append("::"); + } + FullyQualifiedName.append(TypeName); + return FullyQualifiedName; +} + TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) { - // TODO: MSVC emits a S_UDT record. DITypeRef UnderlyingTypeRef = Ty->getBaseType(); TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef); + StringRef TypeName = Ty->getName(); + + SmallVector<StringRef, 5> QualifiedNameComponents; + const DISubprogram *ClosestSubprogram = getQualifiedNameComponents( + Ty->getScope().resolve(), QualifiedNameComponents); + + if (ClosestSubprogram == nullptr) { + std::string FullyQualifiedName = + getQualifiedName(QualifiedNameComponents, TypeName); + GlobalUDTs.emplace_back(std::move(FullyQualifiedName), UnderlyingTypeIndex); + } else if (ClosestSubprogram == CurrentSubprogram) { + std::string FullyQualifiedName = + getQualifiedName(QualifiedNameComponents, TypeName); + LocalUDTs.emplace_back(std::move(FullyQualifiedName), UnderlyingTypeIndex); + } + // TODO: What if the ClosestSubprogram is neither null or the current + // subprogram? Currently, the UDT just gets dropped on the floor. + // + // The current behavior is not desirable. To get maximal fidelity, we would + // need to perform all type translation before beginning emission of .debug$S + // and then make LocalUDTs a member of FunctionInfo + if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) && - Ty->getName() == "HRESULT") + TypeName == "HRESULT") return TypeIndex(SimpleTypeKind::HResult); if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::UInt16Short) && - Ty->getName() == "wchar_t") + TypeName == "wchar_t") return TypeIndex(SimpleTypeKind::WideCharacter); return UnderlyingTypeIndex; } @@ -1307,6 +1366,26 @@ void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) { OS.EmitValueToAlignment(4); } +void CodeViewDebug::emitDebugInfoForUDTs( + ArrayRef<std::pair<std::string, TypeIndex>> UDTs) { + for (const std::pair<std::string, codeview::TypeIndex> &UDT : UDTs) { + MCSymbol *UDTRecordBegin = MMI->getContext().createTempSymbol(), + *UDTRecordEnd = MMI->getContext().createTempSymbol(); + OS.AddComment("Record length"); + OS.emitAbsoluteSymbolDiff(UDTRecordEnd, UDTRecordBegin, 2); + OS.EmitLabel(UDTRecordBegin); + + OS.AddComment("Record kind: S_UDT"); + OS.EmitIntValue(unsigned(SymbolKind::S_UDT), 2); + + OS.AddComment("Type"); + OS.EmitIntValue(UDT.second.getIndex(), 4); + + emitNullTerminatedSymbolName(OS, UDT.first); + OS.EmitLabel(UDTRecordEnd); + } +} + void CodeViewDebug::emitDebugInfoForGlobals() { NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); for (const MDNode *Node : CUs->operands()) { diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index ea88ff0aee6..4e90c770742 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -144,6 +144,13 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { /// always looked up in the normal TypeIndices map. DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices; + const DISubprogram *CurrentSubprogram = nullptr; + + // The UDTs we have seen while processing types; each entry is a pair of type + // index and type name. + std::vector<std::pair<std::string, codeview::TypeIndex>> LocalUDTs, + GlobalUDTs; + typedef std::map<const DIFile *, std::string> FileToFilepathMapTy; FileToFilepathMapTy FileToFilepathMap; StringRef getFullFilepath(const DIFile *S); @@ -157,6 +164,13 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { FileIdMap.clear(); FnDebugInfo.clear(); FileToFilepathMap.clear(); + LocalUDTs.clear(); + GlobalUDTs.clear(); + } + + void setCurrentSubprogram(const DISubprogram *SP) { + CurrentSubprogram = SP; + LocalUDTs.clear(); } /// Emit the magic version number at the start of a CodeView type or symbol @@ -171,6 +185,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { void emitDebugInfoForGlobals(); + void emitDebugInfoForUDTs( + ArrayRef<std::pair<std::string, codeview::TypeIndex>> UDTs); + void emitDebugInfoForGlobal(const DIGlobalVariable *DIGV, MCSymbol *GVSym); /// Opens a subsection of the given kind in a .debug$S codeview section. |