diff options
author | David Blaikie <dblaikie@gmail.com> | 2013-09-06 06:45:04 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2013-09-06 06:45:04 +0000 |
commit | 74341d8fd49db382e83008ecea5c0d8ff9d8b6cb (patch) | |
tree | 54b74d9364622c57891b7b94683d0bcb0313b392 /test/CodeGenCXX/debug-info-template-member.cpp | |
parent | 9c5716c30d91212dcdea5e5c9b9ded9ed2439a09 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190122 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/debug-info-template-member.cpp')
-rw-r--r-- | test/CodeGenCXX/debug-info-template-member.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp index 38019a9357..98bd94635d 100644 --- a/test/CodeGenCXX/debug-info-template-member.cpp +++ b/test/CodeGenCXX/debug-info-template-member.cpp @@ -23,6 +23,13 @@ inline int add3(int x) { // CHECK: [[FOO_FUNC_PARAMS]] = metadata !{null, metadata !{{[0-9]*}}, metadata [[OUTER_FOO_INNER:![0-9]*]]} // CHECK: [[OUTER_FOO_INNER]] = {{.*}} ; [ DW_TAG_structure_type ] [inner] +// CHECK: metadata [[VIRT_MEM:![0-9]*]], i32 0, metadata !{{[0-9]*}}, metadata [[VIRT_TEMP_PARAM:![0-9]*]], metadata !"_ZTS4virtI4elemE"} ; [ DW_TAG_structure_type ] [virt<elem>] {{.*}} [def] +// CHECK: [[ELEM:![0-9]*]] = {{.*}}, metadata [[ELEM_MEM:![0-9]*]], i32 0, null, null, metadata !"_ZTS4elem"} ; [ DW_TAG_structure_type ] [elem] {{.*}} [def] +// CHECK: [[ELEM_MEM]] = metadata !{metadata [[ELEM_X:![0-9]*]]} +// CHECK: [[ELEM_X]] = {{.*}} ; [ DW_TAG_member ] [x] {{.*}} [static] [from virt<elem>] +// CHECK: [[VIRT_TEMP_PARAM]] = metadata !{metadata [[VIRT_T:![0-9]*]]} +// CHECK: [[VIRT_T]] = {{.*}}, metadata !"T", metadata [[ELEM]], {{.*}} ; [ DW_TAG_template_type_parameter ] + // CHECK: [[C:![0-9]*]] = {{.*}}, metadata [[C_MEM:![0-9]*]], i32 0, metadata [[C]], null, metadata !"_ZTS7MyClass"} ; [ DW_TAG_structure_type ] [MyClass] // CHECK: [[C_MEM]] = metadata !{metadata [[C_VPTR:![0-9]*]], metadata [[C_ADD:![0-9]*]], metadata [[C_FUNC:![0-9]*]], metadata [[C_CTOR:![0-9]*]]} // CHECK: [[C_VPTR]] = {{.*}} ; [ DW_TAG_member ] [_vptr$MyClass] @@ -52,3 +59,19 @@ inline void func() { outer<foo>::inner x; // CHECK: metadata [[OUTER_FOO_INNER]], i32 {{[0-9]*}}, i32 {{[0-9]*}}, %"struct.outer<foo>::inner"* @x, {{.*}} ; [ DW_TAG_variable ] [x] + +template <typename T> +struct virt { + T* values; + virtual ~virt(); +}; +struct elem { + static virt<elem> x; // ensure that completing 'elem' will require/completing 'virt<elem>' +}; +inline void f1() { + elem e; // ensure 'elem' is required to be complete when it is emitted as a template argument for 'virt<elem>' +}; +void f2() { + virt<elem> d; // emit 'virt<elem>' +} + |