[Lldb-commits] [lldb] [llvm] [NFC][DebugInfo][DWARF] Create new low-level dwarf library (PR #145081)

via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 20 10:42:44 PDT 2025


https://github.com/Sterling-Augustine created https://github.com/llvm/llvm-project/pull/145081

This is the culmination of a series of changes described in [1].
    
Although somewhat large by line count, it is almost entirely mechanical, creating a new library in DebugInfo/DWARF/LowLevel. This new library has very minimal dependencies, allowing it to be used from more places than the normal DebugInfo/DWARF library--in particular from MC.
    
I am happy to put it in another location, or to structure it differently if that makes sense. Some have suggested in BinaryFormat, but it is not a great fit there. But if that makes more sense to the reviewers, I can do that.
 
Another possibility would be to use pass-through headers to allow clients who don't care to depend only on DebugInfo/DWARF. This would be a much less invasive change, and perhaps easier for clients. But also a system that hides details.

Either way, I'm open.

1. https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2


>From bb6aaad973284f0f378301b576f55717a052675d Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Wed, 18 Jun 2025 10:35:05 -0700
Subject: [PATCH 1/4] Split Dwarf Expression printing into separate files

---
 lldb/source/Expression/DWARFExpression.cpp    |   3 +-
 lldb/source/Symbol/UnwindPlan.cpp             |   4 +-
 .../Symbol/PostfixExpressionTest.cpp          |   3 +-
 .../PdbFPOProgramToDWARFExpressionTests.cpp   |   3 +-
 .../llvm/DebugInfo/DWARF/DWARFExpression.h    |  58 ----
 .../DebugInfo/DWARF/DWARFExpressionPrinter.h  |  66 ++++
 llvm/lib/DebugInfo/DWARF/CMakeLists.txt       |   1 +
 llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp  |   4 +-
 llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp  |   3 +-
 llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp    |   3 +-
 llvm/lib/DebugInfo/DWARF/DWARFDie.cpp         |   3 +-
 llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp  | 284 ----------------
 .../DWARF/DWARFExpressionPrinter.cpp          | 310 ++++++++++++++++++
 .../LogicalView/Readers/LVDWARFReader.cpp     |   3 +-
 llvm/tools/llvm-objdump/SourcePrinter.cpp     |   3 +-
 .../DWARFExpressionCompactPrinterTest.cpp     |   3 +-
 16 files changed, 399 insertions(+), 355 deletions(-)
 create mode 100644 llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
 create mode 100644 llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp

diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 661324338e801..58f1b95b57041 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -37,6 +37,7 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -81,7 +82,7 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
   llvm::DIDumpOptions DumpOpts;
   DumpOpts.GetNameForDWARFReg = GetRegName;
   llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
-  llvm::DWARFExpressionPrinter::print(&E, s->AsRawOstream(), DumpOpts, nullptr);
+  llvm::printDwarfExpression(&E, s->AsRawOstream(), DumpOpts, nullptr);
 }
 
 RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index e9ac6b6cde295..eda57bd29b859 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -18,6 +18,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include <optional>
 
 using namespace lldb;
@@ -89,8 +90,7 @@ static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *threa
                              order_and_width->second);
     llvm::DWARFExpression E(data, order_and_width->second,
                             llvm::dwarf::DWARF32);
-    llvm::DWARFExpressionPrinter::print(&E, s.AsRawOstream(),
-                                        llvm::DIDumpOptions(), nullptr);
+    printDwarfExpression(&E, s.AsRawOstream(), llvm::DIDumpOptions(), nullptr);
   } else
     s.PutCString("dwarf-expr");
 }
diff --git a/lldb/unittests/Symbol/PostfixExpressionTest.cpp b/lldb/unittests/Symbol/PostfixExpressionTest.cpp
index 1e437da5133d9..23c24e67fb9c9 100644
--- a/lldb/unittests/Symbol/PostfixExpressionTest.cpp
+++ b/lldb/unittests/Symbol/PostfixExpressionTest.cpp
@@ -12,6 +12,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/raw_ostream.h"
 #include "gmock/gmock.h"
@@ -160,7 +161,7 @@ static std::string ParseAndGenerateDWARF(llvm::StringRef expr) {
   std::string result;
   llvm::raw_string_ostream os(result);
   llvm::DWARFExpression E(extractor, addr_size, llvm::dwarf::DWARF32);
-  llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);
+  llvm::printDwarfExpression(&E, os, llvm::DIDumpOptions(), nullptr);
   return result;
 }
 
diff --git a/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp b/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
index d746e04f8a9fc..8402ad935bdeb 100644
--- a/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
+++ b/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
@@ -17,6 +17,7 @@
 #include "lldb/Utility/StreamString.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -40,7 +41,7 @@ CheckValidProgramTranslation(llvm::StringRef fpo_program,
   std::string result;
   llvm::raw_string_ostream os(result);
   llvm::DWARFExpression E(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32);
-  llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);
+  llvm::printDwarfExpression(&E, os, llvm::DIDumpOptions(), nullptr);
 
   // actual check
   ASSERT_EQ(expected_dwarf_expression, result);
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
index 44432d3219111..d64150f7a67dd 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
@@ -77,7 +77,6 @@ class DWARFExpression {
 
   private:
     friend class DWARFExpression::iterator;
-    friend class DWARFExpressionPrinter;
     friend class DWARFVerifier;
 
     uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
@@ -156,7 +155,6 @@ class DWARFExpression {
 
   StringRef getData() const { return Data.getData(); }
 
-  friend class DWARFExpressionPrinter;
   friend class DWARFVerifier;
 
 private:
@@ -170,62 +168,6 @@ inline bool operator==(const DWARFExpression::iterator &LHS,
   return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
 }
 
-// This functionality is separated from the main data structure so that nothing
-// in DWARFExpression.cpp needs build-time dependencies on DWARFUnit or other
-// higher-level Dwarf structures. This approach creates better layering and
-// allows DWARFExpression to be used from code which can't have dependencies on
-// those higher-level structures.
-
-class DWARFUnit;
-struct DIDumpOptions;
-class raw_ostream;
-
-class DWARFExpressionPrinter {
-public:
-  /// Print a Dwarf expression/
-  /// \param E to be printed
-  /// \param OS to this stream
-  /// \param GetNameForDWARFReg callback to return dwarf register name
-  static void print(const DWARFExpression *E, raw_ostream &OS,
-                    DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH = false);
-
-  /// Print the expression in a format intended to be compact and useful to a
-  /// user, but not perfectly unambiguous, or capable of representing every
-  /// valid DWARF expression. Returns true if the expression was sucessfully
-  /// printed.
-  ///
-  /// \param E to be printed
-  /// \param OS to this stream
-  /// \param GetNameForDWARFReg callback to return dwarf register name
-  ///
-  /// \returns true if the expression was successfully printed
-  static bool printCompact(const DWARFExpression *E, raw_ostream &OS,
-                           std::function<StringRef(uint64_t RegNum, bool IsEH)>
-                               GetNameForDWARFReg = nullptr);
-
-  /// Pretty print a register opcode and operands.
-  /// \param U within the context of this Dwarf unit, if any.
-  /// \param OS to this stream
-  /// \param DumpOpts with these options
-  /// \param Opcode to print
-  /// \param Operands to the opcode
-  ///
-  /// returns true if the Op was successfully printed
-  static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
-                                    DIDumpOptions DumpOpts, uint8_t Opcode,
-                                    ArrayRef<uint64_t> Operands);
-
-private:
-  static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
-                      DIDumpOptions DumpOpts, const DWARFExpression *Expr,
-                      DWARFUnit *U);
-
-  static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
-                                     DIDumpOptions DumpOpts,
-                                     ArrayRef<uint64_t> Operands,
-                                     unsigned Operand);
-};
-
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
new file mode 100644
index 0000000000000..bd4e939027f7f
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
@@ -0,0 +1,66 @@
+//===--- DWARFExpressionPRinter.h - DWARF Expression Printing ---*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
+#define LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+// This functionality is separated from the main data structure so that nothing
+// in DWARFExpression.cpp needs build-time dependencies on DWARFUnit or other
+// higher-level Dwarf structures. This approach creates better layering and
+// allows DWARFExpression to be used from code which can't have dependencies on
+// those higher-level structures.
+
+class DWARFUnit;
+struct DIDumpOptions;
+class raw_ostream;
+
+  /// Print a Dwarf expression/
+  /// \param E to be printed
+  /// \param OS to this stream
+  /// \param GetNameForDWARFReg callback to return dwarf register name
+void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
+                          DIDumpOptions DumpOpts, DWARFUnit *U,
+                          bool IsEH = false);
+
+/// Print the expression in a format intended to be compact and useful to a
+/// user, but not perfectly unambiguous, or capable of representing every
+/// valid DWARF expression. Returns true if the expression was sucessfully
+/// printed.
+///
+/// \param E to be printed
+/// \param OS to this stream
+/// \param GetNameForDWARFReg callback to return dwarf register name
+///
+/// \returns true if the expression was successfully printed
+bool printDwarfExpressionCompact(
+    const DWARFExpression *E, raw_ostream &OS,
+    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
+        nullptr);
+
+/// Pretty print a register opcode and operands.
+/// \param U within the context of this Dwarf unit, if any.
+/// \param OS to this stream
+/// \param DumpOpts with these options
+/// \param Opcode to print
+/// \param Operands to the opcode
+///
+/// returns true if the Op was successfully printed
+bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
+                                  DIDumpOptions DumpOpts, uint8_t Opcode,
+                                  ArrayRef<uint64_t> Operands);
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
diff --git a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
index 86e74110b15ea..1bc21f56ad2fc 100644
--- a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
@@ -20,6 +20,7 @@ add_llvm_component_library(LLVMDebugInfoDWARF
   DWARFDebugRnglists.cpp
   DWARFDie.cpp
   DWARFExpression.cpp
+  DWARFExpressionPrinter.cpp
   DWARFFormValue.cpp
   DWARFGdbIndex.cpp
   DWARFListTable.cpp
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
index e52f671e4fa1c..e43d23cbced16 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
@@ -10,6 +10,7 @@
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Errc.h"
@@ -100,8 +101,7 @@ static void printOperand(raw_ostream &OS, const DIDumpOptions &DumpOpts,
   case CFIProgram::OT_Expression:
     assert(Instr.Expression && "missing DWARFExpression object");
     OS << " ";
-    DWARFExpressionPrinter::print(&Instr.Expression.value(), OS, DumpOpts,
-                                  nullptr);
+    printDwarfExpression(&Instr.Expression.value(), OS, DumpOpts, nullptr);
     break;
   }
 }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 9dff925073dbe..04e60a14472c8 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -16,6 +16,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Errc.h"
