From: Frederic Riss Date: Sun, 23 Aug 2015 02:38:29 +0000 (+0000) Subject: [dsymutil] Refactor ODR uniquing tests to be more readable. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=b7e7dd4975eb853b140e5b11510206bc29897a9b [dsymutil] Refactor ODR uniquing tests to be more readable. This patch adds all the refactored tests in new files, the old tests will be removed by a followup commit. Thanks to D. Blaikie for all the feedback. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245803 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/dsymutil/Inputs/odr-anon-namespace/1.o b/test/tools/dsymutil/Inputs/odr-anon-namespace/1.o new file mode 100644 index 00000000000..20d4b7fd84e Binary files /dev/null and b/test/tools/dsymutil/Inputs/odr-anon-namespace/1.o differ diff --git a/test/tools/dsymutil/Inputs/odr-anon-namespace/2.o b/test/tools/dsymutil/Inputs/odr-anon-namespace/2.o new file mode 100644 index 00000000000..df8e567bc3a Binary files /dev/null and b/test/tools/dsymutil/Inputs/odr-anon-namespace/2.o differ diff --git a/test/tools/dsymutil/Inputs/odr-member-functions/1.o b/test/tools/dsymutil/Inputs/odr-member-functions/1.o new file mode 100644 index 00000000000..f957a9b9d42 Binary files /dev/null and b/test/tools/dsymutil/Inputs/odr-member-functions/1.o differ diff --git a/test/tools/dsymutil/Inputs/odr-member-functions/2.o b/test/tools/dsymutil/Inputs/odr-member-functions/2.o new file mode 100644 index 00000000000..c696866fcad Binary files /dev/null and b/test/tools/dsymutil/Inputs/odr-member-functions/2.o differ diff --git a/test/tools/dsymutil/Inputs/odr-member-functions/3.o b/test/tools/dsymutil/Inputs/odr-member-functions/3.o new file mode 100644 index 00000000000..962bf6e2b38 Binary files /dev/null and b/test/tools/dsymutil/Inputs/odr-member-functions/3.o differ diff --git a/test/tools/dsymutil/Inputs/odr-uniquing/1.o b/test/tools/dsymutil/Inputs/odr-uniquing/1.o new file mode 100644 index 00000000000..c5209303005 Binary files /dev/null and b/test/tools/dsymutil/Inputs/odr-uniquing/1.o differ diff --git a/test/tools/dsymutil/X86/dummy-debug-map.map b/test/tools/dsymutil/X86/dummy-debug-map.map new file mode 100644 index 00000000000..f9bc7b09985 --- /dev/null +++ b/test/tools/dsymutil/X86/dummy-debug-map.map @@ -0,0 +1,22 @@ +# This is a dummy debug map used for some tests where the contents of the +# map are just an implementation detail. The tests wanting to use that file +# should put all there object files in an explicitely named sub-directory +# of Inputs, and they should be named 1.o, 2.o, ... +# As not finding an object file or symbols isn't a fatal error for dsymutil, +# you can extend this file with as much object files and symbols as needed. + +--- +triple: 'x86_64-apple-darwin' +objects: + - filename: 1.o + symbols: + - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x10000, size: 0x10 } + - filename: 2.o + symbols: + - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x20000, size: 0x10 } + - filename: 3.o + symbols: + - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x30000, size: 0x10 } + - { sym: __ZN1S3bazIiEEvT_, objAddr: 0x0, binAddr: 0x30010, size: 0x10 } +... + diff --git a/test/tools/dsymutil/X86/lit.local.cfg b/test/tools/dsymutil/X86/lit.local.cfg index c8625f4d9d2..7b8ecfecc2b 100644 --- a/test/tools/dsymutil/X86/lit.local.cfg +++ b/test/tools/dsymutil/X86/lit.local.cfg @@ -1,2 +1,4 @@ if not 'X86' in config.root.targets: config.unsupported = True + +config.suffixes = ['.test', '.cpp'] diff --git a/test/tools/dsymutil/X86/odr-anon-namespace.cpp b/test/tools/dsymutil/X86/odr-anon-namespace.cpp new file mode 100644 index 00000000000..a66fc830b67 --- /dev/null +++ b/test/tools/dsymutil/X86/odr-anon-namespace.cpp @@ -0,0 +1,65 @@ +/* Compile with: + for FILE in `seq 2`; do + clang -g -c odr-anon-namespace.cpp -DFILE$FILE -o odr-anon-namespace/$FILE.o + done + */ + +// RUN: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/odr-anon-namespace -y %p/dummy-debug-map.map -o - | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +#ifdef FILE1 +// Currently llvm-dsymutil will unique the contents of anonymous +// namespaces if they are from the same file/line. Force this +// namespace to appear different eventhough it's the same (this +// uniquing is actually a bug kept for backward compatibility, see the +// comments in DeclContextTree::getChildDeclContext()). +#line 42 +#endif +namespace { +class C {}; +} + +void foo() { + C c; +} + +// Keep the ifdef guards for FILE1 and FILE2 even if all the code is +// above to clearly show what the CHECK lines are testing. +#ifdef FILE1 + +// CHECK: TAG_compile_unit +// CHECK-NOT: DW_TAG +// CHECK: AT_name{{.*}}"odr-anon-namespace.cpp" + +// CHECK: DW_TAG_variable +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name {{.*}}"c" +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_type {{.*}}0x00000000[[C_FILE1:[0-9a-f]*]] + +// CHECK: DW_TAG_namespace +// CHECK-NOT: {{DW_AT_name|NULL|DW_TAG}} +// CHECK: 0x[[C_FILE1]]:{{.*}}DW_TAG_class_type +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name{{.*}}"C" + +#elif defined(FILE2) + +// CHECK: TAG_compile_unit +// CHECK-NOT: DW_TAG +// CHECK: AT_name{{.*}}"odr-anon-namespace.cpp" + +// CHECK: DW_TAG_variable +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name {{.*}}"c" +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_type {{.*}}0x00000000[[C_FILE2:[0-9a-f]*]] + +// CHECK: DW_TAG_namespace +// CHECK-NOT: {{DW_AT_name|NULL|DW_TAG}} +// CHECK: 0x[[C_FILE2]]:{{.*}}DW_TAG_class_type +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name{{.*}}"C" + +#else +#error "You must define which file you generate" +#endif diff --git a/test/tools/dsymutil/X86/odr-member-functions.cpp b/test/tools/dsymutil/X86/odr-member-functions.cpp new file mode 100644 index 00000000000..737d5a7abf6 --- /dev/null +++ b/test/tools/dsymutil/X86/odr-member-functions.cpp @@ -0,0 +1,109 @@ +/* Compile with: + for FILE in `seq 3`; do + clang -g -c odr-member-functions.cpp -DFILE$FILE -o odr-member-functions/$FILE.o + done + */ + +// RUN: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/odr-member-functions -y %p/dummy-debug-map.map -o - | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +struct S { + __attribute__((always_inline)) void foo() { bar(); } + __attribute__((always_inline)) void foo(int i) { if (i) bar(); } + void bar(); + + template void baz(T t) {} +}; + +#ifdef FILE1 +void foo() { + S s; +} + +// CHECK: TAG_compile_unit +// CHECK-NOT: {{DW_TAG|NULL}} +// CHECK: AT_name{{.*}}"odr-member-functions.cpp" + +// CHECK: 0x[[S:[0-9a-f]*]]:{{.*}}DW_TAG_structure_type +// CHECK-NOT: {{DW_TAG|NULL}} +// CHECK: DW_AT_name{{.*}}"S" +// CHECK-NOT: NULL +// CHECK: 0x[[FOO:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram +// CHECK-NEXT: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEv" +// CHECK: NULL +// CHECK: 0x[[FOOI:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram +// CHECK-NEXT: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEi" + +#elif defined(FILE2) +void foo() { + S s; + // Check that the overloaded member functions are resolved correctly + s.foo(); + s.foo(1); +} + +// CHECK: TAG_compile_unit +// CHECK-NOT: DW_TAG +// CHECK: AT_name{{.*}}"odr-member-functions.cpp" + +// Normal member functions should be desribed by the type in the first +// CU, thus we should be able to reuse its definition and avoid +// reemiting it. +// CHECK-NOT: DW_TAG_structure_type + +// CHECK: 0x[[FOO_SUB:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram +// CHECK-NEXT: DW_AT_specification{{.*}}[[FOO]] +// CHECK-NOT: DW_TAG_structure_type +// CHECK: 0x[[FOOI_SUB:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram +// CHECK-NEXT: DW_AT_specification{{.*}}[[FOOI]] +// CHECK-NOT: DW_TAG_structure_type + +// CHECK: DW_TAG_variable +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name {{.*}}"s" +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_type {{.*}}[[S]]) +// CHECK: DW_TAG_inlined_subroutine +// CHECK-NEXT: DW_AT_abstract_origin{{.*}}[[FOO_SUB]] +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_call_line{{.*}}40 +// CHECK: DW_TAG_inlined_subroutine +// CHECK-NEXT: DW_AT_abstract_origin{{.*}}[[FOOI_SUB]] +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_call_line{{.*}}41 + +#elif defined(FILE3) +void foo() { + S s; + s.baz(42); +} + +// CHECK: TAG_compile_unit +// CHECK-NOT: DW_TAG +// CHECK: AT_name{{.*}}"odr-member-functions.cpp" + +// Template or other implicit members will be included in the type +// only if they are generated. Thus actually creating a new type. +// CHECK: DW_TAG_structure_type + +// Skip 'normal' member functions +// CHECK: DW_TAG_subprogram +// CHECK: DW_TAG_subprogram +// CHECK: DW_TAG_subprogram + +// This is the 'baz' member +// CHECK: 0x[[BAZ:[0-9a-f]*]]: DW_TAG_subprogram +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_MIPS_linkage_name {{.*}}"_ZN1S3bazIiEEvT_" +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name {{.*}}"baz" + +// Skip foo3 +// CHECK: DW_TAG_subprogram + +// baz instanciation: +// CHECK: DW_TAG_subprogram +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_specification {{.*}}[[BAZ]] "_ZN1S3bazIiEEvT_" +#else +#error "You must define which file you generate" +#endif diff --git a/test/tools/dsymutil/X86/odr-uniquing.cpp b/test/tools/dsymutil/X86/odr-uniquing.cpp new file mode 100644 index 00000000000..e1932d41d8a --- /dev/null +++ b/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" +