|
58 | 58 | using namespace swift;
|
59 | 59 | using namespace irgen;
|
60 | 60 |
|
| 61 | +llvm::cl::opt<bool> VerifyLineTable( |
| 62 | + "verify-linetable", llvm::cl::init(false), |
| 63 | + llvm::cl::desc( |
| 64 | + "Verify that the debug locations within one scope are contiguous.")); |
| 65 | + |
61 | 66 | namespace {
|
62 | 67 | using TrackingDIRefMap =
|
63 | 68 | llvm::DenseMap<const llvm::MDString *, llvm::TrackingMDNodeRef>;
|
@@ -105,6 +110,20 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
|
105 | 110 | SmallVector<std::pair<SILLocation::DebugLoc, const SILDebugScope *>, 8>
|
106 | 111 | LocationStack;
|
107 | 112 |
|
| 113 | +#ifndef NDEBUG |
| 114 | + using UUSTuple = std::pair<std::pair<unsigned, unsigned>, StringRef>; |
| 115 | + struct DebugLocKey : public UUSTuple { |
| 116 | + DebugLocKey(SILLocation::DebugLoc DL) |
| 117 | + : UUSTuple({{DL.Line, DL.Column}, DL.Filename}) {} |
| 118 | + inline bool operator==(const SILLocation::DebugLoc &DL) const { |
| 119 | + return first.first == DL.Line && first.second == DL.Column && |
| 120 | + second.equals(DL.Filename); |
| 121 | + } |
| 122 | + }; |
| 123 | + llvm::DenseSet<UUSTuple> PreviousLineEntries; |
| 124 | + SILLocation::DebugLoc PreviousDebugLoc; |
| 125 | +#endif |
| 126 | + |
108 | 127 | public:
|
109 | 128 | IRGenDebugInfoImpl(const IRGenOptions &Opts, ClangImporter &CI,
|
110 | 129 | IRGenModule &IGM, llvm::Module &M,
|
@@ -307,6 +326,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
|
307 | 326 | }
|
308 | 327 | return true;
|
309 | 328 | }
|
| 329 | + |
| 330 | + /// Assert that within one lexical block, each location is only visited once. |
| 331 | + bool lineEntryIsSane(SILLocation::DebugLoc DL, const SILDebugScope *DS); |
| 332 | + |
310 | 333 | #endif
|
311 | 334 |
|
312 | 335 | llvm::DIFile *getOrCreateFile(StringRef Filename) {
|
@@ -1564,6 +1587,23 @@ void IRGenDebugInfoImpl::finalize() {
|
1564 | 1587 | DBuilder.finalize();
|
1565 | 1588 | }
|
1566 | 1589 |
|
| 1590 | +bool IRGenDebugInfoImpl::lineEntryIsSane(SILLocation::DebugLoc DL, |
| 1591 | + const SILDebugScope *DS) { |
| 1592 | + // All bets are off for optimized code. |
| 1593 | + if (!VerifyLineTable || Opts.shouldOptimize()) |
| 1594 | + return true; |
| 1595 | + // We entered a new lexical block. |
| 1596 | + if (DS != LastScope) |
| 1597 | + PreviousLineEntries.clear(); |
| 1598 | + if (DL.Line == 0 || DL == PreviousDebugLoc) |
| 1599 | + return true; |
| 1600 | + // Save the last non-zero line entry. |
| 1601 | + PreviousDebugLoc = DL; |
| 1602 | + auto ItNew = PreviousLineEntries.insert(DebugLocKey(DL)); |
| 1603 | + // Return true iff DL was not yet in PreviousLineEntries. |
| 1604 | + return ItNew.second; |
| 1605 | +} |
| 1606 | + |
1567 | 1607 | void IRGenDebugInfoImpl::setCurrentLoc(IRBuilder &Builder,
|
1568 | 1608 | const SILDebugScope *DS,
|
1569 | 1609 | SILLocation Loc) {
|
@@ -1612,9 +1652,8 @@ void IRGenDebugInfoImpl::setCurrentLoc(IRBuilder &Builder,
|
1612 | 1652 | }
|
1613 | 1653 |
|
1614 | 1654 | // FIXME: Enable this assertion.
|
1615 |
| - // assert(lineNumberIsSane(Builder, L.Line) && |
1616 |
| - // "-Onone, but line numbers are not monotonically increasing within |
1617 |
| - // bb"); |
| 1655 | + assert(lineEntryIsSane(L, DS) && |
| 1656 | + "non-contiguous debug location in same scope at -Onone"); |
1618 | 1657 | LastDebugLoc = L;
|
1619 | 1658 | LastScope = DS;
|
1620 | 1659 |
|
|
0 commit comments