Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[dsymutil] Don't mark forward declarations as canonical.
This patch completes the work done by Frederic Riss to addresses dsymutil incorrectly considering forward declaration as canonical during uniquing. This resulted in references to the forward declaration even after the definition was encountered. In addition to the test provided by Alexander Shaposhnikov in D29609, I added another test to cover several scenarios that were mentioned in his conversation with Fred. We now also check that uniquing still occurs after the definition was encountered. For more context please refer to D29609 Differential revision: https://reviews.llvm.org/D37127 llvm-svn: 312274
- Loading branch information
1 parent
c2774a5
commit d906365
Showing
9 changed files
with
323 additions
and
17 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* Compile with: | ||
for FILE in `seq 3`; do | ||
clang -g -c X86/odr-fwd-declaration.cpp -DFILE$FILE -o Inputs/odr-fwd-declaration/$FILE.o | ||
done | ||
*/ | ||
|
||
// RUN: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/odr-fwd-declaration -y %p/dummy-debug-map.map -o - | llvm-dwarfdump -debug-dump=info - | FileCheck %s | ||
|
||
#ifdef FILE1 | ||
# 1 "Header.h" 1 | ||
typedef struct S *Sptr; | ||
typedef Sptr *Sptrptr; | ||
# 3 "Source1.cpp" 2 | ||
void foo() { | ||
Sptrptr ptr1 = 0; | ||
} | ||
|
||
// First we confirm that the typedefs reference the forward declaration of the | ||
// struct S. | ||
// | ||
// CHECK: TAG_variable | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "ptr1" | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[TYPEDEF1:[a-f0-9]*]] | ||
// | ||
// CHECK: [[TYPEDEF1]]:{{.*}}TAG_typedef | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[PTR1:[a-f0-9]*]] | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "Sptrptr" | ||
// | ||
// CHECK: [[PTR1]]:{{.*}}TAG_pointer_type | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[TYPEDEF2:[a-f0-9]*]] | ||
// | ||
// CHECK: [[TYPEDEF2]]:{{.*}}TAG_typedef | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[PTR2:[a-f0-9]*]] | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "Sptr" | ||
// | ||
// CHECK: [[PTR2]]:{{.*}}TAG_pointer_type | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[FWDSTRUCT:[a-f0-9]*]] | ||
// | ||
// CHECK: [[FWDSTRUCT]]:{{.*}}TAG_structure_type | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "S" | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_declaration | ||
// CHECK-NOT AT_byte_size | ||
|
||
#elif defined(FILE2) | ||
# 1 "Header.h" 1 | ||
typedef struct S *Sptr; | ||
typedef Sptr *Sptrptr; | ||
# 3 "Source2.cpp" 2 | ||
struct S { | ||
int field; | ||
}; | ||
void bar() { | ||
Sptrptr ptr2 = 0; | ||
} | ||
|
||
// Next we confirm that the typedefs reference the definition rather than the | ||
// previous declaration of S. | ||
// | ||
// CHECK: TAG_variable | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "ptr2" | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[TYPEDEF3:[a-f0-9]*]] | ||
// | ||
// CHECK: [[TYPEDEF3]]:{{.*}}TAG_typedef | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[PTR3:[a-f0-9]*]] | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "Sptrptr" | ||
// | ||
// CHECK: [[PTR3]]:{{.*}}TAG_pointer_type | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[TYPEDEF4:[a-f0-9]*]] | ||
// | ||
// CHECK: [[TYPEDEF4]]:{{.*}}TAG_typedef | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[PTR4:[a-f0-9]*]] | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "Sptr" | ||
// | ||
// CHECK: [[PTR4]]:{{.*}}TAG_pointer_type | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[STRUCT:[a-f0-9]*]] | ||
// | ||
// CHECK: [[STRUCT]]:{{.*}}TAG_structure_type | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "S" | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK-NOT: AT_declaration | ||
// CHECK: AT_byte_size | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: TAG_member | ||
|
||
#elif defined(FILE3) | ||
# 1 "Header.h" 1 | ||
typedef struct S *Sptr; | ||
typedef Sptr *Sptrptr; | ||
# 3 "Source1.cpp" 2 | ||
void foo() { | ||
Sptrptr ptr1 = 0; | ||
} | ||
|
||
// Finally we confirm that uniquing is not broken and the same typedef is | ||
// referenced by ptr1. | ||
// | ||
// CHECK: TAG_variable | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_name{{.*}} "ptr1" | ||
// CHECK-NOT: {{DW_TAG|NULL}} | ||
// CHECK: AT_type{{.*}}0x{{0*}}[[TYPEDEF3]] | ||
// CHECK-NOT: TAG_typedef | ||
// CHECK-NOT: TAG_pointer | ||
// CHECK-NOT: TAG_structure_type | ||
|
||
#else | ||
#error "You must define which file you generate" | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* 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: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/odr-fwd-declaration2 -y %p/dummy-debug-map.map -o - | llvm-dwarfdump -debug-dump=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 |
Oops, something went wrong.