diff options
author | Pedro Alves <palves@redhat.com> | 2017-09-04 20:21:15 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2017-09-04 20:21:15 +0100 |
commit | 858be34c5a03bb8973679ebf00d360182434dc00 (patch) | |
tree | f8f2ee3b71ccc4b20b8501a00b113975b4c48013 /gdb/c-exp.y | |
parent | dd5901a6a5bba75f3dee49f9a27640eedad90afe (diff) | |
download | gdb-858be34c5a03bb8973679ebf00d360182434dc00.zip gdb-858be34c5a03bb8973679ebf00d360182434dc00.tar.gz gdb-858be34c5a03bb8973679ebf00d360182434dc00.tar.bz2 |
Handle "p S::method()::static_var" in the C++ parser
This commit makes "print S::method()::static_var" actually find the
debug symbol for static_var. Currently, you get:
(gdb) print S::method()::static_var
A syntax error in expression, near `'.
Quoting the whole string would seemingly work before the previous
patch that made GDB stop assuming int for no-debug-info variables:
(gdb) p 'S::method()::static_var'
$1 = 1
... except that's incorrect output, because:
(gdb) ptype 'S::method()::static_var'
type = <data variable, no debug info>
The way to make it work correctly currently is by quoting the
function/method part, like this:
(gdb) print 'S::method()'::static_var
$1 = {i1 = 1, i2 = 2, i3 = 3}
(gdb) ptype 'S::method()'::static_var
type = struct aggregate {
int i1;
int i2;
int i3;
}
At least after the "stop assuming int" patch, this is what we
now get:
(gdb) p 'S::method()::static_var'
'S::method()::static_var' has unknown type; cast it to its declared type
(gdb) p (struct aggregate) 'S::method()::static_var'
$1 = {i1 = 1, i2 = 2, i3 = 3}
However, IMO, users shouldn't really have to care about any of this.
GDB should Just Work, without quoting, IMO.
So here's a patch that implements support for that in the C++ parser.
With this patch, you now get:
(gdb) p S::method()::S_M_s_var_aggregate
$1 = {i1 = 1, i2 = 2, i3 = 3}
(gdb) ptype S::method()::S_M_s_var_aggregate
type = struct aggregate {
int i1;
int i2;
int i3;
}
gdb/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
(%type <voidval>): Add function_method.
* c-exp.y (exp): New production for calls with no arguments.
(function_method, function_method_void_or_typelist): New
productions.
(exp): New production for "method()::static_var".
* eval.c (evaluate_subexp_standard): Handle OP_FUNC_STATIC_VAR.
* expprint.c (print_subexp_standard, dump_subexp_body_standard):
Handle OP_FUNC_STATIC_VAR.
* parse.c (operator_length_standard):
Handle OP_FUNC_STATIC_VAR.
* std-operator.def (OP_FUNC_STATIC_VAR): New.
gdb/testsuite/ChangeLog:
2017-09-04 Pedro Alves <palves@redhat.com>
* gdb.base/local-static.c: New.
* gdb.base/local-static.cc: New.
* gdb.base/local-static.exp: New.
Diffstat (limited to 'gdb/c-exp.y')
-rw-r--r-- | gdb/c-exp.y | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/gdb/c-exp.y b/gdb/c-exp.y index a1f9fee..f7f098b 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -127,7 +127,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value); #endif %} -%type <voidval> exp exp1 type_exp start variable qualified_name lcurly +%type <voidval> exp exp1 type_exp start variable qualified_name lcurly function_method %type <lval> rcurly %type <tval> type typebase %type <tvec> nonempty_typelist func_mod parameter_typelist @@ -498,6 +498,18 @@ exp : exp '(' write_exp_elt_opcode (pstate, OP_FUNCALL); } ; +/* This is here to disambiguate with the production for + "func()::static_var" further below, which uses + function_method_void. */ +exp : exp '(' ')' %prec ARROW + { start_arglist (); + write_exp_elt_opcode (pstate, OP_FUNCALL); + write_exp_elt_longcst (pstate, + (LONGEST) end_arglist ()); + write_exp_elt_opcode (pstate, OP_FUNCALL); } + ; + + exp : UNKNOWN_CPP_NAME '(' { /* This could potentially be a an argument defined @@ -539,7 +551,7 @@ arglist : arglist ',' exp %prec ABOVE_COMMA { arglist_len++; } ; -exp : exp '(' parameter_typelist ')' const_or_volatile +function_method: exp '(' parameter_typelist ')' const_or_volatile { int i; VEC (type_ptr) *type_list = $3; struct type *type_elt; @@ -557,6 +569,33 @@ exp : exp '(' parameter_typelist ')' const_or_volatile } ; +function_method_void: exp '(' ')' const_or_volatile + { write_exp_elt_opcode (pstate, TYPE_INSTANCE); + write_exp_elt_longcst (pstate, 0); + write_exp_elt_longcst (pstate, 0); + write_exp_elt_opcode (pstate, TYPE_INSTANCE); + } + ; + +exp : function_method + ; + +/* Normally we must interpret "func()" as a function call, instead of + a type. The user needs to write func(void) to disambiguate. + However, in the "func()::static_var" case, there's no + ambiguity. */ +function_method_void_or_typelist: function_method + | function_method_void + ; + +exp : function_method_void_or_typelist COLONCOLON name + { + write_exp_elt_opcode (pstate, OP_FUNC_STATIC_VAR); + write_exp_string (pstate, $3); + write_exp_elt_opcode (pstate, OP_FUNC_STATIC_VAR); + } + ; + rcurly : '}' { $$ = end_arglist () - 1; } ; |