1Replicate this scenario: 2 3$ cat a.c 4struct Foo { int x; }; 5int g(struct Foo *p); 6int main() { 7 struct Foo f = {42}; 8 return g(&f); 9} 10 11$ cat b.c 12struct Foo { int x; }; 13int g(struct Foo *p) { return p->x; } 14 15$ cl -c a.c b.c -Zi -Fdts.pdb 16 17$ lld-link a.obj b.obj -debug -entry:main -nodefaultlib -out:t.exe 18 19RUN: rm -rf %t && mkdir -p %t && cd %t 20RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj 21RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj 22RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb 23RUN: lld-link a.obj b.obj -entry:main -debug:noghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary | FileCheck %s -check-prefix SUMMARY 24RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s 25 26Re-run with /DEBUG:GHASH 27RUN: lld-link a.obj b.obj -entry:main -debug:ghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary -verbose 28RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s 29 30 31CHECK-LABEL: Types (TPI Stream) 32CHECK: ============================================================ 33 34CHECK: [[FOO_DECL:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo` 35 36CHECK: [[FOO_PTR:[^ ]*]] | LF_POINTER [size = 12] 37CHECK-NEXT: referent = [[FOO_DECL]] 38 39CHECK: [[G_ARGS:[^ ]*]] | LF_ARGLIST [size = 12] 40CHECK-NEXT: [[FOO_PTR]]: `Foo*` 41 42CHECK: [[G_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16] 43CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = [[G_ARGS]] 44CHECK-NEXT: calling conv = cdecl, options = None 45 46CHECK: [[FOO_COMPLETE:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo` 47CHECK-NEXT: unique name: `.?AUFoo@@` 48CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: 0x{{.*}} 49CHECK: options: has unique name 50CHECK: [[MAIN_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16] 51CHECK: return type = 0x0074 (int), # args = 0, param list = 0x{{.*}} 52CHECK: calling conv = cdecl, options = None 53 54 55CHECK-LABEL: Types (IPI Stream) 56CHECK: ============================================================ 57CHECK: [[MAIN_ID:[^ ]*]] | LF_FUNC_ID [size = 20] 58CHECK: name = main, type = [[MAIN_PROTO]], parent scope = <no type> 59CHECK: [[G_ID:[^ ]*]] | LF_FUNC_ID [size = 16] 60CHECK: name = g, type = [[G_PROTO]], parent scope = <no type> 61CHECK: [[A_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28] 62CHECK: {{.*}}: `a.c` 63CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28] 64CHECK: {{.*}}: `b.c` 65 66CHECK-LABEL: Global Symbols 67CHECK: ============================================================ 68CHECK-NEXT: Records 69CHECK-NEXT: 36 | S_PROCREF [size = 20] `main` 70CHECK-NEXT: module = 1, sum name = 0, offset = 104 71CHECK-NEXT: 68 | S_PROCREF [size = 16] `g` 72CHECK-NEXT: module = 2, sum name = 0, offset = 104 73CHECK-NEXT: 56 | S_UDT [size = 12] `Foo` 74CHECK-NEXT: original type = 0x1006 75 76CHECK-LABEL: Symbols 77CHECK: ============================================================ 78CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: 79CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj` 80CHECK: 104 | S_GPROC32 [size = 44] `main` 81CHECK: parent = 0, end = 196, addr = 0001:0000, code size = 27 82CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none 83CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` 84CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`: 85CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj` 86CHECK: 44 | S_COMPILE3 [size = 60] 87CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c 88CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 89CHECK: flags = security checks | hot patchable 90CHECK: 104 | S_GPROC32 [size = 44] `g` 91CHECK: parent = 0, end = 196, addr = 0001:0032, code size = 13 92CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none 93CHECK: 148 | S_FRAMEPROC [size = 32] 94CHECK: size = 0, padding size = 0, offset to padding = 0 95CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 96CHECK: flags = has async eh | opt speed 97CHECK: 180 | S_REGREL32 [size = 16] `p` 98CHECK: type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8 99CHECK: 196 | S_END [size = 4] 100CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` 101CHECK-LABEL: Mod 0002 | `* Linker *`: 102 103SUMMARY: Summary 104SUMMARY-NEXT: -------------------------------------------------------------------------------- 105SUMMARY-NEXT: 2 Input OBJ files (expanded from all cmd-line inputs) 106SUMMARY-NEXT: 1 PDB type server dependencies 107SUMMARY-NEXT: 0 Precomp OBJ dependencies 108SUMMARY-NEXT: 25 Input type records 109SUMMARY-NEXT: 868 Input type records bytes 110SUMMARY-NEXT: 9 Merged TPI records 111SUMMARY-NEXT: 16 Merged IPI records 112SUMMARY-NEXT: 3 Output PDB strings 113SUMMARY-NEXT: 4 Global symbol records 114SUMMARY-NEXT: 14 Module symbol records 115SUMMARY-NEXT: 2 Public symbol records 116 117SUMMARY: Top 10 types responsible for the most TPI input: 118SUMMARY-NEXT: index total bytes count size 119SUMMARY-NEXT: 0x1006: 36 = 1 * 36 120SUMMARY: Run llvm-pdbutil to print details about a particular record: 121SUMMARY-NEXT: llvm-pdbutil dump -types -type-index 0x1006 t.pdb 122 123SUMMARY: Top 10 types responsible for the most IPI input: 124SUMMARY-NEXT: index total bytes count size 125SUMMARY-NEXT: 0x1006: 256 = 1 * 256 126SUMMARY: Run llvm-pdbutil to print details about a particular record: 127SUMMARY-NEXT: llvm-pdbutil dump -ids -id-index 0x1006 t.pdb 128