@@ -113,7 +114,7 @@ void UnwindLocation::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
     break;
   case DWARFExpr: {
     if (Expr)
-      DWARFExpressionPrinter::print(&(*Expr), OS, DumpOpts, nullptr);
+      printDwarfExpression(&Expr.value(), OS, DumpOpts, nullptr);
     break;
   }
   case Constant:
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index fc71be32fdd79..fab2ffa2dba26 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -12,6 +12,7 @@
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
@@ -117,7 +118,7 @@ static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
   if (U)
     Format = U->getFormat();
   DWARFExpression E(Extractor, AddressSize, Format);
-  DWARFExpressionPrinter::print(&E, OS, DumpOpts, U);
+  printDwarfExpression(&E, OS, DumpOpts, U);
 }
 
 bool DWARFLocationTable::dumpLocationList(
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 08dd9d30812d1..29e0373e80590 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -16,6 +16,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
@@ -99,7 +100,7 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
   DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
                      Ctx.isLittleEndian(), 0);
   DWARFExpression DE(Data, U->getAddressByteSize(), U->getFormParams().Format);
-  DWARFExpressionPrinter::print(&DE, OS, DumpOpts, U);
+  printDwarfExpression(&DE, OS, DumpOpts, U);
 }
 
 static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index 8255e013a2d79..a22727a0bad56 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -251,288 +251,4 @@ bool DWARFExpression::operator==(const DWARFExpression &RHS) const {
   return Data.getData() == RHS.Data.getData();
 }
 
-void DWARFExpressionPrinter::prettyPrintBaseTypeRef(DWARFUnit *U,
-                                                    raw_ostream &OS,
-                                                    DIDumpOptions DumpOpts,
-                                                    ArrayRef<uint64_t> Operands,
-                                                    unsigned Operand) {
-  assert(Operand < Operands.size() && "operand out of bounds");
-  if (!U) {
-    OS << format(" <base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
-    return;
-  }
-  auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
-  if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
-    OS << " (";
-    if (DumpOpts.Verbose)
-      OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
-    OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
-    if (auto Name = dwarf::toString(Die.find(dwarf::DW_AT_name)))
-      OS << " \"" << *Name << "\"";
-  } else {
-    OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
-  }
-}
-
-bool DWARFExpressionPrinter::prettyPrintRegisterOp(
-    DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode,
-    ArrayRef<uint64_t> Operands) {
-  if (!DumpOpts.GetNameForDWARFReg)
-    return false;
-
-  uint64_t DwarfRegNum;
-  unsigned OpNum = 0;
-
-  if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
-      Opcode == DW_OP_regval_type)
-    DwarfRegNum = Operands[OpNum++];
-  else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
-    DwarfRegNum = Opcode - DW_OP_breg0;
-  else
-    DwarfRegNum = Opcode - DW_OP_reg0;
-
-  auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
-  if (!RegName.empty()) {
-    if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
-        Opcode == DW_OP_bregx)
-      OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]);
-    else
-      OS << ' ' << RegName.data();
-
-    if (Opcode == DW_OP_regval_type)
-      prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
-    return true;
-  }
-
-  return false;
-}
-
-bool DWARFExpressionPrinter::printOp(const DWARFExpression::Operation *Op,
-                                     raw_ostream &OS, DIDumpOptions DumpOpts,
-                                     const DWARFExpression *Expr,
-                                     DWARFUnit *U) {
-  if (Op->Error) {
-    OS << "<decoding error>";
-    return false;
-  }
-
-  StringRef Name = OperationEncodingString(Op->Opcode);
-  assert(!Name.empty() && "DW_OP has no name!");
-  OS << Name;
-
-  if ((Op->Opcode >= DW_OP_breg0 && Op->Opcode <= DW_OP_breg31) ||
-      (Op->Opcode >= DW_OP_reg0 && Op->Opcode <= DW_OP_reg31) ||
-      Op->Opcode == DW_OP_bregx || Op->Opcode == DW_OP_regx ||
-      Op->Opcode == DW_OP_regval_type)
-    if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->Opcode, Op->Operands))
-      return true;
-
-  for (unsigned Operand = 0; Operand < Op->Desc.Op.size(); ++Operand) {
-    unsigned Size = Op->Desc.Op[Operand];
-    unsigned Signed = Size & DWARFExpression::Operation::SignBit;
-
-    if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
-      StringRef SubName =
-          SubOperationEncodingString(Op->Opcode, Op->Operands[Operand]);
-      assert(!SubName.empty() && "DW_OP SubOp has no name!");
-      OS << " " << SubName;
-    } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
-      // For DW_OP_convert the operand may be 0 to indicate that conversion to
-      // the generic type should be done. The same holds for DW_OP_reinterpret,
-      // which is currently not supported.
-      if (Op->Opcode == DW_OP_convert && Op->Operands[Operand] == 0)
-        OS << " 0x0";
-      else
-        prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->Operands, Operand);
-    } else if (Size == DWARFExpression::Operation::WasmLocationArg) {
-      assert(Operand == 1);
-      switch (Op->Operands[0]) {
-      case 0:
-      case 1:
-      case 2:
-      case 3: // global as uint32
-      case 4:
-        OS << format(" 0x%" PRIx64, Op->Operands[Operand]);
-        break;
-      default: assert(false);
-      }
-    } else if (Size == DWARFExpression::Operation::SizeBlock) {
-      uint64_t Offset = Op->Operands[Operand];
-      for (unsigned i = 0; i < Op->Operands[Operand - 1]; ++i)
-        OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
-    } else {
-      if (Signed)
-        OS << format(" %+" PRId64, (int64_t)Op->Operands[Operand]);
-      else if (Op->Opcode != DW_OP_entry_value &&
-               Op->Opcode != DW_OP_GNU_entry_value)
-        OS << format(" 0x%" PRIx64, Op->Operands[Operand]);
-    }
-  }
-  return true;
-}
-
-void DWARFExpressionPrinter::print(const DWARFExpression *E, raw_ostream &OS,
-                                   DIDumpOptions DumpOpts, DWARFUnit *U,
-                                   bool IsEH) {
-  uint32_t EntryValExprSize = 0;
-  uint64_t EntryValStartOffset = 0;
-  if (E->Data.getData().empty())
-    OS << "<empty>";
-
-  for (auto &Op : *E) {
-    DumpOpts.IsEH = IsEH;
-    if (!printOp(&Op, OS, DumpOpts, E, U)) {
-      uint64_t FailOffset = Op.getEndOffset();
-      while (FailOffset < E->Data.getData().size())
-        OS << format(" %02x", E->Data.getU8(&FailOffset));
-      return;
-    }
-
-    if (Op.getCode() == DW_OP_entry_value ||
-        Op.getCode() == DW_OP_GNU_entry_value) {
-      OS << "(";
-      EntryValExprSize = Op.getRawOperand(0);
-      EntryValStartOffset = Op.getEndOffset();
-      continue;
-    }
-
-    if (EntryValExprSize) {
-      EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
-      if (EntryValExprSize == 0)
-        OS << ")";
-    }
-
-    if (Op.getEndOffset() < E->Data.getData().size())
-      OS << ", ";
-  }
-}
-
-/// A user-facing string representation of a DWARF expression. This might be an
-/// Address expression, in which case it will be implicitly dereferenced, or a
-/// Value expression.
-struct PrintedExpr {
-  enum ExprKind {
-    Address,
-    Value,
-  };
-  ExprKind Kind;
-  SmallString<16> String;
-
-  PrintedExpr(ExprKind K = Address) : Kind(K) {}
-};
-
-static bool printCompactDWARFExpr(
-    raw_ostream &OS, DWARFExpression::iterator I,
-    const DWARFExpression::iterator E,
-    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
-        nullptr) {
-  SmallVector<PrintedExpr, 4> Stack;
-
-  while (I != E) {
-    const DWARFExpression::Operation &Op = *I;
-    uint8_t Opcode = Op.getCode();
-    switch (Opcode) {
-    case dwarf::DW_OP_regx: {
-      // DW_OP_regx: A register, with the register num given as an operand.
-      // Printed as the plain register name.
-      uint64_t DwarfRegNum = Op.getRawOperand(0);
-      auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
-      if (RegName.empty())
-        return false;
-      raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
-      S << RegName;
-      break;
-    }
-    case dwarf::DW_OP_bregx: {
-      int DwarfRegNum = Op.getRawOperand(0);
-      int64_t Offset = Op.getRawOperand(1);
-      auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
-      if (RegName.empty())
-        return false;
-      raw_svector_ostream S(Stack.emplace_back().String);
-      S << RegName;
-      if (Offset)
-        S << format("%+" PRId64, Offset);
-      break;
-    }
-    case dwarf::DW_OP_entry_value:
-    case dwarf::DW_OP_GNU_entry_value: {
-      // DW_OP_entry_value contains a sub-expression which must be rendered
-      // separately.
-      uint64_t SubExprLength = Op.getRawOperand(0);
-      DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
-      ++I;
-      raw_svector_ostream S(Stack.emplace_back().String);
-      S << "entry(";
-      printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
-      S << ")";
-      I = SubExprEnd;
-      continue;
-    }
-    case dwarf::DW_OP_stack_value: {
-      // The top stack entry should be treated as the actual value of tne
-      // variable, rather than the address of the variable in memory.
-      assert(!Stack.empty());
-      Stack.back().Kind = PrintedExpr::Value;
-      break;
-    }
-    case dwarf::DW_OP_nop: {
-      break;
-    }
-    case dwarf::DW_OP_LLVM_user: {
-      assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
-      break;
-    }
-    default:
-      if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
-        // DW_OP_reg<N>: A register, with the register num implied by the
-        // opcode. Printed as the plain register name.
-        uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
-        auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
-        if (RegName.empty())
-          return false;
-        raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
-        S << RegName;
-      } else if (Opcode >= dwarf::DW_OP_breg0 &&
-                 Opcode <= dwarf::DW_OP_breg31) {
-        int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
-        int64_t Offset = Op.getRawOperand(0);
-        auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
-        if (RegName.empty())
-          return false;
-        raw_svector_ostream S(Stack.emplace_back().String);
-        S << RegName;
-        if (Offset)
-          S << format("%+" PRId64, Offset);
-      } else {
-        // If we hit an unknown operand, we don't know its effect on the stack,
-        // so bail out on the whole expression.
-        OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
-           << (int)Opcode << ")>";
-        return false;
-      }
-      break;
-    }
-    ++I;
-  }
-
-  if (Stack.size() != 1) {
-    OS << "<stack of size " << Stack.size() << ", expected 1>";
-    return false;
-  }
-
-  if (Stack.front().Kind == PrintedExpr::Address)
-    OS << "[" << Stack.front().String << "]";
-  else
-    OS << Stack.front().String;
-
-  return true;
-}
-
-bool DWARFExpressionPrinter::printCompact(
-    const DWARFExpression *E, raw_ostream &OS,
-    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
-  return printCompactDWARFExpr(OS, E->begin(), E->end(), GetNameForDWARFReg);
-}
-
 } // namespace llvm
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
new file mode 100644
index 0000000000000..839ee03d37462
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
@@ -0,0 +1,310 @@
+//===-- DWARFExpression.cpp -----------------------------------------------===//
+//
+// 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/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/Support/Format.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+
+namespace llvm {
+
+typedef DWARFExpression::Operation Op;
+typedef Op::Description Desc;
+
+static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
+                                   DIDumpOptions DumpOpts,
+                                   ArrayRef<uint64_t> Operands,
+                                   unsigned Operand) {
+  assert(Operand < Operands.size() && "operand out of bounds");
+  if (!U) {
+    OS << format(" <base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
+    return;
+  }
+  auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
+  if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
+    OS << " (";
+    if (DumpOpts.Verbose)
+      OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
+    OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
+    if (auto Name = dwarf::toString(Die.find(dwarf::DW_AT_name)))
+      OS << " \"" << *Name << "\"";
+  } else {
+    OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
+  }
+}
+
+static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
+                    DIDumpOptions DumpOpts, const DWARFExpression *Expr,
+                    DWARFUnit *U) {
+  if (Op->isError()) {
+    OS << "<decoding error>";
+    return false;
+  }
+
+  StringRef Name = OperationEncodingString(Op->getCode());
+  assert(!Name.empty() && "DW_OP has no name!");
+  OS << Name;
+
+  if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
+      (Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
+      Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
+      Op->getCode() == DW_OP_regval_type)
+    if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
+                              Op->getRawOperands()))
+      return true;
+
+  for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
+       ++Operand) {
+    unsigned Size = Op->getDescription().Op[Operand];
+    unsigned Signed = Size & DWARFExpression::Operation::SignBit;
+
+    if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
+      StringRef SubName =
+          SubOperationEncodingString(Op->getCode(), Op->getRawOperand(Operand));
+      assert(!SubName.empty() && "DW_OP SubOp has no name!");
+      OS << " " << SubName;
+    } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
+      // For DW_OP_convert the operand may be 0 to indicate that conversion to
+      // the generic type should be done. The same holds for DW_OP_reinterpret,
+      // which is currently not supported.
+      if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
+        OS << " 0x0";
+      else
+        prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(), Operand);
+    } else if (Size == DWARFExpression::Operation::WasmLocationArg) {
+      assert(Operand == 1);
+      switch (Op->getRawOperand(0)) {
+      case 0:
+      case 1:
+      case 2:
+      case 3: // global as uint32
+      case 4:
+        OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
+        break;
+      default: assert(false);
+      }
+    } else if (Size == DWARFExpression::Operation::SizeBlock) {
+      uint64_t Offset = Op->getRawOperand(Operand);
+      for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
+        OS << format(" 0x%02x",
+                     static_cast<uint8_t>(Expr->getData()[Offset++]));
+    } else {
+      if (Signed)
+        OS << format(" %+" PRId64, (int64_t)Op->getRawOperand(Operand));
+      else if (Op->getCode() != DW_OP_entry_value &&
+               Op->getCode() != DW_OP_GNU_entry_value)
+        OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
+    }
+  }
+  return true;
+}
+
+void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
+                          DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH) {
+  uint32_t EntryValExprSize = 0;
+  uint64_t EntryValStartOffset = 0;
+  if (E->getData().empty())
+    OS << "<empty>";
+
+  for (auto &Op : *E) {
+    DumpOpts.IsEH = IsEH;
+    if (!printOp(&Op, OS, DumpOpts, E, U)) {
+      uint64_t FailOffset = Op.getEndOffset();
+      while (FailOffset < E->getData().size())
+        OS << format(" %02x", static_cast<uint8_t>(E->getData()[FailOffset++]));
+      return;
+    }
+
+    if (Op.getCode() == DW_OP_entry_value ||
+        Op.getCode() == DW_OP_GNU_entry_value) {
+      OS << "(";
+      EntryValExprSize = Op.getRawOperand(0);
+      EntryValStartOffset = Op.getEndOffset();
+      continue;
+    }
+
+    if (EntryValExprSize) {
+      EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
+      if (EntryValExprSize == 0)
+        OS << ")";
+    }
+
+    if (Op.getEndOffset() < E->getData().size())
+      OS << ", ";
+  }
+}
+
+/// A user-facing string representation of a DWARF expression. This might be an
+/// Address expression, in which case it will be implicitly dereferenced, or a
+/// Value expression.
+struct PrintedExpr {
+  enum ExprKind {
+    Address,
+    Value,
+  };
+  ExprKind Kind;
+  SmallString<16> String;
+
+  PrintedExpr(ExprKind K = Address) : Kind(K) {}
+};
+
+static bool printCompactDWARFExpr(
+    raw_ostream &OS, DWARFExpression::iterator I,
+    const DWARFExpression::iterator E,
+    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
+        nullptr) {
+  SmallVector<PrintedExpr, 4> Stack;
+
+  while (I != E) {
+    const DWARFExpression::Operation &Op = *I;
+    uint8_t Opcode = Op.getCode();
+    switch (Opcode) {
+    case dwarf::DW_OP_regx: {
+      // DW_OP_regx: A register, with the register num given as an operand.
+      // Printed as the plain register name.
+      uint64_t DwarfRegNum = Op.getRawOperand(0);
+      auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+      if (RegName.empty())
+        return false;
+      raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+      S << RegName;
+      break;
+    }
+    case dwarf::DW_OP_bregx: {
+      int DwarfRegNum = Op.getRawOperand(0);
+      int64_t Offset = Op.getRawOperand(1);
+      auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+      if (RegName.empty())
+        return false;
+      raw_svector_ostream S(Stack.emplace_back().String);
+      S << RegName;
+      if (Offset)
+        S << format("%+" PRId64, Offset);
+      break;
+    }
+    case dwarf::DW_OP_entry_value:
+    case dwarf::DW_OP_GNU_entry_value: {
+      // DW_OP_entry_value contains a sub-expression which must be rendered
+      // separately.
+      uint64_t SubExprLength = Op.getRawOperand(0);
+      DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
+      ++I;
+      raw_svector_ostream S(Stack.emplace_back().String);
+      S << "entry(";
+      printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
+      S << ")";
+      I = SubExprEnd;
+      continue;
+    }
+    case dwarf::DW_OP_stack_value: {
+      // The top stack entry should be treated as the actual value of tne
+      // variable, rather than the address of the variable in memory.
+      assert(!Stack.empty());
+      Stack.back().Kind = PrintedExpr::Value;
+      break;
+    }
+    case dwarf::DW_OP_nop: {
+      break;
+    }
+    case dwarf::DW_OP_LLVM_user: {
+      assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
+      break;
+    }
+    default:
+      if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
+        // DW_OP_reg<N>: A register, with the register num implied by the
+        // opcode. Printed as the plain register name.
+        uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
+        auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+        if (RegName.empty())
+          return false;
+        raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+        S << RegName;
+      } else if (Opcode >= dwarf::DW_OP_breg0 &&
+                 Opcode <= dwarf::DW_OP_breg31) {
+        int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
+        int64_t Offset = Op.getRawOperand(0);
+        auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+        if (RegName.empty())
+          return false;
+        raw_svector_ostream S(Stack.emplace_back().String);
+        S << RegName;
+        if (Offset)
+          S << format("%+" PRId64, Offset);
+      } else {
+        // If we hit an unknown operand, we don't know its effect on the stack,
+        // so bail out on the whole expression.
+        OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
+           << (int)Opcode << ")>";
+        return false;
+      }
+      break;
+    }
+    ++I;
+  }
+
+  if (Stack.size() != 1) {
+    OS << "<stack of size " << Stack.size() << ", expected 1>";
+    return false;
+  }
+
+  if (Stack.front().Kind == PrintedExpr::Address)
+    OS << "[" << Stack.front().String << "]";
+  else
+    OS << Stack.front().String;
+
+  return true;
+}
+
+bool printDwarfExpressionCompact(
+    const DWARFExpression *E, raw_ostream &OS,
+    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
+  return printCompactDWARFExpr(OS, E->begin(), E->end(), GetNameForDWARFReg);
+}
+
+bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
+                           DIDumpOptions DumpOpts, uint8_t Opcode,
+                           ArrayRef<uint64_t> Operands) {
+  if (!DumpOpts.GetNameForDWARFReg)
+    return false;
+
+  uint64_t DwarfRegNum;
+  unsigned OpNum = 0;
+
+  if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
+      Opcode == DW_OP_regval_type)
+    DwarfRegNum = Operands[OpNum++];
+  else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
+    DwarfRegNum = Opcode - DW_OP_breg0;
+  else
+    DwarfRegNum = Opcode - DW_OP_reg0;
+
+  auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
+  if (!RegName.empty()) {
+    if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
+        Opcode == DW_OP_bregx)
+      OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]);
+    else
+      OS << ' ' << RegName.data();
+
+    if (Opcode == DW_OP_regval_type)
+      prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
+    return true;
+  }
+
+  return false;
+}
+
+} // namespace llvm
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
index 7ff96ae90a7fd..1c5a41867c0d9 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -15,6 +15,7 @@
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
@@ -592,7 +593,7 @@ std::string LVDWARFReader::getRegisterName(LVSmall Opcode,
     return {};
   };
   DumpOpts.GetNameForDWARFReg = GetRegName;
-  DWARFExpressionPrinter::prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts,
+  prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts,
                                                 Opcode, Operands);
   return Stream.str();
 }
diff --git a/llvm/tools/llvm-objdump/SourcePrinter.cpp b/llvm/tools/llvm-objdump/SourcePrinter.cpp
index bf3363795a4d9..ab3352b0f418b 100644
--- a/llvm/tools/llvm-objdump/SourcePrinter.cpp
+++ b/llvm/tools/llvm-objdump/SourcePrinter.cpp
@@ -16,6 +16,7 @@
 #include "llvm-objdump.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/FormatVariadic.h"
 
 #define DEBUG_TYPE "objdump"
@@ -45,7 +46,7 @@ void LiveVariable::print(raw_ostream &OS, const MCRegisterInfo &MRI) const {
     return {};
   };
 
-  DWARFExpressionPrinter::printCompact(&Expression, OS, GetRegName);
+  printDwarfExpressionCompact(&Expression, OS, GetRegName);
 }
 
 void LiveVariablePrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
index 9225ab0125f2f..a6972e004046c 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
@@ -11,6 +11,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/MC/MCInstrInfo.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/TargetRegistry.h"
@@ -70,7 +71,7 @@ void DWARFExpressionCompactPrinterTest::TestExprPrinter(
     return {};
   };
 
-  DWARFExpressionPrinter::printCompact(&Expr, OS, GetRegName);
+  printDwarfExpressionCompact(&Expr, OS, GetRegName);
   EXPECT_EQ(OS.str(), Expected);
 }
 

>From 1e93d1f1c27807651579d09e958c6a27ff912af7 Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Wed, 18 Jun 2025 14:29:11 -0700
Subject: [PATCH 2/4] [NFC][DebugInfo][DWARF] Create new low-level dwarf
 library

This is the culmination of a series of changes described in [1].

Although somewhat large by line count, it is almost entirely mechanical,
creating a new library in DebugInfo/DWARF/LowLevel. This new library
has very minimal dependencies, allowing it to be used from more places
than the normal DebugInfo/DWARF library, which depends on Object files,
target readers, and additional infrastructure.

I am happy to put it in another location, or to structure it differently
if that makes sense. Some have suggested in BinaryFormat, but that library
is exclusively standardized defines and bit. But if that makes more sense
to the reviewers, I can do that.

1. https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2
---
 bolt/include/bolt/Core/DIEBuilder.h                 |  2 +-
 bolt/lib/Core/CMakeLists.txt                        |  1 +
 bolt/lib/Core/DIEBuilder.cpp                        |  2 +-
 bolt/lib/Core/DebugNames.cpp                        |  2 +-
 bolt/lib/Rewrite/CMakeLists.txt                     |  1 +
 bolt/lib/Rewrite/DWARFRewriter.cpp                  |  2 +-
 lldb/source/Expression/DWARFExpression.cpp          |  2 +-
 lldb/source/Symbol/UnwindPlan.cpp                   |  2 +-
 lldb/unittests/Symbol/PostfixExpressionTest.cpp     |  2 +-
 .../PdbFPOProgramToDWARFExpressionTests.cpp         |  2 +-
 llvm/include/llvm/DWARFLinker/AddressesMap.h        |  2 +-
 llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h |  2 +-
 llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h     |  2 +-
 llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h |  2 +-
 .../llvm/DebugInfo/DWARF/DWARFDataExtractor.h       |  2 +-
 llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h |  4 ++--
 .../llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h   |  2 +-
 llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h   |  2 +-
 .../DWARF/{ => LowLevel}/DWARFCFIProgram.h          |  2 +-
 .../DWARF/{ => LowLevel}/DWARFDataExtractorSimple.h |  0
 .../DWARF/{ => LowLevel}/DWARFExpression.h          |  0
 llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt          |  1 +
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp          |  2 +-
 llvm/lib/DWARFLinker/Classic/CMakeLists.txt         |  1 +
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp        |  2 +-
 .../DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp  |  2 +-
 llvm/lib/DebugInfo/DWARF/CMakeLists.txt             |  5 +++--
 llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp        |  2 +-
 llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp        |  4 ++--
 llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp          |  2 +-
 llvm/lib/DebugInfo/DWARF/DWARFDie.cpp               |  2 +-
 llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp |  2 +-
 llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp              |  2 +-
 llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp          |  2 +-
 llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt    | 13 +++++++++++++
 .../DWARF/{ => LowLevel}/DWARFCFIProgram.cpp        |  2 +-
 .../DWARF/{ => LowLevel}/DWARFExpression.cpp        |  2 +-
 .../DebugInfo/LogicalView/Readers/LVDWARFReader.cpp |  2 +-
 llvm/lib/ProfileData/CMakeLists.txt                 |  1 +
 llvm/lib/ProfileData/InstrProfCorrelator.cpp        |  2 +-
 llvm/tools/dsymutil/CMakeLists.txt                  |  1 +
 llvm/tools/dsymutil/DwarfLinkerForBinary.cpp        |  2 +-
 llvm/tools/llvm-dwarfdump/CMakeLists.txt            |  1 +
 llvm/tools/llvm-dwarfdump/Statistics.cpp            |  2 +-
 llvm/tools/llvm-dwarfutil/CMakeLists.txt            |  1 +
 llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp       |  2 +-
 llvm/tools/llvm-objdump/CMakeLists.txt              |  1 +
 llvm/tools/llvm-objdump/SourcePrinter.cpp           |  2 +-
 llvm/unittests/DebugInfo/DWARF/CMakeLists.txt       |  1 +
 .../DWARF/DWARFExpressionCompactPrinterTest.cpp     |  2 +-
 .../DWARF/DWARFExpressionCopyBytesTest.cpp          |  2 +-
 51 files changed, 65 insertions(+), 41 deletions(-)
 rename llvm/include/llvm/DebugInfo/DWARF/{ => LowLevel}/DWARFCFIProgram.h (98%)
 rename llvm/include/llvm/DebugInfo/DWARF/{ => LowLevel}/DWARFDataExtractorSimple.h (100%)
 rename llvm/include/llvm/DebugInfo/DWARF/{ => LowLevel}/DWARFExpression.h (100%)
 create mode 100644 llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
 rename llvm/lib/DebugInfo/DWARF/{ => LowLevel}/DWARFCFIProgram.cpp (99%)
 rename llvm/lib/DebugInfo/DWARF/{ => LowLevel}/DWARFExpression.cpp (99%)

diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h
index 32e455ad3030a..73f44c5006521 100644
--- a/bolt/include/bolt/Core/DIEBuilder.h
+++ b/bolt/include/bolt/Core/DIEBuilder.h
@@ -20,7 +20,7 @@
 #include "llvm/CodeGen/DIE.h"
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
 #include "llvm/Support/Allocator.h"
 
