llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: nerix (Nerixyz)

<details>
<summary>Changes</summary>

Tag types like stucts or enums didn't have a declaration attached to them. The 
source locations are present in the IPI stream in `LF_UDT_MOD_SRC_LINE` records:

```
   0x101F | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1C63]
            udt = 0x1058, mod = 3, file = 1, line = 0
   0x2789 | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1E5A]
            udt = 0x1253, mod = 35, file = 93, line = 17069
```

The file is an ID in the string table `/names`:

```
     ID | String
      1 | '\&lt;unknown&gt;'
     12 | 
'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\wingdi.h'
     93 | 
'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\winnt.h'
```

Here, we're not interested in `mod`. This would indicate which module 
contributed the UDT.

I was looking at Rustc's PDB and found that it uses `&lt;unknown&gt;` for some 
types, so I added a check for that.

This makes two DIA PDB shell tests to work with the native PDB plugin.

---
Full diff: https://github.com/llvm/llvm-project/pull/152579.diff


4 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp 
(+54-3) 
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h 
(+10) 
- (modified) lldb/test/Shell/SymbolFile/PDB/class-layout.test (+11-1) 
- (modified) lldb/test/Shell/SymbolFile/PDB/enums-layout.test (+6) 


``````````diff
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp 
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index dcea33dd9f854..684d46d1da4e6 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -643,8 +643,7 @@ SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId 
type_id,
 
   std::string uname = GetUnqualifiedTypeName(record);
 
-  // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
-  Declaration decl;
+  Declaration decl = ResolveUdtDeclaration(type_id);
   return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr,
                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
                   Type::ResolveState::Forward);
@@ -667,7 +666,7 @@ lldb::TypeSP 
SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
                                                 CompilerType ct) {
   std::string uname = GetUnqualifiedTypeName(er);
 
-  Declaration decl;
+  Declaration decl = ResolveUdtDeclaration(type_id);
   TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
 
   return MakeType(
@@ -2441,3 +2440,55 @@ SymbolFileNativePDB::GetContextForType(TypeIndex ti) {
   }
   return ctx;
 }
+
+void SymbolFileNativePDB::CacheUdtDeclarations() {
+  if (m_has_cached_udt_declatations)
+    return;
+  m_has_cached_udt_declatations = true;
+
+  for (CVType cvt : m_index->ipi().typeArray()) {
+    if (cvt.kind() != LF_UDT_MOD_SRC_LINE)
+      continue;
+
+    UdtModSourceLineRecord udt_mod_src;
+    llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_mod_src));
+    // Some types might be contributed by multiple modules. We assume that they
+    // all point to the same file and line because we can only provide one
+    // location.
+    m_udt_declarations.try_emplace(udt_mod_src.UDT,
+                                   udt_mod_src.SourceFile.getIndex(),
+                                   udt_mod_src.LineNumber);
+  }
+}
+
+Declaration SymbolFileNativePDB::ResolveUdtDeclaration(PdbTypeSymId type_id) {
+  CacheUdtDeclarations();
+  auto it = m_udt_declarations.find(type_id.index);
+  if (it == m_udt_declarations.end())
+    return Declaration();
+
+  auto [file_index, line] = it->second;
+  auto string_table = m_index->pdb().getStringTable();
+  if (!string_table) {
+    LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), string_table.takeError(),
+                   "Failed to get string table: {0}");
+    return Declaration();
+  }
+
+  llvm::Expected<llvm::StringRef> file_name =
+      string_table->getStringTable().getString(file_index);
+  if (!file_name) {
+    LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), file_name.takeError(),
+                   "Failed to get string with id {1}: {0}", file_index);
+    return Declaration();
+  }
+
+  // rustc sets the filename to "<unknown>" for some files
+  if (*file_name == "\\<unknown>")
+    return Declaration();
+
+  FileSpec::Style style = file_name->starts_with("/")
+                              ? FileSpec::Style::posix
+                              : FileSpec::Style::windows;
+  return Declaration(FileSpec(*file_name, style), line);
+}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h 
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index eda375d4cebe7..2e8270794af1a 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -260,6 +260,9 @@ class SymbolFileNativePDB : public SymbolFileCommon {
 
   std::vector<CompilerContext> GetContextForType(llvm::codeview::TypeIndex ti);
 
+  void CacheUdtDeclarations();
+  Declaration ResolveUdtDeclaration(PdbTypeSymId type_id);
+
   llvm::BumpPtrAllocator m_allocator;
 
   lldb::addr_t m_obj_load_address = 0;
@@ -281,6 +284,13 @@ class SymbolFileNativePDB : public SymbolFileCommon {
   llvm::DenseMap<llvm::codeview::TypeIndex, llvm::codeview::TypeIndex>
       m_parent_types;
 
+  /// type index -> (filename index, line)
+  ///
+  /// The filename index is an index into the `/names` section (string table)
+  llvm::DenseMap<llvm::codeview::TypeIndex, std::pair<uint32_t, uint32_t>>
+      m_udt_declarations;
+  bool m_has_cached_udt_declatations = false;
+
   lldb_private::UniqueCStringMap<uint32_t> m_type_base_names;
 };
 
diff --git a/lldb/test/Shell/SymbolFile/PDB/class-layout.test 
b/lldb/test/Shell/SymbolFile/PDB/class-layout.test
index e9a7d1c0daa9e..eca910e997e40 100644
--- a/lldb/test/Shell/SymbolFile/PDB/class-layout.test
+++ b/lldb/test/Shell/SymbolFile/PDB/class-layout.test
@@ -12,9 +12,19 @@ RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | 
FileCheck --check-prefix
 RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck 
--check-prefix=BASE %s
 RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck 
--check-prefix=FRIEND %s
 RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck 
--check-prefix=CLASS %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNION %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=STRUCT %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=COMPLEX %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=LIST %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNNAMED-STRUCT %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=BASE %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=FRIEND %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=CLASS %s
 
 CHECK: Module [[MOD:.*]]
-CHECK: SymbolFile pdb ([[MOD]])
+CHECK: SymbolFile {{(native-)?}}pdb ([[MOD]])
 CHECK: {{^[0-9A-F]+}}:   CompileUnit{{[{]0x[0-9a-f]+[}]}}, language = "c++", 
file = '{{.*}}\ClassLayoutTest.cpp'
 
 ENUM:  name = "Enum", size = 4,  decl = ClassLayoutTest.cpp:5
diff --git a/lldb/test/Shell/SymbolFile/PDB/enums-layout.test 
b/lldb/test/Shell/SymbolFile/PDB/enums-layout.test
index 6f861c6d65adf..9766d6f8b0324 100644
--- a/lldb/test/Shell/SymbolFile/PDB/enums-layout.test
+++ b/lldb/test/Shell/SymbolFile/PDB/enums-layout.test
@@ -7,6 +7,12 @@ RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | 
FileCheck --check-
 RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck 
--check-prefix=UCHAR-ENUM %s
 RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck 
--check-prefix=CLASS-ENUM %s
 RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck 
--check-prefix=STRUCT-ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=CONST-ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=EMPTY-ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=UCHAR-ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=CLASS-ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols 
%t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=STRUCT-ENUM %s
 
 ; FIXME: PDB does not have information about scoped enumeration (Enum class) 
so the  
 ; compiler type used is the same as the one for unscoped enumeration.

``````````

</details>


https://github.com/llvm/llvm-project/pull/152579
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to