| /* Compile with: | |
| for FILE in `seq 3`; do | |
| clang -g -c X86/odr-fwd-declaration2.cpp -DFILE$FILE -o Inputs/odr-fwd-declaration2/$FILE.o | |
| done | |
| */ | |
| // RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/odr-fwd-declaration2 -y %p/dummy-debug-map.map -o - | llvm-dwarfdump -v -debug-info - | FileCheck %s | |
| #ifdef FILE1 | |
| # 1 "Header.h" 1 | |
| struct A { | |
| struct B; | |
| B *bPtr; | |
| B &bRef; | |
| int B::*bPtrToField; | |
| }; | |
| # 3 "Source1.cpp" 2 | |
| void foo() { | |
| A *ptr1 = 0; | |
| } | |
| // First we confirm that bPtr, bRef and bPtrToField reference the forward | |
| // declaration of the struct B. | |
| // | |
| // CHECK: DW_TAG_member | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "bPtr" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[PTR1:[a-f0-9]*]] | |
| // | |
| // CHECK: [[STRUCT1:[a-f0-9]*]]:{{.*}}TAG_structure_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "B" | |
| // CHECK-NOT: AT_byte_size | |
| // CHECK: DW_AT_declaration | |
| // | |
| // CHECK: DW_TAG_member | |
| // CHECK: AT_name{{.*}} "bRef" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[REF1:[a-f0-9]*]] | |
| // | |
| // CHECK: TAG_member | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "bPtrToField" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[PTRTOMEMBER1:[a-f0-9]*]] | |
| // | |
| // CHECK: [[PTR1]]:{{.*}}TAG_pointer_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[STRUCT1]] | |
| // | |
| // CHECK: [[REF1]]:{{.*}}TAG_reference_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[STRUCT1]] | |
| // | |
| // CHECK: [[PTRTOMEMBER1]]:{{.*}}TAG_ptr_to_member_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_containing_type{{.*}}0x{{0*}}[[STRUCT1]] | |
| #elif defined(FILE2) | |
| # 1 "Header.h" 1 | |
| struct A { | |
| struct B; | |
| B *bPtr; | |
| B &bRef; | |
| int B::*bPtrToField; | |
| }; | |
| # 3 "Source2.cpp" 2 | |
| struct A::B { | |
| int x; | |
| }; | |
| void bar() { | |
| A *ptr2 = 0; | |
| } | |
| // Next we confirm that bPtr, bRef and bPtrToField reference the definition of | |
| // B, rather than its declaration. | |
| // | |
| // CHECK: [[STRUCTA:[a-f0-9]*]]:{{.*}}TAG_structure_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "A" | |
| // CHECK-NOT: AT_byte_size | |
| // CHECK: DW_AT_byte_size | |
| // | |
| // CHECK: DW_TAG_member | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "bPtr" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[PTR2:[a-f0-9]*]] | |
| // | |
| // CHECK: [[STRUCT2:[a-f0-9]*]]:{{.*}}TAG_structure_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "B" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: DW_AT_byte_size | |
| // | |
| // CHECK: DW_TAG_member | |
| // CHECK: AT_name{{.*}} "bRef" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[REF2:[a-f0-9]*]] | |
| // | |
| // CHECK: TAG_member | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "bPtrToField" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[PTRTOMEMBER2:[a-f0-9]*]] | |
| // | |
| // CHECK: [[PTR2]]:{{.*}}TAG_pointer_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[STRUCT2]] | |
| // | |
| // CHECK: [[REF2]]:{{.*}}TAG_reference_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[STRUCT2]] | |
| // | |
| // CHECK: [[PTRTOMEMBER2]]:{{.*}}TAG_ptr_to_member_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_containing_type{{.*}}0x{{0*}}[[STRUCT2:[a-f0-9]*]] | |
| #elif defined(FILE3) | |
| # 1 "Header.h" 1 | |
| struct A { | |
| struct B; | |
| B *bPtr; | |
| B &bRef; | |
| int B::*bPtrToField; | |
| }; | |
| # 3 "Source2.cpp" 2 | |
| struct A::B { | |
| int x; | |
| }; | |
| void bar() { | |
| A *ptr2 = 0; | |
| } | |
| // Finally we confirm that uniquing isn't broken by checking that further | |
| // references to 'struct A' point to its now complete definition. | |
| // | |
| // CHECK: TAG_variable | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_name{{.*}} "ptr2" | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[PTR3:[a-f0-9]*]] | |
| // | |
| // CHECK: [[PTR3]]:{{.*}}TAG_pointer_type | |
| // CHECK-NOT: {{DW_TAG|NULL}} | |
| // CHECK: AT_type{{.*}}0x{{0*}}[[STRUCTA]] | |
| #else | |
| #error "You must define which file you generate" | |
| #endif |