diff --git a/bolt/lib/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt
index 8c1f5d0bb37b5..fc72dc023c590 100644
--- a/bolt/lib/Core/CMakeLists.txt
+++ b/bolt/lib/Core/CMakeLists.txt
@@ -1,5 +1,6 @@
 set(LLVM_LINK_COMPONENTS
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   Demangle
   MC
   MCDisassembler
diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp
index d36dbb3459249..e94fffbf4800d 100644
--- a/bolt/lib/Core/DIEBuilder.cpp
+++ b/bolt/lib/Core/DIEBuilder.cpp
@@ -14,7 +14,7 @@
 #include "llvm/CodeGen/DIE.h"
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp
index aa1c8f3d42d4b..9e3c0f9c79983 100644
--- a/bolt/lib/Core/DebugNames.cpp
+++ b/bolt/lib/Core/DebugNames.cpp
@@ -8,7 +8,7 @@
 
 #include "bolt/Core/DebugNames.h"
 #include "bolt/Core/BinaryContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/Support/EndianStream.h"
 #include "llvm/Support/LEB128.h"
diff --git a/bolt/lib/Rewrite/CMakeLists.txt b/bolt/lib/Rewrite/CMakeLists.txt
index c83cf36982167..775036063dd5a 100644
--- a/bolt/lib/Rewrite/CMakeLists.txt
+++ b/bolt/lib/Rewrite/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS
   Core
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   JITLink
   MC
   Object
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 9c9bdefe08429..a55a3f76b1576 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -24,7 +24,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 58f1b95b57041..57e368b72f56a 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -36,7 +36,7 @@
 #include "lldb/Target/StackID.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 
 using namespace lldb;
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index eda57bd29b859..3739d8cf64f82 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -17,7 +17,7 @@
 #include "lldb/Utility/Log.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include <optional>
 
diff --git a/lldb/unittests/Symbol/PostfixExpressionTest.cpp b/lldb/unittests/Symbol/PostfixExpressionTest.cpp
index 23c24e67fb9c9..c3ce5c59748b4 100644
--- a/lldb/unittests/Symbol/PostfixExpressionTest.cpp
+++ b/lldb/unittests/Symbol/PostfixExpressionTest.cpp
@@ -11,7 +11,7 @@
 #include "lldb/Utility/StreamString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/raw_ostream.h"
diff --git a/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp b/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
index 8402ad935bdeb..9fa1fad8f1ef9 100644
--- a/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
+++ b/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
@@ -16,7 +16,7 @@
 #include "lldb/Utility/StreamBuffer.h"
 #include "lldb/Utility/StreamString.h"
 #include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 
 using namespace lldb;
diff --git a/llvm/include/llvm/DWARFLinker/AddressesMap.h b/llvm/include/llvm/DWARFLinker/AddressesMap.h
index a232aafadc5ce..91321d5aa4471 100644
--- a/llvm/include/llvm/DWARFLinker/AddressesMap.h
+++ b/llvm/include/llvm/DWARFLinker/AddressesMap.h
@@ -12,7 +12,7 @@
 #include "llvm/ADT/AddressRanges.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
 #include <cstdint>
 
diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
index b12d96812108e..5b9535380aebf 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
@@ -20,7 +20,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include <map>
 
diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
index 17a18c4b029f4..99aeb0df076e6 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
@@ -16,7 +16,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include <map>
 namespace llvm {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h
index 32e8247ac4c22..75fa2d83cf549 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h
@@ -9,7 +9,7 @@
 #ifndef LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
 #define LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
 
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
 
 namespace llvm {
 
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
index 005ccd208cdda..0f9a549108540 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
@@ -10,7 +10,7 @@
 #define LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H
 
 #include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractorSimple.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index 051ea6e11e351..4207d8f5ab3e8 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -12,8 +12,8 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/iterator.h"
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
 #include "llvm/TargetParser/Triple.h"
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
index bd4e939027f7f..4aec7e55cf152 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
@@ -11,7 +11,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 
 namespace llvm {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
index 8e1b9589a5d76..0c6d6d529e351 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
@@ -14,7 +14,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
 #include "llvm/Support/Compiler.h"
 #include <cstdint>
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIProgram.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
similarity index 98%
rename from llvm/include/llvm/DebugInfo/DWARF/DWARFCFIProgram.h
rename to llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
index ad7358c28f16b..f7470765512d4 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIProgram.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
@@ -13,7 +13,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
 #include "llvm/TargetParser/Triple.h"
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractorSimple.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h
similarity index 100%
rename from llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractorSimple.h
rename to llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
similarity index 100%
rename from llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
rename to llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
diff --git a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
index 0fe4b905831ff..34969d7524890 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
@@ -38,6 +38,7 @@ add_llvm_component_library(LLVMAsmPrinter
   Core
   DebugInfoCodeView
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   MC
   MCParser
   Remarks
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 0edfca78b0886..ca419a8db18ae 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -32,7 +32,7 @@
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/Function.h"
diff --git a/llvm/lib/DWARFLinker/Classic/CMakeLists.txt b/llvm/lib/DWARFLinker/Classic/CMakeLists.txt
index 5d3b259e4a33a..4e5cb3c6dfb51 100644
--- a/llvm/lib/DWARFLinker/Classic/CMakeLists.txt
+++ b/llvm/lib/DWARFLinker/Classic/CMakeLists.txt
@@ -19,6 +19,7 @@ add_llvm_component_library(LLVMDWARFLinkerClassic
   CodeGen
   CodeGenTypes
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   DWARFLinker
   MC
   Object
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index ae4cc6d85c120..2ab6fd13add7e 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -23,7 +23,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
index 66bf158e60f1d..027363aa394e0 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
@@ -10,7 +10,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/FormatVariadic.h"
 
 namespace llvm {
diff --git a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
index 1bc21f56ad2fc..ce426aeba3f3f 100644
--- a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
@@ -1,9 +1,10 @@
+add_subdirectory(LowLevel)
+
 add_llvm_component_library(LLVMDebugInfoDWARF
   DWARFAbbreviationDeclaration.cpp
   DWARFAddressRange.cpp
   DWARFAcceleratorTable.cpp
   DWARFCFIPrinter.cpp
-  DWARFCFIProgram.cpp
   DWARFCompileUnit.cpp
   DWARFContext.cpp
   DWARFDebugAbbrev.cpp
@@ -19,7 +20,6 @@ add_llvm_component_library(LLVMDebugInfoDWARF
   DWARFDebugRangeList.cpp
   DWARFDebugRnglists.cpp
   DWARFDie.cpp
-  DWARFExpression.cpp
   DWARFExpressionPrinter.cpp
   DWARFFormValue.cpp
   DWARFGdbIndex.cpp
@@ -36,6 +36,7 @@ add_llvm_component_library(LLVMDebugInfoDWARF
 
   LINK_COMPONENTS
   BinaryFormat
+  DebugInfoDWARFLowLevel
   Object
   Support
   TargetParser
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
index e43d23cbced16..4542f70314d06 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
@@ -8,7 +8,7 @@
 
 #include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
 #include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/Compiler.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 04e60a14472c8..b7e73bce21e68 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -13,9 +13,9 @@
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataExtractor.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index fab2ffa2dba26..682be1d828e41 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -11,7 +11,7 @@
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 29e0373e80590..abe271a734655 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -15,7 +15,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
index 839ee03d37462..eadf15f4ed6f1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
@@ -9,7 +9,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Format.h"
 #include <cassert>
 #include <cstdint>
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index d719a47c84072..c7be09e5c3c3a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -19,7 +19,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFListTable.h"
 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index c12786cac8686..77fd178ed3886 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -19,7 +19,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
new file mode 100644
index 0000000000000..764be9601cea9
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_llvm_component_library(LLVMDebugInfoDWARFLowLevel
+  DWARFCFIProgram.cpp
+  DWARFExpression.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF/LowLevel
+
+  // This code should have almost no dependencies. Anything that needs
+  // more should use the higher-level DebugInfo/DWARF/ library.
+  LINK_COMPONENTS
+  BinaryFormat
+  Support
+  )
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCFIProgram.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
similarity index 99%
rename from llvm/lib/DebugInfo/DWARF/DWARFCFIProgram.cpp
rename to llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
index 365b26b98a1e3..868194d917f39 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCFIProgram.cpp
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
 #include "llvm/Support/Compiler.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
similarity index 99%
rename from llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
rename to llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
index a22727a0bad56..fae4c51e0af01 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
 #include "llvm/Support/Format.h"
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
index 1c5a41867c0d9..f99bfdfb3283f 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -14,7 +14,7 @@
 #include "llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
diff --git a/llvm/lib/ProfileData/CMakeLists.txt b/llvm/lib/ProfileData/CMakeLists.txt
index d26af1c3d5547..c2366dc0ae03e 100644
--- a/llvm/lib/ProfileData/CMakeLists.txt
+++ b/llvm/lib/ProfileData/CMakeLists.txt
@@ -35,6 +35,7 @@ add_llvm_component_library(LLVMProfileData
   Demangle
   Symbolize
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   TargetParser
   )
 
diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index d92107f93dc56..8ad66be24a212 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -10,7 +10,7 @@
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt
index 366b63b2a8695..d3cdbe466de08 100644
--- a/llvm/tools/dsymutil/CMakeLists.txt
+++ b/llvm/tools/dsymutil/CMakeLists.txt
@@ -15,6 +15,7 @@ set(LLVM_LINK_COMPONENTS
   DWARFLinkerClassic
   DWARFLinkerParallel
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   MC
   Object
   Option
diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
index e88e076dca996..9589f7d0d132c 100644
--- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -39,7 +39,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
diff --git a/llvm/tools/llvm-dwarfdump/CMakeLists.txt b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
index 7c68aaac05d98..aeb1b8f14d830 100644
--- a/llvm/tools/llvm-dwarfdump/CMakeLists.txt
+++ b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
@@ -1,5 +1,6 @@
 set(LLVM_LINK_COMPONENTS
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   AllTargetsDescs
   AllTargetsInfos
   MC
diff --git a/llvm/tools/llvm-dwarfdump/Statistics.cpp b/llvm/tools/llvm-dwarfdump/Statistics.cpp
index af9a93ad35b9c..f92b2b55fa8dc 100644
--- a/llvm/tools/llvm-dwarfdump/Statistics.cpp
+++ b/llvm/tools/llvm-dwarfdump/Statistics.cpp
@@ -12,7 +12,7 @@
 #include "llvm/ADT/StringSet.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/JSON.h"
 
diff --git a/llvm/tools/llvm-dwarfutil/CMakeLists.txt b/llvm/tools/llvm-dwarfutil/CMakeLists.txt
index 23a526782dd7b..88335928b68dd 100644
--- a/llvm/tools/llvm-dwarfutil/CMakeLists.txt
+++ b/llvm/tools/llvm-dwarfutil/CMakeLists.txt
@@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
   DWARFLinkerClassic
   DWARFLinkerParallel
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   MC
   ObjCopy
   Object
diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
index 285dcf75ecd9d..ccc1324bc66d7 100644
--- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
+++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
@@ -13,7 +13,7 @@
 #include "llvm/DWARFLinker/Classic/DWARFStreamer.h"
 #include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Object/ObjectFile.h"
 #include <memory>
 #include <vector>
diff --git a/llvm/tools/llvm-objdump/CMakeLists.txt b/llvm/tools/llvm-objdump/CMakeLists.txt
index 0306736388979..7e3197f0a0bd3 100644
--- a/llvm/tools/llvm-objdump/CMakeLists.txt
+++ b/llvm/tools/llvm-objdump/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
   BinaryFormat
   DebugInfoBTF
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   Demangle
   MC
   MCDisassembler
diff --git a/llvm/tools/llvm-objdump/SourcePrinter.cpp b/llvm/tools/llvm-objdump/SourcePrinter.cpp
index ab3352b0f418b..001a48bd8e9ff 100644
--- a/llvm/tools/llvm-objdump/SourcePrinter.cpp
+++ b/llvm/tools/llvm-objdump/SourcePrinter.cpp
@@ -15,7 +15,7 @@
 #include "SourcePrinter.h"
 #include "llvm-objdump.h"
 #include "llvm/ADT/SmallSet.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/Support/FormatVariadic.h"
 
diff --git a/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt b/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
index 0c5b3f28ca3d5..dc8240f904b4c 100644
--- a/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
+++ b/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
   BinaryFormat
   CodeGenTypes
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   MC
   Object
   ObjectYAML
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
index a6972e004046c..e45b8dd915f4e 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
@@ -10,7 +10,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
 #include "llvm/MC/MCInstrInfo.h"
 #include "llvm/MC/MCRegisterInfo.h"
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp
index ec9c0dddcbc0c..78d383ed0b22e 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp
@@ -11,7 +11,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCCodeEmitter.h"

>From e2793172be8e16c15e1141beb3b50c200dcb671c Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Wed, 18 Jun 2025 15:41:55 -0700
Subject: [PATCH 3/4] Cleanup some layering issues exposed by the new library.

---
 .../llvm/DebugInfo/DWARF/DWARFDataExtractor.h |   2 +-
 .../DWARF/LowLevel/DWARFCFIProgram.h          | 148 +++++++++++++++++-
 .../DWARF/LowLevel/DWARFCFIProgram.cpp        | 145 +----------------
 .../DWARF/LowLevel/DWARFExpression.cpp        |   1 -
 .../llvm-project-overlay/llvm/BUILD.bazel     |  14 ++
 5 files changed, 161 insertions(+), 149 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
index 0f9a549108540..def291046c7db 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
@@ -10,10 +10,10 @@
 #define LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H
 
 #include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
 #include "llvm/Support/Compiler.h"
 
 namespace llvm {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
index f7470765512d4..56422d3bf86ef 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
@@ -12,7 +12,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/iterator.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
 #include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
@@ -78,8 +78,150 @@ class CFIProgram {
   /// starting at *Offset and ending at EndOffset. *Offset is updated
   /// to EndOffset upon successful parsing, or indicates the offset
   /// where a problem occurred in case an error is returned.
-  LLVM_ABI Error parse(DWARFDataExtractor Data, uint64_t *Offset,
-                       uint64_t EndOffset);
+  template <typename T>
+  LLVM_ABI Error parse(DWARFDataExtractorBase<T> &Data, uint64_t *Offset,
+                       uint64_t EndOffset) {
+    // See DWARF standard v3, section 7.23
+    const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
+    const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
+
+    DataExtractor::Cursor C(*Offset);
+    while (C && C.tell() < EndOffset) {
+      uint8_t Opcode = Data.getRelocatedValue(C, 1);
+      if (!C)
+        break;
+
+      // Some instructions have a primary opcode encoded in the top bits.
+      if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
+        // If it's a primary opcode, the first operand is encoded in the
+        // bottom bits of the opcode itself.
+        uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
+        switch (Primary) {
+        case DW_CFA_advance_loc:
+        case DW_CFA_restore:
+          addInstruction(Primary, Op1);
+          break;
+        case DW_CFA_offset:
+          addInstruction(Primary, Op1, Data.getULEB128(C));
+          break;
+        default:
+          llvm_unreachable("invalid primary CFI opcode");
+        }
+        continue;
+      }
+
+      // Extended opcode - its value is Opcode itself.
+      switch (Opcode) {
+      default:
+        return createStringError(errc::illegal_byte_sequence,
+                                 "invalid extended CFI opcode 0x%" PRIx8,
+                                 Opcode);
+      case DW_CFA_nop:
+      case DW_CFA_remember_state:
+      case DW_CFA_restore_state:
+      case DW_CFA_GNU_window_save:
+      case DW_CFA_AARCH64_negate_ra_state_with_pc:
+        // No operands
+        addInstruction(Opcode);
+        break;
+      case DW_CFA_set_loc:
+        // Operands: Address
+        addInstruction(Opcode, Data.getRelocatedAddress(C));
+        break;
+      case DW_CFA_advance_loc1:
+        // Operands: 1-byte delta
+        addInstruction(Opcode, Data.getRelocatedValue(C, 1));
+        break;
+      case DW_CFA_advance_loc2:
+        // Operands: 2-byte delta
+        addInstruction(Opcode, Data.getRelocatedValue(C, 2));
+        break;
+      case DW_CFA_advance_loc4:
+        // Operands: 4-byte delta
+        addInstruction(Opcode, Data.getRelocatedValue(C, 4));
+        break;
+      case DW_CFA_restore_extended:
+      case DW_CFA_undefined:
+      case DW_CFA_same_value:
+      case DW_CFA_def_cfa_register:
+      case DW_CFA_def_cfa_offset:
+      case DW_CFA_GNU_args_size:
+        // Operands: ULEB128
+        addInstruction(Opcode, Data.getULEB128(C));
+        break;
+      case DW_CFA_def_cfa_offset_sf:
+        // Operands: SLEB128
+        addInstruction(Opcode, Data.getSLEB128(C));
+        break;
+      case DW_CFA_LLVM_def_aspace_cfa:
+      case DW_CFA_LLVM_def_aspace_cfa_sf: {
+        auto RegNum = Data.getULEB128(C);
+        auto CfaOffset = Opcode == DW_CFA_LLVM_def_aspace_cfa
+                             ? Data.getULEB128(C)
+                             : Data.getSLEB128(C);
+        auto AddressSpace = Data.getULEB128(C);
+        addInstruction(Opcode, RegNum, CfaOffset, AddressSpace);
+        break;
+      }
+      case DW_CFA_offset_extended:
+      case DW_CFA_register:
+      case DW_CFA_def_cfa:
+      case DW_CFA_val_offset: {
+        // Operands: ULEB128, ULEB128
+        // Note: We can not embed getULEB128 directly into function
+        // argument list. getULEB128 changes Offset and order of evaluation
+        // for arguments is unspecified.
+        uint64_t op1 = Data.getULEB128(C);
+        uint64_t op2 = Data.getULEB128(C);
+        addInstruction(Opcode, op1, op2);
+        break;
+      }
+      case DW_CFA_offset_extended_sf:
+      case DW_CFA_def_cfa_sf:
+      case DW_CFA_val_offset_sf: {
+        // Operands: ULEB128, SLEB128
+        // Note: see comment for the previous case
+        uint64_t op1 = Data.getULEB128(C);
+        uint64_t op2 = (uint64_t)Data.getSLEB128(C);
+        addInstruction(Opcode, op1, op2);
+        break;
+      }
+      case DW_CFA_def_cfa_expression: {
+        uint64_t ExprLength = Data.getULEB128(C);
+        addInstruction(Opcode, 0);
+        StringRef Expression = Data.getBytes(C, ExprLength);
+
+        DataExtractor Extractor(Expression, Data.isLittleEndian(),
+                                Data.getAddressSize());
+        // Note. We do not pass the DWARF format to DWARFExpression, because
+        // DW_OP_call_ref, the only operation which depends on the format, is
+        // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
+        Instructions.back().Expression =
+            DWARFExpression(Extractor, Data.getAddressSize());
+        break;
+      }
+      case DW_CFA_expression:
+      case DW_CFA_val_expression: {
+        uint64_t RegNum = Data.getULEB128(C);
+        addInstruction(Opcode, RegNum, 0);
+
+        uint64_t BlockLength = Data.getULEB128(C);
+        StringRef Expression = Data.getBytes(C, BlockLength);
+        DataExtractor Extractor(Expression, Data.isLittleEndian(),
+                                Data.getAddressSize());
+        // Note. We do not pass the DWARF format to DWARFExpression, because
+        // DW_OP_call_ref, the only operation which depends on the format, is
+        // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
+        Instructions.back().Expression =
+            DWARFExpression(Extractor, Data.getAddressSize());
+        break;
+      }
+      }
+      }
+
+  *Offset = C.tell();
+  return C.takeError();
+  }
 
   void addInstruction(const Instruction &I) { Instructions.push_back(I); }
 
diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
index 868194d917f39..e30317c470261 100644
--- a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
@@ -7,8 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
-#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Errc.h"
@@ -23,148 +22,6 @@
 using namespace llvm;
 using namespace dwarf;
 
-// See DWARF standard v3, section 7.23
-const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
-const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
-
-Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
-                        uint64_t EndOffset) {
-  DataExtractor::Cursor C(*Offset);
-  while (C && C.tell() < EndOffset) {
-    uint8_t Opcode = Data.getRelocatedValue(C, 1);
-    if (!C)
-      break;
-
-    // Some instructions have a primary opcode encoded in the top bits.
-    if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
-      // If it's a primary opcode, the first operand is encoded in the bottom
-      // bits of the opcode itself.
-      uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
-      switch (Primary) {
-      case DW_CFA_advance_loc:
-      case DW_CFA_restore:
-        addInstruction(Primary, Op1);
-        break;
-      case DW_CFA_offset:
-        addInstruction(Primary, Op1, Data.getULEB128(C));
-        break;
-      default:
-        llvm_unreachable("invalid primary CFI opcode");
-      }
-      continue;
-    }
-
-    // Extended opcode - its value is Opcode itself.
-    switch (Opcode) {
-    default:
-      return createStringError(errc::illegal_byte_sequence,
-                               "invalid extended CFI opcode 0x%" PRIx8, Opcode);
-    case DW_CFA_nop:
-    case DW_CFA_remember_state:
-    case DW_CFA_restore_state:
-    case DW_CFA_GNU_window_save:
-    case DW_CFA_AARCH64_negate_ra_state_with_pc:
-      // No operands
-      addInstruction(Opcode);
-      break;
-    case DW_CFA_set_loc:
-      // Operands: Address
-      addInstruction(Opcode, Data.getRelocatedAddress(C));
-      break;
-    case DW_CFA_advance_loc1:
-      // Operands: 1-byte delta
-      addInstruction(Opcode, Data.getRelocatedValue(C, 1));
-      break;
-    case DW_CFA_advance_loc2:
-      // Operands: 2-byte delta
-      addInstruction(Opcode, Data.getRelocatedValue(C, 2));
-      break;
-    case DW_CFA_advance_loc4:
-      // Operands: 4-byte delta
-      addInstruction(Opcode, Data.getRelocatedValue(C, 4));
-      break;
-    case DW_CFA_restore_extended:
-    case DW_CFA_undefined:
-    case DW_CFA_same_value:
-    case DW_CFA_def_cfa_register:
-    case DW_CFA_def_cfa_offset:
-    case DW_CFA_GNU_args_size:
-      // Operands: ULEB128
-      addInstruction(Opcode, Data.getULEB128(C));
-      break;
-    case DW_CFA_def_cfa_offset_sf:
-      // Operands: SLEB128
-      addInstruction(Opcode, Data.getSLEB128(C));
-      break;
-    case DW_CFA_LLVM_def_aspace_cfa:
-    case DW_CFA_LLVM_def_aspace_cfa_sf: {
-      auto RegNum = Data.getULEB128(C);
-      auto CfaOffset = Opcode == DW_CFA_LLVM_def_aspace_cfa
-                           ? Data.getULEB128(C)
-                           : Data.getSLEB128(C);
-      auto AddressSpace = Data.getULEB128(C);
-      addInstruction(Opcode, RegNum, CfaOffset, AddressSpace);
-      break;
-    }
-    case DW_CFA_offset_extended:
-    case DW_CFA_register:
-    case DW_CFA_def_cfa:
-    case DW_CFA_val_offset: {
-      // Operands: ULEB128, ULEB128
-      // Note: We can not embed getULEB128 directly into function
-      // argument list. getULEB128 changes Offset and order of evaluation
-      // for arguments is unspecified.
-      uint64_t op1 = Data.getULEB128(C);
-      uint64_t op2 = Data.getULEB128(C);
-      addInstruction(Opcode, op1, op2);
-      break;
-    }
-    case DW_CFA_offset_extended_sf:
-    case DW_CFA_def_cfa_sf:
-    case DW_CFA_val_offset_sf: {
-      // Operands: ULEB128, SLEB128
-      // Note: see comment for the previous case
-      uint64_t op1 = Data.getULEB128(C);
-      uint64_t op2 = (uint64_t)Data.getSLEB128(C);
-      addInstruction(Opcode, op1, op2);
-      break;
-    }
-    case DW_CFA_def_cfa_expression: {
-      uint64_t ExprLength = Data.getULEB128(C);
-      addInstruction(Opcode, 0);
-      StringRef Expression = Data.getBytes(C, ExprLength);
-
-      DataExtractor Extractor(Expression, Data.isLittleEndian(),
-                              Data.getAddressSize());
-      // Note. We do not pass the DWARF format to DWARFExpression, because
-      // DW_OP_call_ref, the only operation which depends on the format, is
-      // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
-      Instructions.back().Expression =
-          DWARFExpression(Extractor, Data.getAddressSize());
-      break;
-    }
-    case DW_CFA_expression:
-    case DW_CFA_val_expression: {
-      uint64_t RegNum = Data.getULEB128(C);
-      addInstruction(Opcode, RegNum, 0);
-
-      uint64_t BlockLength = Data.getULEB128(C);
-      StringRef Expression = Data.getBytes(C, BlockLength);
-      DataExtractor Extractor(Expression, Data.isLittleEndian(),
-                              Data.getAddressSize());
-      // Note. We do not pass the DWARF format to DWARFExpression, because
-      // DW_OP_call_ref, the only operation which depends on the format, is
-      // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
-      Instructions.back().Expression =
-          DWARFExpression(Extractor, Data.getAddressSize());
-      break;
-    }
-    }
-  }
-
-  *Offset = C.tell();
-  return C.takeError();
-}
 
 StringRef CFIProgram::callFrameString(unsigned Opcode) const {
   return dwarf::CallFrameString(Opcode, Arch);
diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
index fae4c51e0af01..728ad8ba58ba0 100644
--- a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
@@ -8,7 +8,6 @@
 
 #include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
 #include "llvm/Support/Format.h"
 #include <cassert>
 #include <cstdint>
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index 31855cd5444c2..237580e17b9ef 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -571,6 +571,7 @@ cc_library(
     deps = [
         ":BinaryFormat",
         ":DebugInfo",
+        ":DebugInfoDWARFLowLevel",
         ":MC",
         ":Object",
         ":Support",
@@ -578,6 +579,19 @@ cc_library(
     ],
 )
 
+cc_library(
+    name = "DebugInfoDWARFLowLevel",
+    srcs = glob([
+        "lib/DebugInfo/DWARF/LowLevel/*.cpp",
+    ]),
+    hdrs = glob(["include/llvm/DebugInfo/DWARF/LowLevel/*.h"]),
+    copts = llvm_copts,
+    deps = [
+        ":BinaryFormat",
+        ":Support",
+    ],
+)
+
 cc_library(
     name = "DebugInfoGSYM",
     srcs = glob([

>From 6debeb8b741a866cf917cfc54e001ce2d304210c Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Wed, 18 Jun 2025 17:16:15 -0700
Subject: [PATCH 4/4] BUILD fixes

---
 llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt  |  1 +
 utils/bazel/llvm-project-overlay/bolt/BUILD.bazel |  2 ++
 utils/bazel/llvm-project-overlay/llvm/BUILD.bazel | 10 ++++++++++
 3 files changed, 13 insertions(+)

diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
index 764be9601cea9..c11a2589a552d 100644
--- a/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
@@ -10,4 +10,5 @@ add_llvm_component_library(LLVMDebugInfoDWARFLowLevel
   LINK_COMPONENTS
   BinaryFormat
   Support
+  TargetParser
   )
diff --git a/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel b/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel
index b5cd6dbcbd4f9..97c25bcdece7b 100644
--- a/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel
@@ -106,6 +106,7 @@ cc_library(
         "//llvm:DWARFLinker",
         "//llvm:DWP",
         "//llvm:DebugInfoDWARF",
+        "//llvm:DebugInfoDWARFLowLevel",
         "//llvm:Demangle",
         "//llvm:JITLink",
         "//llvm:MC",
@@ -296,6 +297,7 @@ cc_library(
         "//llvm:BinaryFormat",
         "//llvm:CodeGen",
         "//llvm:DebugInfoDWARF",
+        "//llvm:DebugInfoDWARFLowLevel",
         "//llvm:Demangle",
         "//llvm:ExecutionEngine",
         "//llvm:MC",
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index 237580e17b9ef..df30ff093f4dc 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -492,6 +492,7 @@ cc_library(
         ":DebugInfo",
         ":DebugInfoCodeView",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":DebugInfoPDB",
         ":Demangle",
         ":MC",
@@ -589,6 +590,7 @@ cc_library(
     deps = [
         ":BinaryFormat",
         ":Support",
+        ":TargetParser",
     ],
 )
 
@@ -1167,6 +1169,7 @@ cc_library(
         ":Core",
         ":DebugInfo",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":Demangle",
         ":Object",
         ":Support",
@@ -2060,6 +2063,7 @@ cc_library(
         ":Core",
         ":DebugInfoCodeView",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":IPO",
         ":IRPrinter",
         ":Instrumentation",
@@ -3201,6 +3205,7 @@ cc_library(
         ":CodeGenTypes",
         ":DWARFLinkerBase",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":MC",
         ":Support",
         ":Target",
@@ -3219,6 +3224,7 @@ cc_library(
         ":BinaryFormat",
         ":CodeGen",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":Support",
         ":Target",
     ],
@@ -3519,6 +3525,7 @@ cc_library(
         ":DWARFLinkerParallel",
         ":DebugInfo",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":DsymutilTableGen",
         ":MC",
         ":Object",
@@ -3936,6 +3943,7 @@ cc_binary(
         ":BinaryFormat",
         ":DebugInfo",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":MC",
         ":Object",
         ":Support",
@@ -3967,6 +3975,7 @@ cc_binary(
         ":DWARFLinker",
         ":DWARFLinkerParallel",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":DwarfutilOptionsTableGen",
         ":MC",
         ":ObjCopy",
@@ -4584,6 +4593,7 @@ cc_library(
         ":DebugInfo",
         ":DebugInfoBTF",
         ":DebugInfoDWARF",
+        ":DebugInfoDWARFLowLevel",
         ":Debuginfod",
         ":Demangle",
         ":MC",



More information about the lldb-commits mailing list