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

Javier Lopez-Gomez via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 7 09:40:40 PDT 2025


================
@@ -0,0 +1,2309 @@
+//===-- LVIRReader.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
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements the LVIRReader class.
+// It supports LLVM text IR and bitcode format.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h"
+#include "llvm/CodeGen/DebugHandlerBase.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVType.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IRReader/IRReader.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/SourceMgr.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace llvm::logicalview;
+
+#define DEBUG_TYPE "IRReader"
+
+// These flavours of DINodes are not implemented but technically possible:
+//   DW_TAG_APPLE_property   = 0x4200
+//   DW_TAG_atomic_type      = 0x0047
+//   DW_TAG_common_block     = 0x001a
+//   DW_TAG_file_type        = 0x0029
+//   DW_TAG_friend           = 0x002a
+//   DW_TAG_generic_subrange = 0x0045
+//   DW_TAG_immutable_type   = 0x004b
+//   DW_TAG_module           = 0x001e
+//   DW_TAG_variant_part     = 0x0033
+
+// Create a logical element and setup the following information:
+// - Name, DWARF tag, line
+// - Collect any file information
+LVElement *LVIRReader::constructElement(const DINode *DN) {
+  dwarf::Tag Tag = DN->getTag();
+  LVElement *Element = createElement(Tag);
+  if (Element) {
+    Element->setTag(Tag);
+    addMD(DN, Element);
+
+    StringRef Name = getMDName(DN);
+    if (!Name.empty())
+      Element->setName(Name);
+
+    // Record any file information.
+    if (const DIFile *File = getMDFile(DN))
+      getOrCreateSourceID(File);
+  }
+
+  return Element;
+}
+
+void LVIRReader::mapFortranLanguage(unsigned DWLang) {
+  switch (DWLang) {
+  case dwarf::DW_LANG_Fortran77:
+  case dwarf::DW_LANG_Fortran90:
+  case dwarf::DW_LANG_Fortran95:
+  case dwarf::DW_LANG_Fortran03:
+  case dwarf::DW_LANG_Fortran08:
+  case dwarf::DW_LANG_Fortran18:
+    LanguageIsFortran = true;
+    break;
+  default:
+    LanguageIsFortran = false;
+  }
+}
+
+bool LVIRReader::includeMinimalInlineScopes() const {
+  return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly;
+}
+
+// For the given 'DIFile' generate an index 1-based to indicate the
+// source file where the logical element is declared.
+// The IR reader expects the indexes as 1-indexed.
+// Each compile unit, keeps track of the last assigned index.
+size_t LVIRReader::getOrCreateSourceID(const DIFile *File) {
+  if (!File)
+    return 0;
+
+  LLVM_DEBUG({
+    dbgs() << "\n[getOrCreateSourceID] DIFile\n";
+    File->dump();
+  });
+
+  addMD(File, CompileUnit);
+
+  LLVM_DEBUG({
+    dbgs() << "Directory: '" << File->getDirectory() << "'\n";
+    dbgs() << "Filename:  '" << File->getFilename() << "'\n";
+  });
+  size_t FileIndex = 0;
+  LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File);
+  if (Iter == CompileUnitFiles.end()) {
+    FileIndex = getFileIndex(CompileUnit);
+    std::string Directory(File->getDirectory());
+    if (Directory.empty())
+      Directory = std::string(CompileUnit->getCompilationDirectory());
+
+    std::string FullName;
+    raw_string_ostream Out(FullName);
+    Out << Directory << "/" << llvm::sys::path::filename(File->getFilename());
+    CompileUnit->addFilename(transformPath(FullName));
+    CompileUnitFiles.emplace(File, ++FileIndex);
+    updateFileIndex(CompileUnit, FileIndex);
+  } else {
+    FileIndex = Iter->second;
+  }
+
+  LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; });
+  return FileIndex;
+}
+
+void LVIRReader::addSourceLine(LVElement *Element, unsigned Line,
+                               const DIFile *File) {
+  if (Line == 0)
+    return;
+
+  // After the scopes are created, the generic reader traverses the 'Children'
+  // and perform additional setting tasks (resolve types names, references,
----------------
jalopezg-git wrote:

```suggestion
  // and performs additional setting tasks (resolve types names, references,
```

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


More information about the llvm-commits mailing list