[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.

llvm-svn: 245803
This commit is contained in:
Frederic Riss 2015-08-23 02:38:29 +00:00
parent 24e817d223
commit f8bcc0c610
11 changed files with 385 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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 }
...

View File

@ -1,2 +1,4 @@
if not 'X86' in config.root.targets:
config.unsupported = True
config.suffixes = ['.test', '.cpp']

View File

@ -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

View File

@ -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<typename T> 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<int>(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<int>"
// 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

View File

@ -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"