summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2018-09-20 15:50:13 +0000
committerZachary Turner <zturner@google.com>2018-09-20 15:50:13 +0000
commitcfa1d499f92d52c2ac2443c52fb77ad2fc64591d (patch)
treef2b31c0d4b966be52afdd166dc8434c582bcbb38 /llvm/test
parent0aea310391dded5ff10d8e183cf255b614026cb0 (diff)
downloadbcm5719-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.cpp61
-rw-r--r--llvm/test/DebugInfo/PDB/Inputs/every-class.pdbbin0 -> 102400 bytes
-rw-r--r--llvm/test/DebugInfo/PDB/every-type.test6
-rw-r--r--llvm/test/DebugInfo/PDB/pdb-resolve-forward-refs.test98
-rw-r--r--llvm/test/DebugInfo/PDB/pdbdump-headers.test6
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
new file mode 100644
index 00000000000..6462a705c86
--- /dev/null
+++ b/llvm/test/DebugInfo/PDB/Inputs/every-class.pdb
Binary files differ
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: ============================================================
OpenPOWER on IntegriCloud