2012-11-03 04:49:01 +08:00
|
|
|
struct foo;
|
2013-02-02 03:09:49 +08:00
|
|
|
void func(foo *f) {
|
2012-11-03 04:49:01 +08:00
|
|
|
}
|
|
|
|
class bar;
|
2013-02-02 03:09:49 +08:00
|
|
|
void func(bar *f) {
|
2012-11-03 04:49:01 +08:00
|
|
|
}
|
|
|
|
union baz;
|
2013-02-02 03:09:49 +08:00
|
|
|
void func(baz *f) {
|
2012-11-03 04:49:01 +08:00
|
|
|
}
|
2013-02-03 20:52:54 +08:00
|
|
|
|
2013-02-02 03:09:49 +08:00
|
|
|
class B {
|
2012-12-14 06:29:06 +08:00
|
|
|
public:
|
|
|
|
virtual ~B();
|
|
|
|
};
|
2013-08-19 00:55:33 +08:00
|
|
|
|
2013-08-20 09:28:15 +08:00
|
|
|
B::~B() {
|
|
|
|
}
|
|
|
|
|
2013-08-19 00:55:33 +08:00
|
|
|
struct C {
|
2013-08-20 09:28:15 +08:00
|
|
|
static int s;
|
|
|
|
virtual ~C();
|
|
|
|
};
|
|
|
|
|
|
|
|
C::~C() {
|
|
|
|
}
|
|
|
|
|
|
|
|
struct D {
|
|
|
|
D();
|
|
|
|
virtual ~D();
|
|
|
|
void func() {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct E {
|
|
|
|
E();
|
|
|
|
virtual ~E();
|
|
|
|
virtual void func() {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct F {
|
|
|
|
struct inner {
|
|
|
|
};
|
|
|
|
static const int i = 2;
|
|
|
|
virtual ~F();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct G {
|
2013-08-19 00:55:33 +08:00
|
|
|
virtual void func();
|
|
|
|
struct inner {
|
|
|
|
int j;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2013-08-22 23:23:05 +08:00
|
|
|
struct H {};
|
|
|
|
struct I : virtual H {};
|
|
|
|
struct J : I {};
|
|
|
|
J j;
|
|
|
|
|
2013-02-02 03:09:49 +08:00
|
|
|
struct A {
|
2010-08-12 08:02:44 +08:00
|
|
|
int one;
|
2013-02-02 03:09:49 +08:00
|
|
|
static const int HdrSize = 52;
|
2010-08-12 08:02:44 +08:00
|
|
|
int two;
|
|
|
|
A() {
|
|
|
|
int x = 1;
|
|
|
|
}
|
|
|
|
};
|
2012-12-14 06:29:06 +08:00
|
|
|
|
2013-08-20 09:28:15 +08:00
|
|
|
void f1() {
|
|
|
|
D x;
|
|
|
|
x.func();
|
|
|
|
E y;
|
|
|
|
int i = F::i;
|
|
|
|
F::inner z;
|
|
|
|
}
|
2012-12-14 06:29:06 +08:00
|
|
|
|
2013-02-02 03:09:49 +08:00
|
|
|
int main(int argc, char **argv) {
|
2012-11-03 04:49:01 +08:00
|
|
|
B b;
|
2013-08-20 09:28:15 +08:00
|
|
|
G::inner c_i;
|
2013-02-02 03:09:49 +08:00
|
|
|
if (argc) {
|
|
|
|
A a;
|
|
|
|
}
|
|
|
|
return 0;
|
2010-08-12 08:02:44 +08:00
|
|
|
}
|
2013-02-02 03:09:49 +08:00
|
|
|
|
2013-02-03 20:52:54 +08:00
|
|
|
// RUN: %clang -target x86_64-unknown_unknown -emit-llvm -g -S %s -o - | FileCheck %s
|
|
|
|
// RUN: %clang -target i686-cygwin -emit-llvm -g -S %s -o - | FileCheck %s
|
|
|
|
// RUN: %clang -target armv7l-unknown-linux-gnueabihf -emit-llvm -g -S %s -o - | FileCheck %s
|
|
|
|
|
|
|
|
// CHECK: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b)
|
2013-02-02 06:53:19 +08:00
|
|
|
// CHECK-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]]
|
|
|
|
// CHECK: store i32 0, i32* %{{.+}}, !dbg ![[RETLOC:.*]]
|
2013-02-02 03:09:49 +08:00
|
|
|
// CHECK: DW_TAG_structure_type ] [foo]
|
|
|
|
// CHECK: DW_TAG_class_type ] [bar]
|
|
|
|
// CHECK: DW_TAG_union_type ] [baz]
|
PR17046, PR17092: Debug Info assert-on-valid due to member loss when context creation recreates the item the context is created for
By removing the possibility of strange partial definitions with no
members that older GCC's produced for the otherwise unreferenced outer
types of referenced inner types, we can simplify debug info generation
and correct this bug. Newer (4.8.1 and ToT) GCC's don't produce this
quirky debug info, and instead produce the full definition for the outer
type (except in the case where that type is dynamic and its vtable is
not emitted in this TU).
During the creation of the context for a type, we may revisit that type
(due to the need to visit template parameters, among other things) and
used to end up visiting it first there. Then when we would reach the
original code attempting to define that type, we would lose debug info
by overwriting its members.
By avoiding the possibility of latent "defined with no members" types,
we can be sure than whenever we already have a type in a cache (either a
definition or declaration), we can just return that. In the case of a
full definition, our work is done. In the case of a partial definition,
we must already be in the process of completing it. And in the case of a
declaration, the completed/vtable/etc callbacks can handle converting it
to a definition.
llvm-svn: 190122
2013-09-06 14:45:04 +08:00
|
|
|
// CHECK: DW_TAG_class_type ] [B] {{.*}} [def]
|
2013-02-02 03:09:49 +08:00
|
|
|
// CHECK: metadata !"_vptr$B", {{.*}}, i32 64, metadata !{{.*}}} ; [ DW_TAG_member ]
|
2013-08-20 09:28:15 +08:00
|
|
|
|
2013-09-07 02:46:30 +08:00
|
|
|
// CHECK: [[C:![0-9]*]] = {{.*}} metadata [[C_MEM:![0-9]*]], i32 0, metadata !"_ZTS1C", null, metadata !"_ZTS1C"} ; [ DW_TAG_structure_type ] [C] {{.*}} [def]
|
2013-08-20 09:28:15 +08:00
|
|
|
// CHECK: [[C_MEM]] = metadata !{metadata [[C_VPTR:![0-9]*]], metadata [[C_S:![0-9]*]], metadata [[C_DTOR:![0-9]*]]}
|
|
|
|
// CHECK: [[C_VPTR]] = {{.*}} ; [ DW_TAG_member ] [_vptr$C] {{.*}} [artificial]
|
|
|
|
// CHECK: [[C_S]] = {{.*}} ; [ DW_TAG_member ] [s] {{.*}} [static] [from int]
|
|
|
|
// CHECK: [[C_DTOR]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [~C]
|
|
|
|
|
2013-12-21 07:19:47 +08:00
|
|
|
// CHECK: null, i32 0, null, null, metadata !"_ZTS1D"} ; [ DW_TAG_structure_type ] [D] {{.*}} [decl]
|
2013-08-30 07:19:58 +08:00
|
|
|
// CHECK: null, i32 0, null, null, metadata !"_ZTS1E"} ; [ DW_TAG_structure_type ] [E] {{.*}} [decl]
|
2013-12-21 07:19:47 +08:00
|
|
|
// CHECK: [[F:![0-9]*]] = {{.*}} null, i32 0, null, null, metadata !"_ZTS1F"} ; [ DW_TAG_structure_type ] [F] {{.*}} [decl]
|
2013-08-20 09:28:15 +08:00
|
|
|
|
PR17046, PR17092: Debug Info assert-on-valid due to member loss when context creation recreates the item the context is created for
By removing the possibility of strange partial definitions with no
members that older GCC's produced for the otherwise unreferenced outer
types of referenced inner types, we can simplify debug info generation
and correct this bug. Newer (4.8.1 and ToT) GCC's don't produce this
quirky debug info, and instead produce the full definition for the outer
type (except in the case where that type is dynamic and its vtable is
not emitted in this TU).
During the creation of the context for a type, we may revisit that type
(due to the need to visit template parameters, among other things) and
used to end up visiting it first there. Then when we would reach the
original code attempting to define that type, we would lose debug info
by overwriting its members.
By avoiding the possibility of latent "defined with no members" types,
we can be sure than whenever we already have a type in a cache (either a
definition or declaration), we can just return that. In the case of a
full definition, our work is done. In the case of a partial definition,
we must already be in the process of completing it. And in the case of a
declaration, the completed/vtable/etc callbacks can handle converting it
to a definition.
llvm-svn: 190122
2013-09-06 14:45:04 +08:00
|
|
|
// CHECK: null, i32 0, null, null, metadata !"_ZTS1G"} ; [ DW_TAG_structure_type ] [G] {{.*}} [decl]
|
2013-08-30 07:19:58 +08:00
|
|
|
// CHECK: metadata [[G_INNER_MEM:![0-9]*]], i32 0, null, null, metadata !"_ZTSN1G5innerE"} ; [ DW_TAG_structure_type ] [inner] [line 50, {{.*}} [def]
|
2013-08-20 09:28:15 +08:00
|
|
|
// CHECK: [[G_INNER_MEM]] = metadata !{metadata [[G_INNER_I:![0-9]*]]}
|
|
|
|
// CHECK: [[G_INNER_I]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int]
|
|
|
|
|
2013-08-30 07:19:58 +08:00
|
|
|
// CHECK: ; [ DW_TAG_structure_type ] [A]
|
|
|
|
// CHECK: HdrSize
|
2013-10-09 06:56:54 +08:00
|
|
|
// CHECK: ; [ DW_TAG_structure_type ] [I] {{.*}} [def]
|
2013-12-21 07:19:47 +08:00
|
|
|
//
|
|
|
|
// CHECK: metadata !"_ZTS1D", {{.*}}, metadata [[D_FUNC_DECL:![0-9]*]], metadata {{![0-9]*}}, i32 {{[0-9]*}}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func]
|
|
|
|
// CHECK: [[D_FUNC_DECL]] = {{.*}}, metadata !"_ZTS1D", {{.*}}, i32 0, metadata {{![0-9]*}}, i32 {{[0-9]*}}} ; [ DW_TAG_subprogram ] {{.*}} [func]
|
2013-08-30 07:19:58 +08:00
|
|
|
|
2013-12-21 07:19:47 +08:00
|
|
|
// CHECK: [[F_I_DEF:![0-9]*]] = {{.*}}, metadata [[F_I:![0-9]*]]} ; [ DW_TAG_variable ] [i]
|
|
|
|
|
|
|
|
// CHECK: [[F_I]] = {{.*}}, metadata !"_ZTS1F", {{.*}} ; [ DW_TAG_member ] [i]
|
2013-08-30 07:19:58 +08:00
|
|
|
|
2013-08-22 23:23:05 +08:00
|
|
|
// CHECK: ![[EXCEPTLOC]] = metadata !{i32 84,
|
|
|
|
// CHECK: ![[RETLOC]] = metadata !{i32 83,
|