Zachary Turner | 511bff2 | 2018-10-30 18:57:08 +0000 | [diff] [blame] | 1 | // clang-format off |
| 2 | // REQUIRES: lld |
| 3 | |
| 4 | // Test that we can display tag types. |
Zachary Turner | 58db03a | 2018-11-19 15:12:34 +0000 | [diff] [blame] | 5 | // RUN: %clang_cl /Z7 /GS- /GR- /c -Xclang -fkeep-static-consts /Fo%t.obj -- %s |
Zachary Turner | 511bff2 | 2018-10-30 18:57:08 +0000 | [diff] [blame] | 6 | // RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb -- %t.obj |
Zachary Turner | 58db03a | 2018-11-19 15:12:34 +0000 | [diff] [blame] | 7 | // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \ |
Zachary Turner | 511bff2 | 2018-10-30 18:57:08 +0000 | [diff] [blame] | 8 | // RUN: %p/Inputs/globals-classes.lldbinit | FileCheck %s |
| 9 | |
| 10 | enum class EnumType : unsigned { |
| 11 | A = 1, |
| 12 | B = 2 |
| 13 | }; |
| 14 | |
| 15 | class ClassNoPadding { |
| 16 | /* [ 0] */ unsigned char a = 86; |
| 17 | /* [ 1] */ char b = 'a'; |
| 18 | /* [ 2] */ bool c = false; |
| 19 | /* [ 3] */ bool d = true; |
| 20 | /* [ 4] */ short e = -1234; |
| 21 | /* [ 6] */ unsigned short f = 8123; |
| 22 | /* [ 8] */ unsigned int g = 123908; |
| 23 | /* [12] */ int h = -890234; |
| 24 | /* [16] */ unsigned long i = 2908234; |
| 25 | /* [20] */ long j = 7234890; |
| 26 | /* [24] */ float k = 908234.12392; |
| 27 | /* [28] */ EnumType l = EnumType::A; |
| 28 | /* [32] */ double m = 23890.897423; |
| 29 | /* [40] */ unsigned long long n = 23490782; |
| 30 | /* [48] */ long long o = -923409823; |
| 31 | /* [56] */ int p[5] = { 2, 3, 5, 8, 13 }; |
| 32 | }; |
| 33 | |
| 34 | class ClassWithPadding { |
| 35 | /* [ 0] */ char a = '0'; |
| 36 | // char padding[1]; |
| 37 | /* [ 2] */ short b = 50; |
| 38 | /* [ 4] */ char c[2] = { '0', '1' }; |
| 39 | // char padding[2]; |
| 40 | /* [ 8] */ int d = 100; |
| 41 | /* [12] */ char e = '0'; |
| 42 | // char padding[3]; |
| 43 | /* [16] */ int f = 200; |
| 44 | // char padding[4]; |
| 45 | /* [24] */ long long g = 300; |
| 46 | /* [32] */ char h[3] = { '0', '1', '2' }; |
| 47 | // char padding[5]; |
| 48 | /* [40] */ long long i = 400; |
| 49 | /* [48] */ char j[2] = { '0', '1' }; |
| 50 | // char padding[6]; |
| 51 | /* [56] */ long long k = 500; |
| 52 | /* [64] */ char l = '0'; |
| 53 | // char padding[7]; |
| 54 | /* [72] */ long long m = 600; |
| 55 | } ; |
| 56 | |
| 57 | struct EmptyBase {}; |
| 58 | |
| 59 | template<typename T> |
| 60 | struct BaseClass { |
| 61 | constexpr BaseClass(int N) |
| 62 | : BaseMember(N) {} |
| 63 | |
| 64 | int BaseMember; |
| 65 | }; |
| 66 | |
| 67 | struct DerivedClass : public BaseClass<int> { |
| 68 | constexpr DerivedClass(int Base, int Derived) |
| 69 | : BaseClass(Base), DerivedMember(Derived) {} |
| 70 | |
| 71 | int DerivedMember; |
| 72 | }; |
| 73 | |
| 74 | struct EBO : public EmptyBase { |
| 75 | constexpr EBO(int N) : Member(N) {} |
| 76 | int Member; |
| 77 | }; |
| 78 | |
| 79 | struct PaddedBases : public BaseClass<char>, public BaseClass<short>, BaseClass<int> { |
| 80 | constexpr PaddedBases(char CH, short S, int N, long long D) |
| 81 | : BaseClass<char>(CH), BaseClass<short>(S), BaseClass<int>(N), DerivedMember(D) {} |
| 82 | long long DerivedMember; |
| 83 | }; |
| 84 | |
| 85 | struct Statics { |
| 86 | static char a; |
| 87 | static bool b; |
| 88 | static short c; |
| 89 | static unsigned short d; |
| 90 | static unsigned int e; |
| 91 | static int f; |
| 92 | static unsigned long g; |
| 93 | static long h; |
| 94 | static float i; |
| 95 | static EnumType j; |
| 96 | static double k; |
| 97 | static unsigned long long l; |
| 98 | static long long m; |
| 99 | }; |
| 100 | |
| 101 | char Statics::a = 'a'; |
| 102 | bool Statics::b = true; |
| 103 | short Statics::c = 1234; |
| 104 | unsigned short Statics::d = 2345; |
| 105 | unsigned int Statics::e = 3456; |
| 106 | int Statics::f = 4567; |
| 107 | unsigned long Statics::g = 5678; |
| 108 | long Statics::h = 6789; |
| 109 | float Statics::i = 7890.1234; |
| 110 | EnumType Statics::j = EnumType::A; |
| 111 | double Statics::k = 8901.2345; |
| 112 | unsigned long long Statics::l = 9012345; |
| 113 | long long Statics::m = 1234567; |
| 114 | |
| 115 | |
| 116 | struct Pointers { |
| 117 | void *a = nullptr; |
| 118 | char *b = &Statics::a; |
| 119 | bool *c = &Statics::b; |
| 120 | short *e = &Statics::c; |
| 121 | unsigned short *f = &Statics::d; |
| 122 | unsigned int *g = &Statics::e; |
| 123 | int *h = &Statics::f; |
| 124 | unsigned long *i = &Statics::g; |
| 125 | long *j = &Statics::h; |
| 126 | float *k = &Statics::i; |
| 127 | EnumType *l = &Statics::j; |
| 128 | double *m = &Statics::k; |
| 129 | unsigned long long *n = &Statics::l; |
| 130 | long long *o = &Statics::m; |
| 131 | }; |
| 132 | |
| 133 | struct References { |
| 134 | char &a = Statics::a; |
| 135 | bool &b = Statics::b; |
| 136 | short &c = Statics::c; |
| 137 | unsigned short &d = Statics::d; |
| 138 | unsigned int &e = Statics::e; |
| 139 | int &f = Statics::f; |
| 140 | unsigned long &g = Statics::g; |
| 141 | long &h = Statics::h; |
| 142 | float &i = Statics::i; |
| 143 | EnumType &j = Statics::j; |
| 144 | double &k = Statics::k; |
| 145 | unsigned long long &l = Statics::l; |
| 146 | long long &m = Statics::m; |
| 147 | }; |
| 148 | |
| 149 | |
| 150 | constexpr ClassWithPadding ClassWithPaddingInstance; |
| 151 | // CHECK: (lldb) target variable -T ClassWithPaddingInstance |
| 152 | // CHECK-NEXT: (const ClassWithPadding) ClassWithPaddingInstance = { |
| 153 | // CHECK-NEXT: (char) a = '0' |
| 154 | // CHECK-NEXT: (short) b = 50 |
| 155 | // CHECK-NEXT: (char [2]) c = "01" |
| 156 | // CHECK-NEXT: (int) d = 100 |
| 157 | // CHECK-NEXT: (char) e = '0' |
| 158 | // CHECK-NEXT: (int) f = 200 |
| 159 | // CHECK-NEXT: (long long) g = 300 |
| 160 | // CHECK-NEXT: (char [3]) h = "012" |
| 161 | // CHECK-NEXT: (long long) i = 400 |
| 162 | // CHECK-NEXT: (char [2]) j = "01" |
| 163 | // CHECK-NEXT: (long long) k = 500 |
| 164 | // CHECK-NEXT: (char) l = '0' |
| 165 | // CHECK-NEXT: (long long) m = 600 |
| 166 | // CHECK-NEXT: } |
| 167 | |
| 168 | constexpr ClassNoPadding ClassNoPaddingInstance; |
| 169 | // CHECK: (lldb) target variable -T ClassNoPaddingInstance |
| 170 | // CHECK-NEXT: (const ClassNoPadding) ClassNoPaddingInstance = { |
| 171 | // CHECK-NEXT: (unsigned char) a = 'V' |
| 172 | // CHECK-NEXT: (char) b = 'a' |
| 173 | // CHECK-NEXT: (bool) c = false |
| 174 | // CHECK-NEXT: (bool) d = true |
| 175 | // CHECK-NEXT: (short) e = -1234 |
| 176 | // CHECK-NEXT: (unsigned short) f = 8123 |
| 177 | // CHECK-NEXT: (unsigned int) g = 123908 |
| 178 | // CHECK-NEXT: (int) h = -890234 |
| 179 | // CHECK-NEXT: (unsigned long) i = 2908234 |
| 180 | // CHECK-NEXT: (long) j = 7234890 |
| 181 | // CHECK-NEXT: (float) k = 908234.125 |
| 182 | // CHECK-NEXT: (EnumType) l = A |
| 183 | // CHECK-NEXT: (double) m = 23890.897422999999 |
| 184 | // CHECK-NEXT: (unsigned long long) n = 23490782 |
| 185 | // CHECK-NEXT: (long long) o = -923409823 |
| 186 | // CHECK-NEXT: (int [5]) p = { |
| 187 | // CHECK-NEXT: (int) [0] = 2 |
| 188 | // CHECK-NEXT: (int) [1] = 3 |
| 189 | // CHECK-NEXT: (int) [2] = 5 |
| 190 | // CHECK-NEXT: (int) [3] = 8 |
| 191 | // CHECK-NEXT: (int) [4] = 13 |
| 192 | // CHECK-NEXT: } |
| 193 | // CHECK-NEXT: } |
| 194 | |
| 195 | constexpr DerivedClass DC(10, 20); |
| 196 | // CHECK: (lldb) target variable -T DC |
| 197 | // CHECK-NEXT: (const DerivedClass) DC = { |
| 198 | // CHECK-NEXT: (BaseClass<int>) BaseClass<int> = { |
| 199 | // CHECK-NEXT: (int) BaseMember = 10 |
| 200 | // CHECK-NEXT: } |
| 201 | // CHECK-NEXT: (int) DerivedMember = 20 |
| 202 | // CHECK-NEXT: } |
| 203 | |
| 204 | constexpr EBO EBOC(20); |
| 205 | // CHECK: (lldb) target variable -T EBOC |
| 206 | // CHECK-NEXT: (const EBO) EBOC = { |
| 207 | // CHECK-NEXT: (int) Member = 20 |
| 208 | // CHECK-NEXT: } |
| 209 | |
| 210 | constexpr PaddedBases PBC('a', 12, 120, 1200); |
| 211 | // CHECK: (lldb) target variable -T PBC |
| 212 | // CHECK-NEXT: (const PaddedBases) PBC = { |
| 213 | // CHECK-NEXT: (BaseClass<char>) BaseClass<char> = { |
| 214 | // CHECK-NEXT: (int) BaseMember = 97 |
| 215 | // CHECK-NEXT: } |
| 216 | // CHECK-NEXT: (BaseClass<short>) BaseClass<short> = { |
| 217 | // CHECK-NEXT: (int) BaseMember = 12 |
| 218 | // CHECK-NEXT: } |
| 219 | // CHECK-NEXT: (BaseClass<int>) BaseClass<int> = { |
| 220 | // CHECK-NEXT: (int) BaseMember = 120 |
| 221 | // CHECK-NEXT: } |
| 222 | // CHECK-NEXT: (long long) DerivedMember = 1200 |
| 223 | // CHECK-NEXT: } |
| 224 | |
| 225 | constexpr struct { |
| 226 | int x = 12; |
| 227 | EBO EBOC{ 42 }; |
| 228 | } UnnamedClassInstance; |
| 229 | // CHECK: (lldb) target variable -T UnnamedClassInstance |
| 230 | // CHECK-NEXT: (const <unnamed-type-UnnamedClassInstance>) UnnamedClassInstance = { |
| 231 | // CHECK-NEXT: (int) x = 12 |
| 232 | // CHECK-NEXT: (EBO) EBOC = { |
| 233 | // CHECK-NEXT: (int) Member = 42 |
| 234 | // CHECK-NEXT: } |
| 235 | // CHECK-NEXT: } |
| 236 | |
| 237 | constexpr Pointers PointersInstance; |
| 238 | // CHECK: (lldb) target variable -T PointersInstance |
| 239 | // CHECK-NEXT: (const Pointers) PointersInstance = { |
| 240 | // CHECK-NEXT: (void *) a = {{.*}} |
| 241 | // CHECK-NEXT: (char *) b = {{.*}} |
| 242 | // CHECK-NEXT: (bool *) c = {{.*}} |
| 243 | // CHECK-NEXT: (short *) e = {{.*}} |
| 244 | // CHECK-NEXT: (unsigned short *) f = {{.*}} |
| 245 | // CHECK-NEXT: (unsigned int *) g = {{.*}} |
| 246 | // CHECK-NEXT: (int *) h = {{.*}} |
| 247 | // CHECK-NEXT: (unsigned long *) i = {{.*}} |
| 248 | // CHECK-NEXT: (long *) j = {{.*}} |
| 249 | // CHECK-NEXT: (float *) k = {{.*}} |
| 250 | // CHECK-NEXT: (EnumType *) l = {{.*}} |
| 251 | // CHECK-NEXT: (double *) m = {{.*}} |
| 252 | // CHECK-NEXT: (unsigned long long *) n = {{.*}} |
| 253 | // CHECK-NEXT: (long long *) o = {{.*}} |
| 254 | // CHECK-NEXT: } |
| 255 | constexpr References ReferencesInstance; |
| 256 | // CHECK: (lldb) target variable -T ReferencesInstance |
| 257 | // CHECK-NEXT: (const References) ReferencesInstance = { |
| 258 | // CHECK-NEXT: (char &) a = {{.*}} |
| 259 | // CHECK-NEXT: (bool &) b = {{.*}} |
| 260 | // CHECK-NEXT: (short &) c = {{.*}} |
| 261 | // CHECK-NEXT: (unsigned short &) d = {{.*}} |
| 262 | // CHECK-NEXT: (unsigned int &) e = {{.*}} |
| 263 | // CHECK-NEXT: (int &) f = {{.*}} |
| 264 | // CHECK-NEXT: (unsigned long &) g = {{.*}} |
| 265 | // CHECK-NEXT: (long &) h = {{.*}} |
| 266 | // CHECK-NEXT: (float &) i = {{.*}} |
| 267 | // CHECK-NEXT: (EnumType &) j = {{.*}} |
| 268 | // CHECK-NEXT: (double &) k = {{.*}} |
| 269 | // CHECK-NEXT: (unsigned long long &) l = {{.*}} |
| 270 | // CHECK-NEXT: (long long &) m = {{.*}} |
| 271 | // CHECK-NEXT: } |
| 272 | |
Zachary Turner | 056e4ab | 2018-11-08 18:50:11 +0000 | [diff] [blame] | 273 | // CHECK: Dumping clang ast for 1 modules. |
| 274 | // CHECK: TranslationUnitDecl {{.*}} |
| 275 | // CHECK: |-CXXRecordDecl {{.*}} class ClassWithPadding definition |
| 276 | // CHECK: | |-FieldDecl {{.*}} a 'char' |
| 277 | // CHECK: | |-FieldDecl {{.*}} b 'short' |
| 278 | // CHECK: | |-FieldDecl {{.*}} c 'char [2]' |
| 279 | // CHECK: | |-FieldDecl {{.*}} d 'int' |
| 280 | // CHECK: | |-FieldDecl {{.*}} e 'char' |
| 281 | // CHECK: | |-FieldDecl {{.*}} f 'int' |
| 282 | // CHECK: | |-FieldDecl {{.*}} g 'long long' |
| 283 | // CHECK: | |-FieldDecl {{.*}} h 'char [3]' |
| 284 | // CHECK: | |-FieldDecl {{.*}} i 'long long' |
| 285 | // CHECK: | |-FieldDecl {{.*}} j 'char [2]' |
| 286 | // CHECK: | |-FieldDecl {{.*}} k 'long long' |
| 287 | // CHECK: | |-FieldDecl {{.*}} l 'char' |
| 288 | // CHECK: | `-FieldDecl {{.*}} m 'long long' |
| 289 | // CHECK: |-CXXRecordDecl {{.*}} class ClassNoPadding definition |
| 290 | // CHECK: | |-FieldDecl {{.*}} a 'unsigned char' |
| 291 | // CHECK: | |-FieldDecl {{.*}} b 'char' |
| 292 | // CHECK: | |-FieldDecl {{.*}} c 'bool' |
| 293 | // CHECK: | |-FieldDecl {{.*}} d 'bool' |
| 294 | // CHECK: | |-FieldDecl {{.*}} e 'short' |
| 295 | // CHECK: | |-FieldDecl {{.*}} f 'unsigned short' |
| 296 | // CHECK: | |-FieldDecl {{.*}} g 'unsigned int' |
| 297 | // CHECK: | |-FieldDecl {{.*}} h 'int' |
| 298 | // CHECK: | |-FieldDecl {{.*}} i 'unsigned long' |
| 299 | // CHECK: | |-FieldDecl {{.*}} j 'long' |
| 300 | // CHECK: | |-FieldDecl {{.*}} k 'float' |
| 301 | // CHECK: | |-FieldDecl {{.*}} l 'EnumType' |
| 302 | // CHECK: | |-FieldDecl {{.*}} m 'double' |
| 303 | // CHECK: | |-FieldDecl {{.*}} n 'unsigned long long' |
| 304 | // CHECK: | |-FieldDecl {{.*}} o 'long long' |
| 305 | // CHECK: | `-FieldDecl {{.*}} p 'int [5]' |
| 306 | // CHECK: |-EnumDecl {{.*}} EnumType |
Zachary Turner | eb98774 | 2018-11-09 01:09:10 +0000 | [diff] [blame] | 307 | // CHECK: | |-EnumConstantDecl {{.*}} A 'EnumType' |
| 308 | // CHECK: | `-EnumConstantDecl {{.*}} B 'EnumType' |
Zachary Turner | 056e4ab | 2018-11-08 18:50:11 +0000 | [diff] [blame] | 309 | // CHECK: |-CXXRecordDecl {{.*}} struct DerivedClass definition |
| 310 | // CHECK: | |-public 'BaseClass<int>' |
| 311 | // CHECK: | `-FieldDecl {{.*}} DerivedMember 'int' |
| 312 | // CHECK: |-CXXRecordDecl {{.*}} struct BaseClass<int> definition |
| 313 | // CHECK: | `-FieldDecl {{.*}} BaseMember 'int' |
| 314 | // CHECK: |-CXXRecordDecl {{.*}} struct EBO definition |
| 315 | // CHECK: | |-public 'EmptyBase' |
| 316 | // CHECK: | `-FieldDecl {{.*}} Member 'int' |
| 317 | // CHECK: |-CXXRecordDecl {{.*}} struct EmptyBase definition |
| 318 | // CHECK: |-CXXRecordDecl {{.*}} struct PaddedBases definition |
| 319 | // CHECK: | |-public 'BaseClass<char>' |
| 320 | // CHECK: | |-public 'BaseClass<short>' |
| 321 | // CHECK: | |-public 'BaseClass<int>' |
| 322 | // CHECK: | `-FieldDecl {{.*}} DerivedMember 'long long' |
| 323 | // CHECK: |-CXXRecordDecl {{.*}} struct BaseClass<char> definition |
| 324 | // CHECK: | `-FieldDecl {{.*}} BaseMember 'int' |
| 325 | // CHECK: |-CXXRecordDecl {{.*}} struct BaseClass<short> definition |
| 326 | // CHECK: | `-FieldDecl {{.*}} BaseMember 'int' |
| 327 | // CHECK: |-CXXRecordDecl {{.*}} struct <unnamed-type-UnnamedClassInstance> definition |
| 328 | // CHECK: | |-FieldDecl {{.*}} x 'int' |
| 329 | // CHECK: | `-FieldDecl {{.*}} EBOC 'EBO' |
| 330 | // CHECK: |-CXXRecordDecl {{.*}} struct Pointers definition |
| 331 | // CHECK: | |-FieldDecl {{.*}} a 'void *' |
| 332 | // CHECK: | |-FieldDecl {{.*}} b 'char *' |
| 333 | // CHECK: | |-FieldDecl {{.*}} c 'bool *' |
| 334 | // CHECK: | |-FieldDecl {{.*}} e 'short *' |
| 335 | // CHECK: | |-FieldDecl {{.*}} f 'unsigned short *' |
| 336 | // CHECK: | |-FieldDecl {{.*}} g 'unsigned int *' |
| 337 | // CHECK: | |-FieldDecl {{.*}} h 'int *' |
| 338 | // CHECK: | |-FieldDecl {{.*}} i 'unsigned long *' |
| 339 | // CHECK: | |-FieldDecl {{.*}} j 'long *' |
| 340 | // CHECK: | |-FieldDecl {{.*}} k 'float *' |
| 341 | // CHECK: | |-FieldDecl {{.*}} l 'EnumType *' |
| 342 | // CHECK: | |-FieldDecl {{.*}} m 'double *' |
| 343 | // CHECK: | |-FieldDecl {{.*}} n 'unsigned long long *' |
| 344 | // CHECK: | `-FieldDecl {{.*}} o 'long long *' |
| 345 | // CHECK: |-CXXRecordDecl {{.*}} struct References definition |
| 346 | // CHECK: | |-FieldDecl {{.*}} a 'char &' |
| 347 | // CHECK: | |-FieldDecl {{.*}} b 'bool &' |
| 348 | // CHECK: | |-FieldDecl {{.*}} c 'short &' |
| 349 | // CHECK: | |-FieldDecl {{.*}} d 'unsigned short &' |
| 350 | // CHECK: | |-FieldDecl {{.*}} e 'unsigned int &' |
| 351 | // CHECK: | |-FieldDecl {{.*}} f 'int &' |
| 352 | // CHECK: | |-FieldDecl {{.*}} g 'unsigned long &' |
| 353 | // CHECK: | |-FieldDecl {{.*}} h 'long &' |
| 354 | // CHECK: | |-FieldDecl {{.*}} i 'float &' |
| 355 | // CHECK: | |-FieldDecl {{.*}} j 'EnumType &' |
| 356 | // CHECK: | |-FieldDecl {{.*}} k 'double &' |
| 357 | // CHECK: | |-FieldDecl {{.*}} l 'unsigned long long &' |
| 358 | // CHECK: | `-FieldDecl {{.*}} m 'long long &' |
| 359 | // CHECK: `-<undeserialized declarations> |
| 360 | |
Zachary Turner | 511bff2 | 2018-10-30 18:57:08 +0000 | [diff] [blame] | 361 | int main(int argc, char **argv) { |
| 362 | return 0; |
Jonas Devlieghere | ceff664 | 2018-11-11 23:17:06 +0000 | [diff] [blame] | 363 | } |