diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index e99c029af30..3f3e3792d54 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -68,19 +68,16 @@ class DIInliningInfo { /// DILineInfoSpecifier - controls which fields of DILineInfo container /// should be filled with data. -class DILineInfoSpecifier { - const uint32_t Flags; // Or'ed flags that set the info we want to fetch. -public: - enum Specification { - FileLineInfo = 1 << 0, - AbsoluteFilePath = 1 << 1, - FunctionName = 1 << 2 - }; - // Use file/line info by default. - DILineInfoSpecifier(uint32_t flags = FileLineInfo) : Flags(flags) {} - bool needs(Specification spec) const { - return (Flags & spec) > 0; - } +struct DILineInfoSpecifier { + enum class FileLineInfoKind { None, Default, AbsoluteFilePath }; + enum class FunctionNameKind { None, LinkageName }; + + FileLineInfoKind FLIKind; + FunctionNameKind FNKind; + + DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default, + FunctionNameKind FNKind = FunctionNameKind::None) + : FLIKind(FLIKind), FNKind(FNKind) {} }; /// Selects which debug sections get dumped. diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 3d04e73903e..e52e8afab84 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -25,6 +25,8 @@ using namespace object; #define DEBUG_TYPE "dwarf" typedef DWARFDebugLine::LineTable DWARFLineTable; +typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; +typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, bool LittleEndian, bool GnuStyle) { @@ -425,14 +427,13 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { static bool getFileNameForCompileUnit(DWARFCompileUnit *CU, const DWARFLineTable *LineTable, - uint64_t FileIndex, - bool NeedsAbsoluteFilePath, + uint64_t FileIndex, FileLineInfoKind Kind, std::string &FileName) { - if (!CU || !LineTable || - !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath, - FileName)) + if (!CU || !LineTable || Kind == FileLineInfoKind::None || + !LineTable->getFileNameByIndex(FileIndex, Kind, FileName)) return false; - if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) { + if (Kind == FileLineInfoKind::AbsoluteFilePath && + sys::path::is_relative(FileName)) { // We may still need to append compilation directory of compile unit. SmallString<16> AbsolutePath; if (const char *CompilationDir = CU->getCompilationDir()) { @@ -447,7 +448,7 @@ static bool getFileNameForCompileUnit(DWARFCompileUnit *CU, static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, const DWARFLineTable *LineTable, uint64_t Address, - bool NeedsAbsoluteFilePath, + FileLineInfoKind Kind, DILineInfo &Result) { if (!CU || !LineTable) return false; @@ -457,7 +458,7 @@ 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, + if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind, Result.FileName)) return false; Result.Line = Row.Line; @@ -466,7 +467,10 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, } static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, + FunctionNameKind Kind, std::string &FunctionName) { + if (Kind == FunctionNameKind::None) + return false; // 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. @@ -475,7 +479,8 @@ static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, if (InlinedChain.DIEs.size() == 0) return false; const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) { + if (const char *Name = + TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) { FunctionName = Name; return true; } @@ -483,41 +488,34 @@ static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, } DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier) { + DILineInfoSpecifier Spec) { DILineInfo Result; DWARFCompileUnit *CU = getCompileUnitForAddress(Address); if (!CU) return Result; - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - getFunctionNameForAddress(CU, Address, Result.FunctionName); - } - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { + getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName); + if (Spec.FLIKind != FileLineInfoKind::None) { const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); - getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath, - Result); + getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result); } return Result; } -DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, - uint64_t Size, - DILineInfoSpecifier Specifier) { +DILineInfoTable +DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, + DILineInfoSpecifier Spec) { DILineInfoTable Lines; DWARFCompileUnit *CU = getCompileUnitForAddress(Address); if (!CU) return Lines; std::string FunctionName = ""; - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - getFunctionNameForAddress(CU, Address, FunctionName); - } + getFunctionNameForAddress(CU, Address, Spec.FNKind, 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)) { + if (Spec.FLIKind == FileLineInfoKind::None) { DILineInfo Result; Result.FunctionName = FunctionName; Lines.push_back(std::make_pair(Address, Result)); @@ -525,8 +523,6 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, } const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); // Get the index of row we're looking for in the line table. std::vector RowVector; @@ -537,7 +533,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, // Take file number and line/column from the row. const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; DILineInfo Result; - getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath, + getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind, Result.FileName); Result.FunctionName = FunctionName; Result.Line = Row.Line; @@ -548,8 +544,9 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, return Lines; } -DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier) { +DIInliningInfo +DWARFContext::getInliningInfoForAddress(uint64_t Address, + DILineInfoSpecifier Spec) { DIInliningInfo InliningInfo; DWARFCompileUnit *CU = getCompileUnitForAddress(Address); @@ -557,18 +554,16 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; const DWARFLineTable *LineTable = nullptr; - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); const DWARFDebugInfoEntryInlinedChain &InlinedChain = CU->getInlinedChainForAddress(Address); if (InlinedChain.DIEs.size() == 0) { // If there is no DIE for address (e.g. it is in unavailable .dwo file), // try to at least get file/line info from symbol table. - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { + if (Spec.FLIKind != FileLineInfoKind::None) { DILineInfo Frame; LineTable = getLineTableForCompileUnit(CU); - if (getFileLineInfoForCompileUnit(CU, LineTable, Address, - NeedsAbsoluteFilePath, Frame)) { + if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, + Frame)) { InliningInfo.addFrame(Frame); } } @@ -580,23 +575,22 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i]; DILineInfo Frame; // Get function name if necessary. - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U)) - Frame.FunctionName = Name; - } - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { + if (const char *Name = + FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind)) + Frame.FunctionName = Name; + if (Spec.FLIKind != FileLineInfoKind::None) { if (i == 0) { // For the topmost frame, initialize the line table of this // compile unit and fetch file/line info from it. LineTable = getLineTableForCompileUnit(CU); // For the topmost routine, get file/line info from line table. - getFileLineInfoForCompileUnit(CU, LineTable, Address, - NeedsAbsoluteFilePath, Frame); + getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, + Frame); } else { // Otherwise, use call file, call line and call column from // previous DIE in inlined chain. - getFileNameForCompileUnit(CU, LineTable, CallFile, - NeedsAbsoluteFilePath, Frame.FileName); + getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind, + Frame.FileName); Frame.Line = CallLine; Frame.Column = CallColumn; } diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp index c23c9c6ed67..d2b529346fb 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace dwarf; +typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth, @@ -272,8 +273,9 @@ bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( } const char * -DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const { - if (!isSubroutineDIE()) +DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, + FunctionNameKind Kind) const { + if (!isSubroutineDIE() || Kind == FunctionNameKind::None) return nullptr; // Try to get mangled name if possible. if (const char *name = @@ -290,7 +292,7 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const { if (spec_ref != -1U) { DWARFDebugInfoEntryMinimal spec_die; if (spec_die.extractFast(U, &spec_ref)) { - if (const char *name = spec_die.getSubroutineName(U)) + if (const char *name = spec_die.getSubroutineName(U, Kind)) return name; } } @@ -300,7 +302,7 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const { if (abs_origin_ref != -1U) { DWARFDebugInfoEntryMinimal abs_origin_die; if (abs_origin_die.extractFast(U, &abs_origin_ref)) { - if (const char *name = abs_origin_die.getSubroutineName(U)) + if (const char *name = abs_origin_die.getSubroutineName(U, Kind)) return name; } } diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.h b/lib/DebugInfo/DWARFDebugInfoEntry.h index 35140d73594..916e1ed340e 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.h +++ b/lib/DebugInfo/DWARFDebugInfoEntry.h @@ -13,6 +13,7 @@ #include "DWARFAbbreviationDeclaration.h" #include "DWARFDebugRangeList.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/DIContext.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -122,7 +123,9 @@ public: /// returns its mangled name (or short name, if mangled is missing). /// This name may be fetched from specification or abstract origin /// for this subprogram. Returns null if no name is found. - const char *getSubroutineName(const DWARFUnit *U) const; + const char * + getSubroutineName(const DWARFUnit *U, + DILineInfoSpecifier::FunctionNameKind Kind) const; /// Retrieves values of DW_AT_call_file, DW_AT_call_line and /// DW_AT_call_column from DIE (or zeroes if they are missing). diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp index a5261d7644e..ce87635507e 100644 --- a/lib/DebugInfo/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARFDebugLine.cpp @@ -15,6 +15,7 @@ #include using namespace llvm; using namespace dwarf; +typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; DWARFDebugLine::Prologue::Prologue() { clear(); @@ -643,13 +644,14 @@ bool DWARFDebugLine::LineTable::lookupAddressRange( bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, - bool NeedsAbsoluteFilePath, + FileLineInfoKind Kind, std::string &Result) const { - if (FileIndex == 0 || FileIndex > Prologue.FileNames.size()) + if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() || + Kind == FileLineInfoKind::None) return false; const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; const char *FileName = Entry.Name; - if (!NeedsAbsoluteFilePath || + if (Kind != FileLineInfoKind::AbsoluteFilePath || sys::path::is_absolute(FileName)) { Result = FileName; return true; diff --git a/lib/DebugInfo/DWARFDebugLine.h b/lib/DebugInfo/DWARFDebugLine.h index 0b3e267c2f8..c7b7ec2c0e7 100644 --- a/lib/DebugInfo/DWARFDebugLine.h +++ b/lib/DebugInfo/DWARFDebugLine.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H #include "DWARFRelocMap.h" +#include "llvm/DebugInfo/DIContext.h" #include "llvm/Support/DataExtractor.h" #include #include @@ -179,7 +180,7 @@ public: // Extracts filename by its index in filename table in prologue. // Returns true on success. bool getFileNameByIndex(uint64_t FileIndex, - bool NeedsAbsoluteFilePath, + DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const; void dump(raw_ostream &OS) const; diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index e41ae251683..58914f08a45 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -108,13 +108,13 @@ static void DumpInput(const StringRef &Filename) { DICtx->dump(outs(), DumpType); } else { // Print line info for the specified address. - int SpecFlags = DILineInfoSpecifier::FileLineInfo | - DILineInfoSpecifier::AbsoluteFilePath; - if (PrintFunctions) - SpecFlags |= DILineInfoSpecifier::FunctionName; + DILineInfoSpecifier Spec( + DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, + PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName + : DILineInfoSpecifier::FunctionNameKind::None); if (PrintInlining) { DIInliningInfo InliningInfo = - DICtx->getInliningInfoForAddress(Address, SpecFlags); + DICtx->getInliningInfoForAddress(Address, Spec); uint32_t n = InliningInfo.getNumberOfFrames(); if (n == 0) { // Print one empty debug line info in any case. @@ -126,7 +126,7 @@ static void DumpInput(const StringRef &Filename) { } } } else { - DILineInfo dli = DICtx->getLineInfoForAddress(Address, SpecFlags); + DILineInfo dli = DICtx->getLineInfoForAddress(Address, Spec); PrintDILineInfo(dli); } } diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 4a9bbe5e822..7018ebed731 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -35,13 +35,12 @@ static bool error(error_code ec) { return true; } -static uint32_t -getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) { - uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo | - llvm::DILineInfoSpecifier::AbsoluteFilePath; - if (Opts.PrintFunctions) - Flags |= llvm::DILineInfoSpecifier::FunctionName; - return Flags; +static DILineInfoSpecifier +getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) { + return DILineInfoSpecifier( + DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, + Opts.PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName + : DILineInfoSpecifier::FunctionNameKind::None); } ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) @@ -115,7 +114,7 @@ DILineInfo ModuleInfo::symbolizeCode( DILineInfo LineInfo; if (DebugInfoContext) { LineInfo = DebugInfoContext->getLineInfoForAddress( - ModuleOffset, getDILineInfoSpecifierFlags(Opts)); + ModuleOffset, getDILineInfoSpecifier(Opts)); } // Override function name from symbol table if necessary. if (Opts.PrintFunctions && Opts.UseSymbolTable) { @@ -134,7 +133,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode( DIInliningInfo InlinedContext; if (DebugInfoContext) { InlinedContext = DebugInfoContext->getInliningInfoForAddress( - ModuleOffset, getDILineInfoSpecifierFlags(Opts)); + ModuleOffset, getDILineInfoSpecifier(Opts)); } // Make sure there is at least one frame in context. if (InlinedContext.getNumberOfFrames() == 0) {