diff options
| author | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2018-08-14 07:57:44 +0000 |
|---|---|---|
| committer | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2018-08-14 07:57:44 +0000 |
| commit | 7d2a74fc545df8db42d40992a3027e09c523c26c (patch) | |
| tree | 038734fb1400e82b1b0b8f7dcac3b85320ed4813 /lldb/lit/SymbolFile/PDB/Inputs | |
| parent | 3c859b3ec3fe20f0878c7e1c9ff66172ba3345ac (diff) | |
| download | bcm5719-llvm-7d2a74fc545df8db42d40992a3027e09c523c26c.tar.gz bcm5719-llvm-7d2a74fc545df8db42d40992a3027e09c523c26c.zip | |
[PDB] Parse UDT symbols and pointers to members (combined patch)
Summary:
In this patch I've tried to combine the best ideas from D49368 and D49410,
so it implements following:
- Completion of UDTs from a PDB with a filling of a layout info;
- Pointers to members;
- Fixes the bug relating to a virtual base offset reading from `vbtable`.
The offset was treated as an unsigned, but it can be a negative sometimes.
- Support of MSInheritance attribute
Reviewers: asmith, zturner, rnk, labath, clayborg, lldb-commits
Reviewed By: zturner
Subscribers: aleksandr.urakov, stella.stamenova, JDevlieghere, lldb-commits
Differential Revision: https://reviews.llvm.org/D49980
llvm-svn: 339649
Diffstat (limited to 'lldb/lit/SymbolFile/PDB/Inputs')
| -rw-r--r-- | lldb/lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp | 111 | ||||
| -rw-r--r-- | lldb/lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp | 23 | ||||
| -rw-r--r-- | lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp | 61 | ||||
| -rw-r--r-- | lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script | 4 |
4 files changed, 199 insertions, 0 deletions
diff --git a/lldb/lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp b/lldb/lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp new file mode 100644 index 00000000000..3c4b005cdf1 --- /dev/null +++ b/lldb/lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp @@ -0,0 +1,111 @@ +// To avoid linking MSVC specific libs, we don't test virtual/override methods +// that needs vftable support in this file. + +// Enum. +enum Enum { RED, GREEN, BLUE }; +Enum EnumVar; + +// Union. +union Union { + short Row; + unsigned short Col; + int Line : 16; // Test named bitfield. + short : 8; // Unnamed bitfield symbol won't be generated in PDB. + long Table; +}; +Union UnionVar; + +// Struct. +struct Struct; +typedef Struct StructTypedef; + +struct Struct { + bool A; + unsigned char UCharVar; + unsigned int UIntVar; + long long LongLongVar; + Enum EnumVar; // Test struct has UDT member. + int array[10]; +}; +struct Struct StructVar; + +struct _List; // Forward declaration. +struct Complex { + struct _List *array[90]; + struct { // Test unnamed struct. MSVC treats it as `int x` + int x; + }; + union { // Test unnamed union. MSVC treats it as `int a; float b;` + int a; + float b; + }; +}; +struct Complex c; + +struct _List { // Test doubly linked list. + struct _List *current; + struct _List *previous; + struct _List *next; +}; +struct _List ListVar; + +typedef struct { + int a; +} UnnamedStruct; // Test unnamed typedef-ed struct. +UnnamedStruct UnnanmedVar; + +// Class. +namespace MemberTest { +class Base { +public: + Base() {} + ~Base() {} + +public: + int Get() { return 0; } + +protected: + int a; +}; +class Friend { +public: + int f() { return 3; } +}; +class Class : public Base { // Test base class. + friend Friend; + static int m_static; // Test static member variable. +public: + Class() : m_public(), m_private(), m_protected() {} + explicit Class(int a) { m_public = a; } // Test first reference of m_public. + ~Class() {} + + static int StaticMemberFunc(int a, ...) { + return 1; + } // Test static member function. + int Get() { return 1; } + int f(Friend c) { return c.f(); } + inline bool operator==(const Class &rhs) const // Test operator. + { + return (m_public == rhs.m_public); + } + +public: + int m_public; + struct Struct m_struct; + +private: + Union m_union; + int m_private; + +protected: + friend class Friend; + int m_protected; +}; +} // namespace MemberTest + +int main() { + MemberTest::Base B1; + B1.Get(); + MemberTest::Class::StaticMemberFunc(1, 10, 2); + return 0; +} diff --git a/lldb/lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp b/lldb/lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp new file mode 100644 index 00000000000..6612c30f00d --- /dev/null +++ b/lldb/lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp @@ -0,0 +1,23 @@ +int main() { + // Test pointer to array. + int array[2][4]; + int(*array_pointer)[2][4] = &array; + + struct ST { + int a; + int f(int x) { return 1; } + }; + + ST s = {10}; + + // Test pointer to a local. + int *p_int = &s.a; + + // Test pointer to data member. + int ST::*p_member_field = &ST::a; + + // Test pointer to member function. + int (ST::*p_member_method)(int) = &ST::f; + + return 0; +} diff --git a/lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp b/lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp new file mode 100644 index 00000000000..59a4fc585d7 --- /dev/null +++ b/lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp @@ -0,0 +1,61 @@ +struct A { + explicit A(int u) { _u._u3 = u; } + A(const A &) = default; + virtual ~A() = default; + +private: + union U { + char _u1; + short _u2; + int _u3; + }; + + A::U _u; +}; + +#pragma pack(push, 1) +template <int I> struct B : public virtual A { + B(char a, unsigned short b, int c) : A(a + b + c), _a(a), _b(b), _c(c) {} + +private: + char _a; + unsigned short : 3; + unsigned short _b : 6; + unsigned short : 4; + int _c; +}; +#pragma pack(pop) + +#pragma pack(push, 16) +class C : private virtual B<0>, public virtual B<1>, private B<2>, public B<3> { +public: + C(char x, char y, char z) + : A(x - y + z), B<0>(x, y, z), B<1>(x * 2, y * 2, z * 2), + B<2>(x * 3, y * 3, z * 3), B<3>(x * 4, y * 4, z * 4), _x(x * 5), + _y(y * 5), _z(z * 5) {} + + static int abc; + +private: + int _x; + short _y; + char _z; +}; +int C::abc = 123; +#pragma pack(pop) + +class List { +public: + List() = default; + List(List *p, List *n, C v) : Prev(p), Next(n), Value(v) {} + +private: + List *Prev = nullptr; + List *Next = nullptr; + C Value{1, 2, 3}; +}; + +int main() { + List ls[16]; + return 0; +} diff --git a/lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script b/lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script new file mode 100644 index 00000000000..91de55f4ade --- /dev/null +++ b/lldb/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script @@ -0,0 +1,4 @@ +breakpoint set --file UdtLayoutTest.cpp --line 60 +run +target variable +frame variable |

