From af84796a91f74549996aca0783894700d0d24657 Mon Sep 17 00:00:00 2001 From: ctice Date: Tue, 14 Nov 2006 20:55:56 +0000 Subject: [PATCH] Add ability to generate DWARF pubtypes section if DEBUG_PUBTYPES_SECTION is defined. Also add dejagnu testcases for pubtypes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@118826 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 31 +++++++ gcc/config/darwin.c | 1 + gcc/config/darwin.h | 1 + gcc/dwarf2out.c | 169 +++++++++++++++++++++++++++----------- gcc/testsuite/ChangeLog | 8 ++ gcc/testsuite/g++.dg/pubtypes.C | 64 +++++++++++++++ gcc/testsuite/gcc.dg/pubtypes-1.c | 47 +++++++++++ gcc/testsuite/gcc.dg/pubtypes-2.c | 46 +++++++++++ gcc/testsuite/gcc.dg/pubtypes-3.c | 83 +++++++++++++++++++ gcc/testsuite/gcc.dg/pubtypes-4.c | 96 ++++++++++++++++++++++ 10 files changed, 496 insertions(+), 50 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pubtypes.C create mode 100644 gcc/testsuite/gcc.dg/pubtypes-1.c create mode 100644 gcc/testsuite/gcc.dg/pubtypes-2.c create mode 100644 gcc/testsuite/gcc.dg/pubtypes-3.c create mode 100644 gcc/testsuite/gcc.dg/pubtypes-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2458b0e..8e2c89c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2006-11-14 Caroline Tice + + * dwarf2out.c (debug_pubtypes_section): New static global variable. + (pubname_entry): Add DEF_VEC_O and DEF_VEC_ALLOC_O statements for + this type. + (pubname_table): Redefine as a vector. + (pubtype_table): New static global variable, defined as a vector. + (pubname_table_allocated): Remove static global variable. + (pubname_table_in_use): Remove static global variable. + (PUBNAME_TABLE_INCREMENT): Remove constant. + (size_of_pubnames): Add parameter to deal with either pubnames or + pubtypes, and change code to deal with table being a vector. + (add_pubname): Change to deal with table being a vector. + (add_pubtype): New function. + (output_pubnames): Add parameter to deal with either pubnames or + pubtypes, and change code to deal with table being a vector. + (gen_array_type_die): Add call to add_pubtype. + (gen_enumeration_type_die): Add call to add_pubtype. + (gen_struct_or_union_type_die): Add call to add_pubtype. + (gen_subroutine_type_die): Add call to add_pubtype. + (gen_typedef_die): Add call to add_pubtype. + (dwarf2out_init): Add code to initialize pubname_table and + pubtype_table vectors; also initialize debug_pubtypes_section. + (prune_unused_types): Change to deal with pubnames being a vector. + (dwarf2out_finish): Change to deal with pubnames being a vector; add + pubnames table to call to output_pubnames; Add code to output pubtypes + table if DEBUG_PUBTYPES_SECTION is defined. + * config/darwin.c (darwin_file_start): Add DEBUG_PUBTYPES_SECTION to + debugnames. + * config/darwin.h (DEBUG_PUBTYPES_SECTION): Define new global variable. + 2006-11-14 Joseph Myers * config/arm/arm.h (FUNCTION_ARG_ADVANCE): Only adjust diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 7475b1a..9332cc1 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -1516,6 +1516,7 @@ darwin_file_start (void) DEBUG_LINE_SECTION, DEBUG_LOC_SECTION, DEBUG_PUBNAMES_SECTION, + DEBUG_PUBTYPES_SECTION, DEBUG_STR_SECTION, DEBUG_RANGES_SECTION }; diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index bbb1f89..a518a2c 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -407,6 +407,7 @@ extern GTY(()) int darwin_ms_struct; #define DEBUG_LINE_SECTION "__DWARF,__debug_line,regular,debug" #define DEBUG_LOC_SECTION "__DWARF,__debug_loc,regular,debug" #define DEBUG_PUBNAMES_SECTION "__DWARF,__debug_pubnames,regular,debug" +#define DEBUG_PUBTYPES_SECTION "__DWARF,__debug_pubtypes,regular,debug" #define DEBUG_STR_SECTION "__DWARF,__debug_str,regular,debug" #define DEBUG_RANGES_SECTION "__DWARF,__debug_ranges,regular,debug" diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 28108ec..c61f3d8 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -156,6 +156,7 @@ static GTY(()) section *debug_macinfo_section; static GTY(()) section *debug_line_section; static GTY(()) section *debug_loc_section; static GTY(()) section *debug_pubnames_section; +static GTY(()) section *debug_pubtypes_section; static GTY(()) section *debug_str_section; static GTY(()) section *debug_ranges_section; static GTY(()) section *debug_frame_section; @@ -3759,6 +3760,9 @@ typedef struct pubname_struct GTY(()) } pubname_entry; +DEF_VEC_O(pubname_entry); +DEF_VEC_ALLOC_O(pubname_entry, gc); + struct dw_ranges_struct GTY(()) { int block_num; @@ -3940,17 +3944,11 @@ static GTY(()) unsigned separate_line_info_table_in_use; /* A pointer to the base of a table that contains a list of publicly accessible names. */ -static GTY ((length ("pubname_table_allocated"))) pubname_ref pubname_table; - -/* Number of elements currently allocated for pubname_table. */ -static GTY(()) unsigned pubname_table_allocated; - -/* Number of elements in pubname_table currently in use. */ -static GTY(()) unsigned pubname_table_in_use; +static GTY (()) VEC (pubname_entry, gc) * pubname_table; -/* Size (in elements) of increments by which we may expand the - pubname_table. */ -#define PUBNAME_TABLE_INCREMENT 64 +/* A pointer to the base of a table that contains a list of publicly + accessible types. */ +static GTY (()) VEC (pubname_entry, gc) * pubtype_table; /* Array of dies for which we should generate .debug_arange info. */ static GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table; @@ -4115,7 +4113,7 @@ static void calc_die_sizes (dw_die_ref); static void mark_dies (dw_die_ref); static void unmark_dies (dw_die_ref); static void unmark_all_dies (dw_die_ref); -static unsigned long size_of_pubnames (void); +static unsigned long size_of_pubnames (VEC (pubname_entry,gc) *); static unsigned long size_of_aranges (void); static enum dwarf_form value_format (dw_attr_ref); static void output_value_format (dw_attr_ref); @@ -4126,7 +4124,8 @@ static void output_compilation_unit_header (void); static void output_comp_unit (dw_die_ref, int); static const char *dwarf2_name (tree, int); static void add_pubname (tree, dw_die_ref); -static void output_pubnames (void); +static void add_pubtype (tree, dw_die_ref); +static void output_pubnames (VEC (pubname_entry,gc) *); static void add_arange (tree, dw_die_ref); static void output_aranges (void); static unsigned int add_ranges (tree); @@ -6749,21 +6748,22 @@ unmark_all_dies (dw_die_ref die) unmark_all_dies (AT_ref (a)); } -/* Return the size of the .debug_pubnames table generated for the - compilation unit. */ +/* Return the size of the .debug_pubnames or .debug_pubtypes table + generated for the compilation unit. */ static unsigned long -size_of_pubnames (void) +size_of_pubnames (VEC (pubname_entry, gc) * names) { unsigned long size; unsigned i; + pubname_ref p; size = DWARF_PUBNAMES_HEADER_SIZE; - for (i = 0; i < pubname_table_in_use; i++) - { - pubname_ref p = &pubname_table[i]; - size += DWARF_OFFSET_SIZE + strlen (p->name) + 1; - } + for (i = 0; VEC_iterate (pubname_entry, names, i, p); i++) + if (names != pubtype_table + || p->die->die_offset != 0 + || !flag_eliminate_unused_debug_types) + size += strlen (p->name) + DWARF_OFFSET_SIZE + 1; size += DWARF_OFFSET_SIZE; return size; @@ -7330,41 +7330,73 @@ dwarf2_name (tree decl, int scope) static void add_pubname (tree decl, dw_die_ref die) { - pubname_ref p; + pubname_entry e; if (! TREE_PUBLIC (decl)) return; - if (pubname_table_in_use == pubname_table_allocated) + e.die = die; + e.name = xstrdup (dwarf2_name (decl, 1)); + VEC_safe_push (pubname_entry, gc, pubname_table, &e); +} + +/* Add a new entry to .debug_pubtypes if appropriate. */ + +static void +add_pubtype (tree decl, dw_die_ref die) +{ + pubname_entry e; + + e.name = NULL; + if ((TREE_PUBLIC (decl) + || die->die_parent == comp_unit_die) + && (die->die_tag == DW_TAG_typedef || COMPLETE_TYPE_P (decl))) { - pubname_table_allocated += PUBNAME_TABLE_INCREMENT; - pubname_table - = ggc_realloc (pubname_table, - (pubname_table_allocated * sizeof (pubname_entry))); - memset (pubname_table + pubname_table_in_use, 0, - PUBNAME_TABLE_INCREMENT * sizeof (pubname_entry)); - } + e.die = die; + if (TYPE_P (decl)) + { + if (TYPE_NAME (decl)) + { + if (TREE_CODE (TYPE_NAME (decl)) == IDENTIFIER_NODE) + e.name = xstrdup ((const char *) IDENTIFIER_POINTER + (TYPE_NAME (decl))); + else if (TREE_CODE (TYPE_NAME (decl)) == TYPE_DECL + && DECL_NAME (TYPE_NAME (decl))) + e.name = xstrdup ((const char *) IDENTIFIER_POINTER + (DECL_NAME (TYPE_NAME (decl)))); + else + e.name = xstrdup ((const char *) get_AT_string (die, DW_AT_name)); + } + } + else + e.name = xstrdup (dwarf2_name (decl, 1)); - p = &pubname_table[pubname_table_in_use++]; - p->die = die; - p->name = xstrdup (dwarf2_name (decl, 1)); + /* If we don't have a name for the type, there's no point in adding + it to the table. */ + if (e.name && e.name[0] != '\0') + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); + } } /* Output the public names table used to speed up access to externally - visible names. For now, only generate entries for externally - visible procedures. */ + visible names; or the public types table used to find type definitions. */ static void -output_pubnames (void) +output_pubnames (VEC (pubname_entry, gc) * names) { unsigned i; - unsigned long pubnames_length = size_of_pubnames (); + unsigned long pubnames_length = size_of_pubnames (names); + pubname_ref pub; if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) dw2_asm_output_data (4, 0xffffffff, "Initial length escape value indicating 64-bit DWARF extension"); - dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length, - "Length of Public Names Info"); + if (names == pubname_table) + dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length, + "Length of Public Names Info"); + else + dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length, + "Length of Public Type Names Info"); dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version"); dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label, debug_info_section, @@ -7372,17 +7404,21 @@ output_pubnames (void) dw2_asm_output_data (DWARF_OFFSET_SIZE, next_die_offset, "Compilation Unit Length"); - for (i = 0; i < pubname_table_in_use; i++) + for (i = 0; VEC_iterate (pubname_entry, names, i, pub); i++) { - pubname_ref pub = &pubname_table[i]; - - /* We shouldn't see pubnames for DIEs outside of the main CU. */ - gcc_assert (pub->die->die_mark); + /* We shouldn't see pubnames for DIEs outside of the main CU. */ + if (names == pubname_table) + gcc_assert (pub->die->die_mark); - dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset, - "DIE offset"); + if (names != pubtype_table + || pub->die->die_offset != 0 + || !flag_eliminate_unused_debug_types) + { + dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset, + "DIE offset"); - dw2_asm_output_nstring (pub->name, -1, "external name"); + dw2_asm_output_nstring (pub->name, -1, "external name"); + } } dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, NULL); @@ -11250,6 +11286,9 @@ gen_array_type_die (tree type, dw_die_ref context_die) #endif add_type_attribute (array_die, element_type, 0, 0, context_die); + + if (get_AT (array_die, DW_AT_name)) + add_pubtype (type, array_die); } #if 0 @@ -11385,6 +11424,9 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) else add_AT_flag (type_die, DW_AT_declaration, 1); + if (get_AT (type_die, DW_AT_name)) + add_pubtype (type, type_die); + return type_die; } @@ -12502,6 +12544,9 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die) && ! decl_function_context (TYPE_STUB_DECL (type))) VEC_safe_push (tree, gc, incomplete_types, type); } + + if (get_AT (type_die, DW_AT_name)) + add_pubtype (type, type_die); } /* Generate a DIE for a subroutine _type_. */ @@ -12518,6 +12563,9 @@ gen_subroutine_type_die (tree type, dw_die_ref context_die) add_prototyped_attribute (subr_die, type); add_type_attribute (subr_die, return_type, 0, 0, context_die); gen_formal_types_die (type, subr_die); + + if (get_AT (subr_die, DW_AT_name)) + add_pubtype (type, subr_die); } /* Generate a DIE for a type definition. */ @@ -12557,6 +12605,9 @@ gen_typedef_die (tree decl, dw_die_ref context_die) if (DECL_ABSTRACT (decl)) equate_decl_number_to_die (decl, type_die); + + if (get_AT (type_die, DW_AT_name)) + add_pubtype (decl, type_die); } /* Generate a type description DIE. */ @@ -13848,6 +13899,10 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) /* Zero-th entry is allocated, but unused. */ line_info_table_in_use = 1; + /* Allocate the pubtypes and pubnames vectors. */ + pubname_table = VEC_alloc (pubname_entry, gc, 32); + pubtype_table = VEC_alloc (pubname_entry, gc, 32); + /* Generate the initial DIE for the .debug section. Note that the (string) value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE will (typically) be a relative pathname and that this pathname should be @@ -13874,6 +13929,10 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) SECTION_DEBUG, NULL); debug_pubnames_section = get_section (DEBUG_PUBNAMES_SECTION, SECTION_DEBUG, NULL); +#ifdef DEBUG_PUBTYPES_SECTION + debug_pubtypes_section = get_section (DEBUG_PUBTYPES_SECTION, + SECTION_DEBUG, NULL); +#endif debug_str_section = get_section (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS, NULL); debug_ranges_section = get_section (DEBUG_RANGES_SECTION, @@ -14157,6 +14216,7 @@ prune_unused_types (void) { unsigned int i; limbo_die_node *node; + pubname_ref pub; #if ENABLE_ASSERT_CHECKING /* All the marks should already be clear. */ @@ -14172,8 +14232,8 @@ prune_unused_types (void) /* Also set the mark on nodes referenced from the pubname_table or arange_table. */ - for (i = 0; i < pubname_table_in_use; i++) - prune_unused_types_mark (pubname_table[i].die, 1); + for (i = 0; VEC_iterate (pubname_entry, pubname_table, i, pub); i++) + prune_unused_types_mark (pub->die, 1); for (i = 0; i < arange_table_in_use; i++) prune_unused_types_mark (arange_table[i], 1); @@ -14352,12 +14412,21 @@ dwarf2out_finish (const char *filename) output_abbrev_section (); /* Output public names table if necessary. */ - if (pubname_table_in_use) + if (!VEC_empty (pubname_entry, pubname_table)) { switch_to_section (debug_pubnames_section); - output_pubnames (); + output_pubnames (pubname_table); } +#ifdef DEBUG_PUBTYPES_SECTION + /* Output public types table if necessary. */ + if (!VEC_empty (pubname_entry, pubtype_table)) + { + switch_to_section (debug_pubtypes_section); + output_pubnames (pubtype_table); + } +#endif + /* Output the address range information. We only put functions in the arange table, so don't write it out if we don't have any. */ if (fde_table_in_use) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 49e77ab..2ad8fb3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2006-11-14 Caroline Tice + + * gcc.dg/pubtypes-1.c: New file/testcase. + * gcc.dg/pubtypes-2.c: New file/testcase. + * gcc.dg/pubtypes-3.c: New file/testcase. + * gcc.dg/pubtypes-4.c: New file/testcase. + * g++.dg/pubtypes.C: New file/testcase. + 2006-11-14 Mark Mitchell PR c++/29106 diff --git a/gcc/testsuite/g++.dg/pubtypes.C b/gcc/testsuite/g++.dg/pubtypes.C new file mode 100644 index 0000000..a17ad20 --- /dev/null +++ b/gcc/testsuite/g++.dg/pubtypes.C @@ -0,0 +1,64 @@ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-O0 -gdwarf-2 -dA -fno-eliminate-unused-debug-types" } */ +/* { dg-final { scan-assembler "__debug_pubtypes" } } */ +/* { dg-final { scan-assembler "long+\[ \t\]+0x24+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */ +/* { dg-final { scan-assembler "\"empty\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler "\"A\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler "\"B\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + + +struct A +{ + virtual ~A (); + int a1; +}; + +A::~A() +{ + a1 = 800; +} + +struct B : public A +{ + virtual ~B (); + int b1; + int b2; +}; + +B::~B() +{ + a1 = 900; + b1 = 901; + b2 = 902; +} + +// Stop the compiler from optimizing away data. +void refer (A *) +{ + ; +} + +struct empty {}; + +// Stop the compiler from optimizing away data. +void refer (empty *) +{ + ; +} + +int main (void) +{ + A alpha, *aap, *abp; + B beta, *bbp; + empty e; + + alpha.a1 = 100; + beta.a1 = 200; beta.b1 = 201; beta.b2 = 202; + + aap = α refer (aap); + abp = β refer (abp); + bbp = β refer (bbp); + refer (&e); + + return 0; // marker return 0 +} // marker close brace diff --git a/gcc/testsuite/gcc.dg/pubtypes-1.c b/gcc/testsuite/gcc.dg/pubtypes-1.c new file mode 100644 index 0000000..5c6767e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pubtypes-1.c @@ -0,0 +1,47 @@ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-O0 -gdwarf-2 -dA -fno-eliminate-unused-debug-types" } */ +/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */ +/* { dg-final { scan-assembler "__debug_pubtypes" } } */ +/* { dg-final { scan-assembler "long+\[ \t\]+0x\[0-9a-f]+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */ +/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + + +#include +#include + +struct used_struct +{ + int key; + char *name; +}; + +struct unused_struct +{ + int key1; + int f2; + double f3; + char *f4; + struct unused_struct *next; +}; + +int +main (int argc, char **argv) +{ + int i; + struct used_struct *my_list; + + my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct)); + + for (i = 0; i < 10; i++) + { + my_list[i].key = i; + my_list[i].name = (char *) malloc (11); + sprintf (my_list[i].name, "Alice_%d", i); + } + + for (i = 0; i < 10; i++) + fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pubtypes-2.c b/gcc/testsuite/gcc.dg/pubtypes-2.c new file mode 100644 index 0000000..fec4661 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pubtypes-2.c @@ -0,0 +1,46 @@ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-O0 -gdwarf-2 -dA" } */ +/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */ +/* { dg-final { scan-assembler "__debug_pubtypes" } } */ +/* { dg-final { scan-assembler "long+\[ \t\]+0x6a+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */ +/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + +#include +#include + +struct used_struct +{ + int key; + char *name; +}; + +struct unused_struct +{ + int key1; + int f2; + double f3; + char *f4; + struct unused_struct *next; +}; + +int +main (int argc, char **argv) +{ + int i; + struct used_struct *my_list; + + my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct)); + + for (i = 0; i < 10; i++) + { + my_list[i].key = i; + my_list[i].name = (char *) malloc (11); + sprintf (my_list[i].name, "Alice_%d", i); + } + + for (i = 0; i < 10; i++) + fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pubtypes-3.c b/gcc/testsuite/gcc.dg/pubtypes-3.c new file mode 100644 index 0000000..455dadf --- /dev/null +++ b/gcc/testsuite/gcc.dg/pubtypes-3.c @@ -0,0 +1,83 @@ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-O0 -gdwarf-2 -dA" } */ +/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */ +/* { dg-final { scan-assembler "__debug_pubtypes" } } */ +/* { dg-final { scan-assembler "long+\[ \t\]+0x6a+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */ +/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler-not "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + +#include +#include + +struct used_struct +{ + int key; + char *name; +}; + +struct unused_struct +{ + int key1; + int f2; + double f3; + char *f4; + struct unused_struct *next; +}; + +void +foo (struct used_struct *list) +{ + enum list_name_type { + boy_name, + girl_name, + unknown + }; + + int b_count = 0; + int g_count = 0; + int i; + enum list_name_type *enum_list; + + enum_list = (enum list_name_type *) malloc (10 * sizeof (enum list_name_type)); + + for (i = 0; i < 10; i++) + { + if (strncmp (list[i].name, "Alice", 5) == 0) + { + enum_list[i] = girl_name; + g_count++; + } + else if (strncmp (list[i].name, "David", 5) == 0) + { + enum_list[i] = boy_name; + b_count++; + } + else + enum_list[i] = unknown; + } + +} + +int +main (int argc, char **argv) +{ + int i; + struct used_struct *my_list; + + my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct)); + + for (i = 0; i < 10; i++) + { + my_list[i].key = i; + my_list[i].name = (char *) malloc (11); + sprintf (my_list[i].name, "Alice_%d", i); + } + + foo (my_list); + + for (i = 0; i < 10; i++) + fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pubtypes-4.c b/gcc/testsuite/gcc.dg/pubtypes-4.c new file mode 100644 index 0000000..db222da --- /dev/null +++ b/gcc/testsuite/gcc.dg/pubtypes-4.c @@ -0,0 +1,96 @@ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-options "-O0 -gdwarf-2 -dA" } */ +/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */ +/* { dg-final { scan-assembler "__debug_pubtypes" } } */ +/* { dg-final { scan-assembler "long+\[ \t\]+0xa1+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */ +/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler "\"enum_list_array\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +/* { dg-final { scan-assembler "\"field_union\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + +#include +#include + +struct used_struct +{ + int key; + char *name; + union field_union + { + char u_c; + int u_i; + long u_l; + double u_d; + } u; +}; + +struct unused_struct +{ + int key1; + int f2; + double f3; + char *f4; + struct unused_struct *next; +}; + +enum list_name_type { + boy_name, + girl_name, + unknown +}; + + +typedef enum list_name_type *enum_list_array; + +enum_list_array enum_list; + +void +foo (struct used_struct *list) +{ + int b_count = 0; + int g_count = 0; + int i; + + enum_list = (enum_list_array) malloc (10 * sizeof (enum list_name_type)); + + for (i = 0; i < 10; i++) + { + if (strncmp (list[i].name, "Alice", 5) == 0) + { + enum_list[i] = girl_name; + g_count++; + } + else if (strncmp (list[i].name, "David", 5) == 0) + { + enum_list[i] = boy_name; + b_count++; + } + else + enum_list[i] = unknown; + } + +} + +int +main (int argc, char **argv) +{ + int i; + struct used_struct *my_list; + + my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct)); + + for (i = 0; i < 10; i++) + { + my_list[i].key = i; + my_list[i].name = (char *) malloc (11); + sprintf (my_list[i].name, "Alice_%d", i); + } + + foo (my_list); + + for (i = 0; i < 10; i++) + fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name); + + return 0; +} -- 2.7.4