llvm.org GIT mirror llvm / 08ef020
[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 Alexey Samsonov 6 years ago
6 changed file(s) with 66 addition(s) and 96 deletion(s). Raw diff Collapse all Expand all
1515 #define LLVM_DEBUGINFO_DICONTEXT_H
1616
1717 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/SmallString.h"
1918 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
2119 #include "llvm/Object/ObjectFile.h"
2220 #include "llvm/Object/RelocVisitor.h"
2321 #include "llvm/Support/Casting.h"
2422 #include "llvm/Support/DataTypes.h"
23
24 #include
2525
2626 namespace llvm {
2727
2828 class raw_ostream;
2929
3030 /// DILineInfo - a format-neutral container for source line information.
31 class DILineInfo {
32 SmallString<16> FileName;
33 SmallString<16> FunctionName;
31 struct DILineInfo {
32 std::string FileName;
33 std::string FunctionName;
3434 uint32_t Line;
3535 uint32_t Column;
36 public:
36
3737 DILineInfo()
38 : FileName(""), FunctionName(""),
39 Line(0), Column(0) {}
40 DILineInfo(StringRef fileName, StringRef functionName, uint32_t line,
41 uint32_t column)
42 : FileName(fileName), FunctionName(functionName), Line(line),
43 Column(column) {}
44
45 const char *getFileName() { return FileName.c_str(); }
46 const char *getFunctionName() { return FunctionName.c_str(); }
47 uint32_t getLine() const { return Line; }
48 uint32_t getColumn() const { return Column; }
38 : FileName(""), FunctionName(""), Line(0), Column(0) {}
4939
5040 bool operator==(const DILineInfo &RHS) const {
5141 return Line == RHS.Line && Column == RHS.Column &&
52 FileName.equals(RHS.FileName) &&
53 FunctionName.equals(RHS.FunctionName);
42 FileName == RHS.FileName && FunctionName == RHS.FunctionName;
5443 }
5544 bool operator!=(const DILineInfo &RHS) const {
5645 return !(*this == RHS);
442442 const DWARFLineTable *LineTable,
443443 uint64_t Address,
444444 bool NeedsAbsoluteFilePath,
445 std::string &FileName,
446 uint32_t &Line, uint32_t &Column) {
445 DILineInfo &Result) {
447446 if (!CU || !LineTable)
448447 return false;
449448 // Get the index of row we're looking for in the line table.
452451 return false;
453452 // Take file number and line/column from the row.
454453 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
455 if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
456 NeedsAbsoluteFilePath, FileName))
454 if (!getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
455 Result.FileName))
457456 return false;
458 Line = Row.Line;
459 Column = Row.Column;
457 Result.Line = Row.Line;
458 Result.Column = Row.Column;
460459 return true;
460 }
461
462 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
463 std::string &FunctionName) {
464 // The address may correspond to instruction in some inlined function,
465 // so we have to build the chain of inlined functions and take the
466 // name of the topmost function in it.
467 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
468 CU->getInlinedChainForAddress(Address);
469 if (InlinedChain.DIEs.size() == 0)
470 return false;
471 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
472 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) {
473 FunctionName = Name;
474 return true;
475 }
476 return false;
461477 }
462478
463479 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
464480 DILineInfoSpecifier Specifier) {
481 DILineInfo Result;
482
465483 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
466484 if (!CU)
467 return DILineInfo();
468 std::string FileName = "";
469 std::string FunctionName = "";
470 uint32_t Line = 0;
471 uint32_t Column = 0;
485 return Result;
472486 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
473 // The address may correspond to instruction in some inlined function,
474 // so we have to build the chain of inlined functions and take the
475 // name of the topmost function in it.
476 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
477 CU->getInlinedChainForAddress(Address);
478 if (InlinedChain.DIEs.size() > 0) {
479 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
480 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
481 FunctionName = Name;
482 }
487 getFunctionNameForAddress(CU, Address, Result.FunctionName);
483488 }
484489 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
485490 const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
486491 const bool NeedsAbsoluteFilePath =
487492 Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
488 getFileLineInfoForCompileUnit(CU, LineTable, Address,
489 NeedsAbsoluteFilePath,
490 FileName, Line, Column);
491 }
492 return DILineInfo(StringRef(FileName), StringRef(FunctionName),
493 Line, Column);
493 getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath,
494 Result);
495 }
496 return Result;
494497 }
495498
496499 DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
503506
504507 std::string FunctionName = "";
505508 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
506 // The address may correspond to instruction in some inlined function,
507 // so we have to build the chain of inlined functions and take the
508 // name of the topmost function in it.
509 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
510 CU->getInlinedChainForAddress(Address);
511 if (InlinedChain.DIEs.size() > 0) {
512 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
513 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
514 FunctionName = Name;
515 }
509 getFunctionNameForAddress(CU, Address, FunctionName);
516510 }
517511
518512 // If the Specifier says we don't need FileLineInfo, just
519513 // return the top-most function at the starting address.
520514 if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
521 Lines.push_back(
522 std::make_pair(Address, DILineInfo("", FunctionName, 0, 0)));
515 DILineInfo Result;
516 Result.FunctionName = FunctionName;
517 Lines.push_back(std::make_pair(Address, Result));
523518 return Lines;
524519 }
525520
535530 for (uint32_t RowIndex : RowVector) {
536531 // Take file number and line/column from the row.
537532 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
538 std::string FileName = "";
539 getFileNameForCompileUnit(CU, LineTable, Row.File,
540 NeedsAbsoluteFilePath, FileName);
541 Lines.push_back(std::make_pair(
542 Row.Address, DILineInfo(FileName, FunctionName, Row.Line, Row.Column)));
533 DILineInfo Result;
534 getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
535 Result.FileName);
536 Result.FunctionName = FunctionName;
537 Result.Line = Row.Line;
538 Result.Column = Row.Column;
539 Lines.push_back(std::make_pair(Row.Address, Result));
543540 }
544541
545542 return Lines;
561558 const DWARFLineTable *LineTable = nullptr;
562559 for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
563560 const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
564 std::string FileName = "";
565 std::string FunctionName = "";
566 uint32_t Line = 0;
567 uint32_t Column = 0;
561 DILineInfo Frame;
568562 // Get function name if necessary.
569563 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
570564 if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
571 FunctionName = Name;
565 Frame.FunctionName = Name;
572566 }
573567 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
574568 const bool NeedsAbsoluteFilePath =
580574 // For the topmost routine, get file/line info from line table.
581575 getFileLineInfoForCompileUnit(CU, LineTable, Address,
582576 NeedsAbsoluteFilePath,
583 FileName, Line, Column);
577 Frame);
584578 } else {
585579 // Otherwise, use call file, call line and call column from
586580 // previous DIE in inlined chain.
587581 getFileNameForCompileUnit(CU, LineTable, CallFile,
588 NeedsAbsoluteFilePath, FileName);
589 Line = CallLine;
590 Column = CallColumn;
582 NeedsAbsoluteFilePath, Frame.FileName);
583 Frame.Line = CallLine;
584 Frame.Column = CallColumn;
591585 }
592586 // Get call file/line/column of a current DIE.
593587 if (i + 1 < n) {
595589 CallColumn);
596590 }
597591 }
598 DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
599 Line, Column);
600592 InliningInfo.addFrame(Frame);
601593 }
602594 return InliningInfo;
7979
8080 static void PrintDILineInfo(DILineInfo dli) {
8181 if (PrintFunctions)
82 outs() << (dli.getFunctionName() ? dli.getFunctionName() : "")
83 << "\n";
84 outs() << (dli.getFileName() ? dli.getFileName() : "") << ':'
85 << dli.getLine() << ':' << dli.getColumn() << '\n';
82 outs() << dli.FunctionName << "\n";
83 outs() << dli.FileName << ':' << dli.Line << ':' << dli.Column << '\n';
8684 }
8785
8886 static void DumpInput(const StringRef &Filename) {
420420 DILineInfo dli =
421421 diContext->getLineInfoForAddress(SectAddress + Index);
422422 // Print valid line info if it changed.
423 if (dli != lastLine && dli.getLine() != 0)
424 outs() << "\t## " << dli.getFileName() << ':'
425 << dli.getLine() << ':' << dli.getColumn();
423 if (dli != lastLine && dli.Line != 0)
424 outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
425 << dli.Column;
426426 lastLine = dli;
427427 }
428428 outs() << "\n";
171171 DILineInfoTable::iterator End = Lines.end();
172172 for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
173173 outs() << " Line info @ " << It->first - Addr << ": "
174 << It->second.getFileName()
175 << ", line:" << It->second.getLine() << "\n";
174 << It->second.FileName << ", line:" << It->second.Line << "\n";
176175 }
177176 }
178177 }
4141 if (Opts.PrintFunctions)
4242 Flags |= llvm::DILineInfoSpecifier::FunctionName;
4343 return Flags;
44 }
45
46 static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName,
47 DILineInfo &LineInfo) {
48 std::string FileName = LineInfo.getFileName();
49 LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName),
50 LineInfo.getLine(), LineInfo.getColumn());
5144 }
5245
5346 ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
129122 uint64_t Start, Size;
130123 if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
131124 FunctionName, Start, Size)) {
132 patchFunctionNameInDILineInfo(FunctionName, LineInfo);
125 LineInfo.FunctionName = FunctionName;
133126 }
134127 }
135128 return LineInfo;
156149 uint64_t Start, Size;
157150 if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
158151 FunctionName, Start, Size)) {
159 patchFunctionNameInDILineInfo(FunctionName, LineInfo);
152 LineInfo.FunctionName = FunctionName;
160153 }
161154 }
162155 PatchedInlinedContext.addFrame(LineInfo);
407400 static const std::string kDILineInfoBadString = "";
408401 std::stringstream Result;
409402 if (Opts.PrintFunctions) {
410 std::string FunctionName = LineInfo.getFunctionName();
403 std::string FunctionName = LineInfo.FunctionName;
411404 if (FunctionName == kDILineInfoBadString)
412405 FunctionName = kBadString;
413406 else if (Opts.Demangle)
414407 FunctionName = DemangleName(FunctionName);
415408 Result << FunctionName << "\n";
416409 }
417 std::string Filename = LineInfo.getFileName();
410 std::string Filename = LineInfo.FileName;
418411 if (Filename == kDILineInfoBadString)
419412 Filename = kBadString;
420 Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn()
421 << "\n";
413 Result << Filename << ":" << LineInfo.Line << ":" << LineInfo.Column << "\n";
422414 return Result.str();
423415 }
424416