[llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #202120)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 7 05:24:16 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: Carlos Alberto Enciso (CarlosAlbertoEnciso)

<details>
<summary>Changes</summary>

llvm-debuginfo-analyzer is a command line tool that processes debug
info contained in a binary file and produces a debug information
format agnostic “Logical View”, which is a high-level semantic
representation of the debug info, independent of the low-level format.

Add support for the LLVM IR format and be able to generate logical
views. Both textual representation (.ll) and bitcode (.bc) formats
are supported.

This relands https://github.com/llvm/llvm-project/pull/135440,
which was:
reverted in: https://github.com/llvm/llvm-project/pull/199890
relanded in: https://github.com/llvm/llvm-project/pull/200603
reverted in: https://github.com/llvm/llvm-project/pull/201019

It includes the fixes for the buildbots problems.

---

Patch is 240.42 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/202120.diff


41 Files Affected:

- (modified) llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst (+79-126) 
- (modified) llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h (+7) 
- (modified) llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h (+7) 
- (modified) llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h (+3) 
- (modified) llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h (+14-1) 
- (modified) llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h (+8-2) 
- (modified) llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h (+1) 
- (added) llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h (+303) 
- (modified) llvm/lib/DebugInfo/LogicalView/CMakeLists.txt (+5) 
- (modified) llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp (+13-4) 
- (modified) llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp (+5) 
- (modified) llvm/lib/DebugInfo/LogicalView/Core/LVReader.cpp (+29-1) 
- (modified) llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp (+43-14) 
- (added) llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp (+2630) 
- (modified) llvm/lib/Transforms/Utils/DebugSSAUpdater.cpp (+9-2) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-compare-logical-elements.test (+121) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test (+78) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test (+151) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test (+60) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/03-ir-incorrect-lexical-scope-typedef.test (+131) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/04-ir-missing-nested-enumerators.test (+144) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/05-ir-incorrect-lexical-scope-variable.test (+113) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test (+121) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/07-ir-debug-formats.test (+48) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/08-ir-multiple-compile-units.test (+168) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-1.ll (+58) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-2.ll (+58) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-3.ll (+58) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit.ll (+34) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/hello-world-clang.ll (+49) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-43860-clang.ll (+92) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-44884-clang.ll (+98) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-46466-clang.ll (+44) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang-intrinsics.ll (+87) 
- (added) llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang.ll (+83) 
- (modified) llvm/tools/llvm-debuginfo-analyzer/CMakeLists.txt (+3) 
- (modified) llvm/unittests/DebugInfo/LogicalView/CMakeLists.txt (+3) 
- (added) llvm/unittests/DebugInfo/LogicalView/IRReaderTest.cpp (+362) 
- (modified) llvm/unittests/DebugInfo/LogicalView/Inputs/README.md (+12) 
- (added) llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.bc () 
- (added) llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.ll (+83) 


``````````diff
diff --git a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
index 6fcf8423e8125..221732775e74c 100644
--- a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
+++ b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
@@ -13,10 +13,11 @@ SYNOPSIS
 DESCRIPTION
 -----------
 :program:`llvm-debuginfo-analyzer` parses debug and text sections in
-binary object files and prints their contents in a logical view, which
-is a human-readable representation that closely matches the structure
-of the original user source code. Supported object file formats include
-ELF, Mach-O, WebAssembly, PDB and COFF.
+binary object files or LLVM IR textual / bitcode representation and prints
+their contents in a logical view, which is a human readable representation
+that closely matches the structure of the original user source code.
+Supported object file formats include ELF, Mach-O, WebAssembly, PDB,
+COFF and IR (textual representation and bitcode).
 
 The **logical view** abstracts the complexity associated with the
 different low-level representations of the debugging information that
@@ -2131,143 +2132,95 @@ layout and given the number of matches.
   -----------------------------
   Total           71          8
 
-COMPARISON MODE
-^^^^^^^^^^^^^^^
-Given the previous example we found the above debug information issue
-(related to the previous invalid scope location for the **'typedef int
-INTEGER'**) by comparing against another compiler.
-
-Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern
-with the printing mode to obtain the following logical view output.
-
-.. code-block:: none
-
-  llvm-debuginfo-analyzer --attribute=level
-                          --select-regex --select-nocase --select=INTe
-                          --report=list
-                          --print=symbols,types
-                          test-clang.o test-dwarf-gcc.o
-
-  Logical View:
-  [000]           {File} 'test-clang.o'
-
-  [001]           {CompileUnit} 'test.cpp'
-  [003]     4     {TypeAlias} 'INTEGER' -> 'int'
-  [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
-
-  Logical View:
-  [000]           {File} 'test-dwarf-gcc.o'
-
-  [001]           {CompileUnit} 'test.cpp'
-  [004]     4     {TypeAlias} 'INTEGER' -> 'int'
-  [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
-
-The output shows that both objects contain the same elements. But the
-**'typedef INTEGER'** is located at different scope level. The GCC
-generated object, shows **'4'**, which is the correct value.
+LLVM IR (textual / bitcode representation) SUPPORT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The below example is used to show the IR output generated by
+:program:`llvm-debuginfo-analyzer`. We compiled the example for a
+IR 64-bit target with Clang (-O0 -g --target=x86_64-linux):
 
-There are 2 comparison methods: logical view and logical elements.
+.. code-block:: c++
 
-LOGICAL VIEW
-""""""""""""
-It compares the logical view as a whole unit; for a match, each compared
-logical element must have the same parents and children.
+  1  using INTPTR = const int *;
+  2  int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
+  3    if (ParamBool) {
+  4      typedef int INTEGER;
+  5      const INTEGER CONSTANT = 7;
+  6      return CONSTANT;
+  7    }
+  8    return ParamUnsigned;
+  9  }
 
-The output shows in view form the **missing (-), added (+)** elements,
-giving more context by swapping the reference and target object files.
+PRINT BASIC DETAILS
+^^^^^^^^^^^^^^^^^^^
+The following command prints basic details for all the logical elements
+sorted by the debug information internal offset; it includes its lexical
+level and debug info format.
 
 .. code-block:: none
 
-  llvm-debuginfo-analyzer --attribute=level
-                          --compare=types
-                          --report=view
-                          --print=symbols,types
-                          test-clang.o test-dwarf-gcc.o
-
-  Reference: 'test-clang.o'
-  Target:    'test-dwarf-gcc.o'
-
-  Logical View:
-   [000]           {File} 'test-clang.o'
-
-   [001]             {CompileUnit} 'test.cpp'
-   [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
-   [002]     2         {Function} extern not_inlined 'foo' -> 'int'
-   [003]                 {Block}
-   [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
-  +[004]     4             {TypeAlias} 'INTEGER' -> 'int'
-   [003]     2           {Parameter} 'ParamBool' -> 'bool'
-   [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
-   [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
-  -[003]     4           {TypeAlias} 'INTEGER' -> 'int'
-
-The output shows the merging view path (reference and target) with the
-missing and added elements.
+  llvm-debuginfo-analyzer --attribute=level,format
+                          --output-sort=offset
+                          --print=scopes,symbols,types,lines,instructions
+                          test-clang.ll
 
-LOGICAL ELEMENTS
-""""""""""""""""
-It compares individual logical elements without considering if their
-parents are the same. For both comparison methods, the equal criteria
-includes the name, source code location, type, lexical scope level.
+or
 
 .. code-block:: none
 
-  llvm-debuginfo-analyzer --attribute=level
-                          --compare=types
-                          --report=list
-                          --print=symbols,types,summary
-                          test-clang.o test-dwarf-gcc.o
-
-  Reference: 'test-clang.o'
-  Target:    'test-dwarf-gcc.o'
-
-  (1) Missing Types:
-  -[003]     4     {TypeAlias} 'INTEGER' -> 'int'
-
-  (1) Added Types:
-  +[004]     4     {TypeAlias} 'INTEGER' -> 'int'
-
-  ----------------------------------------
-  Element   Expected    Missing      Added
-  ----------------------------------------
-  Scopes           4          0          0
-  Symbols          0          0          0
-  Types            2          1          1
-  Lines            0          0          0
-  ----------------------------------------
-  Total            6          1          1
+  llvm-debuginfo-analyzer --attribute=level,format
+                          --output-sort=offset
+                          --print=elements
+                          test-clang.ll
 
-Changing the *Reference* and *Target* order:
+Each row represents an element that is present within the debug
+information. The first column represents the scope level, followed by
+the associated line number (if any), and finally the description of
+the element.
 
 .. code-block:: none
 
-  llvm-debuginfo-analyzer --attribute=level
-                          --compare=types
-                          --report=list
-                          --print=symbols,types,summary
-                          test-dwarf-gcc.o test-clang.o
-
-  Reference: 'test-dwarf-gcc.o'
-  Target:    'test-clang.o'
-
-  (1) Missing Types:
-  -[004]     4     {TypeAlias} 'INTEGER' -> 'int'
-
-  (1) Added Types:
-  +[003]     4     {TypeAlias} 'INTEGER' -> 'int'
-
-  ----------------------------------------
-  Element   Expected    Missing      Added
-  ----------------------------------------
-  Scopes           4          0          0
-  Symbols          0          0          0
-  Types            2          1          1
-  Lines            0          0          0
-  ----------------------------------------
-  Total            6          1          1
+  Logical View:
+  [000]           {File} 'test-clang.ll' -> Textual IR
 
-As the *Reference* and *Target* are switched, the *Added Types* from
-the first case now are listed as *Missing Types*.
+  [001]             {CompileUnit} 'test.cpp'
+  [002]     2         {Function} extern not_inlined 'foo' -> 'int'
+  [003]                 {Block}
+  [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
+  [004]     5             {Line}
+  [004]                   {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32'
+  [004]     6             {Line}
+  [004]                   {Code} 'store i32 7, ptr %retval, align 4, !dbg !33'
+  [004]     6             {Line}
+  [004]                   {Code} 'br label %return, !dbg !33'
+  [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
+  [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
+  [003]     2           {Parameter} 'ParamBool' -> 'bool'
+  [003]     4           {TypeAlias} 'INTEGER' -> 'int'
+  [003]     2           {Line}
+  [003]                 {Code} '%retval = alloca i32, align 4'
+  [003]                 {Code} '%ParamPtr.addr = alloca ptr, align 8'
+  [003]                 {Code} '%ParamUnsigned.addr = alloca i32, align 4'
+  [003]                 {Code} '%ParamBool.addr = alloca i8, align 1'
+  [003]                 {Code} '%CONSTANT = alloca i32, align 4'
+  [003]                 {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8'
+  [003]                 {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4'
+  [003]                 {Code} '%storedv = zext i1 %ParamBool to i8'
+  [003]                 {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1'
+  [003]     8           {Line}
+  [003]                 {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34'
+  [003]     8           {Line}
+  [003]                 {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35'
+  [003]     8           {Line}
+  [003]                 {Code} 'br label %return, !dbg !35'
+  [003]     9           {Line}
+  [003]                 {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36'
+  [003]     9           {Line}
+  [003]                 {Code} 'ret i32 %2, !dbg !36'
+  [003]     3           {Line}
+  [003]     3           {Line}
+  [003]     3           {Line}
+  [003]                 {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26'
+  [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
 
 EXIT STATUS
 -----------
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index 34bace886a15f..793a66e40b02b 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -374,6 +374,13 @@ class LLVM_ABI LVElement : public LVObject {
   // Report the current element as missing or added during comparison.
   virtual void report(LVComparePass Pass) {}
 
+  // Print the basic and extra information. Used mainly to debug IR.
+  void printCommon(raw_ostream &OS, bool Full = true) const;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+  void dumpCommon() const { printCommon(dbgs(), /*Full=*/true); }
+#endif
+
   static LVElementDispatch &getDispatch() { return Dispatch; }
 };
 
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
index 090af54cd1b85..6bf7f9d2105f8 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
@@ -159,6 +159,13 @@ class LLVM_ABI LVLocation : public LVObject {
 
   void print(raw_ostream &OS, bool Full = true) const override;
   void printExtra(raw_ostream &OS, bool Full = true) const override;
+
+  // Print the basic and extra information. Used mainly to debug IR.
+  void printCommon(raw_ostream &OS, bool Full = true) const;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+  void dumpCommon() const { printCommon(dbgs(), /*Full=*/true); }
+#endif
 };
 
 class LLVM_ABI LVLocationSymbol final : public LVLocation {
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
index 371bffb2ed163..774318cb3c53e 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
@@ -193,6 +193,9 @@ class LLVM_ABI LVReader {
   virtual Error printMatchedElements(bool UseMatchedElements);
   virtual void sortScopes() {}
 
+  void printCollectedElements(LVScope *Root);
+  bool checkIntegrityScopesTree(LVScope *Root);
+
 public:
   LVReader() = delete;
   LVReader(StringRef InputFilename, StringRef FileFormatName, ScopedPrinter &W,
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
index 058ca2da9a960..89b78042a615f 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
@@ -119,7 +119,20 @@ template <typename T> class LVProperties {
 #define KIND_3(ENUM, FIELD, F1, F2, F3)                                        \
   BOOL_BIT_3(Kinds, ENUM, FIELD, F1, F2, F3)
 
-const int HEX_WIDTH = 12;
+static constexpr int DEC_WIDTH = 8;
+inline FormattedNumber decValue(uint64_t N, unsigned Width = DEC_WIDTH) {
+  return format_decimal(N, Width);
+}
+
+// Output the decimal representation of 'Value'.
+inline std::string decString(uint64_t Value, size_t Width = DEC_WIDTH) {
+  std::string String;
+  raw_string_ostream Stream(String);
+  Stream << decValue(Value, Width);
+  return String;
+}
+
+static constexpr int HEX_WIDTH = 12;
 inline FormattedNumber hexValue(uint64_t N, unsigned Width = HEX_WIDTH,
                                 bool Upper = false) {
   return format_hex(N, Width, Upper);
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h
index f6dc65f39c7ac..8d65d2e93f5ad 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h
@@ -17,12 +17,14 @@
 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/Object/Archive.h"
+#include "llvm/Object/IRObjectFile.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include <string>
+#include <variant>
 #include <vector>
 
 namespace llvm {
@@ -30,7 +32,9 @@ namespace logicalview {
 
 using LVReaders = std::vector<std::unique_ptr<LVReader>>;
 using ArgVector = std::vector<std::string>;
-using PdbOrObj = PointerUnion<object::ObjectFile *, pdb::PDBFile *>;
+using InputHandle =
+    std::variant<StringRef *, MemoryBufferRef *, object::ObjectFile *,
+                 object::IRObjectFile *, pdb::PDBFile *>;
 
 // This class performs the following tasks:
 // - Creates a logical reader for every binary file in the command line,
@@ -61,8 +65,10 @@ class LVReaderHandler {
                      object::Binary &Binary);
   Error handleObject(LVReaders &Readers, StringRef Filename, StringRef Buffer,
                      StringRef ExePath);
+  Error handleObject(LVReaders &Readers, StringRef Filename,
+                     MemoryBufferRef Buffer);
 
-  Error createReader(StringRef Filename, LVReaders &Readers, PdbOrObj &Input,
+  Error createReader(StringRef Filename, LVReaders &Readers, InputHandle &Input,
                      StringRef FileFormatName, StringRef ExePath = {});
 
 public:
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
index cc8dda2f82bee..f4c1245cfb801 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
@@ -25,6 +25,7 @@
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Object/COFF.h"
+#include "llvm/Object/IRObjectFile.h"
 #include "llvm/Object/ObjectFile.h"
 
 namespace llvm {
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h
new file mode 100644
index 0000000000000..db2bf8e8ec033
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h
@@ -0,0 +1,303 @@
+//===-- LVIRReader.h --------------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LVIRReader class, which is used to describe a
+// LLVM IR reader.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H
+#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H
+
+#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
+#include "llvm/Transforms/Utils/DebugSSAUpdater.h"
+#include <unordered_map>
+
+namespace llvm {
+class DIFile;
+class DINode;
+class DILocation;
+class DIScope;
+class DISubprogram;
+class DIVariable;
+class BasicBlock;
+class Module;
+
+namespace object {
+class IRObjectFile;
+}
+
+namespace logicalview {
+
+class LVElement;
+class LVLine;
+class LVScopeCompileUnit;
+class LVSymbol;
+class LVType;
+struct LVSourceLanguage;
+
+class LVIRReader final : public LVReader {
+  PointerUnion<MemoryBufferRef *, object::IRObjectFile *> InputFile;
+
+  // Used by the metadata 'dump' functions, so the metadata nodes will be
+  // numbered canonically; otherwise, pointer addresses are substituted.
+  Module *TheModule = nullptr;
+
+  // Symbols with locations for current compile unit.
+  LVSymbols SymbolsWithLocations;
+
+  const DICompileUnit *CUNode = nullptr;
+
+  // The Dwarf version (from the module flags).
+  unsigned DwarfVersion = 0;
+
+  // Location index for global variables.
+  uint64_t PoolAddressIndex = 0;
+
+  // Default lower bound for arrays.
+  int64_t DefaultLowerBound = 0;
+
+  // Whether to emit all linkage names, or just abstract subprograms.
+  bool UseAllLinkageNames = true;
+
+  SSAValueNameMap ValueNameMap;
+  DenseMap<void *, uint64_t> InstrLineAddrMap;
+  std::unique_ptr<DbgValueRangeTable> DbgValueRanges;
+
+  // Record the last assigned file index for each compile unit.
+  // This data structure is to aid mapping DIFiles onto a DWARF-like file table.
+  using LVIndexFiles = std::unordered_map<LVScopeCompileUnit *, size_t>;
+  LVIndexFiles IndexFiles;
+
+  // Store a FileID number for each DIFile seen.
+  using LVCompileUnitFiles = std::unordered_map<const DIFile *, size_t>;
+  LVCompileUnitFiles CompileUnitFiles;
+
+  // Associate the metadata objects to logical elements.
+  using LVMDObjects = std::unordered_map<const MDNode *, LVElement *>;
+  LVMDObjects MDObjects;
+
+  // An anonymous type for index type.
+  LVType *NodeIndexType = nullptr;
+
+  // Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only
+  // difference is setting the 'DICompileUnit::splitDebugFilename' to the
+  // name of the split filename: "xxx.dwo".
+  bool includeMinimalInlineScopes() const;
+  bool useAllLinkageNames() const { return UseAllLinkageNames; }
+
+  int64_t getDefaultLowerBound() const { return DefaultLowerBound; }
+  void setDefaultLowerBound(LVSourceLanguage *SL);
+
+  // We assume a constant instruction-size increase between instructions.
+  static constexpr unsigned OFFSET_INCREASE = 4;
+  void updateLineOffset() { CurrentOffset += OFFSET_INCREASE; }
+
+  void updateFileIndex(LVScopeCompileUnit *CompileUnit, size_t FileIndex) {
+    auto [Iter, Inserted] = IndexFiles.try_emplace(CompileUnit, FileIndex);
+    if (!Inserted)
+      Iter->second = FileIndex;
+  }
+
+  // Get the current assigned index file for the given compile unit.
+  size_t getFileIndex(LVScopeCompileUnit *CompileUnit) {
+    LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit);
+    return Iter != IndexFiles.end() ? Iter->second : 0;
+  }
+
+  // For the given 'DIFile', generate a 1-based index to indicate the
+  // source file where the logical element is declared.
+  // The IR reader expects the indexes to be 1-based.
+  // Each compile unit, keeps track of the last assigned index.
+  size_t getOrCreateSourceID(const DIFile *File);
+
+  void addMD(const MDNode *MD, LVElement *Element) {
+    MDObjects.try_emplace(MD, Element);
+  }
+  LVElement *getElementForSeenMD(const MDNode *MD) const {
+    LVMDObjects::const_iterator Iter = MDObjects.find(MD);
+    return Iter != MDObjec...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list