Skip to content

Conversation

@Nerixyz
Copy link
Contributor

@Nerixyz Nerixyz commented Oct 15, 2025

When creating all types in a compilation unit, simple types (~> primitive and pointer types) that were only used in function arguments or return types weren't created as LLDB Types.

With this PR, they're created when creating the function/method types.
This makes it possible to run the SymbolFile/PDB/typedefs.test with both plugins.

@Nerixyz Nerixyz requested a review from Michael137 October 15, 2025 19:50
@Nerixyz Nerixyz requested a review from JDevlieghere as a code owner October 15, 2025 19:50
@llvmbot llvmbot added the lldb label Oct 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 15, 2025

@llvm/pr-subscribers-lldb

Author: nerix (Nerixyz)

Changes

When creating all types in a compilation unit, simple types (~> primitive and pointer types) that were only used in function arguments or return types weren't created as LLDB Types.

With this PR, they're created when creating the function/method types.
This makes it possible to run the SymbolFile/PDB/typedefs.test with both plugins.


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

4 Files Affected:

  • (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (+25)
  • (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h (+2)
  • (modified) lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp (+5-7)
  • (modified) lldb/test/Shell/SymbolFile/PDB/typedefs.test (+12-11)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index ecd3188b3d564..e76b7a3cf274a 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -754,6 +754,10 @@ TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id,
 TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
                                                const MemberFunctionRecord &mfr,
                                                CompilerType ct) {
+  if (mfr.ReturnType.isSimple())
+    GetOrCreateType(mfr.ReturnType);
+  CreateSimpleArgumentListTypes(mfr.ArgumentList);
+
   Declaration decl;
   return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
@@ -763,12 +767,33 @@ TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
 TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
                                                 const ProcedureRecord &pr,
                                                 CompilerType ct) {
+  if (pr.ReturnType.isSimple())
+    GetOrCreateType(pr.ReturnType);
+  CreateSimpleArgumentListTypes(pr.ArgumentList);
+
   Declaration decl;
   return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
                   ct, lldb_private::Type::ResolveState::Full);
 }
 
+void SymbolFileNativePDB::CreateSimpleArgumentListTypes(
+    llvm::codeview::TypeIndex arglist_ti) {
+  if (arglist_ti.isNoneType())
+    return;
+
+  CVType arglist_cvt = m_index->tpi().getType(arglist_ti);
+  if (arglist_cvt.kind() != LF_ARGLIST)
+    return; // invalid debug info
+
+  ArgListRecord alr;
+  llvm::cantFail(
+      TypeDeserializer::deserializeAs<ArgListRecord>(arglist_cvt, alr));
+  for (TypeIndex id : alr.getIndices())
+    if (!id.isNoneType() && id.isSimple())
+      GetOrCreateType(id);
+}
+
 TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
   if (type_id.index.isSimple())
     return CreateSimpleType(type_id.index, ct);
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index a5fef354af65c..11b982e6fc67e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -255,6 +255,8 @@ class SymbolFileNativePDB : public SymbolFileCommon {
                                       VariableList &variables);
   size_t ParseVariablesForBlock(PdbCompilandSymId block_id);
 
+  void CreateSimpleArgumentListTypes(llvm::codeview::TypeIndex arglist_ti);
+
   llvm::Expected<uint32_t> GetFileIndex(const CompilandIndexItem &cii,
                                         uint32_t file_id);
 
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp
index 3781194e2e992..3664b04fd22bd 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp
@@ -3,7 +3,6 @@
 // Test that simple types can be found
 // RUN: %build --std=c++20 --nodefaultlib --compiler=clang-cl --arch=64 -o %t.exe -- %s
 // RUN: lldb-test symbols %t.exe | FileCheck %s
-// RUN: lldb-test symbols %t.exe | FileCheck --check-prefix=FUNC-PARAMS %s
 
 bool *PB;
 bool &RB = *PB;
