diff options
Diffstat (limited to 'gdb/parse.c')
-rw-r--r-- | gdb/parse.c | 206 |
1 files changed, 108 insertions, 98 deletions
diff --git a/gdb/parse.c b/gdb/parse.c index 3dd7075..6bbf25f 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -50,6 +50,7 @@ #include "objfiles.h" #include "user-regs.h" #include <algorithm> +#include "common/gdb_optional.h" /* Standard set of definitions for printing, dumping, prefixifying, * and evaluating expressions. */ @@ -110,8 +111,6 @@ show_parserdebug (struct ui_file *file, int from_tty, } -static void free_funcalls (void *ignore); - static int prefixify_subexp (struct expression *, struct expression *, int, int); @@ -122,18 +121,10 @@ static expression_up parse_exp_in_context_1 (const char **, CORE_ADDR, const struct block *, int, int, int *); -void _initialize_parse (void); - /* Data structure for saving values of arglist_len for function calls whose arguments contain other function calls. */ -struct funcall - { - struct funcall *next; - int arglist_len; - }; - -static struct funcall *funcall_chain; +static std::vector<int> *funcall_chain; /* Begin counting arguments for a function call, saving the data about any containing call. */ @@ -141,13 +132,8 @@ static struct funcall *funcall_chain; void start_arglist (void) { - struct funcall *newobj; - - newobj = XNEW (struct funcall); - newobj->next = funcall_chain; - newobj->arglist_len = arglist_len; + funcall_chain->push_back (arglist_len); arglist_len = 0; - funcall_chain = newobj; } /* Return the number of arguments in a function call just terminated, @@ -157,28 +143,11 @@ int end_arglist (void) { int val = arglist_len; - struct funcall *call = funcall_chain; - - funcall_chain = call->next; - arglist_len = call->arglist_len; - xfree (call); + arglist_len = funcall_chain->back (); + funcall_chain->pop_back (); return val; } -/* Free everything in the funcall chain. - Used when there is an error inside parsing. */ - -static void -free_funcalls (void *ignore) -{ - struct funcall *call, *next; - - for (call = funcall_chain; call; call = next) - { - next = call->next; - xfree (call); - } -} /* See definition in parser-defs.h. */ @@ -255,6 +224,16 @@ write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt) } void +write_exp_elt_msym (struct parser_state *ps, minimal_symbol *expelt) +{ + union exp_element tmp; + + memset (&tmp, 0, sizeof (union exp_element)); + tmp.msymbol = expelt; + write_exp_elt (ps, &tmp); +} + +void write_exp_elt_block (struct parser_state *ps, const struct block *b) { union exp_element tmp; @@ -469,22 +448,30 @@ write_exp_bitstring (struct parser_state *ps, struct stoken str) write_exp_elt_longcst (ps, (LONGEST) bits); } -/* Add the appropriate elements for a minimal symbol to the end of - the expression. */ +/* Return the type of MSYMBOL, a minimal symbol of OBJFILE. If + ADDRESS_P is not NULL, set it to the MSYMBOL's resolved + address. */ -void -write_exp_msymbol (struct parser_state *ps, - struct bound_minimal_symbol bound_msym) +type * +find_minsym_type_and_address (minimal_symbol *msymbol, + struct objfile *objfile, + CORE_ADDR *address_p) { - struct minimal_symbol *msymbol = bound_msym.minsym; - struct objfile *objfile = bound_msym.objfile; + bound_minimal_symbol bound_msym = {msymbol, objfile}; struct gdbarch *gdbarch = get_objfile_arch (objfile); - - CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (bound_msym); struct obj_section *section = MSYMBOL_OBJ_SECTION (objfile, msymbol); enum minimal_symbol_type type = MSYMBOL_TYPE (msymbol); CORE_ADDR pc; + bool is_tls = (section != NULL + && section->the_bfd_section->flags & SEC_THREAD_LOCAL); + + /* Addresses of TLS symbols are really offsets into a + per-objfile/per-thread storage block. */ + CORE_ADDR addr = (is_tls + ? MSYMBOL_VALUE_RAW_ADDRESS (bound_msym.minsym) + : BMSYMBOL_VALUE_ADDRESS (bound_msym)); + /* The minimal symbol might point to a function descriptor; resolve it to the actual code address instead. */ pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_target); @@ -514,51 +501,54 @@ write_exp_msymbol (struct parser_state *ps, if (overlay_debugging) addr = symbol_overlayed_address (addr, section); - write_exp_elt_opcode (ps, OP_LONG); - /* Let's make the type big enough to hold a 64-bit address. */ - write_exp_elt_type (ps, objfile_type (objfile)->builtin_core_addr); - write_exp_elt_longcst (ps, (LONGEST) addr); - write_exp_elt_opcode (ps, OP_LONG); - - if (section && section->the_bfd_section->flags & SEC_THREAD_LOCAL) + if (is_tls) { - write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS); - write_exp_elt_objfile (ps, objfile); - write_exp_elt_type (ps, objfile_type (objfile)->nodebug_tls_symbol); - write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS); - return; + /* Skip translation if caller does not need the address. */ + if (address_p != NULL) + *address_p = target_translate_tls_address (objfile, addr); + return objfile_type (objfile)->nodebug_tls_symbol; } - write_exp_elt_opcode (ps, UNOP_MEMVAL); + if (address_p != NULL) + *address_p = addr; + + struct type *the_type; + switch (type) { case mst_text: case mst_file_text: case mst_solib_trampoline: - write_exp_elt_type (ps, objfile_type (objfile)->nodebug_text_symbol); - break; + return objfile_type (objfile)->nodebug_text_symbol; case mst_text_gnu_ifunc: - write_exp_elt_type (ps, objfile_type (objfile) - ->nodebug_text_gnu_ifunc_symbol); - break; + return objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol; case mst_data: case mst_file_data: case mst_bss: case mst_file_bss: - write_exp_elt_type (ps, objfile_type (objfile)->nodebug_data_symbol); - break; + return objfile_type (objfile)->nodebug_data_symbol; case mst_slot_got_plt: - write_exp_elt_type (ps, objfile_type (objfile)->nodebug_got_plt_symbol); - break; + return objfile_type (objfile)->nodebug_got_plt_symbol; default: - write_exp_elt_type (ps, objfile_type (objfile)->nodebug_unknown_symbol); - break; + return objfile_type (objfile)->nodebug_unknown_symbol; } - write_exp_elt_opcode (ps, UNOP_MEMVAL); +} + +/* Add the appropriate elements for a minimal symbol to the end of + the expression. */ + +void +write_exp_msymbol (struct parser_state *ps, + struct bound_minimal_symbol bound_msym) +{ + write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE); + write_exp_elt_objfile (ps, bound_msym.objfile); + write_exp_elt_msym (ps, bound_msym.minsym); + write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE); } /* Mark the current index as the starting location of a structure @@ -883,9 +873,16 @@ operator_length_standard (const struct expression *expr, int endpos, case OP_DOUBLE: case OP_DECFLOAT: case OP_VAR_VALUE: + case OP_VAR_MSYM_VALUE: oplen = 4; break; + case OP_FUNC_STATIC_VAR: + oplen = longest_to_int (expr->elts[endpos - 2].longconst); + oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1); + args = 1; + break; + case OP_TYPE: case OP_BOOL: case OP_LAST: @@ -906,7 +903,7 @@ operator_length_standard (const struct expression *expr, int endpos, break; case TYPE_INSTANCE: - oplen = 4 + longest_to_int (expr->elts[endpos - 2].longconst); + oplen = 5 + longest_to_int (expr->elts[endpos - 2].longconst); args = 1; break; @@ -935,11 +932,6 @@ operator_length_standard (const struct expression *expr, int endpos, args = 1; break; - case UNOP_MEMVAL_TLS: - oplen = 4; - args = 1; - break; - case UNOP_ABS: case UNOP_CAP: case UNOP_CHR: @@ -1136,7 +1128,6 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc, const struct block *block, int comma, int void_context_p, int *out_subexp) { - struct cleanup *old_chain, *inner_chain; const struct language_defn *lang = NULL; struct parser_state ps; int subexp; @@ -1156,8 +1147,9 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc, if (lexptr == 0 || *lexptr == 0) error_no_arg (_("expression to compute")); - old_chain = make_cleanup (free_funcalls, 0 /*ignore*/); - funcall_chain = 0; + std::vector<int> funcalls; + scoped_restore save_funcall_chain = make_scoped_restore (&funcall_chain, + &funcalls); expression_context_block = block; @@ -1214,7 +1206,8 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc, to the value matching SELECTED_FRAME as set by get_current_arch. */ initialize_expout (&ps, 10, lang, get_current_arch ()); - inner_chain = make_cleanup_restore_current_language (); + + scoped_restore_current_language lang_saver; set_language (lang->la_language); TRY @@ -1250,9 +1243,6 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc, if (expressiondebug) dump_prefix_expression (ps.expout, gdb_stdlog); - do_cleanups (inner_chain); - discard_cleanups (old_chain); - *stringptr = lexptr; return expression_up (ps.expout); } @@ -1275,19 +1265,14 @@ parse_expression (const char *string) expression_up parse_expression_with_language (const char *string, enum language lang) { - struct cleanup *old_chain = NULL; - + gdb::optional<scoped_restore_current_language> lang_saver; if (current_language->la_language != lang) { - old_chain = make_cleanup_restore_current_language (); + lang_saver.emplace (); set_language (lang); } - expression_up expr = parse_expression (string); - - if (old_chain != NULL) - do_cleanups (old_chain); - return expr; + return parse_expression (string); } /* Parse STRING as an expression. If parsing ends in the middle of a @@ -1631,6 +1616,33 @@ push_typelist (VEC (type_ptr) *list) push_type (tp_function_with_arguments); } +/* Pop the type stack and return a type_instance_flags that + corresponds the const/volatile qualifiers on the stack. This is + called by the C++ parser when parsing methods types, and as such no + other kind of type in the type stack is expected. */ + +type_instance_flags +follow_type_instance_flags () +{ + type_instance_flags flags = 0; + + for (;;) + switch (pop_type ()) + { + case tp_end: + return flags; + case tp_const: + flags |= TYPE_INSTANCE_FLAG_CONST; + break; + case tp_volatile: + flags |= TYPE_INSTANCE_FLAG_VOLATILE; + break; + default: + gdb_assert_not_reached ("unrecognized tp_ value in follow_types"); + } +} + + /* Pop the type stack and return the type which corresponds to FOLLOW_TYPE as modified by all the stuff on the stack. */ struct type * @@ -1810,11 +1822,11 @@ operator_check_standard (struct expression *exp, int pos, case TYPE_INSTANCE: { - LONGEST arg, nargs = elts[pos + 1].longconst; + LONGEST arg, nargs = elts[pos + 2].longconst; for (arg = 0; arg < nargs; arg++) { - struct type *type = elts[pos + 2 + arg].type; + struct type *type = elts[pos + 3 + arg].type; struct objfile *objfile = TYPE_OBJFILE (type); if (objfile && (*objfile_func) (objfile, data)) @@ -1823,11 +1835,6 @@ operator_check_standard (struct expression *exp, int pos, } break; - case UNOP_MEMVAL_TLS: - objfile = elts[pos + 1].objfile; - type = elts[pos + 2].type; - break; - case OP_VAR_VALUE: { const struct block *const block = elts[pos + 1].block; @@ -1844,6 +1851,9 @@ operator_check_standard (struct expression *exp, int pos, type = SYMBOL_TYPE (symbol); } break; + case OP_VAR_MSYM_VALUE: + objfile = elts[pos + 1].objfile; + break; } /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */ |