diff options
Diffstat (limited to 'llvm/test/tools/dsymutil/X86/odr-uniquing.cpp')
| -rw-r--r-- | llvm/test/tools/dsymutil/X86/odr-uniquing.cpp | 187 | 
1 files changed, 187 insertions, 0 deletions
diff --git a/llvm/test/tools/dsymutil/X86/odr-uniquing.cpp b/llvm/test/tools/dsymutil/X86/odr-uniquing.cpp new file mode 100644 index 00000000000..e1932d41d8a --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/odr-uniquing.cpp @@ -0,0 +1,187 @@ +/* Compile with: +   clang -g -c  odr-uniquing.cpp -o odr-uniquing/1.o +  +   The aim of these test is to check that all the 'type types' that +   should be uniqued through the ODR really are. +    +   The resulting object file is linked against itself using a fake +   debug map. The end result is: +    - with ODR uniquing: all types (expect for the union for now) in +   the second CU should point back to the types of the first CU. +    - without ODR uniquing: all types are re-emited in the second CU + */ + +// RUN: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/odr-uniquing -y %p/dummy-debug-map.map -o - | llvm-dwarfdump -debug-dump=info - | FileCheck -check-prefix=ODR -check-prefix=CHECK %s +// RUN: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/odr-uniquing -y %p/dummy-debug-map.map -no-odr -o - | llvm-dwarfdump -debug-dump=info - | FileCheck -check-prefix=NOODR -check-prefix=CHECK %s + +// The first compile unit contains all the types: +// CHECK: TAG_compile_unit +// CHECK-NOT: DW_TAG +// CHECK: AT_name{{.*}}"odr-uniquing.cpp" + +struct S { +  struct Nested {}; +}; + +// CHECK: 0x[[S:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type +// CHECK-NEXT: DW_AT_name{{.*}}"S" +// CHECK-NOT: NULL +// CHECK: 0x[[NESTED:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name{{.*}}"Nested" +// CHECK: NULL + +namespace N { +class C {}; +} + +// CHECK: DW_TAG_namespace +// CHECK-NEXT: DW_AT_name{{.*}}"N" +// CHECK-NOT: NULL +// CHECK: 0x[[NC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type +// CHECK-NEXT: DW_AT_name{{.*}}"C" +// CHECK: NULL + +union U { +  class C {} C; +  struct S {} S; +}; + +// CHECK:  0x[[U:[0-9a-f]*]]:{{.*}}DW_TAG_union_type +// CHECK-NEXT: DW_AT_name{{.*}}"U" +// CHECK-NOT: NULL +// CHECK:  0x[[UC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type +// CHECK-NOT: NULL +// CHECK:  0x[[US:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type +// CHECK: NULL + +typedef S AliasForS; + +// CHECK: 0x[[ALIASFORS:[0-9a-f]*]]:{{.*}}DW_TAG_typedef +// CHECK-NEXT: DW_AT_type{{.*}}[[S]] +// CHECK-NEXT: DW_AT_name{{.*}}"AliasForS" + +namespace { +class AnonC {}; +} + +// CHECK: DW_TAG_namespace +// CHECK-NOT: {{DW_AT_name|NULL|DW_TAG}} +// CHECK: 0x[[ANONC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type +// CHECK-NEXT: DW_AT_name{{.*}}"AnonC" + +// This function is only here to hold objects that refer to the above types. +void foo() { +  AliasForS s; +  S::Nested n; +  N::C nc; +  AnonC ac; +  U u; +} + +// The second CU contents depend on wether we disabled ODR uniquing or +// not. + +// CHECK: TAG_compile_unit +// CHECK-NOT: DW_TAG +// CHECK: AT_name{{.*}}"odr-uniquing.cpp" + +// The union itself is not uniqued for now (for dsymutil-compatibility), +// but the types defined inside it should be. +// ODR: DW_TAG_union_type +// ODR-NEXT: DW_AT_name{{.*}}"U" +// ODR: DW_TAG_member +// ODR-NEXT: DW_AT_name{{.*}}"C" +// ODR-NOT: DW_TAG +// ODR: DW_AT_type{{.*}}[[UC]] +// ODR: DW_TAG_member +// ODR-NEXT: DW_AT_name{{.*}}"S" +// ODR-NOT: DW_TAG +// ODR: DW_AT_type{{.*}}[[US]] + +// Check that the variables point to the right type +// ODR: DW_TAG_subprogram +// ODR-NOT: DW_TAG +// ODR: DW_AT_name{{.*}}"foo" +// ODR-NOT: NULL +// ODR: DW_TAG_variable +// ODR-NOT: DW_TAG +// ODR: DW_AT_name{{.*}}"s" +// ODR-NOT: DW_TAG +// ODR: DW_AT_type{{.*}}[[ALIASFORS]] +// ODR: DW_AT_name{{.*}}"n" +// ODR-NOT: DW_TAG +// ODR: DW_AT_type{{.*}}[[NESTED]] +// ODR: DW_TAG_variable +// ODR-NOT: DW_TAG +// ODR: DW_AT_name{{.*}}"nc" +// ODR-NOT: DW_TAG +// ODR: DW_AT_type{{.*}}[[NC]] +// ODR: DW_TAG_variable +// ODR-NOT: DW_TAG +// ODR: DW_AT_name{{.*}}"ac" +// ODR-NOT: DW_TAG +// ODR: DW_AT_type{{.*}}[[ANONC]] + +// With no ODR uniquing, we should get copies of all the types: + +// This is "struct S" +// NOODR: 0x[[DUP_S:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type +// NOODR-NEXT: DW_AT_name{{.*}}"S" +// NOODR-NOT: NULL +// NOODR: 0x[[DUP_NESTED:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_name{{.*}}"Nested" + +// This is "class N::C" +// NOODR: DW_TAG_namespace +// NOODR-NEXT: DW_AT_name{{.*}}"N" +// NOODR: 0x[[DUP_NC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type +// NOODR-NEXT: DW_AT_name{{.*}}"C" + +// This is "union U" +// NOODR:  0x[[DUP_U:[0-9a-f]*]]:{{.*}}DW_TAG_union_type +// NOODR-NEXT: DW_AT_name{{.*}}"U" +// NOODR-NOT: NULL +// NOODR:  0x[[DUP_UC:[0-9a-f]*]]:{{.*}}DW_TAG_class_type +// NOODR-NOT: NULL +// NOODR:  0x[[DUP_US:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type +// NOODR: NULL + +// Check that the variables point to the right type +// NOODR: DW_TAG_subprogram +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_name{{.*}}"foo" +// NOODR-NOT: NULL +// NOODR: DW_TAG_variable +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_name{{.*}}"s" +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_type{{.*}}0x[[DUP_ALIASFORS:[0-9a-f]*]] +// NOODR: DW_TAG_variable +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_name{{.*}}"n" +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_type{{.*}}[[DUP_NESTED]] +// NOODR: DW_TAG_variable +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_name{{.*}}"nc" +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_type{{.*}}[[DUP_NC]] +// NOODR: DW_TAG_variable +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_name{{.*}}"ac" +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_type{{.*}}0x[[DUP_ANONC:[0-9a-f]*]] + +// This is "AliasForS" +// NOODR: 0x[[DUP_ALIASFORS]]:{{.*}}DW_TAG_typedef +// NOODR-NOT: DW_TAG +// NOODR: DW_AT_name{{.*}}"AliasForS" + +// This is "(anonymous namespace)::AnonC" +// NOODR: DW_TAG_namespace +// NOODR-NOT: {{DW_AT_name|NULL|DW_TAG}} +// NOODR: 0x[[DUP_ANONC]]:{{.*}}DW_TAG_class_type +// NOODR-NEXT: DW_AT_name{{.*}}"AnonC" +  | 