@@ -101,12 +100,14 @@ int main() {
 // CHECK-DAG: Type{{.*}} , name = "float", size = 4, compiler_type = 0x{{[0-9a-f]+}} float
 // CHECK-DAG: Type{{.*}} , name = "const float", size = 4, compiler_type = 0x{{[0-9a-f]+}} const float
 
+// CHECK-DAG: Type{{.*}} , name = "double", size = 8, compiler_type = 0x{{[0-9a-f]+}} double
+
 // CHECK-DAG: Type{{.*}} , name = "_Complex float", size = 4, compiler_type = 0x{{[0-9a-f]+}} _Complex float
 // CHECK-DAG: Type{{.*}} , name = "_Complex double", size = 8, compiler_type = 0x{{[0-9a-f]+}} _Complex double
 
-// CHECK-DAG:  Type{{.*}} , name = "ReturnedStruct1", size = 1, decl = simple-types.cpp:21, compiler_type = 0x{{[0-9a-f]+}} struct ReturnedStruct1 {
-// CHECK-DAG:  Type{{.*}} , name = "ReturnedStruct2", size = 1, decl = simple-types.cpp:22, compiler_type = 0x{{[0-9a-f]+}} struct ReturnedStruct2 {
-// CHECK-DAG:  Type{{.*}} , name = "MyStruct", size = 1, decl = simple-types.cpp:24, compiler_type = 0x{{[0-9a-f]+}} struct MyStruct {
+// CHECK-DAG:  Type{{.*}} , name = "ReturnedStruct1", size = 1, decl = simple-types.cpp:20, compiler_type = 0x{{[0-9a-f]+}} struct ReturnedStruct1 {
+// CHECK-DAG:  Type{{.*}} , name = "ReturnedStruct2", size = 1, decl = simple-types.cpp:21, compiler_type = 0x{{[0-9a-f]+}} struct ReturnedStruct2 {
+// CHECK-DAG:  Type{{.*}} , name = "MyStruct", size = 1, decl = simple-types.cpp:23, compiler_type = 0x{{[0-9a-f]+}} struct MyStruct {
 
 // CHECK-DAG:  Type{{.*}} , size = 8, compiler_type = 0x{{[0-9a-f]+}} struct MyStruct *const
 // CHECK-DAG:  Type{{.*}} , size = 8, compiler_type = 0x{{[0-9a-f]+}} const struct MyStruct *const
@@ -137,6 +138,3 @@ int main() {
 // CHECK-DAG: Type{{.*}} , size = 0, compiler_type = 0x{{[0-9a-f]+}} struct ReturnedStruct2 (char *)
 
 // CHECK-DAG: Type{{.*}} , size = 8, compiler_type = 0x{{[0-9a-f]+}} long[2]
-
-// double is used as a parameter to `PF`, but not created as an LLDB type
-// FUNC-PARAMS-NOT: Type{{.*}} , name = "double"
diff --git a/lldb/test/Shell/SymbolFile/PDB/typedefs.test b/lldb/test/Shell/SymbolFile/PDB/typedefs.test
index 86846fb51126a..31bf7140b9219 100644
--- a/lldb/test/Shell/SymbolFile/PDB/typedefs.test
+++ b/lldb/test/Shell/SymbolFile/PDB/typedefs.test
@@ -1,7 +1,8 @@
 REQUIRES: system-windows, msvc
 RUN: mkdir -p %t.dir
 RUN: %build --compiler=msvc --arch=32 --nodefaultlib --output=%t.dir/SimpleTypesTest.cpp.typedefs.exe %S/Inputs/SimpleTypesTest.cpp
-RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.typedefs.exe | FileCheck %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols %t.dir/SimpleTypesTest.cpp.typedefs.exe | FileCheck %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols %t.dir/SimpleTypesTest.cpp.typedefs.exe | FileCheck %s
 
 ; Generate 32-bit target
 
@@ -13,7 +14,7 @@ RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.typedefs.exe | FileCheck %s
 ; both of them is the same.
 
 CHECK: Module [[MOD:.*]]
-CHECK: SymbolFile pdb ([[MOD]])
+CHECK: SymbolFile {{(native-)?}}pdb ([[MOD]])
 CHECK-DAG: name = "char32_t", size = 4, compiler_type = {{.*}} char32_t
 CHECK-DAG: name = "char16_t", size = 2, compiler_type = {{.*}} char16_t
 CHECK-DAG: Type{{.*}} , name = "unsigned long", size = 4, compiler_type = {{.*}} unsigned long
@@ -23,7 +24,7 @@ CHECK-DAG: Type{{.*}} , size = 40, compiler_type = {{.*}} unsigned long[10]
 CHECK-DAG: Type{{.*}} , name = "double", size = 8, compiler_type = {{.*}} double
 CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} double *
 CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} double *&
