From a60f3166aa946336c68e7a873d5eed6061b5733c Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 20 May 2018 23:58:35 -0600 Subject: [PATCH] Move the context stack to buildsym_compunit This moves the context stack globals to be members of buildsym_compunit, changing the type to a std::vector in the process. Because the callers expect the context stack object to be valid after being popped, at Simon's suggestion I've changed pop_context to return the object rather than the pointer. gdb/ChangeLog 2018-07-20 Tom Tromey * coffread.c (coff_symtab_read): Update. * xcoffread.c (read_xcoff_symtab): Update. * dwarf2read.c (new_symbol): Update. (read_func_scope, read_lexical_block_scope): Update. * dbxread.c (process_one_symbol): Update. * buildsym.h (context_stack, context_stack_depth): Don't declare. (outermost_context_p): Remove macro. (outermost_context_p, get_current_context_stack) (get_context_stack_depth): Declare. (pop_context): Return struct context_stack. * buildsym.c (struct buildsym_compunit) + * coffread.c (coff_symtab_read): Update. + * xcoffread.c (read_xcoff_symtab): Update. + * dwarf2read.c (new_symbol): Update. + (read_func_scope, read_lexical_block_scope): Update. + * dbxread.c (process_one_symbol): Update. + * buildsym.h (context_stack, context_stack_depth): Don't declare. + (outermost_context_p): Remove macro. + (outermost_context_p, get_current_context_stack) + (get_context_stack_depth): Declare. + (pop_context): Return struct context_stack. + * buildsym.c (struct buildsym_compunit) + * rust-exp.y: Now a pure parser. Update all rules. (%union): Move earlier. (current_parser, work_obstack): Remove globals. diff --git a/gdb/buildsym.c b/gdb/buildsym.c index c50bbb4..aa7191d 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -210,6 +210,10 @@ struct buildsym_compunit /* Global "using" directives. */ struct using_direct *m_global_using_directives = nullptr; + + /* The stack of contexts that are pushed by push_context and popped + by pop_context. */ + std::vector m_context_stack; }; /* The work-in-progress of the compunit we are building. @@ -257,10 +261,6 @@ struct pending_block static struct pending_block *pending_blocks; -/* Currently allocated size of context stack. */ - -static int context_stack_size; - static void free_buildsym_compunit (void); static int compare_line_numbers (const void *ln1p, const void *ln2p); @@ -275,7 +275,6 @@ static void free_pending_blocks (); needed, and realloc'd down to the size actually used, when completed. */ -#define INITIAL_CONTEXT_STACK_SIZE 10 #define INITIAL_LINE_VECTOR_LENGTH 1000 @@ -1025,8 +1024,6 @@ prepare_for_building () { local_symbols = NULL; - context_stack_depth = 0; - /* These should have been reset either by successful completion of building a symtab, or by the scoped_free_pendings destructor. */ gdb_assert (file_symbols == NULL); @@ -1215,15 +1212,15 @@ end_symtab_get_static_block (CORE_ADDR end_addr, int expandable, int required) /* Finish the lexical context of the last function in the file; pop the context stack. */ - if (context_stack_depth > 0) + if (!buildsym_compunit->m_context_stack.empty ()) { - struct context_stack *cstk = pop_context (); + struct context_stack cstk = pop_context (); /* Make a block for the local symbols within. */ - finish_block (cstk->name, &local_symbols, cstk->old_blocks, NULL, - cstk->start_addr, end_addr); + finish_block (cstk.name, &local_symbols, cstk.old_blocks, NULL, + cstk.start_addr, end_addr); - if (context_stack_depth > 0) + if (!buildsym_compunit->m_context_stack.empty ()) { /* This is said to happen with SCO. The old coffread.c code simply emptied the context stack, so we do the @@ -1231,7 +1228,7 @@ end_symtab_get_static_block (CORE_ADDR end_addr, int expandable, int required) believed to happen in most cases (even for coffread.c); it used to be an abort(). */ complaint (_("Context stack not empty in end_symtab")); - context_stack_depth = 0; + buildsym_compunit->m_context_stack.clear (); } } @@ -1575,11 +1572,8 @@ augment_type_symtab (void) struct compunit_symtab *cust = buildsym_compunit->compunit_symtab; const struct blockvector *blockvector = COMPUNIT_BLOCKVECTOR (cust); - if (context_stack_depth > 0) - { - complaint (_("Context stack not empty in augment_type_symtab")); - context_stack_depth = 0; - } + if (!buildsym_compunit->m_context_stack.empty ()) + complaint (_("Context stack not empty in augment_type_symtab")); if (pending_blocks != NULL) complaint (_("Blocks in a type symtab")); if (buildsym_compunit->m_pending_macros != NULL) @@ -1619,17 +1613,11 @@ augment_type_symtab (void) struct context_stack * push_context (int desc, CORE_ADDR valu) { - struct context_stack *newobj; + gdb_assert (buildsym_compunit != nullptr); - if (context_stack_depth == context_stack_size) - { - context_stack_size *= 2; - context_stack = (struct context_stack *) - xrealloc ((char *) context_stack, - (context_stack_size * sizeof (struct context_stack))); - } + buildsym_compunit->m_context_stack.emplace_back (); + struct context_stack *newobj = &buildsym_compunit->m_context_stack.back (); - newobj = &context_stack[context_stack_depth++]; newobj->depth = desc; newobj->locals = local_symbols; newobj->old_blocks = pending_blocks; @@ -1647,11 +1635,14 @@ push_context (int desc, CORE_ADDR valu) /* Pop a context block. Returns the address of the context block just popped. */ -struct context_stack * -pop_context (void) +struct context_stack +pop_context () { - gdb_assert (context_stack_depth > 0); - return (&context_stack[--context_stack_depth]); + gdb_assert (buildsym_compunit != nullptr); + gdb_assert (!buildsym_compunit->m_context_stack.empty ()); + struct context_stack result = buildsym_compunit->m_context_stack.back (); + buildsym_compunit->m_context_stack.pop_back (); + return result; } @@ -1735,6 +1726,35 @@ get_global_using_directives () return &buildsym_compunit->m_global_using_directives; } +/* See buildsym.h. */ + +bool +outermost_context_p () +{ + gdb_assert (buildsym_compunit != nullptr); + return buildsym_compunit->m_context_stack.empty (); +} + +/* See buildsym.h. */ + +struct context_stack * +get_current_context_stack () +{ + gdb_assert (buildsym_compunit != nullptr); + if (buildsym_compunit->m_context_stack.empty ()) + return nullptr; + return &buildsym_compunit->m_context_stack.back (); +} + +/* See buildsym.h. */ + +int +get_context_stack_depth () +{ + gdb_assert (buildsym_compunit != nullptr); + return buildsym_compunit->m_context_stack.size (); +} + /* Initialize anything that needs initializing when starting to read a @@ -1746,14 +1766,6 @@ buildsym_init () { pending_addrmap_interesting = 0; - /* Context stack is initially empty. Allocate first one with room - for a few levels; reuse it forever afterward. */ - if (context_stack == NULL) - { - context_stack_size = INITIAL_CONTEXT_STACK_SIZE; - context_stack = XNEWVEC (struct context_stack, context_stack_size); - } - /* Ensure the scoped_free_pendings destructor was called after the last time. */ gdb_assert (free_pendings == NULL); diff --git a/gdb/buildsym.h b/gdb/buildsym.h index efb35c9..32a2e1b 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -133,15 +133,6 @@ struct context_stack }; -EXTERN struct context_stack *context_stack; - -/* Index of first unused entry in context stack. */ - -EXTERN int context_stack_depth; - -/* Non-zero if the context stack is empty. */ -#define outermost_context_p() (context_stack_depth == 0) - /* The type of the record_line function. */ typedef void (record_line_ftype) (struct subfile *subfile, int line, CORE_ADDR pc); @@ -201,7 +192,7 @@ extern void buildsym_init (); extern struct context_stack *push_context (int desc, CORE_ADDR valu); -extern struct context_stack *pop_context (void); +extern struct context_stack pop_context (); extern record_line_ftype record_line; @@ -270,6 +261,19 @@ extern void set_local_using_directives (struct using_direct *new_local); extern struct using_direct **get_global_using_directives (); +/* True if the context stack is empty. */ + +extern bool outermost_context_p (); + +/* Return the top of the context stack, or nullptr if there is an + entry. */ + +extern struct context_stack *get_current_context_stack (); + +/* Return the context stack depth. */ + +extern int get_context_stack_depth (); + #undef EXTERN #endif /* defined (BUILDSYM_H) */ diff --git a/gdb/coffread.c b/gdb/coffread.c index ff55542..718c334 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -1100,7 +1100,7 @@ coff_symtab_read (minimal_symbol_reader &reader, break; } - newobj = pop_context (); + struct context_stack cstk = pop_context (); /* Stack must be empty now. */ if (!outermost_context_p () || newobj == NULL) { @@ -1135,8 +1135,8 @@ coff_symtab_read (minimal_symbol_reader &reader, enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line, objfile); - finish_block (newobj->name, &local_symbols, newobj->old_blocks, - NULL, newobj->start_addr, + finish_block (cstk.name, &local_symbols, cstk.old_blocks, + NULL, cstk.start_addr, fcn_cs_saved.c_value + fcn_aux_saved.x_sym.x_misc.x_fsize + ANOFFSET (objfile->section_offsets, @@ -1163,8 +1163,8 @@ coff_symtab_read (minimal_symbol_reader &reader, break; } - newobj = pop_context (); - if (depth-- != newobj->depth) + struct context_stack cstk = pop_context (); + if (depth-- != cstk.depth) { complaint (_("Mismatched .eb symbol ignored " "starting at symnum %d"), @@ -1177,11 +1177,11 @@ coff_symtab_read (minimal_symbol_reader &reader, cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Make a block for the local symbols within. */ - finish_block (0, &local_symbols, newobj->old_blocks, NULL, - newobj->start_addr, tmpaddr); + finish_block (0, &local_symbols, cstk.old_blocks, NULL, + cstk.start_addr, tmpaddr); } /* Now pop locals of block just finished. */ - local_symbols = newobj->locals; + local_symbols = cstk.locals; } break; diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 996da27..ad3f2a9 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -2448,6 +2448,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, { struct gdbarch *gdbarch = get_objfile_arch (objfile); struct context_stack *newobj; + struct context_stack cstk; /* This remembers the address of the start of a function. It is used because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are relative to the current function's start address. On systems @@ -2512,16 +2513,16 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, } within_function = 0; - newobj = pop_context (); + cstk = pop_context (); /* Make a block for the local symbols within. */ - block = finish_block (newobj->name, &local_symbols, - newobj->old_blocks, NULL, - newobj->start_addr, newobj->start_addr + valu); + block = finish_block (cstk.name, &local_symbols, + cstk.old_blocks, NULL, + cstk.start_addr, cstk.start_addr + valu); /* For C++, set the block's scope. */ - if (SYMBOL_LANGUAGE (newobj->name) == language_cplus) - cp_set_block_scope (newobj->name, block, &objfile->objfile_obstack); + if (SYMBOL_LANGUAGE (cstk.name) == language_cplus) + cp_set_block_scope (cstk.name, block, &objfile->objfile_obstack); /* May be switching to an assembler file which may not be using block relative stabs, so reset the offset. */ @@ -2568,8 +2569,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, break; } - newobj = pop_context (); - if (desc != newobj->depth) + cstk = pop_context (); + if (desc != cstk.depth) lbrac_mismatch_complaint (symnum); if (local_symbols != NULL) @@ -2581,9 +2582,9 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, complaint (_("misplaced N_LBRAC entry; discarding local " "symbols which have no enclosing block")); } - local_symbols = newobj->locals; + local_symbols = cstk.locals; - if (context_stack_depth > 1) + if (get_context_stack_depth () > 1) { /* This is not the outermost LBRAC...RBRAC pair in the function, its local symbols preceded it, and are the ones @@ -2596,14 +2597,14 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, /* Muzzle a compiler bug that makes end < start. ??? Which compilers? Is this ever harmful?. */ - if (newobj->start_addr > valu) + if (cstk.start_addr > valu) { complaint (_("block start larger than block end")); - newobj->start_addr = valu; + cstk.start_addr = valu; } /* Make a block for the local symbols within. */ - finish_block (0, &local_symbols, newobj->old_blocks, NULL, - newobj->start_addr, valu); + finish_block (0, &local_symbols, cstk.old_blocks, NULL, + cstk.start_addr, valu); } } else @@ -2876,7 +2877,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, within_function = 1; - if (context_stack_depth > 1) + if (get_context_stack_depth () > 1) { complaint (_("unmatched N_LBRAC before symtab pos %d"), symnum); @@ -2887,15 +2888,15 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, { struct block *block; - newobj = pop_context (); + cstk = pop_context (); /* Make a block for the local symbols within. */ - block = finish_block (newobj->name, &local_symbols, - newobj->old_blocks, NULL, - newobj->start_addr, valu); + block = finish_block (cstk.name, &local_symbols, + cstk.old_blocks, NULL, + cstk.start_addr, valu); /* For C++, set the block's scope. */ - if (SYMBOL_LANGUAGE (newobj->name) == language_cplus) - cp_set_block_scope (newobj->name, block, + if (SYMBOL_LANGUAGE (cstk.name) == language_cplus) + cp_set_block_scope (cstk.name, block, &objfile->objfile_obstack); } diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b7933de..859419e 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -13683,10 +13683,10 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) } } - newobj = pop_context (); + struct context_stack cstk = pop_context (); /* Make a block for the local symbols within. */ - block = finish_block (newobj->name, &local_symbols, newobj->old_blocks, - newobj->static_link, lowpc, highpc); + block = finish_block (cstk.name, &local_symbols, cstk.old_blocks, + cstk.static_link, lowpc, highpc); /* For C++, set the block's scope. */ if ((cu->language == language_cplus @@ -13700,7 +13700,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) /* If we have address ranges, record them. */ dwarf2_record_block_ranges (die, block, baseaddr, cu); - gdbarch_make_symbol_special (gdbarch, newobj->name, objfile); + gdbarch_make_symbol_special (gdbarch, cstk.name, objfile); /* Attach template arguments to function. */ if (!template_args.empty ()) @@ -13720,8 +13720,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) a function declares a class that has methods). This means that when we finish processing a function scope, we may need to go back to building a containing block's symbol lists. */ - local_symbols = newobj->locals; - set_local_using_directives (newobj->local_using_directives); + local_symbols = cstk.locals; + set_local_using_directives (cstk.local_using_directives); /* If we've finished processing a top-level function, subsequent symbols go in the file symbol list. */ @@ -13737,7 +13737,6 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile; struct gdbarch *gdbarch = get_objfile_arch (objfile); - struct context_stack *newobj; CORE_ADDR lowpc, highpc; struct die_info *child_die; CORE_ADDR baseaddr; @@ -13777,13 +13776,13 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) } } inherit_abstract_dies (die, cu); - newobj = pop_context (); + struct context_stack cstk = pop_context (); if (local_symbols != NULL || (*get_local_using_directives ()) != NULL) { struct block *block - = finish_block (0, &local_symbols, newobj->old_blocks, NULL, - newobj->start_addr, highpc); + = finish_block (0, &local_symbols, cstk.old_blocks, NULL, + cstk.start_addr, highpc); /* Note that recording ranges after traversing children, as we do here, means that recording a parent's ranges entails @@ -13797,8 +13796,8 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) to do. */ dwarf2_record_block_ranges (die, block, baseaddr, cu); } - local_symbols = newobj->locals; - set_local_using_directives (newobj->local_using_directives); + local_symbols = cstk.locals; + set_local_using_directives (cstk.local_using_directives); } /* Read in DW_TAG_call_site and insert it to CU->call_site_htab. */ @@ -21348,26 +21347,28 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, } break; case DW_TAG_formal_parameter: - /* If we are inside a function, mark this as an argument. If - not, we might be looking at an argument to an inlined function - when we do not have enough information to show inlined frames; - pretend it's a local variable in that case so that the user can - still see it. */ - if (!outermost_context_p () - && context_stack[context_stack_depth - 1].name != NULL) - SYMBOL_IS_ARGUMENT (sym) = 1; - attr = dwarf2_attr (die, DW_AT_location, cu); - if (attr) - { - var_decode_location (attr, sym, cu); - } - attr = dwarf2_attr (die, DW_AT_const_value, cu); - if (attr) - { - dwarf2_const_value (attr, sym, cu); - } + { + /* If we are inside a function, mark this as an argument. If + not, we might be looking at an argument to an inlined function + when we do not have enough information to show inlined frames; + pretend it's a local variable in that case so that the user can + still see it. */ + struct context_stack *curr = get_current_context_stack (); + if (curr != nullptr && curr->name != nullptr) + SYMBOL_IS_ARGUMENT (sym) = 1; + attr = dwarf2_attr (die, DW_AT_location, cu); + if (attr) + { + var_decode_location (attr, sym, cu); + } + attr = dwarf2_attr (die, DW_AT_const_value, cu); + if (attr) + { + dwarf2_const_value (attr, sym, cu); + } - list_to_add = cu->list_in_scope; + list_to_add = cu->list_in_scope; + } break; case DW_TAG_unspecified_parameters: /* From varargs functions; gdb doesn't seem to have any diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c index 7f4e63e..785de29 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -1397,17 +1397,17 @@ read_xcoff_symtab (struct objfile *objfile, struct partial_symtab *pst) within_function = 0; break; } - newobj = pop_context (); + struct context_stack cstk = pop_context (); /* Stack must be empty now. */ - if (!outermost_context_p () || newobj == NULL) + if (!outermost_context_p ()) { ef_complaint (cs->c_symnum); within_function = 0; break; } - finish_block (newobj->name, &local_symbols, newobj->old_blocks, - NULL, newobj->start_addr, + finish_block (cstk.name, &local_symbols, cstk.old_blocks, + NULL, cstk.start_addr, (fcn_cs_saved.c_value + fcn_aux_saved.x_sym.x_misc.x_fsize + ANOFFSET (objfile->section_offsets, @@ -1488,8 +1488,8 @@ read_xcoff_symtab (struct objfile *objfile, struct partial_symtab *pst) eb_complaint (cs->c_symnum); break; } - newobj = pop_context (); - if (depth-- != newobj->depth) + struct context_stack cstk = pop_context (); + if (depth-- != cstk.depth) { eb_complaint (cs->c_symnum); break; @@ -1497,14 +1497,14 @@ read_xcoff_symtab (struct objfile *objfile, struct partial_symtab *pst) if (local_symbols && !outermost_context_p ()) { /* Make a block for the local symbols within. */ - finish_block (newobj->name, &local_symbols, - newobj->old_blocks, NULL, - newobj->start_addr, + finish_block (cstk.name, &local_symbols, + cstk.old_blocks, NULL, + cstk.start_addr, (cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))); } - local_symbols = newobj->locals; + local_symbols = cstk.locals; } break; -- 2.7.4