gdb/parse.c - gdb
Global variables defined
Data types defined
Functions defined
Source code
- #include "defs.h"
- #include <ctype.h>
- #include "arch-utils.h"
- #include "symtab.h"
- #include "gdbtypes.h"
- #include "frame.h"
- #include "expression.h"
- #include "value.h"
- #include "command.h"
- #include "language.h"
- #include "f-lang.h"
- #include "parser-defs.h"
- #include "gdbcmd.h"
- #include "symfile.h"
- #include "inferior.h"
- #include "doublest.h"
- #include "block.h"
- #include "source.h"
- #include "objfiles.h"
- #include "user-regs.h"
- const struct exp_descriptor exp_descriptor_standard =
- {
- print_subexp_standard,
- operator_length_standard,
- operator_check_standard,
- op_name_standard,
- dump_subexp_body_standard,
- evaluate_subexp_standard
- };
- const struct block *expression_context_block;
- CORE_ADDR expression_context_pc;
- const struct block *innermost_block;
- int arglist_len;
- static struct type_stack type_stack;
- const char *lexptr;
- const char *prev_lexptr;
- int paren_depth;
- int comma_terminates;
- int parse_completion;
- static int expout_last_struct = -1;
- static enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;
- static char *expout_completion_name;
- static unsigned int expressiondebug = 0;
- static void
- show_expressiondebug (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
- fprintf_filtered (file, _("Expression debugging is %s.\n"), value);
- }
- int parser_debug;
- static void
- show_parserdebug (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
- fprintf_filtered (file, _("Parser debugging is %s.\n"), value);
- }
- static void free_funcalls (void *ignore);
- static int prefixify_subexp (struct expression *, struct expression *, int,
- int);
- static struct expression *parse_exp_in_context (const char **, CORE_ADDR,
- const struct block *, int,
- int, int *);
- static struct expression *parse_exp_in_context_1 (const char **, CORE_ADDR,
- const struct block *, int,
- int, int *);
- void _initialize_parse (void);
- struct funcall
- {
- struct funcall *next;
- int arglist_len;
- };
- static struct funcall *funcall_chain;
- void
- start_arglist (void)
- {
- struct funcall *new;
- new = (struct funcall *) xmalloc (sizeof (struct funcall));
- new->next = funcall_chain;
- new->arglist_len = arglist_len;
- arglist_len = 0;
- funcall_chain = new;
- }
- int
- end_arglist (void)
- {
- int val = arglist_len;
- struct funcall *call = funcall_chain;
- funcall_chain = call->next;
- arglist_len = call->arglist_len;
- xfree (call);
- return val;
- }
- static void
- free_funcalls (void *ignore)
- {
- struct funcall *call, *next;
- for (call = funcall_chain; call; call = next)
- {
- next = call->next;
- xfree (call);
- }
- }
- void
- initialize_expout (struct parser_state *ps, size_t initial_size,
- const struct language_defn *lang,
- struct gdbarch *gdbarch)
- {
- ps->expout_size = initial_size;
- ps->expout_ptr = 0;
- ps->expout = xmalloc (sizeof (struct expression)
- + EXP_ELEM_TO_BYTES (ps->expout_size));
- ps->expout->language_defn = lang;
- ps->expout->gdbarch = gdbarch;
- }
- void
- reallocate_expout (struct parser_state *ps)
- {
-
- ps->expout->nelts = ps->expout_ptr;
- ps->expout = (struct expression *)
- xrealloc (ps->expout,
- sizeof (struct expression)
- + EXP_ELEM_TO_BYTES (ps->expout_ptr));
- }
- static void
- write_exp_elt (struct parser_state *ps, const union exp_element *expelt)
- {
- if (ps->expout_ptr >= ps->expout_size)
- {
- ps->expout_size *= 2;
- ps->expout = (struct expression *)
- xrealloc (ps->expout, sizeof (struct expression)
- + EXP_ELEM_TO_BYTES (ps->expout_size));
- }
- ps->expout->elts[ps->expout_ptr++] = *expelt;
- }
- void
- write_exp_elt_opcode (struct parser_state *ps, enum exp_opcode expelt)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.opcode = expelt;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.symbol = expelt;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_block (struct parser_state *ps, const struct block *b)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.block = b;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_objfile (struct parser_state *ps, struct objfile *objfile)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.objfile = objfile;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_longcst (struct parser_state *ps, LONGEST expelt)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.longconst = expelt;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_dblcst (struct parser_state *ps, DOUBLEST expelt)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.doubleconst = expelt;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_decfloatcst (struct parser_state *ps, gdb_byte expelt[16])
- {
- union exp_element tmp;
- int index;
- for (index = 0; index < 16; index++)
- tmp.decfloatconst[index] = expelt[index];
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_type (struct parser_state *ps, struct type *expelt)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.type = expelt;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_elt_intern (struct parser_state *ps, struct internalvar *expelt)
- {
- union exp_element tmp;
- memset (&tmp, 0, sizeof (union exp_element));
- tmp.internalvar = expelt;
- write_exp_elt (ps, &tmp);
- }
- void
- write_exp_string (struct parser_state *ps, struct stoken str)
- {
- int len = str.length;
- size_t lenelt;
- char *strdata;
-
- lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1);
- increase_expout_size (ps, lenelt);
-
- write_exp_elt_longcst (ps, (LONGEST) len);
- strdata = (char *) &ps->expout->elts[ps->expout_ptr];
- memcpy (strdata, str.ptr, len);
- *(strdata + len) = '\0';
- ps->expout_ptr += lenelt - 2;
- write_exp_elt_longcst (ps, (LONGEST) len);
- }
- void
- write_exp_string_vector (struct parser_state *ps, int type,
- struct stoken_vector *vec)
- {
- int i, len;
- size_t n_slots;
-
- n_slots = 0;
- for (i = 0; i < vec->len; ++i)
- {
-
- n_slots += 1 + BYTES_TO_EXP_ELEM (vec->tokens[i].length);
- }
-
- ++n_slots;
-
- len = EXP_ELEM_TO_BYTES (n_slots) - 1;
- n_slots += 4;
- increase_expout_size (ps, n_slots);
- write_exp_elt_opcode (ps, OP_STRING);
- write_exp_elt_longcst (ps, len);
- write_exp_elt_longcst (ps, type);
- for (i = 0; i < vec->len; ++i)
- {
- write_exp_elt_longcst (ps, vec->tokens[i].length);
- memcpy (&ps->expout->elts[ps->expout_ptr], vec->tokens[i].ptr,
- vec->tokens[i].length);
- ps->expout_ptr += BYTES_TO_EXP_ELEM (vec->tokens[i].length);
- }
- write_exp_elt_longcst (ps, len);
- write_exp_elt_opcode (ps, OP_STRING);
- }
- void
- write_exp_bitstring (struct parser_state *ps, struct stoken str)
- {
- int bits = str.length;
- int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
- size_t lenelt;
- char *strdata;
-
- lenelt = 2 + BYTES_TO_EXP_ELEM (len);
- increase_expout_size (ps, lenelt);
-
- write_exp_elt_longcst (ps, (LONGEST) bits);
- strdata = (char *) &ps->expout->elts[ps->expout_ptr];
- memcpy (strdata, str.ptr, len);
- ps->expout_ptr += lenelt - 2;
- write_exp_elt_longcst (ps, (LONGEST) bits);
- }
- void
- write_exp_msymbol (struct parser_state *ps,
- struct bound_minimal_symbol bound_msym)
- {
- struct minimal_symbol *msymbol = bound_msym.minsym;
- struct objfile *objfile = bound_msym.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;
-
- pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_target);
- if (pc != addr)
- {
- struct bound_minimal_symbol ifunc_msym = lookup_minimal_symbol_by_pc (pc);
-
- if (ifunc_msym.minsym != NULL
- && MSYMBOL_TYPE (ifunc_msym.minsym) == mst_text_gnu_ifunc
- && BMSYMBOL_VALUE_ADDRESS (ifunc_msym) == pc)
- {
-
- type = mst_text_gnu_ifunc;
- }
- else
- type = mst_text;
- section = NULL;
- addr = pc;
- }
- if (overlay_debugging)
- addr = symbol_overlayed_address (addr, section);
- write_exp_elt_opcode (ps, OP_LONG);
-
- 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)
- {
- 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;
- }
- write_exp_elt_opcode (ps, UNOP_MEMVAL);
- 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;
- case mst_text_gnu_ifunc:
- write_exp_elt_type (ps, objfile_type (objfile)
- ->nodebug_text_gnu_ifunc_symbol);
- break;
- 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;
- case mst_slot_got_plt:
- write_exp_elt_type (ps, objfile_type (objfile)->nodebug_got_plt_symbol);
- break;
- default:
- write_exp_elt_type (ps, objfile_type (objfile)->nodebug_unknown_symbol);
- break;
- }
- write_exp_elt_opcode (ps, UNOP_MEMVAL);
- }
- void
- mark_struct_expression (struct parser_state *ps)
- {
- gdb_assert (parse_completion
- && expout_tag_completion_type == TYPE_CODE_UNDEF);
- expout_last_struct = ps->expout_ptr;
- }
- void
- mark_completion_tag (enum type_code tag, const char *ptr, int length)
- {
- gdb_assert (parse_completion
- && expout_tag_completion_type == TYPE_CODE_UNDEF
- && expout_completion_name == NULL
- && expout_last_struct == -1);
- gdb_assert (tag == TYPE_CODE_UNION
- || tag == TYPE_CODE_STRUCT
- || tag == TYPE_CODE_ENUM);
- expout_tag_completion_type = tag;
- expout_completion_name = xmalloc (length + 1);
- memcpy (expout_completion_name, ptr, length);
- expout_completion_name[length] = '\0';
- }
- void
- write_dollar_variable (struct parser_state *ps, struct stoken str)
- {
- struct symbol *sym = NULL;
- struct bound_minimal_symbol msym;
- struct internalvar *isym = NULL;
-
- int negate = 0;
- int i = 1;
-
- if (str.length >= 2 && str.ptr[1] == '$')
- {
- negate = 1;
- i = 2;
- }
- if (i == str.length)
- {
-
- i = -negate;
- goto handle_last;
- }
-
- for (; i < str.length; i++)
- if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9'))
- break;
- if (i == str.length)
- {
- i = atoi (str.ptr + 1 + negate);
- if (negate)
- i = -i;
- goto handle_last;
- }
-
- i = user_reg_map_name_to_regnum (parse_gdbarch (ps),
- str.ptr + 1, str.length - 1);
- if (i >= 0)
- goto handle_register;
-
- isym = lookup_only_internalvar (copy_name (str) + 1);
- if (isym)
- {
- write_exp_elt_opcode (ps, OP_INTERNALVAR);
- write_exp_elt_intern (ps, isym);
- write_exp_elt_opcode (ps, OP_INTERNALVAR);
- return;
- }
-
- sym = lookup_symbol (copy_name (str), (struct block *) NULL,
- VAR_DOMAIN, NULL);
- if (sym)
- {
- write_exp_elt_opcode (ps, OP_VAR_VALUE);
- write_exp_elt_block (ps, block_found);
- write_exp_elt_sym (ps, sym);
- write_exp_elt_opcode (ps, OP_VAR_VALUE);
- return;
- }
- msym = lookup_bound_minimal_symbol (copy_name (str));
- if (msym.minsym)
- {
- write_exp_msymbol (ps, msym);
- return;
- }
-
- write_exp_elt_opcode (ps, OP_INTERNALVAR);
- write_exp_elt_intern (ps, create_internalvar (copy_name (str) + 1));
- write_exp_elt_opcode (ps, OP_INTERNALVAR);
- return;
- handle_last:
- write_exp_elt_opcode (ps, OP_LAST);
- write_exp_elt_longcst (ps, (LONGEST) i);
- write_exp_elt_opcode (ps, OP_LAST);
- return;
- handle_register:
- write_exp_elt_opcode (ps, OP_REGISTER);
- str.length--;
- str.ptr++;
- write_exp_string (ps, str);
- write_exp_elt_opcode (ps, OP_REGISTER);
- return;
- }
- const char *
- find_template_name_end (const char *p)
- {
- int depth = 1;
- int just_seen_right = 0;
- int just_seen_colon = 0;
- int just_seen_space = 0;
- if (!p || (*p != '<'))
- return 0;
- while (*++p)
- {
- switch (*p)
- {
- case '\'':
- case '\"':
- case '{':
- case '}':
-
- return 0;
- case '<':
- depth++;
- if (just_seen_colon || just_seen_right || just_seen_space)
- return 0;
- break;
- case '>':
- if (just_seen_colon || just_seen_right)
- return 0;
- just_seen_right = 1;
- if (--depth == 0)
- return ++p;
- break;
- case ':':
- if (just_seen_space || (just_seen_colon > 1))
- return 0;
- just_seen_colon++;
- break;
- case ' ':
- break;
- default:
- if (!((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9') ||
- (*p == '_') || (*p == ',') ||
- (*p == '&') || (*p == '*') ||
- (*p == '(') || (*p == ')') ||
- (*p == '[') || (*p == ']')))
- return 0;
- }
- if (*p != ' ')
- just_seen_space = 0;
- if (*p != ':')
- just_seen_colon = 0;
- if (*p != '>')
- just_seen_right = 0;
- }
- return 0;
- }
- char *
- copy_name (struct stoken token)
- {
-
- static char *namecopy;
- static size_t namecopy_size;
-
- if (namecopy_size < token.length + 1)
- {
- namecopy_size = token.length + 1;
- namecopy = xrealloc (namecopy, token.length + 1);
- }
- memcpy (namecopy, token.ptr, token.length);
- namecopy[token.length] = 0;
- return namecopy;
- }
- int
- prefixify_expression (struct expression *expr)
- {
- int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
- struct expression *temp;
- int inpos = expr->nelts, outpos = 0;
- temp = (struct expression *) alloca (len);
-
- memcpy (temp, expr, len);
- return prefixify_subexp (temp, expr, inpos, outpos);
- }
- int
- length_of_subexp (struct expression *expr, int endpos)
- {
- int oplen, args;
- operator_length (expr, endpos, &oplen, &args);
- while (args > 0)
- {
- oplen += length_of_subexp (expr, endpos - oplen);
- args--;
- }
- return oplen;
- }
- void
- operator_length (const struct expression *expr, int endpos, int *oplenp,
- int *argsp)
- {
- expr->language_defn->la_exp_desc->operator_length (expr, endpos,
- oplenp, argsp);
- }
- void
- operator_length_standard (const struct expression *expr, int endpos,
- int *oplenp, int *argsp)
- {
- int oplen = 1;
- int args = 0;
- enum f90_range_type range_type;
- int i;
- if (endpos < 1)
- error (_("?error in operator_length_standard"));
- i = (int) expr->elts[endpos - 1].opcode;
- switch (i)
- {
-
- case OP_SCOPE:
- oplen = longest_to_int (expr->elts[endpos - 2].longconst);
- oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
- break;
- case OP_LONG:
- case OP_DOUBLE:
- case OP_DECFLOAT:
- case OP_VAR_VALUE:
- oplen = 4;
- break;
- case OP_TYPE:
- case OP_BOOL:
- case OP_LAST:
- case OP_INTERNALVAR:
- case OP_VAR_ENTRY_VALUE:
- oplen = 3;
- break;
- case OP_COMPLEX:
- oplen = 3;
- args = 2;
- break;
- case OP_FUNCALL:
- case OP_F77_UNDETERMINED_ARGLIST:
- oplen = 3;
- args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
- break;
- case TYPE_INSTANCE:
- oplen = 4 + longest_to_int (expr->elts[endpos - 2].longconst);
- args = 1;
- break;
- case OP_OBJC_MSGCALL:
- oplen = 4;
- args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
- break;
- case UNOP_MAX:
- case UNOP_MIN:
- oplen = 3;
- break;
- case UNOP_CAST_TYPE:
- case UNOP_DYNAMIC_CAST:
- case UNOP_REINTERPRET_CAST:
- case UNOP_MEMVAL_TYPE:
- oplen = 1;
- args = 2;
- break;
- case BINOP_VAL:
- case UNOP_CAST:
- case UNOP_MEMVAL:
- oplen = 3;
- args = 1;
- break;
- case UNOP_MEMVAL_TLS:
- oplen = 4;
- args = 1;
- break;
- case UNOP_ABS:
- case UNOP_CAP:
- case UNOP_CHR:
- case UNOP_FLOAT:
- case UNOP_HIGH:
- case UNOP_ODD:
- case UNOP_ORD:
- case UNOP_TRUNC:
- case OP_TYPEOF:
- case OP_DECLTYPE:
- case OP_TYPEID:
- oplen = 1;
- args = 1;
- break;
- case OP_ADL_FUNC:
- oplen = longest_to_int (expr->elts[endpos - 2].longconst);
- oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
- oplen++;
- oplen++;
- break;
- case STRUCTOP_STRUCT:
- case STRUCTOP_PTR:
- args = 1;
-
- case OP_REGISTER:
- case OP_M2_STRING:
- case OP_STRING:
- case OP_OBJC_NSSTRING:
- case OP_OBJC_SELECTOR:
- case OP_NAME:
- oplen = longest_to_int (expr->elts[endpos - 2].longconst);
- oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
- break;
- case OP_ARRAY:
- oplen = 4;
- args = longest_to_int (expr->elts[endpos - 2].longconst);
- args -= longest_to_int (expr->elts[endpos - 3].longconst);
- args += 1;
- break;
- case TERNOP_COND:
- case TERNOP_SLICE:
- args = 3;
- break;
-
- case MULTI_SUBSCRIPT:
- oplen = 3;
- args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
- break;
- case BINOP_ASSIGN_MODIFY:
- oplen = 3;
- args = 2;
- break;
-
- case OP_THIS:
- oplen = 2;
- break;
- case OP_F90_RANGE:
- oplen = 3;
- range_type = longest_to_int (expr->elts[endpos - 2].longconst);
- switch (range_type)
- {
- case LOW_BOUND_DEFAULT:
- case HIGH_BOUND_DEFAULT:
- args = 1;
- break;
- case BOTH_BOUND_DEFAULT:
- args = 0;
- break;
- case NONE_BOUND_DEFAULT:
- args = 2;
- break;
- }
- break;
- default:
- args = 1 + (i < (int) BINOP_END);
- }
- *oplenp = oplen;
- *argsp = args;
- }
- static int
- prefixify_subexp (struct expression *inexpr,
- struct expression *outexpr, int inend, int outbeg)
- {
- int oplen;
- int args;
- int i;
- int *arglens;
- int result = -1;
- operator_length (inexpr, inend, &oplen, &args);
-
- inend -= oplen;
- memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend],
- EXP_ELEM_TO_BYTES (oplen));
- outbeg += oplen;
- if (expout_last_struct == inend)
- result = outbeg - oplen;
-
- arglens = (int *) alloca (args * sizeof (int));
- for (i = args - 1; i >= 0; i--)
- {
- oplen = length_of_subexp (inexpr, inend);
- arglens[i] = oplen;
- inend -= oplen;
- }
-
- for (i = 0; i < args; i++)
- {
- int r;
- oplen = arglens[i];
- inend += oplen;
- r = prefixify_subexp (inexpr, outexpr, inend, outbeg);
- if (r != -1)
- {
-
- return r;
- }
- outbeg += oplen;
- }
- return result;
- }
- struct expression *
- parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
- int comma)
- {
- return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL);
- }
- static struct expression *
- parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
- const struct block *block,
- int comma, int void_context_p, int *out_subexp)
- {
- return parse_exp_in_context_1 (stringptr, pc, block, comma,
- void_context_p, out_subexp);
- }
- static struct expression *
- parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
- const struct block *block,
- int comma, int void_context_p, int *out_subexp)
- {
- volatile struct gdb_exception except;
- struct cleanup *old_chain, *inner_chain;
- const struct language_defn *lang = NULL;
- struct parser_state ps;
- int subexp;
- lexptr = *stringptr;
- prev_lexptr = NULL;
- paren_depth = 0;
- type_stack.depth = 0;
- expout_last_struct = -1;
- expout_tag_completion_type = TYPE_CODE_UNDEF;
- xfree (expout_completion_name);
- expout_completion_name = NULL;
- comma_terminates = comma;
- if (lexptr == 0 || *lexptr == 0)
- error_no_arg (_("expression to compute"));
- old_chain = make_cleanup (free_funcalls, 0 );
- funcall_chain = 0;
- expression_context_block = block;
-
- if (!expression_context_block)
- expression_context_block = get_selected_block (&expression_context_pc);
- else if (pc == 0)
- expression_context_pc = BLOCK_START (expression_context_block);
- else
- expression_context_pc = pc;
-
- if (!expression_context_block)
- {
- struct symtab_and_line cursal = get_current_source_symtab_and_line ();
- if (cursal.symtab)
- expression_context_block
- = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (cursal.symtab),
- STATIC_BLOCK);
- if (expression_context_block)
- expression_context_pc = BLOCK_START (expression_context_block);
- }
- if (language_mode == language_mode_auto && block != NULL)
- {
-
- struct symbol *func = block_linkage_function (block);
- if (func != NULL)
- lang = language_def (SYMBOL_LANGUAGE (func));
- if (lang == NULL || lang->la_language == language_unknown)
- lang = current_language;
- }
- else
- lang = current_language;
-
- initialize_expout (&ps, 10, lang, get_current_arch ());
- inner_chain = make_cleanup_restore_current_language ();
- set_language (lang->la_language);
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- if (lang->la_parser (&ps))
- lang->la_error (NULL);
- }
- if (except.reason < 0)
- {
- if (! parse_completion)
- {
- xfree (ps.expout);
- throw_exception (except);
- }
- }
- reallocate_expout (&ps);
-
- if (expressiondebug)
- dump_raw_expression (ps.expout, gdb_stdlog,
- "before conversion to prefix form");
- subexp = prefixify_expression (ps.expout);
- if (out_subexp)
- *out_subexp = subexp;
- lang->la_post_parser (&ps.expout, void_context_p);
- if (expressiondebug)
- dump_prefix_expression (ps.expout, gdb_stdlog);
- do_cleanups (inner_chain);
- discard_cleanups (old_chain);
- *stringptr = lexptr;
- return ps.expout;
- }
- struct expression *
- parse_expression (const char *string)
- {
- struct expression *exp;
- exp = parse_exp_1 (&string, 0, 0, 0);
- if (*string)
- error (_("Junk after end of expression."));
- return exp;
- }
- struct type *
- parse_expression_for_completion (const char *string, char **name,
- enum type_code *code)
- {
- struct expression *exp = NULL;
- struct value *val;
- int subexp;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ERROR)
- {
- parse_completion = 1;
- exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp);
- }
- parse_completion = 0;
- if (except.reason < 0 || ! exp)
- return NULL;
- if (expout_tag_completion_type != TYPE_CODE_UNDEF)
- {
- *code = expout_tag_completion_type;
- *name = expout_completion_name;
- expout_completion_name = NULL;
- return NULL;
- }
- if (expout_last_struct == -1)
- {
- xfree (exp);
- return NULL;
- }
- *name = extract_field_op (exp, &subexp);
- if (!*name)
- {
- xfree (exp);
- return NULL;
- }
-
- val = evaluate_subexpression_type (exp, subexp);
-
- *name = xstrdup (*name);
- xfree (exp);
- return value_type (val);
- }
- void
- null_post_parser (struct expression **exp, int void_context_p)
- {
- }
- int
- parse_float (const char *p, int len, DOUBLEST *d, const char **suffix)
- {
- char *copy;
- int n, num;
- copy = xmalloc (len + 1);
- memcpy (copy, p, len);
- copy[len] = 0;
- num = sscanf (copy, "%" DOUBLEST_SCAN_FORMAT "%n", d, &n);
- xfree (copy);
-
- if (num == 0)
- return 0;
- *suffix = p + n;
- return 1;
- }
- int
- parse_c_float (struct gdbarch *gdbarch, const char *p, int len,
- DOUBLEST *d, struct type **t)
- {
- const char *suffix;
- int suffix_len;
- const struct builtin_type *builtin_types = builtin_type (gdbarch);
- if (! parse_float (p, len, d, &suffix))
- return 0;
- suffix_len = p + len - suffix;
- if (suffix_len == 0)
- *t = builtin_types->builtin_double;
- else if (suffix_len == 1)
- {
-
- if (tolower (*suffix) == 'f')
- *t = builtin_types->builtin_float;
- else if (tolower (*suffix) == 'l')
- *t = builtin_types->builtin_long_double;
- else
- return 0;
- }
- else
- return 0;
- return 1;
- }
- static void
- type_stack_reserve (struct type_stack *stack, int howmuch)
- {
- if (stack->depth + howmuch >= stack->size)
- {
- stack->size *= 2;
- if (stack->size < howmuch)
- stack->size = howmuch;
- stack->elements = xrealloc (stack->elements,
- stack->size * sizeof (union type_stack_elt));
- }
- }
- static void
- check_type_stack_depth (void)
- {
- type_stack_reserve (&type_stack, 1);
- }
- static void
- insert_into_type_stack (int slot, union type_stack_elt element)
- {
- check_type_stack_depth ();
- if (slot < type_stack.depth)
- memmove (&type_stack.elements[slot + 1], &type_stack.elements[slot],
- (type_stack.depth - slot) * sizeof (union type_stack_elt));
- type_stack.elements[slot] = element;
- ++type_stack.depth;
- }
- void
- insert_type (enum type_pieces tp)
- {
- union type_stack_elt element;
- int slot;
- gdb_assert (tp == tp_pointer || tp == tp_reference
- || tp == tp_const || tp == tp_volatile);
-
- if (type_stack.depth && (tp == tp_const || tp == tp_volatile))
- slot = 1;
- else
- slot = 0;
- element.piece = tp;
- insert_into_type_stack (slot, element);
- }
- void
- push_type (enum type_pieces tp)
- {
- check_type_stack_depth ();
- type_stack.elements[type_stack.depth++].piece = tp;
- }
- void
- push_type_int (int n)
- {
- check_type_stack_depth ();
- type_stack.elements[type_stack.depth++].int_val = n;
- }
- void
- insert_type_address_space (struct parser_state *pstate, char *string)
- {
- union type_stack_elt element;
- int slot;
-
- if (type_stack.depth)
- slot = 1;
- else
- slot = 0;
- element.piece = tp_space_identifier;
- insert_into_type_stack (slot, element);
- element.int_val = address_space_name_to_int (parse_gdbarch (pstate),
- string);
- insert_into_type_stack (slot, element);
- }
- enum type_pieces
- pop_type (void)
- {
- if (type_stack.depth)
- return type_stack.elements[--type_stack.depth].piece;
- return tp_end;
- }
- int
- pop_type_int (void)
- {
- if (type_stack.depth)
- return type_stack.elements[--type_stack.depth].int_val;
-
- return 0;
- }
- static VEC (type_ptr) *
- pop_typelist (void)
- {
- gdb_assert (type_stack.depth);
- return type_stack.elements[--type_stack.depth].typelist_val;
- }
- static struct type_stack *
- pop_type_stack (void)
- {
- gdb_assert (type_stack.depth);
- return type_stack.elements[--type_stack.depth].stack_val;
- }
- struct type_stack *
- append_type_stack (struct type_stack *to, struct type_stack *from)
- {
- type_stack_reserve (to, from->depth);
- memcpy (&to->elements[to->depth], &from->elements[0],
- from->depth * sizeof (union type_stack_elt));
- to->depth += from->depth;
- return to;
- }
- void
- push_type_stack (struct type_stack *stack)
- {
- check_type_stack_depth ();
- type_stack.elements[type_stack.depth++].stack_val = stack;
- push_type (tp_type_stack);
- }
- struct type_stack *
- get_type_stack (void)
- {
- struct type_stack *result = XNEW (struct type_stack);
- *result = type_stack;
- type_stack.depth = 0;
- type_stack.size = 0;
- type_stack.elements = NULL;
- return result;
- }
- void
- type_stack_cleanup (void *arg)
- {
- struct type_stack *stack = arg;
- xfree (stack->elements);
- xfree (stack);
- }
- void
- push_typelist (VEC (type_ptr) *list)
- {
- check_type_stack_depth ();
- type_stack.elements[type_stack.depth++].typelist_val = list;
- push_type (tp_function_with_arguments);
- }
- struct type *
- follow_types (struct type *follow_type)
- {
- int done = 0;
- int make_const = 0;
- int make_volatile = 0;
- int make_addr_space = 0;
- int array_size;
- while (!done)
- switch (pop_type ())
- {
- case tp_end:
- done = 1;
- if (make_const)
- follow_type = make_cv_type (make_const,
- TYPE_VOLATILE (follow_type),
- follow_type, 0);
- if (make_volatile)
- follow_type = make_cv_type (TYPE_CONST (follow_type),
- make_volatile,
- follow_type, 0);
- if (make_addr_space)
- follow_type = make_type_with_address_space (follow_type,
- make_addr_space);
- make_const = make_volatile = 0;
- make_addr_space = 0;
- break;
- case tp_const:
- make_const = 1;
- break;
- case tp_volatile:
- make_volatile = 1;
- break;
- case tp_space_identifier:
- make_addr_space = pop_type_int ();
- break;
- case tp_pointer:
- follow_type = lookup_pointer_type (follow_type);
- if (make_const)
- follow_type = make_cv_type (make_const,
- TYPE_VOLATILE (follow_type),
- follow_type, 0);
- if (make_volatile)
- follow_type = make_cv_type (TYPE_CONST (follow_type),
- make_volatile,
- follow_type, 0);
- if (make_addr_space)
- follow_type = make_type_with_address_space (follow_type,
- make_addr_space);
- make_const = make_volatile = 0;
- make_addr_space = 0;
- break;
- case tp_reference:
- follow_type = lookup_reference_type (follow_type);
- if (make_const)
- follow_type = make_cv_type (make_const,
- TYPE_VOLATILE (follow_type),
- follow_type, 0);
- if (make_volatile)
- follow_type = make_cv_type (TYPE_CONST (follow_type),
- make_volatile,
- follow_type, 0);
- if (make_addr_space)
- follow_type = make_type_with_address_space (follow_type,
- make_addr_space);
- make_const = make_volatile = 0;
- make_addr_space = 0;
- break;
- case tp_array:
- array_size = pop_type_int ();
- FIXME
- follow_type =
- lookup_array_range_type (follow_type,
- 0, array_size >= 0 ? array_size - 1 : 0);
- if (array_size < 0)
- TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (follow_type))
- = PROP_UNDEFINED;
- break;
- case tp_function:
- FIXME
- follow_type = lookup_function_type (follow_type);
- break;
- case tp_function_with_arguments:
- {
- VEC (type_ptr) *args = pop_typelist ();
- follow_type
- = lookup_function_type_with_arguments (follow_type,
- VEC_length (type_ptr, args),
- VEC_address (type_ptr,
- args));
- VEC_free (type_ptr, args);
- }
- break;
- case tp_type_stack:
- {
- struct type_stack *stack = pop_type_stack ();
-
- struct type_stack save = type_stack;
- type_stack = *stack;
- follow_type = follow_types (follow_type);
- gdb_assert (type_stack.depth == 0);
- type_stack = save;
- }
- break;
- default:
- gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
- }
- return follow_type;
- }
- void
- parser_fprintf (FILE *x, const char *y, ...)
- {
- va_list args;
- va_start (args, y);
- if (x == stderr)
- vfprintf_unfiltered (gdb_stderr, y, args);
- else
- {
- fprintf_unfiltered (gdb_stderr, " Unknown FILE used.\n");
- vfprintf_unfiltered (gdb_stderr, y, args);
- }
- va_end (args);
- }
- int
- operator_check_standard (struct expression *exp, int pos,
- int (*objfile_func) (struct objfile *objfile,
- void *data),
- void *data)
- {
- const union exp_element *const elts = exp->elts;
- struct type *type = NULL;
- struct objfile *objfile = NULL;
-
- gdb_assert (elts[pos].opcode < OP_EXTENDED0);
-
- switch (elts[pos].opcode)
- {
- case BINOP_VAL:
- case OP_COMPLEX:
- case OP_DECFLOAT:
- case OP_DOUBLE:
- case OP_LONG:
- case OP_SCOPE:
- case OP_TYPE:
- case UNOP_CAST:
- case UNOP_MAX:
- case UNOP_MEMVAL:
- case UNOP_MIN:
- type = elts[pos + 1].type;
- break;
- case TYPE_INSTANCE:
- {
- LONGEST arg, nargs = elts[pos + 1].longconst;
- for (arg = 0; arg < nargs; arg++)
- {
- struct type *type = elts[pos + 2 + arg].type;
- struct objfile *objfile = TYPE_OBJFILE (type);
- if (objfile && (*objfile_func) (objfile, data))
- return 1;
- }
- }
- 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;
- const struct symbol *const symbol = elts[pos + 2].symbol;
-
- if ((*objfile_func) (symbol_objfile (symbol), data))
- return 1;
-
- objfile = lookup_objfile_from_block (block);
- type = SYMBOL_TYPE (symbol);
- }
- break;
- }
-
- if (type && TYPE_OBJFILE (type)
- && (*objfile_func) (TYPE_OBJFILE (type), data))
- return 1;
- if (objfile && (*objfile_func) (objfile, data))
- return 1;
- return 0;
- }
- static int
- exp_iterate (struct expression *exp,
- int (*objfile_func) (struct objfile *objfile, void *data),
- void *data)
- {
- int endpos;
- for (endpos = exp->nelts; endpos > 0; )
- {
- int pos, args, oplen = 0;
- operator_length (exp, endpos, &oplen, &args);
- gdb_assert (oplen > 0);
- pos = endpos - oplen;
- if (exp->language_defn->la_exp_desc->operator_check (exp, pos,
- objfile_func, data))
- return 1;
- endpos = pos;
- }
- return 0;
- }
- static int
- exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
- {
- struct objfile *objfile = objfile_voidp;
- if (exp_objfile->separate_debug_objfile_backlink)
- exp_objfile = exp_objfile->separate_debug_objfile_backlink;
- return exp_objfile == objfile;
- }
- int
- exp_uses_objfile (struct expression *exp, struct objfile *objfile)
- {
- gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
- return exp_iterate (exp, exp_uses_objfile_iter, objfile);
- }
- void
- increase_expout_size (struct parser_state *ps, size_t lenelt)
- {
- if ((ps->expout_ptr + lenelt) >= ps->expout_size)
- {
- ps->expout_size = max (ps->expout_size * 2,
- ps->expout_ptr + lenelt + 10);
- ps->expout = (struct expression *)
- xrealloc (ps->expout, (sizeof (struct expression)
- + EXP_ELEM_TO_BYTES (ps->expout_size)));
- }
- }
- void
- _initialize_parse (void)
- {
- type_stack.size = 0;
- type_stack.depth = 0;
- type_stack.elements = NULL;
- add_setshow_zuinteger_cmd ("expression", class_maintenance,
- &expressiondebug,
- _("Set expression debugging."),
- _("Show expression debugging."),
- _("When non-zero, the internal representation "
- "of expressions will be printed."),
- NULL,
- show_expressiondebug,
- &setdebuglist, &showdebuglist);
- add_setshow_boolean_cmd ("parser", class_maintenance,
- &parser_debug,
- _("Set parser debugging."),
- _("Show parser debugging."),
- _("When non-zero, expression parser "
- "tracing will be enabled."),
- NULL,
- show_parserdebug,
- &setdebuglist, &showdebuglist);
- }