diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e9766b62b61ef72760b5f2c58e41635ab326c048..fba9d742f1b5691d5c695ba9842ec23dac156fce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-10-23 Paul Koning <ni1d@arrl.net> + + PR debug/54508 + * dwarf2out.c (prune_unused_types_prune): If pruning a class and + not all its children were marked, add DW_AT_declaration flag. + 2012-10-23 Ian Bolton <ian.bolton@arm.com> James Greenhalgh <james.greenhalgh@arm.com> Jim MacArthur <jim.macarthur@arm.com> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index bc5868b6a252c19105585d6860be3e033789e73b..bed3d67353a2613191fbbbb8a0b9ad94cab4c4a7 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -21220,6 +21220,7 @@ static void prune_unused_types_prune (dw_die_ref die) { dw_die_ref c; + int pruned = 0; gcc_assert (die->die_mark); prune_unused_types_update_strings (die); @@ -21242,13 +21243,24 @@ prune_unused_types_prune (dw_die_ref die) prev->die_sib = c->die_sib; die->die_child = prev; } - return; + pruned = 1; + goto finished; } if (c != prev->die_sib) - prev->die_sib = c; + { + prev->die_sib = c; + pruned = 1; + } prune_unused_types_prune (c); } while (c != die->die_child); + + finished: + /* If we pruned children, and this is a class, mark it as a + declaration to inform debuggers that this is not a complete + class definition. */ + if (pruned && die->die_mark == 1 && class_scope_p (die)) + add_AT_flag (die, DW_AT_declaration, 1); } /* Remove dies representing declarations that we never use. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8267df660e07f0bd06fa54d39dd5ce90b6800dc2..79ccb547bd660b45e2bb657c8d9e8733e23b5e8b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-10-23 Paul Koning <ni1d@arrl.net> + + PR debug/54508 + * g++.dg/debug/dwarf2/pr54508.C: New. + 2012-10-23 Jakub Jelinek <jakub@redhat.com> PR c++/54844 diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C new file mode 100644 index 0000000000000000000000000000000000000000..c1163c9f71d4c7a69bab509bde7629b937a0619c --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C @@ -0,0 +1,72 @@ +// PR debug/54508 +// { dg-do compile } +// { dg-options "-g2 -dA -fno-merge-debug-strings" } + +// { dg-final { scan-assembler-not "\"cbase\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } +// { dg-final { scan-assembler "\"c\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name\[\r\n\]+\[\^\r\n\]+\[\r\n\]+\[\^\r\n\]+\[\r\n\]+\[\^#;/!|@\]+\[#;/!|@\]+ DW_AT_decl_line\[\r\n\]+\[\^#;/!|@\]+\[#;/!|@\]+ DW_AT_declaration" } } +// { dg-final { scan-assembler-not "\"OPCODE\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } +// { dg-final { scan-assembler-not "\"bi\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } +// { dg-final { scan-assembler-not "\"si\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } +// { dg-final { scan-assembler "\"s\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } +// { dg-final { scan-assembler-not "\"s\\\\0\"\[^#;/!|@\]+\[#;/!|@\]+ DW_AT_name\[\r\n\]+\[\^\r\n\]+\[\r\n\]+\[\^\r\n\]+\[\r\n\]+\[\^#;/!|@\]+\[#;/!|@\]+ DW_AT_decl_line\[\r\n\]+\[ \t\]+\[#;/!|@\]+ DW_AT_declaration" } } +// { dg-final { scan-assembler "\"f1\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } +// { dg-final { scan-assembler "\"u\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name\[\r\n\]+\[\^\r\n\]+\[\r\n\]+\[\^\r\n\]+\[\r\n\]+\[\^#;/!|@\]+\[#;/!|@\]+ DW_AT_decl_line\[\r\n\]+\[^#;/!|@\]+\[#;/!|@\]+ DW_AT_declaration" } } +// { dg-final { scan-assembler-not "\"f2\\\\0\"\[ \t\]+\[#;/!|@\]+ DW_AT_name" } } +// { dg-final { scan-assembler-not "\"nc\\\\0\"\[ \t\]+\# DW_AT_name" } } + +class cbase + +{ +public: + static int si; + int bi; +}; + +class c : public cbase + +{ +public: + enum + { + OPCODE = 251 + }; + int i ; + static const char *testc (void) { return "foo"; } +}; + +struct s +{ + int f1; + static const char *tests (void) { return "test"; } +}; + +union u +{ + int f2; + double d; + static const char *testu (void) { return "test union"; } +}; + +namespace n +{ + const char *ntest (void) { return "test n"; } + + class nc + { + public: + int i; + static int sj; + }; +} + +extern void send (int, int, const void *, int); + +void test (int src) +{ + int cookie = 1; + static struct s ss; + + send(src, c::OPCODE, c::testc (), cookie); + send(src, c::OPCODE, u::testu (), cookie); + send(src, c::OPCODE, n::ntest (), cookie); +}