[llvm] [llvm-dwarfdump][LineCov 1/3] Add variable coverage metrics (PR #169646)

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 10 05:50:32 PST 2025


================
@@ -0,0 +1,257 @@
+//===-- Coverage.cpp - Debug info coverage metrics ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-dwarfdump.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugProgramInstruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IRReader/IRReader.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include <set>
+
+using namespace llvm;
+using namespace llvm::dwarf;
+using namespace llvm::object;
+
+typedef std::pair<std::string, std::string> StringPair;
+/// Pair of file index and line number representing a source location.
+typedef std::pair<uint16_t, std::size_t> SourceLocation;
+
+/// Returns the set of source lines covered by a variable's debug information.
+static std::optional<std::set<SourceLocation>>
+computeVariableCoverage(DWARFContext &DICtx, DWARFDie VariableDIE,
+                        const DWARFDebugLine::LineTable *const LineTable) {
+  /// Adds source locations to the set that correspond to an address range.
+  auto addLines = [](const DWARFDebugLine::LineTable *LineTable,
+                     std::set<SourceLocation> &Lines, DWARFAddressRange Range,
+                     std::map<std::string, uint16_t, std::less<>> &FileNames) {
+    std::vector<uint32_t> Rows;
+    if (LineTable->lookupAddressRange({Range.LowPC, Range.SectionIndex},
+                                      Range.HighPC - Range.LowPC, Rows)) {
+      for (const auto &RowI : Rows) {
+        const auto Row = LineTable->Rows[RowI];
+        // Lookup can return addresses below the LowPC - filter these out.
+        if (Row.Address.Address < Range.LowPC)
+          continue;
+        const auto FileIndex = Row.File;
+
+        // Add the file's name to the map if not present.
+        if (!any_of(FileNames,
+                    [FileIndex](auto &FN) { return FN.second == FileIndex; })) {
+          std::string Name;
+          LineTable->getFileNameByIndex(
+              FileIndex, "",
+              DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath, Name);
+          FileNames.emplace(Name, FileIndex);
+        }
+
+        const auto Line = Row.Line;
+        if (Line) // Ignore zero lines.
+          Lines.insert({FileIndex, Line});
+      }
+    }
+  };
+
+  std::map<std::string, uint16_t, std::less<>> FileNames;
----------------
SLTozer wrote:

What's the purpose of `FileNames`? As far as I can tell, we insert into it, but never read from it (except for deciding whether or not to insert into it).

https://github.com/llvm/llvm-project/pull/169646


More information about the llvm-commits mailing list