aboutsummaryrefslogtreecommitdiff
path: root/gdb/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/parse.c')
-rw-r--r--gdb/parse.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/gdb/parse.c b/gdb/parse.c
index 79b1ca1..d6f98bf 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -545,6 +545,133 @@ parser_state::mark_completion_tag (enum type_code tag, const char *ptr,
m_completion_state.expout_completion_name.reset (xstrndup (ptr, length));
}
+/* See parser-defs.h. */
+
+void
+parser_state::push_c_string (int kind, struct stoken_vector *vec)
+{
+ std::vector<std::string> data (vec->len);
+ for (int i = 0; i < vec->len; ++i)
+ data[i] = std::string (vec->tokens[i].ptr, vec->tokens[i].length);
+
+ push_new<expr::c_string_operation> ((enum c_string_type_values) kind,
+ std::move (data));
+}
+
+/* See parser-defs.h. */
+
+void
+parser_state::push_symbol (const char *name, block_symbol sym)
+{
+ if (sym.symbol != nullptr)
+ {
+ if (symbol_read_needs_frame (sym.symbol))
+ block_tracker->update (sym);
+ push_new<expr::var_value_operation> (sym.symbol, sym.block);
+ }
+ else
+ {
+ struct bound_minimal_symbol msymbol = lookup_bound_minimal_symbol (name);
+ if (msymbol.minsym != NULL)
+ push_new<expr::var_msym_value_operation> (msymbol.minsym,
+ msymbol.objfile);
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error (_("No symbol table is loaded. Use the \"file\" command."));
+ else
+ error (_("No symbol \"%s\" in current context."), name);
+ }
+}
+
+/* See parser-defs.h. */
+
+void
+parser_state::push_dollar (struct stoken str)
+{
+ struct block_symbol sym;
+ struct bound_minimal_symbol msym;
+ struct internalvar *isym = NULL;
+ std::string copy;
+
+ /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
+ and $$digits (equivalent to $<-digits> if you could type that). */
+
+ int negate = 0;
+ int i = 1;
+ /* Double dollar means negate the number and add -1 as well.
+ Thus $$ alone means -1. */
+ if (str.length >= 2 && str.ptr[1] == '$')
+ {
+ negate = 1;
+ i = 2;
+ }
+ if (i == str.length)
+ {
+ /* Just dollars (one or two). */
+ i = -negate;
+ goto handle_last;
+ }
+ /* Is the rest of the token digits? */
+ 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;
+ }
+
+ /* Handle tokens that refer to machine registers:
+ $ followed by a register name. */
+ i = user_reg_map_name_to_regnum (gdbarch (),
+ str.ptr + 1, str.length - 1);
+ if (i >= 0)
+ goto handle_register;
+
+ /* Any names starting with $ are probably debugger internal variables. */
+
+ copy = copy_name (str);
+ isym = lookup_only_internalvar (copy.c_str () + 1);
+ if (isym)
+ {
+ push_new<expr::internalvar_operation> (isym);
+ return;
+ }
+
+ /* On some systems, such as HP-UX and hppa-linux, certain system routines
+ have names beginning with $ or $$. Check for those, first. */
+
+ sym = lookup_symbol (copy.c_str (), NULL, VAR_DOMAIN, NULL);
+ if (sym.symbol)
+ {
+ push_new<expr::var_value_operation> (sym.symbol, sym.block);
+ return;
+ }
+ msym = lookup_bound_minimal_symbol (copy.c_str ());
+ if (msym.minsym)
+ {
+ push_new<expr::var_msym_value_operation> (msym.minsym, msym.objfile);
+ return;
+ }
+
+ /* Any other names are assumed to be debugger internal variables. */
+
+ push_new<expr::internalvar_operation>
+ (create_internalvar (copy.c_str () + 1));
+ return;
+handle_last:
+ push_new<expr::last_operation> (i);
+ return;
+handle_register:
+ str.length--;
+ str.ptr++;
+ push_new<expr::register_operation> (copy_name (str));
+ block_tracker->update (expression_context_block,
+ INNERMOST_BLOCK_FOR_REGISTERS);
+ return;
+}
+
/* Recognize tokens that start with '$'. These include: