--- ./gdb/ada-lang.c.orig Thu Nov 30 16:32:29 2006 +++ ./gdb/ada-lang.c Thu Dec 14 18:01:00 2006 @@ -2728,6 +2728,11 @@ resolve_subexp (struct expression **expp *pos += 3; break; + case OP_LAST_INTERNALVAR: + *pos ++; + nargs = 1; + break; + case UNOP_MEMVAL: *pos += 3; nargs = 1; --- ./gdb/eval.c.orig Mon Oct 9 20:17:53 2006 +++ ./gdb/eval.c Thu Dec 14 18:01:00 2006 @@ -473,6 +473,12 @@ evaluate_subexp_standard (struct type *e return access_value_history (longest_to_int (exp->elts[pc + 1].longconst)); + case OP_LAST_INTERNALVAR: + { + arg1 = evaluate_subexp(NULL_TYPE, exp, pos, noside); + return access_value_history(*(int*)value_contents(arg1)); + } + case OP_REGISTER: { int regno = longest_to_int (exp->elts[pc + 1].longconst); --- ./gdb/expprint.c.orig Mon Oct 9 20:17:53 2006 +++ ./gdb/expprint.c Thu Dec 14 18:01:00 2006 @@ -151,6 +151,12 @@ print_subexp_standard (struct expression internalvar_name (exp->elts[pc + 1].internalvar)); return; + case OP_LAST_INTERNALVAR: + (*pos) += 2; + fprintf_filtered (stream, "$$%s", + internalvar_name (exp->elts[pc + 1].internalvar)); + return; + case OP_FUNCALL: (*pos) += 2; nargs = longest_to_int (exp->elts[pc + 1].longconst); @@ -695,6 +701,8 @@ op_name_standard (enum exp_opcode opcode return "OP_REGISTER"; case OP_INTERNALVAR: return "OP_INTERNALVAR"; + case OP_LAST_INTERNALVAR: + return "OP_LAST_INTERNALVAR"; case OP_FUNCALL: return "OP_FUNCALL"; case OP_STRING: @@ -976,6 +984,9 @@ dump_subexp_body_standard (struct expres fprintf_filtered (stream, " (%s)", exp->elts[elt].internalvar->name); elt += 2; + break; + case OP_LAST_INTERNALVAR: + fprintf_filtered (stream, "History element from Internal var"); break; case OP_FUNCALL: { --- ./gdb/expression.h.orig Mon Oct 9 20:17:53 2006 +++ ./gdb/expression.h Thu Dec 14 18:01:00 2006 @@ -174,6 +174,12 @@ enum exp_opcode /* OP_INTERNALVAR is followed by an internalvar ptr in the next exp_element. With another OP_INTERNALVAR at the end, this makes three exp_elements. */ OP_INTERNALVAR, + + /* OP_LAST_INTERNALVAR is used for accessing the history programmatically. + It is followed by an internalvar ptr in the next exp_element. + With another OP_LAST_INTERNALVAR at the end, this makes three + exp_elements. */ + OP_LAST_INTERNALVAR, /* OP_FUNCALL is followed by an integer in the next exp_element. The integer is the number of args to the function call. --- ./gdb/parse.c.orig Sat Nov 18 15:54:32 2006 +++ ./gdb/parse.c Thu Dec 14 18:01:00 2006 @@ -476,6 +476,7 @@ write_dollar_variable (struct stoken str { struct symbol *sym = NULL; struct minimal_symbol *msym = NULL; + int stroff = 1; /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1) and $$digits (equivalent to $<-digits> if you could type that). */ @@ -487,7 +488,7 @@ write_dollar_variable (struct stoken str if (str.length >= 2 && str.ptr[1] == '$') { negate = 1; - i = 2; + i = stroff = 2; } if (i == str.length) { @@ -536,11 +537,17 @@ write_dollar_variable (struct stoken str return; } - /* Any other names starting in $ are debugger internal variables. */ + /* Any other names starting in $ are debugger internal variables. + A 'negated' internal variable should be treated as an indirect + history reference, which adds another LAST_INTERNALVAR opcode */ write_exp_elt_opcode (OP_INTERNALVAR); - write_exp_elt_intern (lookup_internalvar (copy_name (str) + 1)); + write_exp_elt_intern (lookup_internalvar (copy_name (str) + stroff)); write_exp_elt_opcode (OP_INTERNALVAR); + + if (negate) + write_exp_elt_opcode (OP_LAST_INTERNALVAR); + return; handle_last: write_exp_elt_opcode (OP_LAST); @@ -904,6 +911,10 @@ operator_length_standard (struct express oplen = 3; break; + case OP_LAST_INTERNALVAR: + oplen = 1; + args = 1; + break; case OP_COMPLEX: oplen = 1; args = 2;