-CHECK-DAG: Type{{.*}} , name = "RefTypedef", compiler_type = {{.*}} typedef RefTypedef
+CHECK-DAG: Type{{.*}} , name = "RefTypedef"{{(, size = 4)?}}, compiler_type = {{.*}} typedef RefTypedef
 
 CHECK-DAG: Type{{.*}} , name = "wchar_t", size = 2, compiler_type = {{.*}} wchar_t
 
@@ -37,23 +38,23 @@ CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} short *
 CHECK-DAG: Type{{.*}} , name = "const double", size = 8, compiler_type = {{.*}} const double
 CHECK-DAG: Type{{.*}} , name = "volatile bool", size = 1, compiler_type = {{.*}} volatile _Bool
 CHECK-DAG: Type{{.*}} , name = "long long", size = 8, compiler_type = {{.*}} long long
-CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} long long (int &, unsigned char **, short *, const double, volatile _Bool)
-CHECK-DAG: Type{{.*}} , name = "FuncPtrTypedef", compiler_type = {{.*}} typedef FuncPtrTypedef
+CHECK-DAG: Type{{.*}} {{(, size = 0)?}}, compiler_type = {{.*}} long long (int &, unsigned char **, short *, const double, volatile _Bool)
+CHECK-DAG: Type{{.*}} , name = "FuncPtrTypedef"{{(, size = 4)?}}, compiler_type = {{.*}} typedef FuncPtrTypedef
 
-CHECK-DAG: Type{{.*}} , name = "void", compiler_type = {{.*}} void
+CHECK-DAG: Type{{.*}} , name = "void"{{(, size = 0)?}}, compiler_type = {{.*}} void
 CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} void *
 CHECK-DAG: Type{{.*}} , name = "long", size = 4, compiler_type = {{.*}} long
 CHECK-DAG: Type{{.*}} , name = "unsigned short", size = 2, compiler_type = {{.*}} unsigned short
-CHECK-DAG: Type{{.*}} , name = "unsigned int", size = 4, compiler_type = {{.*}} unsigned int
+CHECK-DAG: Type{{.*}} , name = "unsigned{{( int)?}}", size = 4, compiler_type = {{.*}} unsigned int
 CHECK-DAG: Type{{.*}} , name = "char", size = 1, compiler_type = {{.*}} char
 CHECK-DAG: Type{{.*}} , name = "signed char", size = 1, compiler_type = {{.*}} signed char
-CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} char (void *, long, unsigned short, unsigned int, ...)
+CHECK-DAG: Type{{.*}} {{(, size = 0)?}}, compiler_type = {{.*}} char (void *, long, unsigned short, unsigned int, ...)
 CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} char (*)(void *, long, unsigned short, unsigned int, ...)
-CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedef", compiler_type = {{.*}} typedef VarArgsFuncTypedef
+CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedef"{{(, size = 4)?}}, compiler_type = {{.*}} typedef VarArgsFuncTypedef
 
 CHECK-DAG: Type{{.*}} , name = "float", size = 4, compiler_type = {{.*}} float
-CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} float (...)
+CHECK-DAG: Type{{.*}} {{(, size = 0)?}}, compiler_type = {{.*}} float (...)
 CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} float (*)(...)
-CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedefA", compiler_type = {{.*}} typedef VarArgsFuncTypedefA
+CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedefA"{{(, size = 4)?}}, compiler_type = {{.*}} typedef VarArgsFuncTypedefA
 
 CHECK-DAG: {{^[0-9A-F]+}}:   CompileUnit{{[{]0x[0-9a-f]+[}]}}, language = "c++", file = '{{.*}}\SimpleTypesTest.cpp'

@Nerixyz
Copy link
Contributor Author

Nerixyz commented Oct 27, 2025

Ping - this should be the last PDB shell test

@Nerixyz Nerixyz merged commit 51cecd3 into llvm:main Oct 27, 2025
12 checks passed
dvbuka pushed a commit to dvbuka/llvm-project that referenced this pull request Oct 27, 2025
…urn types (llvm#163621)

When creating all types in a compilation unit, simple types (~>
primitive and pointer types) that were only used in function arguments
or return types weren't created as LLDB `Type`s.

With this PR, they're created when creating the function/method types.
This makes it possible to run the `SymbolFile/PDB/typedefs.test` with
both plugins.
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
…urn types (llvm#163621)

When creating all types in a compilation unit, simple types (~>
primitive and pointer types) that were only used in function arguments
or return types weren't created as LLDB `Type`s.

With this PR, they're created when creating the function/method types.
This makes it possible to run the `SymbolFile/PDB/typedefs.test` with
both plugins.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants