From 08ef0202ce1b2324cccafba3d640cc8a9b859dd0 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Fri, 18 Apr 2014 21:36:39 +0000 Subject: [DWARF parser] Turn DILineInfo into a struct. Immutable DILineInfo doesn't bring any benefits and complicates code. Also, use std::string instead of SmallString<16> for file and function names - their length can vary significantly. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206654 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DIContext.h | 27 +++------ lib/DebugInfo/DWARFContext.cpp | 100 +++++++++++++++----------------- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 6 +- tools/llvm-objdump/MachODump.cpp | 6 +- tools/llvm-rtdyld/llvm-rtdyld.cpp | 3 +- tools/llvm-symbolizer/LLVMSymbolize.cpp | 18 ++---- 6 files changed, 65 insertions(+), 95 deletions(-) diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 69a4f8d1f6..e99c029af3 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -16,42 +16,31 @@ #define LLVM_DEBUGINFO_DICONTEXT_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/RelocVisitor.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" +#include + namespace llvm { class raw_ostream; /// DILineInfo - a format-neutral container for source line information. -class DILineInfo { - SmallString<16> FileName; - SmallString<16> FunctionName; +struct DILineInfo { + std::string FileName; + std::string FunctionName; uint32_t Line; uint32_t Column; -public: + DILineInfo() - : FileName(""), FunctionName(""), - Line(0), Column(0) {} - DILineInfo(StringRef fileName, StringRef functionName, uint32_t line, - uint32_t column) - : FileName(fileName), FunctionName(functionName), Line(line), - Column(column) {} - - const char *getFileName() { return FileName.c_str(); } - const char *getFunctionName() { return FunctionName.c_str(); } - uint32_t getLine() const { return Line; } - uint32_t getColumn() const { return Column; } + : FileName(""), FunctionName(""), Line(0), Column(0) {} bool operator==(const DILineInfo &RHS) const { return Line == RHS.Line && Column == RHS.Column && - FileName.equals(RHS.FileName) && - FunctionName.equals(RHS.FunctionName); + FileName == RHS.FileName && FunctionName == RHS.FunctionName; } bool operator!=(const DILineInfo &RHS) const { return !(*this == RHS); diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 5b65d0ae1a..50ec4d3cb4 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -443,8 +443,7 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, const DWARFLineTable *LineTable, uint64_t Address, bool NeedsAbsoluteFilePath, - std::string &FileName, - uint32_t &Line, uint32_t &Column) { + DILineInfo &Result) { if (!CU || !LineTable) return false; // Get the index of row we're looking for in the line table. @@ -453,45 +452,49 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, return false; // Take file number and line/column from the row. const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; - if (!getFileNameForCompileUnit(CU, LineTable, Row.File, - NeedsAbsoluteFilePath, FileName)) + if (!getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath, + Result.FileName)) return false; - Line = Row.Line; - Column = Row.Column; + Result.Line = Row.Line; + Result.Column = Row.Column; return true; } +static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, + std::string &FunctionName) { + // The address may correspond to instruction in some inlined function, + // so we have to build the chain of inlined functions and take the + // name of the topmost function in it. + const DWARFDebugInfoEntryInlinedChain &InlinedChain = + CU->getInlinedChainForAddress(Address); + if (InlinedChain.DIEs.size() == 0) + return false; + const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; + if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) { + FunctionName = Name; + return true; + } + return false; +} + DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier) { + DILineInfo Result; + DWARFCompileUnit *CU = getCompileUnitForAddress(Address); if (!CU) - return DILineInfo(); - std::string FileName = ""; - std::string FunctionName = ""; - uint32_t Line = 0; - uint32_t Column = 0; + return Result; if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - // The address may correspond to instruction in some inlined function, - // so we have to build the chain of inlined functions and take the - // name of the topmost function in it. - const DWARFDebugInfoEntryInlinedChain &InlinedChain = - CU->getInlinedChainForAddress(Address); - if (InlinedChain.DIEs.size() > 0) { - const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) - FunctionName = Name; - } + getFunctionNameForAddress(CU, Address, Result.FunctionName); } if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); const bool NeedsAbsoluteFilePath = Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); - getFileLineInfoForCompileUnit(CU, LineTable, Address, - NeedsAbsoluteFilePath, - FileName, Line, Column); + getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath, + Result); } - return DILineInfo(StringRef(FileName), StringRef(FunctionName), - Line, Column); + return Result; } DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, @@ -504,23 +507,15 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, std::string FunctionName = ""; if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - // The address may correspond to instruction in some inlined function, - // so we have to build the chain of inlined functions and take the - // name of the topmost function in it. - const DWARFDebugInfoEntryInlinedChain &InlinedChain = - CU->getInlinedChainForAddress(Address); - if (InlinedChain.DIEs.size() > 0) { - const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) - FunctionName = Name; - } + getFunctionNameForAddress(CU, Address, FunctionName); } // If the Specifier says we don't need FileLineInfo, just // return the top-most function at the starting address. if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { - Lines.push_back( - std::make_pair(Address, DILineInfo("", FunctionName, 0, 0))); + DILineInfo Result; + Result.FunctionName = FunctionName; + Lines.push_back(std::make_pair(Address, Result)); return Lines; } @@ -536,11 +531,13 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, for (uint32_t RowIndex : RowVector) { // Take file number and line/column from the row. const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; - std::string FileName = ""; - getFileNameForCompileUnit(CU, LineTable, Row.File, - NeedsAbsoluteFilePath, FileName); - Lines.push_back(std::make_pair( - Row.Address, DILineInfo(FileName, FunctionName, Row.Line, Row.Column))); + DILineInfo Result; + getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath, + Result.FileName); + Result.FunctionName = FunctionName; + Result.Line = Row.Line; + Result.Column = Row.Column; + Lines.push_back(std::make_pair(Row.Address, Result)); } return Lines; @@ -562,14 +559,11 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, const DWARFLineTable *LineTable = nullptr; for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) { const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i]; - std::string FileName = ""; - std::string FunctionName = ""; - uint32_t Line = 0; - uint32_t Column = 0; + DILineInfo Frame; // Get function name if necessary. if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U)) - FunctionName = Name; + Frame.FunctionName = Name; } if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { const bool NeedsAbsoluteFilePath = @@ -581,14 +575,14 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, // For the topmost routine, get file/line info from line table. getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath, - FileName, Line, Column); + Frame); } else { // Otherwise, use call file, call line and call column from // previous DIE in inlined chain. getFileNameForCompileUnit(CU, LineTable, CallFile, - NeedsAbsoluteFilePath, FileName); - Line = CallLine; - Column = CallColumn; + NeedsAbsoluteFilePath, Frame.FileName); + Frame.Line = CallLine; + Frame.Column = CallColumn; } // Get call file/line/column of a current DIE. if (i + 1 < n) { @@ -596,8 +590,6 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, CallColumn); } } - DILineInfo Frame(StringRef(FileName), StringRef(FunctionName), - Line, Column); InliningInfo.addFrame(Frame); } return InliningInfo; diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index f4a9ae8bef..e41ae25168 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -80,10 +80,8 @@ DumpType("debug-dump", cl::init(DIDT_All), static void PrintDILineInfo(DILineInfo dli) { if (PrintFunctions) - outs() << (dli.getFunctionName() ? dli.getFunctionName() : "") - << "\n"; - outs() << (dli.getFileName() ? dli.getFileName() : "") << ':' - << dli.getLine() << ':' << dli.getColumn() << '\n'; + outs() << dli.FunctionName << "\n"; + outs() << dli.FileName << ':' << dli.Line << ':' << dli.Column << '\n'; } static void DumpInput(const StringRef &Filename) { diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index b6b851f6d4..376948e382 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -421,9 +421,9 @@ static void DisassembleInputMachO2(StringRef Filename, DILineInfo dli = diContext->getLineInfoForAddress(SectAddress + Index); // Print valid line info if it changed. - if (dli != lastLine && dli.getLine() != 0) - outs() << "\t## " << dli.getFileName() << ':' - << dli.getLine() << ':' << dli.getColumn(); + if (dli != lastLine && dli.Line != 0) + outs() << "\t## " << dli.FileName << ':' << dli.Line << ':' + << dli.Column; lastLine = dli; } outs() << "\n"; diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index ac43653d58..5e3c488c7b 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -172,8 +172,7 @@ static int printLineInfoForInput() { DILineInfoTable::iterator End = Lines.end(); for (DILineInfoTable::iterator It = Begin; It != End; ++It) { outs() << " Line info @ " << It->first - Addr << ": " - << It->second.getFileName() - << ", line:" << It->second.getLine() << "\n"; + << It->second.FileName << ", line:" << It->second.Line << "\n"; } } } diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 13f2f8fc58..7ffb1a13c5 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -44,13 +44,6 @@ getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) { return Flags; } -static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName, - DILineInfo &LineInfo) { - std::string FileName = LineInfo.getFileName(); - LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName), - LineInfo.getLine(), LineInfo.getColumn()); -} - ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) : Module(Obj), DebugInfoContext(DICtx) { for (const SymbolRef &Symbol : Module->symbols()) { @@ -130,7 +123,7 @@ DILineInfo ModuleInfo::symbolizeCode( uint64_t Start, Size; if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, FunctionName, Start, Size)) { - patchFunctionNameInDILineInfo(FunctionName, LineInfo); + LineInfo.FunctionName = FunctionName; } } return LineInfo; @@ -157,7 +150,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode( uint64_t Start, Size; if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, FunctionName, Start, Size)) { - patchFunctionNameInDILineInfo(FunctionName, LineInfo); + LineInfo.FunctionName = FunctionName; } } PatchedInlinedContext.addFrame(LineInfo); @@ -408,18 +401,17 @@ std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const { static const std::string kDILineInfoBadString = ""; std::stringstream Result; if (Opts.PrintFunctions) { - std::string FunctionName = LineInfo.getFunctionName(); + std::string FunctionName = LineInfo.FunctionName; if (FunctionName == kDILineInfoBadString) FunctionName = kBadString; else if (Opts.Demangle) FunctionName = DemangleName(FunctionName); Result << FunctionName << "\n"; } - std::string Filename = LineInfo.getFileName(); + std::string Filename = LineInfo.FileName; if (Filename == kDILineInfoBadString) Filename = kBadString; - Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn() - << "\n"; + Result << Filename << ":" << LineInfo.Line << ":" << LineInfo.Column << "\n"; return Result.str(); } -- cgit v1.2.3