diff options
author | Zachary Turner <zturner@google.com> | 2018-09-20 15:50:13 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2018-09-20 15:50:13 +0000 |
commit | cfa1d499f92d52c2ac2443c52fb77ad2fc64591d (patch) | |
tree | f2b31c0d4b966be52afdd166dc8434c582bcbb38 /llvm/test | |
parent | 0aea310391dded5ff10d8e183cf255b614026cb0 (diff) | |
download | bcm5719-llvm-cfa1d499f92d52c2ac2443c52fb77ad2fc64591d.tar.gz bcm5719-llvm-cfa1d499f92d52c2ac2443c52fb77ad2fc64591d.zip |
[PDB] Add the ability to map forward references to full decls.
Some records point to an LF_CLASS, LF_UNION, LF_STRUCTURE, or LF_ENUM
which is a forward reference and doesn't contain complete debug
information. In these cases, we'd like to be able to quickly locate the
full record. The TPI stream stores an array of pre-computed record hash
values, one for each type record. If we pre-process this on startup, we
can build a mapping from hash value -> {list of possible matching type
indices}. Since hashes of full records are only based on the name and or
unique name and not the full record contents, we can then use forward
ref record to compute the hash of what *would* be the full record by
just hashing the name, use this to get the list of possible matches, and
iterate those looking for a match on name or unique name.
llvm-pdbutil is updated to resolve forward references for the purposes
of testing (plus it's just useful).
Differential Revision: https://reviews.llvm.org/D52283
llvm-svn: 342656
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/DebugInfo/PDB/Inputs/every-class.cpp | 61 | ||||
-rw-r--r-- | llvm/test/DebugInfo/PDB/Inputs/every-class.pdb | bin | 0 -> 102400 bytes | |||
-rw-r--r-- | llvm/test/DebugInfo/PDB/every-type.test | 6 | ||||
-rw-r--r-- | llvm/test/DebugInfo/PDB/pdb-resolve-forward-refs.test | 98 | ||||
-rw-r--r-- | llvm/test/DebugInfo/PDB/pdbdump-headers.test | 6 |
5 files changed, 167 insertions, 4 deletions
diff --git a/llvm/test/DebugInfo/PDB/Inputs/every-class.cpp b/llvm/test/DebugInfo/PDB/Inputs/every-class.cpp new file mode 100644 index 00000000000..c439bc2f365 --- /dev/null +++ b/llvm/test/DebugInfo/PDB/Inputs/every-class.cpp @@ -0,0 +1,61 @@ +// Build with "cl.exe /Z7 /GR- /GS- /GX- every-class.cpp /link /debug:full /nodefaultlib /incremental:no /entry:main" + +#include <stdint.h> + +// clang-format off +void *__purecall = 0; + +void __cdecl operator delete(void *, unsigned int) {} +void __cdecl operator delete(void *, unsigned __int64) {} + +struct Nothing {}; +struct Constructor { Constructor() {} }; +struct Assignment { + Assignment &operator=(Assignment Other) { return *this; } +}; +struct Cast { + operator int() { return 42; } +}; + +struct Nested { + struct F {}; +}; +struct Operator { + int operator+(int X) { return 42; } +}; + +class Class {}; + +union Union {}; + +enum class Enum {A}; + + +template<typename T> void f(T t) {} + +int main(int argc, char **argv) { + struct Scoped {}; + + struct { } Anonymous; + + f(Nothing{}); + f(Constructor{}); + f(Assignment{}); + f(Cast{}); + f(Nested{}); + f(Operator{}); + f(Nested::F{}); + f(Scoped{}); + f(Class{}); + f(Union{}); + f(Anonymous); + f(Enum::A); + + + f<const Nothing>(Nothing{}); + f<volatile Nothing>(Nothing{}); + f<const volatile Nothing>(Nothing{}); + f<__unaligned Nothing>(Nothing{}); + + return 0; +} diff --git a/llvm/test/DebugInfo/PDB/Inputs/every-class.pdb b/llvm/test/DebugInfo/PDB/Inputs/every-class.pdb Binary files differnew file mode 100644 index 00000000000..6462a705c86 --- /dev/null +++ b/llvm/test/DebugInfo/PDB/Inputs/every-class.pdb diff --git a/llvm/test/DebugInfo/PDB/every-type.test b/llvm/test/DebugInfo/PDB/every-type.test index f188c746e60..39772d4161f 100644 --- a/llvm/test/DebugInfo/PDB/every-type.test +++ b/llvm/test/DebugInfo/PDB/every-type.test @@ -9,12 +9,14 @@ we claim to understand. We then test this in two ways: RUN: llvm-pdbutil dump -type-index=0x101A,0x102C,0x103D,0x104D,0x1098,0x10AA,0x10AC \ -RUN: -dependents %p/Inputs/every-type.pdb | FileCheck --check-prefix=TYPES %s +RUN: -dont-resolve-forward-refs -dependents %p/Inputs/every-type.pdb \ +RUN: | FileCheck --check-prefix=TYPES %s RUN: llvm-pdbutil pdb2yaml -tpi-stream -ipi-stream %p/Inputs/every-type.pdb > %t.pdb.yaml RUN: llvm-pdbutil yaml2pdb -pdb=%t.yaml.pdb %t.pdb.yaml RUN: llvm-pdbutil dump -type-index=0x101A,0x102C,0x103D,0x104D,0x1098,0x10AA,0x10AC \ -RUN: -dependents %t.yaml.pdb | FileCheck --check-prefix=TYPES %s +RUN: -dependents -dont-resolve-forward-refs %t.yaml.pdb \ +RUN: | FileCheck --check-prefix=TYPES %s TYPES: Types (TPI Stream) TYPES-NEXT: ============================================================ diff --git a/llvm/test/DebugInfo/PDB/pdb-resolve-forward-refs.test b/llvm/test/DebugInfo/PDB/pdb-resolve-forward-refs.test new file mode 100644 index 00000000000..adb1c61d862 --- /dev/null +++ b/llvm/test/DebugInfo/PDB/pdb-resolve-forward-refs.test @@ -0,0 +1,98 @@ +; RUN: llvm-pdbutil dump -types %p/Inputs/every-class.pdb \ +; RUN: | FileCheck %s + +; CHECK: Types (TPI Stream) +; CHECK: ============================================================ +; CHECK: Showing 157 records +; CHECK: 0x1008 | LF_STRUCTURE [size = 124] `main::__l2::<unnamed-type-Anonymous>` +; CHECK: unique name: `.?AU<unnamed-type-Anonymous>@?1??main@@YAHHPEAPEAD@Z@`aa6523bc` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1007 +; CHECK: options: has unique name | scoped, sizeof 1 +; CHECK: 0x1009 | LF_STRUCTURE [size = 88] `main::__l2::Scoped` +; CHECK: unique name: `.?AUScoped@?1??main@@YAHHPEAPEAD@Z@`aa6523bc` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1007 +; CHECK: options: has unique name | scoped, sizeof 1 +; CHECK: 0x1054 | LF_STRUCTURE [size = 48] `Nested::F` +; CHECK: unique name: `.?AUF@Nested@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (-> 0x1057) | has unique name | is nested, sizeof 0 +; CHECK: 0x1056 | LF_STRUCTURE [size = 44] `Nested` +; CHECK: unique name: `.?AUNested@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1055 +; CHECK: options: contains nested class | has unique name, sizeof 1 +; CHECK: 0x1057 | LF_STRUCTURE [size = 48] `Nested::F` +; CHECK: unique name: `.?AUF@Nested@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1007 +; CHECK: options: has unique name | is nested, sizeof 1 +; CHECK: 0x1058 | LF_STRUCTURE [size = 52] `Constructor` +; CHECK: unique name: `.?AUConstructor@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (-> 0x105C) | has unique name, sizeof 0 +; CHECK: 0x105C | LF_STRUCTURE [size = 52] `Constructor` +; CHECK: unique name: `.?AUConstructor@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x105B +; CHECK: options: has ctor / dtor | has unique name, sizeof 1 +; CHECK: 0x105D | LF_CLASS [size = 40] `Class` +; CHECK: unique name: `.?AVClass@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1007 +; CHECK: options: has unique name, sizeof 1 +; CHECK: 0x105E | LF_UNION [size = 32] `Union` +; CHECK: unique name: `.?ATUnion@@` +; CHECK: field list: 0x1007 +; CHECK: options: has unique name | sealed, sizeof 1 +; CHECK: 0x105F | LF_STRUCTURE [size = 48] `Operator` +; CHECK: unique name: `.?AUOperator@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (-> 0x1064) | has unique name, sizeof 0 +; CHECK: 0x1064 | LF_STRUCTURE [size = 48] `Operator` +; CHECK: unique name: `.?AUOperator@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1063 +; CHECK: options: has unique name | overloaded operator, sizeof 1 +; CHECK: 0x1066 | LF_ENUM [size = 36] `Enum` +; CHECK: unique name: `.?AW4Enum@@` +; CHECK: field list: 0x1065, underlying type: 0x0074 (int) +; CHECK: options: has unique name +; CHECK: 0x1067 | LF_STRUCTURE [size = 40] `Cast` +; CHECK: unique name: `.?AUCast@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (-> 0x106B) | has unique name, sizeof 0 +; CHECK: 0x106B | LF_STRUCTURE [size = 40] `Cast` +; CHECK: unique name: `.?AUCast@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x106A +; CHECK: options: conversion operator | has unique name | overloaded operator, sizeof 1 +; CHECK: 0x106C | LF_STRUCTURE [size = 44] `Nothing` +; CHECK: unique name: `.?AUNothing@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1007 +; CHECK: options: has unique name, sizeof 1 +; CHECK: 0x106D | LF_STRUCTURE [size = 52] `Assignment` +; CHECK: unique name: `.?AUAssignment@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (-> 0x1073) | has unique name, sizeof 0 +; CHECK: 0x1073 | LF_STRUCTURE [size = 52] `Assignment` +; CHECK: unique name: `.?AUAssignment@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: 0x1072 +; CHECK: options: has unique name | overloaded operator | overloaded operator=, sizeof 1 +; CHECK: 0x1074 | LF_STRUCTURE [size = 44] `Nothing` +; CHECK: unique name: `.?AUNothing@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (<- 0x106C) | has unique name, sizeof 0 +; CHECK: 0x1081 | LF_UNION [size = 32] `Union` +; CHECK: unique name: `.?ATUnion@@` +; CHECK: field list: <no type> +; CHECK: options: forward ref (<- 0x105E) | has unique name, sizeof 0 +; CHECK: 0x1084 | LF_STRUCTURE [size = 124] `main::__l2::<unnamed-type-Anonymous>` +; CHECK: unique name: `.?AU<unnamed-type-Anonymous>@?1??main@@YAHHPEAPEAD@Z@`aa6523bc` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (<- 0x1008) | has unique name | scoped, sizeof 0 +; CHECK: 0x108E | LF_STRUCTURE [size = 44] `Nested` +; CHECK: unique name: `.?AUNested@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (<- 0x1056) | has unique name, sizeof 0 +; CHECK: 0x1095 | LF_STRUCTURE [size = 88] `main::__l2::Scoped` +; CHECK: unique name: `.?AUScoped@?1??main@@YAHHPEAPEAD@Z@`aa6523bc` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (<- 0x1009) | has unique name | scoped, sizeof 0 +; CHECK: 0x1098 | LF_CLASS [size = 40] `Class` +; CHECK: unique name: `.?AVClass@@` +; CHECK: vtable: <no type>, base list: <no type>, field list: <no type> +; CHECK: options: forward ref (<- 0x105D) | has unique name, sizeof 0 diff --git a/llvm/test/DebugInfo/PDB/pdbdump-headers.test b/llvm/test/DebugInfo/PDB/pdbdump-headers.test index 99c37218e92..2a6c862ac2a 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-headers.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-headers.test @@ -1,7 +1,9 @@ -; RUN: llvm-pdbutil dump -all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s +; RUN: llvm-pdbutil dump -all -dont-resolve-forward-refs %p/Inputs/empty.pdb \ +; RUN: | FileCheck -check-prefix=ALL %s ; RUN: llvm-pdbutil dump -summary -modules -files \ ; RUN: %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s -; RUN: not llvm-pdbutil dump -summary %p/Inputs/bad-block-size.pdb 2>&1 | FileCheck -check-prefix=BAD-BLOCK-SIZE %s +; RUN: not llvm-pdbutil dump -summary %p/Inputs/bad-block-size.pdb 2>&1 \ +; RUN: | FileCheck -check-prefix=BAD-BLOCK-SIZE %s ALL: Summary ALL-NEXT: ============================================================ |