aboutsummaryrefslogtreecommitdiff
path: root/gdb/c-exp.y
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-09-04 20:21:15 +0100
committerPedro Alves <palves@redhat.com>2017-09-04 20:21:15 +0100
commit858be34c5a03bb8973679ebf00d360182434dc00 (patch)
treef8f2ee3b71ccc4b20b8501a00b113975b4c48013 /gdb/c-exp.y
parentdd5901a6a5bba75f3dee49f9a27640eedad90afe (diff)
downloadgdb-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.y43
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; }
;