nerix 3f61e4eae6
[LLDB][NativePDB] Resolve declaration for tag types (#152579)
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 | '\<unknown>'
     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 `<unknown>` for some
types, so I added a check for that.

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

---------

Co-authored-by: Michael Buch <michaelbuch12@gmail.com>
2025-08-13 14:47:21 +01:00

104 lines
4.5 KiB
Plaintext

REQUIRES: target-windows, msvc
RUN: mkdir -p %t.dir
RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%t.dir/ClassLayoutTest.cpp.obj %S/Inputs/ClassLayoutTest.cpp
RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%t.dir/ClassLayoutTest.cpp.exe %t.dir/ClassLayoutTest.cpp.obj
RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck %s
RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=ENUM %s
RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNION %s
RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=STRUCT %s
RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=COMPLEX %s
RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=LIST %s
RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNNAMED-STRUCT %s
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 {{(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
ENUM-SAME: enum Enum {
ENUM: RED,
ENUM: GREEN,
ENUM: BLUE
ENUM:}
UNION: name = "Union", size = 4, decl = ClassLayoutTest.cpp:9
UNION-SAME: union Union {
UNION: short Row;
UNION: unsigned short Col;
UNION: int Line : 16;
UNION: long Table;
UNION:}
STRUCT: name = "Struct", size = 64, decl = ClassLayoutTest.cpp:22
STRUCT-SAME: struct Struct {
STRUCT: bool A;
STRUCT: unsigned char UCharVar;
STRUCT: unsigned int UIntVar;
STRUCT: long long LongLongVar;
STRUCT: Enum EnumVar;
STRUCT: int array[10];
STRUCT:}
COMPLEX: name = "Complex", size = 368, decl = ClassLayoutTest.cpp:33
COMPLEX-SAME: struct Complex {
COMPLEX: _List *array[90];
COMPLEX: int x;
COMPLEX: int a;
COMPLEX: float b;
COMPLEX:}
LIST: name = "_List", size = 12, decl = ClassLayoutTest.cpp:45
LIST-SAME: struct _List {
LIST: _List *current;
LIST: _List *previous;
LIST: _List *next;
LIST:}
UNNAMED-STRUCT: name = "UnnamedStruct", size = 4, decl = ClassLayoutTest.cpp:52
UNNAMED-STRUCT-SAME: struct UnnamedStruct {
UNNAMED-STRUCT: int a;
UNNAMED-STRUCT:}
BASE: name = "Base", size = 4, decl = ClassLayoutTest.cpp:59
BASE-SAME: class Base {
BASE: int a;
BASE: Base();
BASE: ~Base();
BASE: int Get();
BASE:}
FRIEND: name = "Friend", size = 1, decl = ClassLayoutTest.cpp:70
FRIEND-SAME: class Friend {
FRIEND: int f();
FRIEND: }
CLASS: name = "Class", size = 88, decl = ClassLayoutTest.cpp:74
CLASS-SAME: class Class : public MemberTest::Base {
CLASS: static int m_static;
CLASS: int m_public;
CLASS: Struct m_struct;
CLASS: Union m_union;
CLASS: int m_private;
CLASS: int m_protected;
CLASS: Class();
CLASS: Class(int);
CLASS: ~Class();
CLASS: {{(static )?}}int {{.*}}StaticMemberFunc(int, ...);
CLASS: int Get();
CLASS: int f(MemberTest::Friend);
CLASS: bool operator==(const MemberTest::Class &)
CLASS:}