1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[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.

llvm-svn: 206654
This commit is contained in:
Alexey Samsonov 2014-04-18 21:36:39 +00:00
parent 3465898e26
commit 5a3863a395
6 changed files with 65 additions and 95 deletions

View File

@ -16,42 +16,31 @@
#define LLVM_DEBUGINFO_DICONTEXT_H #define LLVM_DEBUGINFO_DICONTEXT_H
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ObjectFile.h" #include "llvm/Object/ObjectFile.h"
#include "llvm/Object/RelocVisitor.h" #include "llvm/Object/RelocVisitor.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm { namespace llvm {
class raw_ostream; class raw_ostream;
/// DILineInfo - a format-neutral container for source line information. /// DILineInfo - a format-neutral container for source line information.
class DILineInfo { struct DILineInfo {
SmallString<16> FileName; std::string FileName;
SmallString<16> FunctionName; std::string FunctionName;
uint32_t Line; uint32_t Line;
uint32_t Column; uint32_t Column;
public:
DILineInfo()
: FileName("<invalid>"), FunctionName("<invalid>"),
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(); } DILineInfo()
const char *getFunctionName() { return FunctionName.c_str(); } : FileName("<invalid>"), FunctionName("<invalid>"), Line(0), Column(0) {}
uint32_t getLine() const { return Line; }
uint32_t getColumn() const { return Column; }
bool operator==(const DILineInfo &RHS) const { bool operator==(const DILineInfo &RHS) const {
return Line == RHS.Line && Column == RHS.Column && return Line == RHS.Line && Column == RHS.Column &&
FileName.equals(RHS.FileName) && FileName == RHS.FileName && FunctionName == RHS.FunctionName;
FunctionName.equals(RHS.FunctionName);
} }
bool operator!=(const DILineInfo &RHS) const { bool operator!=(const DILineInfo &RHS) const {
return !(*this == RHS); return !(*this == RHS);

View File

@ -443,8 +443,7 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
const DWARFLineTable *LineTable, const DWARFLineTable *LineTable,
uint64_t Address, uint64_t Address,
bool NeedsAbsoluteFilePath, bool NeedsAbsoluteFilePath,
std::string &FileName, DILineInfo &Result) {
uint32_t &Line, uint32_t &Column) {
if (!CU || !LineTable) if (!CU || !LineTable)
return false; return false;
// Get the index of row we're looking for in the line table. // Get the index of row we're looking for in the line table.
@ -453,45 +452,49 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
return false; return false;
// Take file number and line/column from the row. // Take file number and line/column from the row.
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
if (!getFileNameForCompileUnit(CU, LineTable, Row.File, if (!getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
NeedsAbsoluteFilePath, FileName)) Result.FileName))
return false; return false;
Line = Row.Line; Result.Line = Row.Line;
Column = Row.Column; Result.Column = Row.Column;
return true; 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, DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier) { DILineInfoSpecifier Specifier) {
DILineInfo Result;
DWARFCompileUnit *CU = getCompileUnitForAddress(Address); DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
if (!CU) if (!CU)
return DILineInfo(); return Result;
std::string FileName = "<invalid>";
std::string FunctionName = "<invalid>";
uint32_t Line = 0;
uint32_t Column = 0;
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
// The address may correspond to instruction in some inlined function, getFunctionNameForAddress(CU, Address, Result.FunctionName);
// 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;
}
} }
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
const bool NeedsAbsoluteFilePath = const bool NeedsAbsoluteFilePath =
Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
getFileLineInfoForCompileUnit(CU, LineTable, Address, getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath,
NeedsAbsoluteFilePath, Result);
FileName, Line, Column);
} }
return DILineInfo(StringRef(FileName), StringRef(FunctionName), return Result;
Line, Column);
} }
DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
@ -504,23 +507,15 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
std::string FunctionName = "<invalid>"; std::string FunctionName = "<invalid>";
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
// The address may correspond to instruction in some inlined function, getFunctionNameForAddress(CU, Address, FunctionName);
// 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;
}
} }
// If the Specifier says we don't need FileLineInfo, just // If the Specifier says we don't need FileLineInfo, just
// return the top-most function at the starting address. // return the top-most function at the starting address.
if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
Lines.push_back( DILineInfo Result;
std::make_pair(Address, DILineInfo("<invalid>", FunctionName, 0, 0))); Result.FunctionName = FunctionName;
Lines.push_back(std::make_pair(Address, Result));
return Lines; return Lines;
} }
@ -536,11 +531,13 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
for (uint32_t RowIndex : RowVector) { for (uint32_t RowIndex : RowVector) {
// Take file number and line/column from the row. // Take file number and line/column from the row.
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
std::string FileName = "<invalid>"; DILineInfo Result;
getFileNameForCompileUnit(CU, LineTable, Row.File, getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
NeedsAbsoluteFilePath, FileName); Result.FileName);
Lines.push_back(std::make_pair( Result.FunctionName = FunctionName;
Row.Address, DILineInfo(FileName, FunctionName, Row.Line, Row.Column))); Result.Line = Row.Line;
Result.Column = Row.Column;
Lines.push_back(std::make_pair(Row.Address, Result));
} }
return Lines; return Lines;
@ -562,14 +559,11 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
const DWARFLineTable *LineTable = nullptr; const DWARFLineTable *LineTable = nullptr;
for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) { for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i]; const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
std::string FileName = "<invalid>"; DILineInfo Frame;
std::string FunctionName = "<invalid>";
uint32_t Line = 0;
uint32_t Column = 0;
// Get function name if necessary. // Get function name if necessary.
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U)) if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
FunctionName = Name; Frame.FunctionName = Name;
} }
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
const bool NeedsAbsoluteFilePath = const bool NeedsAbsoluteFilePath =
@ -581,14 +575,14 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
// For the topmost routine, get file/line info from line table. // For the topmost routine, get file/line info from line table.
getFileLineInfoForCompileUnit(CU, LineTable, Address, getFileLineInfoForCompileUnit(CU, LineTable, Address,
NeedsAbsoluteFilePath, NeedsAbsoluteFilePath,
FileName, Line, Column); Frame);
} else { } else {
// Otherwise, use call file, call line and call column from // Otherwise, use call file, call line and call column from
// previous DIE in inlined chain. // previous DIE in inlined chain.
getFileNameForCompileUnit(CU, LineTable, CallFile, getFileNameForCompileUnit(CU, LineTable, CallFile,
NeedsAbsoluteFilePath, FileName); NeedsAbsoluteFilePath, Frame.FileName);
Line = CallLine; Frame.Line = CallLine;
Column = CallColumn; Frame.Column = CallColumn;
} }
// Get call file/line/column of a current DIE. // Get call file/line/column of a current DIE.
if (i + 1 < n) { if (i + 1 < n) {
@ -596,8 +590,6 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
CallColumn); CallColumn);
} }
} }
DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
Line, Column);
InliningInfo.addFrame(Frame); InliningInfo.addFrame(Frame);
} }
return InliningInfo; return InliningInfo;

View File

@ -80,10 +80,8 @@ DumpType("debug-dump", cl::init(DIDT_All),
static void PrintDILineInfo(DILineInfo dli) { static void PrintDILineInfo(DILineInfo dli) {
if (PrintFunctions) if (PrintFunctions)
outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>") outs() << dli.FunctionName << "\n";
<< "\n"; outs() << dli.FileName << ':' << dli.Line << ':' << dli.Column << '\n';
outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
<< dli.getLine() << ':' << dli.getColumn() << '\n';
} }
static void DumpInput(const StringRef &Filename) { static void DumpInput(const StringRef &Filename) {

View File

@ -421,9 +421,9 @@ static void DisassembleInputMachO2(StringRef Filename,
DILineInfo dli = DILineInfo dli =
diContext->getLineInfoForAddress(SectAddress + Index); diContext->getLineInfoForAddress(SectAddress + Index);
// Print valid line info if it changed. // Print valid line info if it changed.
if (dli != lastLine && dli.getLine() != 0) if (dli != lastLine && dli.Line != 0)
outs() << "\t## " << dli.getFileName() << ':' outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
<< dli.getLine() << ':' << dli.getColumn(); << dli.Column;
lastLine = dli; lastLine = dli;
} }
outs() << "\n"; outs() << "\n";

View File

@ -172,8 +172,7 @@ static int printLineInfoForInput() {
DILineInfoTable::iterator End = Lines.end(); DILineInfoTable::iterator End = Lines.end();
for (DILineInfoTable::iterator It = Begin; It != End; ++It) { for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
outs() << " Line info @ " << It->first - Addr << ": " outs() << " Line info @ " << It->first - Addr << ": "
<< It->second.getFileName() << It->second.FileName << ", line:" << It->second.Line << "\n";
<< ", line:" << It->second.getLine() << "\n";
} }
} }
} }

View File

@ -44,13 +44,6 @@ getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) {
return Flags; 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) ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
: Module(Obj), DebugInfoContext(DICtx) { : Module(Obj), DebugInfoContext(DICtx) {
for (const SymbolRef &Symbol : Module->symbols()) { for (const SymbolRef &Symbol : Module->symbols()) {
@ -130,7 +123,7 @@ DILineInfo ModuleInfo::symbolizeCode(
uint64_t Start, Size; uint64_t Start, Size;
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
FunctionName, Start, Size)) { FunctionName, Start, Size)) {
patchFunctionNameInDILineInfo(FunctionName, LineInfo); LineInfo.FunctionName = FunctionName;
} }
} }
return LineInfo; return LineInfo;
@ -157,7 +150,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode(
uint64_t Start, Size; uint64_t Start, Size;
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
FunctionName, Start, Size)) { FunctionName, Start, Size)) {
patchFunctionNameInDILineInfo(FunctionName, LineInfo); LineInfo.FunctionName = FunctionName;
} }
} }
PatchedInlinedContext.addFrame(LineInfo); PatchedInlinedContext.addFrame(LineInfo);
@ -408,18 +401,17 @@ std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const {
static const std::string kDILineInfoBadString = "<invalid>"; static const std::string kDILineInfoBadString = "<invalid>";
std::stringstream Result; std::stringstream Result;
if (Opts.PrintFunctions) { if (Opts.PrintFunctions) {
std::string FunctionName = LineInfo.getFunctionName(); std::string FunctionName = LineInfo.FunctionName;
if (FunctionName == kDILineInfoBadString) if (FunctionName == kDILineInfoBadString)
FunctionName = kBadString; FunctionName = kBadString;
else if (Opts.Demangle) else if (Opts.Demangle)
FunctionName = DemangleName(FunctionName); FunctionName = DemangleName(FunctionName);
Result << FunctionName << "\n"; Result << FunctionName << "\n";
} }
std::string Filename = LineInfo.getFileName(); std::string Filename = LineInfo.FileName;
if (Filename == kDILineInfoBadString) if (Filename == kDILineInfoBadString)
Filename = kBadString; Filename = kBadString;
Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn() Result << Filename << ":" << LineInfo.Line << ":" << LineInfo.Column << "\n";
<< "\n";
return Result.str(); return Result.str();
} }