|
10 | 10 | // |
11 | 11 | //===----------------------------------------------------------------------===// |
12 | 12 |
|
| 13 | +#include "llvm/ADT/SetVector.h" |
13 | 14 | #include "llvm/DebugInfo/LogicalView/Core/LVReader.h" |
14 | 15 | #include "llvm/DebugInfo/LogicalView/Core/LVScope.h" |
15 | 16 | #include "llvm/Support/FileSystem.h" |
@@ -516,13 +517,182 @@ Error LVReader::doPrint() { |
516 | 517 | if (options().getReportParents() || options().getReportView()) |
517 | 518 | if (Error Err = printScopes()) |
518 | 519 | return Err; |
519 | | - |
| 520 | + // Requested debugger report |
| 521 | + if (options().getReportDebugger()) |
| 522 | + if (Error Err = printDebugger()) |
| 523 | + return Err; |
520 | 524 | return Error::success(); |
521 | 525 | } |
522 | 526 |
|
523 | 527 | return printScopes(); |
524 | 528 | } |
525 | 529 |
|
| 530 | +namespace { |
| 531 | + |
| 532 | +struct DebuggerViewPrinter { |
| 533 | + std::vector<const LVLine *> Lines; |
| 534 | + std::unordered_map<LVAddress, std::vector<const LVLocation *>> LivetimeBegins; |
| 535 | + std::unordered_map<LVAddress, std::vector<const LVLocation *>> |
| 536 | + LivetimeEndsExclusive; |
| 537 | + raw_ostream &OS; |
| 538 | + |
| 539 | + const bool IncludeRanges = false; |
| 540 | + |
| 541 | + void Walk(raw_ostream &OS, const LVScope *Scope) { |
| 542 | + if (Scope->scopeCount()) { |
| 543 | + for (const LVScope *ChildScope : *Scope->getScopes()) |
| 544 | + Walk(OS, ChildScope); |
| 545 | + } |
| 546 | + if (Scope->lineCount()) { |
| 547 | + for (const LVLine *Line : *Scope->getLines()) { |
| 548 | + Lines.push_back(Line); |
| 549 | + } |
| 550 | + } |
| 551 | + if (Scope->symbolCount()) { |
| 552 | + for (const LVSymbol *Symbol : *Scope->getSymbols()) { |
| 553 | + LVLocations SymbolLocations; |
| 554 | + Symbol->getLocations(SymbolLocations); |
| 555 | + if (SymbolLocations.empty()) |
| 556 | + continue; |
| 557 | + |
| 558 | + if (IncludeRanges) { |
| 559 | + OS << "{Range}: " << Symbol->getName() << " (line " |
| 560 | + << Symbol->getLineNumber() << ")" << ": "; |
| 561 | + } |
| 562 | + |
| 563 | + for (const LVLocation *Loc : SymbolLocations) { |
| 564 | + if (Loc->getIsGapEntry()) |
| 565 | + continue; |
| 566 | + |
| 567 | + LVAddress Begin = Loc->getLowerAddress(); |
| 568 | + LVAddress End = Loc->getUpperAddress(); |
| 569 | + LivetimeBegins[Begin].push_back(Loc); |
| 570 | + LivetimeEndsExclusive[End].push_back(Loc); |
| 571 | + if (IncludeRanges) { |
| 572 | + OS << "[" << hexValue(Begin) << ":" << hexValue(End) << "] "; |
| 573 | + } |
| 574 | + } |
| 575 | + |
| 576 | + if (IncludeRanges) |
| 577 | + OS << "\n"; |
| 578 | + } |
| 579 | + } |
| 580 | + } |
| 581 | + |
| 582 | + DebuggerViewPrinter(raw_ostream &OS, const LVScopeFunction *Fn) : OS(OS) { |
| 583 | + Walk(OS, Fn); |
| 584 | + std::sort(Lines.begin(), Lines.end(), |
| 585 | + [](const LVLine *a, const LVLine *b) -> bool { |
| 586 | + if (a->getAddress() != b->getAddress()) |
| 587 | + return a->getAddress() < b->getAddress(); |
| 588 | + if (a->getIsLineDebug() != b->getIsLineDebug()) |
| 589 | + return a->getIsLineDebug(); |
| 590 | + return a->getID() < b->getID(); |
| 591 | + }); |
| 592 | + } |
| 593 | + |
| 594 | + static void PrintIndent(raw_ostream &OS, int Indent) { |
| 595 | + for (int i = 0; i < Indent; i++) |
| 596 | + OS << " "; |
| 597 | + } |
| 598 | + |
| 599 | + static void PrintCallstack(raw_ostream &OS, const LVScope *Scope) { |
| 600 | + const LVScope *PrevScope = nullptr; |
| 601 | + while (Scope) { |
| 602 | + if (Scope->getIsFunction() || Scope->getIsInlinedFunction()) { |
| 603 | + OS << "[" << Scope->getName(); |
| 604 | + if (PrevScope && PrevScope->getIsInlinedFunction()) { |
| 605 | + OS << ":" |
| 606 | + << cast<LVScopeFunctionInlined>(PrevScope)->getCallLineNumber(); |
| 607 | + } |
| 608 | + OS << "]"; |
| 609 | + PrevScope = Scope; |
| 610 | + } |
| 611 | + Scope = Scope->getParentScope(); |
| 612 | + } |
| 613 | + } |
| 614 | + |
| 615 | + static bool IsChildScopeOf(const LVScope *A, const LVScope *B) { |
| 616 | + while (A) { |
| 617 | + A = A->getParentScope(); |
| 618 | + if (A == B) |
| 619 | + return true; |
| 620 | + } |
| 621 | + return false; |
| 622 | + } |
| 623 | + |
| 624 | + void Print() { |
| 625 | + const bool IncludeVars = options().getPrintSymbols(); |
| 626 | + const bool IncludeCode = options().getPrintInstructions(); |
| 627 | + SetVector<const LVLocation *> |
| 628 | + LiveSymbols; // This needs to be ordered since we're iterating over it. |
| 629 | + for (const LVLine *Line : Lines) { |
| 630 | + const LVScope *Scope = Line->getParentScope(); |
| 631 | + // Update live list: Add lives |
| 632 | + for (auto Loc : LivetimeBegins[Line->getAddress()]) |
| 633 | + LiveSymbols.insert(Loc); |
| 634 | + // Update live list: remove dead |
| 635 | + for (auto Loc : LivetimeEndsExclusive[Line->getAddress()]) |
| 636 | + LiveSymbols.remove(Loc); |
| 637 | + |
| 638 | + if (Line->getIsNewStatement() && Line->getIsLineDebug() && |
| 639 | + Line->getLineNumber() != 0) { |
| 640 | + auto LineDebug = cast<LVLineDebug>(Line); |
| 641 | + |
| 642 | + PrintIndent(OS, 1); |
| 643 | + OS << "{Line}: " << " [" << hexValue(LineDebug->getAddress()) << "] " |
| 644 | + << LineDebug->getPathname() << ":" << LineDebug->getLineNumber() |
| 645 | + << " "; |
| 646 | + PrintCallstack(OS, Scope); |
| 647 | + OS << "\n"; |
| 648 | + if (IncludeVars) { |
| 649 | + for (auto SymLoc : LiveSymbols) { |
| 650 | + const LVSymbol *Sym = SymLoc->getParentSymbol(); |
| 651 | + auto SymScope = Sym->getParentScope(); |
| 652 | + auto LineScope = LineDebug->getParentScope(); |
| 653 | + if (SymScope != LineScope && !IsChildScopeOf(LineScope, SymScope)) |
| 654 | + continue; |
| 655 | + PrintIndent(OS, 2); |
| 656 | + OS << "{Variable}: " << Sym->getName() << ": " << Sym->getType()->getName() |
| 657 | + << " : "; |
| 658 | + SymLoc->printLocations(OS); |
| 659 | + OS << " (line " << Sym->getLineNumber() << ")"; |
| 660 | + OS << "\n"; |
| 661 | + } |
| 662 | + } |
| 663 | + |
| 664 | + } else if (IncludeCode && Line->getIsLineAssembler()) { |
| 665 | + OS << " {Code}: " << " [" << hexValue(Line->getAddress()) << "] " |
| 666 | + << Line->getName() << "\n"; |
| 667 | + } |
| 668 | + } |
| 669 | + } |
| 670 | +}; |
| 671 | + |
| 672 | +} // namespace |
| 673 | + |
| 674 | +Error LVReader::printDebugger() { |
| 675 | + auto *CU = getCompileUnit(); |
| 676 | + if (!CU) { |
| 677 | + return createStringError(std::make_error_code(std::errc::invalid_argument), "Error: No compute unit found."); |
| 678 | + } |
| 679 | + |
| 680 | + for (LVElement *Child : *CU->getChildren()) { |
| 681 | + auto *Fn = dyn_cast<LVScopeFunction>(Child); |
| 682 | + if (Fn) { |
| 683 | + const LVLines *Lines = Fn->getLines(); |
| 684 | + // If there's no lines, this function has no body. |
| 685 | + if (!Lines) |
| 686 | + continue; |
| 687 | + outs() << "{Function}: " << Child->getName() << "\n"; |
| 688 | + |
| 689 | + DebuggerViewPrinter P(OS, Fn); |
| 690 | + P.Print(); |
| 691 | + } |
| 692 | + } |
| 693 | + return Error::success(); |
| 694 | +} |
| 695 | + |
526 | 696 | Error LVReader::printScopes() { |
527 | 697 | if (bool DoPrint = |
528 | 698 | (options().getPrintExecute() || options().getComparePrint())) { |
|
0 commit comments