X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fgo-exp.y;h=dd84ae557c57258fba333bc429c8d048ffea8f87;hb=21af24c8371a3e040f6f548ddfafb20114442c28;hp=974bdb180668ca55caa9ea121ca4a40c5b388ce7;hpb=ecd75fc8eed3bde86036141228074a20e55dcfc9;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/go-exp.y b/gdb/go-exp.y index 974bdb1806..dd84ae557c 100644 --- a/gdb/go-exp.y +++ b/gdb/go-exp.y @@ -1,6 +1,6 @@ /* YACC parser for Go expressions, for GDB. - Copyright (C) 2012-2014 Free Software Foundation, Inc. + Copyright (C) 2012-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -52,7 +52,6 @@ %{ #include "defs.h" -#include #include #include "expression.h" #include "value.h" @@ -66,67 +65,23 @@ #include "charset.h" #include "block.h" -#define parse_type builtin_type (parse_gdbarch) - -/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), - as well as gratuitiously global symbol names, so we can have multiple - yacc generated parsers in gdb. Note that these are only the variables - produced by yacc. If other parser generators (bison, byacc, etc) produce - additional global names that conflict at link time, then those parser - generators need to be fixed instead of adding those names to this list. */ - -#define yymaxdepth go_maxdepth -#define yyparse go_parse_internal -#define yylex go_lex -#define yyerror go_error -#define yylval go_lval -#define yychar go_char -#define yydebug go_debug -#define yypact go_pact -#define yyr1 go_r1 -#define yyr2 go_r2 -#define yydef go_def -#define yychk go_chk -#define yypgo go_pgo -#define yyact go_act -#define yyexca go_exca -#define yyerrflag go_errflag -#define yynerrs go_nerrs -#define yyps go_ps -#define yypv go_pv -#define yys go_s -#define yy_yys go_yys -#define yystate go_state -#define yytmp go_tmp -#define yyv go_v -#define yy_yyv go_yyv -#define yyval go_val -#define yylloc go_lloc -#define yyreds go_reds /* With YYDEBUG defined */ -#define yytoks go_toks /* With YYDEBUG defined */ -#define yyname go_name /* With YYDEBUG defined */ -#define yyrule go_rule /* With YYDEBUG defined */ -#define yylhs go_yylhs -#define yylen go_yylen -#define yydefred go_yydefred -#define yydgoto go_yydgoto -#define yysindex go_yysindex -#define yyrindex go_yyrindex -#define yygindex go_yygindex -#define yytable go_yytable -#define yycheck go_yycheck - -#ifndef YYDEBUG -#define YYDEBUG 1 /* Default to yydebug support */ -#endif - -#define YYFPRINTF parser_fprintf +#define parse_type(ps) builtin_type (ps->gdbarch ()) + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, + etc). */ +#define GDB_YY_REMAP_PREFIX go_ +#include "yy-remap.h" + +/* The state of the parser, used internally when we are parsing the + expression. */ + +static struct parser_state *pstate = NULL; int yyparse (void); static int yylex (void); -void yyerror (char *); +static void yyerror (const char *); %} @@ -142,7 +97,7 @@ void yyerror (char *); struct type *type; } typed_val_int; struct { - DOUBLEST dval; + gdb_byte val[16]; struct type *type; } typed_val_float; struct stoken sval; @@ -158,9 +113,8 @@ void yyerror (char *); %{ /* YYSTYPE gets defined by %union. */ -static int parse_number (const char *, int, int, YYSTYPE *); -static int parse_go_float (struct gdbarch *gdbarch, const char *p, int len, - DOUBLEST *d, struct type **t); +static int parse_number (struct parser_state *, + const char *, int, int, YYSTYPE *); %} %type exp exp1 type_exp start variable lcurly @@ -239,118 +193,119 @@ start : exp1 ; type_exp: type - { write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type($1); - write_exp_elt_opcode(OP_TYPE); } + { write_exp_elt_opcode (pstate, OP_TYPE); + write_exp_elt_type (pstate, $1); + write_exp_elt_opcode (pstate, OP_TYPE); } ; /* Expressions, including the comma operator. */ exp1 : exp | exp1 ',' exp - { write_exp_elt_opcode (BINOP_COMMA); } + { write_exp_elt_opcode (pstate, BINOP_COMMA); } ; /* Expressions, not including the comma operator. */ exp : '*' exp %prec UNARY - { write_exp_elt_opcode (UNOP_IND); } + { write_exp_elt_opcode (pstate, UNOP_IND); } ; exp : '&' exp %prec UNARY - { write_exp_elt_opcode (UNOP_ADDR); } + { write_exp_elt_opcode (pstate, UNOP_ADDR); } ; exp : '-' exp %prec UNARY - { write_exp_elt_opcode (UNOP_NEG); } + { write_exp_elt_opcode (pstate, UNOP_NEG); } ; exp : '+' exp %prec UNARY - { write_exp_elt_opcode (UNOP_PLUS); } + { write_exp_elt_opcode (pstate, UNOP_PLUS); } ; exp : '!' exp %prec UNARY - { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + { write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); } ; exp : '^' exp %prec UNARY - { write_exp_elt_opcode (UNOP_COMPLEMENT); } + { write_exp_elt_opcode (pstate, UNOP_COMPLEMENT); } ; exp : exp INCREMENT %prec UNARY - { write_exp_elt_opcode (UNOP_POSTINCREMENT); } + { write_exp_elt_opcode (pstate, UNOP_POSTINCREMENT); } ; exp : exp DECREMENT %prec UNARY - { write_exp_elt_opcode (UNOP_POSTDECREMENT); } + { write_exp_elt_opcode (pstate, UNOP_POSTDECREMENT); } ; /* foo->bar is not in Go. May want as a gdb extension. Later. */ exp : exp '.' name_not_typename - { write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string ($3.stoken); - write_exp_elt_opcode (STRUCTOP_STRUCT); } + { write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); + write_exp_string (pstate, $3.stoken); + write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } ; exp : exp '.' name_not_typename COMPLETE - { mark_struct_expression (); - write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string ($3.stoken); - write_exp_elt_opcode (STRUCTOP_STRUCT); } + { pstate->mark_struct_expression (); + write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); + write_exp_string (pstate, $3.stoken); + write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } ; exp : exp '.' COMPLETE { struct stoken s; - mark_struct_expression (); - write_exp_elt_opcode (STRUCTOP_STRUCT); + pstate->mark_struct_expression (); + write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); s.ptr = ""; s.length = 0; - write_exp_string (s); - write_exp_elt_opcode (STRUCTOP_STRUCT); } + write_exp_string (pstate, s); + write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } ; exp : exp '[' exp1 ']' - { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + { write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); } ; exp : exp '(' /* This is to save the value of arglist_len being accumulated by an outer function call. */ - { start_arglist (); } + { pstate->start_arglist (); } arglist ')' %prec LEFT_ARROW - { write_exp_elt_opcode (OP_FUNCALL); - write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_FUNCALL); } + { write_exp_elt_opcode (pstate, OP_FUNCALL); + write_exp_elt_longcst (pstate, + pstate->end_arglist ()); + write_exp_elt_opcode (pstate, OP_FUNCALL); } ; lcurly : '{' - { start_arglist (); } + { pstate->start_arglist (); } ; arglist : ; arglist : exp - { arglist_len = 1; } + { pstate->arglist_len = 1; } ; arglist : arglist ',' exp %prec ABOVE_COMMA - { arglist_len++; } + { pstate->arglist_len++; } ; rcurly : '}' - { $$ = end_arglist () - 1; } + { $$ = pstate->end_arglist () - 1; } ; exp : lcurly type rcurly exp %prec UNARY - { write_exp_elt_opcode (UNOP_MEMVAL); - write_exp_elt_type ($2); - write_exp_elt_opcode (UNOP_MEMVAL); } + { write_exp_elt_opcode (pstate, UNOP_MEMVAL); + write_exp_elt_type (pstate, $2); + write_exp_elt_opcode (pstate, UNOP_MEMVAL); } ; exp : type '(' exp ')' %prec UNARY - { write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type ($1); - write_exp_elt_opcode (UNOP_CAST); } + { write_exp_elt_opcode (pstate, UNOP_CAST); + write_exp_elt_type (pstate, $1); + write_exp_elt_opcode (pstate, UNOP_CAST); } ; exp : '(' exp1 ')' @@ -360,100 +315,100 @@ exp : '(' exp1 ')' /* Binary operators in order of decreasing precedence. */ exp : exp '@' exp - { write_exp_elt_opcode (BINOP_REPEAT); } + { write_exp_elt_opcode (pstate, BINOP_REPEAT); } ; exp : exp '*' exp - { write_exp_elt_opcode (BINOP_MUL); } + { write_exp_elt_opcode (pstate, BINOP_MUL); } ; exp : exp '/' exp - { write_exp_elt_opcode (BINOP_DIV); } + { write_exp_elt_opcode (pstate, BINOP_DIV); } ; exp : exp '%' exp - { write_exp_elt_opcode (BINOP_REM); } + { write_exp_elt_opcode (pstate, BINOP_REM); } ; exp : exp '+' exp - { write_exp_elt_opcode (BINOP_ADD); } + { write_exp_elt_opcode (pstate, BINOP_ADD); } ; exp : exp '-' exp - { write_exp_elt_opcode (BINOP_SUB); } + { write_exp_elt_opcode (pstate, BINOP_SUB); } ; exp : exp LSH exp - { write_exp_elt_opcode (BINOP_LSH); } + { write_exp_elt_opcode (pstate, BINOP_LSH); } ; exp : exp RSH exp - { write_exp_elt_opcode (BINOP_RSH); } + { write_exp_elt_opcode (pstate, BINOP_RSH); } ; exp : exp EQUAL exp - { write_exp_elt_opcode (BINOP_EQUAL); } + { write_exp_elt_opcode (pstate, BINOP_EQUAL); } ; exp : exp NOTEQUAL exp - { write_exp_elt_opcode (BINOP_NOTEQUAL); } + { write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); } ; exp : exp LEQ exp - { write_exp_elt_opcode (BINOP_LEQ); } + { write_exp_elt_opcode (pstate, BINOP_LEQ); } ; exp : exp GEQ exp - { write_exp_elt_opcode (BINOP_GEQ); } + { write_exp_elt_opcode (pstate, BINOP_GEQ); } ; exp : exp '<' exp - { write_exp_elt_opcode (BINOP_LESS); } + { write_exp_elt_opcode (pstate, BINOP_LESS); } ; exp : exp '>' exp - { write_exp_elt_opcode (BINOP_GTR); } + { write_exp_elt_opcode (pstate, BINOP_GTR); } ; exp : exp '&' exp - { write_exp_elt_opcode (BINOP_BITWISE_AND); } + { write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); } ; exp : exp '^' exp - { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + { write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); } ; exp : exp '|' exp - { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + { write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); } ; exp : exp ANDAND exp - { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + { write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); } ; exp : exp OROR exp - { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + { write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); } ; exp : exp '?' exp ':' exp %prec '?' - { write_exp_elt_opcode (TERNOP_COND); } + { write_exp_elt_opcode (pstate, TERNOP_COND); } ; exp : exp '=' exp - { write_exp_elt_opcode (BINOP_ASSIGN); } + { write_exp_elt_opcode (pstate, BINOP_ASSIGN); } ; exp : exp ASSIGN_MODIFY exp - { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode ($2); - write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } + { write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode (pstate, $2); + write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY); } ; exp : INT - { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type ($1.type); - write_exp_elt_longcst ((LONGEST)($1.val)); - write_exp_elt_opcode (OP_LONG); } + { write_exp_elt_opcode (pstate, OP_LONG); + write_exp_elt_type (pstate, $1.type); + write_exp_elt_longcst (pstate, (LONGEST)($1.val)); + write_exp_elt_opcode (pstate, OP_LONG); } ; exp : CHAR @@ -461,28 +416,28 @@ exp : CHAR struct stoken_vector vec; vec.len = 1; vec.tokens = &$1; - write_exp_string_vector ($1.type, &vec); + write_exp_string_vector (pstate, $1.type, &vec); } ; exp : NAME_OR_INT { YYSTYPE val; - parse_number ($1.stoken.ptr, $1.stoken.length, - 0, &val); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (val.typed_val_int.type); - write_exp_elt_longcst ((LONGEST) + parse_number (pstate, $1.stoken.ptr, + $1.stoken.length, 0, &val); + write_exp_elt_opcode (pstate, OP_LONG); + write_exp_elt_type (pstate, val.typed_val_int.type); + write_exp_elt_longcst (pstate, (LONGEST) val.typed_val_int.val); - write_exp_elt_opcode (OP_LONG); + write_exp_elt_opcode (pstate, OP_LONG); } ; exp : FLOAT - { write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type ($1.type); - write_exp_elt_dblcst ($1.dval); - write_exp_elt_opcode (OP_DOUBLE); } + { write_exp_elt_opcode (pstate, OP_FLOAT); + write_exp_elt_type (pstate, $1.type); + write_exp_elt_floatcst (pstate, $1.val); + write_exp_elt_opcode (pstate, OP_FLOAT); } ; exp : variable @@ -490,26 +445,29 @@ exp : variable exp : DOLLAR_VARIABLE { - write_dollar_variable ($1); + write_dollar_variable (pstate, $1); } ; exp : SIZEOF_KEYWORD '(' type ')' %prec UNARY { /* TODO(dje): Go objects in structs. */ - write_exp_elt_opcode (OP_LONG); + write_exp_elt_opcode (pstate, OP_LONG); /* TODO(dje): What's the right type here? */ - write_exp_elt_type (parse_type->builtin_unsigned_int); - CHECK_TYPEDEF ($3); - write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3)); - write_exp_elt_opcode (OP_LONG); + write_exp_elt_type + (pstate, + parse_type (pstate)->builtin_unsigned_int); + $3 = check_typedef ($3); + write_exp_elt_longcst (pstate, + (LONGEST) TYPE_LENGTH ($3)); + write_exp_elt_opcode (pstate, OP_LONG); } ; exp : SIZEOF_KEYWORD '(' exp ')' %prec UNARY { /* TODO(dje): Go objects in structs. */ - write_exp_elt_opcode (UNOP_SIZEOF); + write_exp_elt_opcode (pstate, UNOP_SIZEOF); } string_exp: @@ -526,7 +484,7 @@ string_exp: vec->type = $1.type; vec->length = $1.length; - vec->ptr = malloc ($1.length + 1); + vec->ptr = (char *) malloc ($1.length + 1); memcpy (vec->ptr, $1.ptr, $1.length + 1); } @@ -536,10 +494,10 @@ string_exp: for convenience. */ char *p; ++$$.len; - $$.tokens = realloc ($$.tokens, - $$.len * sizeof (struct typed_stoken)); + $$.tokens = XRESIZEVEC (struct typed_stoken, + $$.tokens, $$.len); - p = malloc ($3.length + 1); + p = (char *) malloc ($3.length + 1); memcpy (p, $3.ptr, $3.length + 1); $$.tokens[$$.len - 1].type = $3.type; @@ -552,7 +510,8 @@ exp : string_exp %prec ABOVE_COMMA { int i; - write_exp_string_vector (0 /*always utf8*/, &$1); + write_exp_string_vector (pstate, 0 /*always utf8*/, + &$1); for (i = 0; i < $1.len; ++i) free ($1.tokens[i].ptr); free ($1.tokens); @@ -560,53 +519,45 @@ exp : string_exp %prec ABOVE_COMMA ; exp : TRUE_KEYWORD - { write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_BOOL); } + { write_exp_elt_opcode (pstate, OP_BOOL); + write_exp_elt_longcst (pstate, (LONGEST) $1); + write_exp_elt_opcode (pstate, OP_BOOL); } ; exp : FALSE_KEYWORD - { write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_BOOL); } + { write_exp_elt_opcode (pstate, OP_BOOL); + write_exp_elt_longcst (pstate, (LONGEST) $1); + write_exp_elt_opcode (pstate, OP_BOOL); } ; variable: name_not_typename ENTRY - { struct symbol *sym = $1.sym; + { struct symbol *sym = $1.sym.symbol; if (sym == NULL || !SYMBOL_IS_ARGUMENT (sym) || !symbol_read_needs_frame (sym)) error (_("@entry can be used only for function " "parameters, not for \"%s\""), - copy_name ($1.stoken)); + copy_name ($1.stoken).c_str ()); - write_exp_elt_opcode (OP_VAR_ENTRY_VALUE); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_ENTRY_VALUE); + write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE); + write_exp_elt_sym (pstate, sym); + write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE); } ; variable: name_not_typename - { struct symbol *sym = $1.sym; + { struct block_symbol sym = $1.sym; - if (sym) + if (sym.symbol) { - if (symbol_read_needs_frame (sym)) - { - if (innermost_block == 0 - || contained_in (block_found, - innermost_block)) - innermost_block = block_found; - } - - write_exp_elt_opcode (OP_VAR_VALUE); - /* We want to use the selected frame, not - another more inner frame which happens to - be in the same block. */ - write_exp_elt_block (NULL); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); + if (symbol_read_needs_frame (sym.symbol)) + pstate->block_tracker->update (sym); + + write_exp_elt_opcode (pstate, OP_VAR_VALUE); + write_exp_elt_block (pstate, sym.block); + write_exp_elt_sym (pstate, sym.symbol); + write_exp_elt_opcode (pstate, OP_VAR_VALUE); } else if ($1.is_a_field_of_this) { @@ -617,19 +568,19 @@ variable: name_not_typename else { struct bound_minimal_symbol msymbol; - char *arg = copy_name ($1.stoken); + std::string arg = copy_name ($1.stoken); msymbol = - lookup_bound_minimal_symbol (arg); + lookup_bound_minimal_symbol (arg.c_str ()); if (msymbol.minsym != NULL) - write_exp_msymbol (msymbol); + write_exp_msymbol (pstate, msymbol); 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."), - copy_name ($1.stoken)); + arg.c_str ()); } } ; @@ -652,7 +603,7 @@ type /* Implements (approximately): [*] type-specifier */ expression_context_block); } */ | BYTE_KEYWORD - { $$ = builtin_go_type (parse_gdbarch) + { $$ = builtin_go_type (pstate->gdbarch ()) ->builtin_uint8; } ; @@ -676,24 +627,6 @@ name_not_typename %% -/* Wrapper on parse_c_float to get the type right for Go. */ - -static int -parse_go_float (struct gdbarch *gdbarch, const char *p, int len, - DOUBLEST *d, struct type **t) -{ - int result = parse_c_float (gdbarch, p, len, d, t); - const struct builtin_type *builtin_types = builtin_type (gdbarch); - const struct builtin_go_type *builtin_go_types = builtin_go_type (gdbarch); - - if (*t == builtin_types->builtin_float) - *t = builtin_go_types->builtin_float32; - else if (*t == builtin_types->builtin_double) - *t = builtin_go_types->builtin_float64; - - return result; -} - /* Take care of parsing a number (anything that starts with a digit). Set yylval and return the token type; update lexptr. LEN is the number of characters in it. */ @@ -704,7 +637,8 @@ parse_go_float (struct gdbarch *gdbarch, const char *p, int len, as our YYSTYPE is different than c-exp.y's */ static int -parse_number (const char *p, int len, int parsed_float, YYSTYPE *putithere) +parse_number (struct parser_state *par_state, + const char *p, int len, int parsed_float, YYSTYPE *putithere) { /* FIXME: Shouldn't these be unsigned? We don't deal with negative values here, and we do kind of silly things like cast to unsigned. */ @@ -729,10 +663,34 @@ parse_number (const char *p, int len, int parsed_float, YYSTYPE *putithere) if (parsed_float) { - if (! parse_go_float (parse_gdbarch, p, len, - &putithere->typed_val_float.dval, - &putithere->typed_val_float.type)) - return ERROR; + const struct builtin_go_type *builtin_go_types + = builtin_go_type (par_state->gdbarch ()); + + /* Handle suffixes: 'f' for float32, 'l' for long double. + FIXME: This appears to be an extension -- do we want this? */ + if (len >= 1 && tolower (p[len - 1]) == 'f') + { + putithere->typed_val_float.type + = builtin_go_types->builtin_float32; + len--; + } + else if (len >= 1 && tolower (p[len - 1]) == 'l') + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_long_double; + len--; + } + /* Default type for floating-point literals is float64. */ + else + { + putithere->typed_val_float.type + = builtin_go_types->builtin_float64; + } + + if (!parse_float (p, len, + putithere->typed_val_float.type, + putithere->typed_val_float.val)) + return ERROR; return FLOAT; } @@ -845,9 +803,10 @@ parse_number (const char *p, int len, int parsed_float, YYSTYPE *putithere) un = (ULONGEST)n >> 2; if (long_p == 0 - && (un >> (gdbarch_int_bit (parse_gdbarch) - 2)) == 0) + && (un >> (gdbarch_int_bit (par_state->gdbarch ()) - 2)) == 0) { - high_bit = ((ULONGEST)1) << (gdbarch_int_bit (parse_gdbarch) - 1); + high_bit + = ((ULONGEST)1) << (gdbarch_int_bit (par_state->gdbarch ()) - 1); /* A large decimal (not hex or octal) constant (between INT_MAX and UINT_MAX) is a long or unsigned long, according to ANSI, @@ -855,28 +814,29 @@ parse_number (const char *p, int len, int parsed_float, YYSTYPE *putithere) int. This probably should be fixed. GCC gives a warning on such constants. */ - unsigned_type = parse_type->builtin_unsigned_int; - signed_type = parse_type->builtin_int; + unsigned_type = parse_type (par_state)->builtin_unsigned_int; + signed_type = parse_type (par_state)->builtin_int; } else if (long_p <= 1 - && (un >> (gdbarch_long_bit (parse_gdbarch) - 2)) == 0) + && (un >> (gdbarch_long_bit (par_state->gdbarch ()) - 2)) == 0) { - high_bit = ((ULONGEST)1) << (gdbarch_long_bit (parse_gdbarch) - 1); - unsigned_type = parse_type->builtin_unsigned_long; - signed_type = parse_type->builtin_long; + high_bit + = ((ULONGEST)1) << (gdbarch_long_bit (par_state->gdbarch ()) - 1); + unsigned_type = parse_type (par_state)->builtin_unsigned_long; + signed_type = parse_type (par_state)->builtin_long; } else { int shift; if (sizeof (ULONGEST) * HOST_CHAR_BIT - < gdbarch_long_long_bit (parse_gdbarch)) + < gdbarch_long_long_bit (par_state->gdbarch ())) /* A long long does not fit in a LONGEST. */ shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1); else - shift = (gdbarch_long_long_bit (parse_gdbarch) - 1); + shift = (gdbarch_long_long_bit (par_state->gdbarch ()) - 1); high_bit = (ULONGEST) 1 << shift; - unsigned_type = parse_type->builtin_unsigned_long_long; - signed_type = parse_type->builtin_long_long; + unsigned_type = parse_type (par_state)->builtin_unsigned_long_long; + signed_type = parse_type (par_state)->builtin_long_long; } putithere->typed_val_int.val = n; @@ -965,7 +925,7 @@ parse_string_or_char (const char *tokptr, const char **outptr, ++tokptr; value->type = C_STRING | (quote == '\'' ? C_CHAR : 0); /*FIXME*/ - value->ptr = obstack_base (&tempbuf); + value->ptr = (char *) obstack_base (&tempbuf); value->length = obstack_object_size (&tempbuf); *outptr = tokptr; @@ -975,7 +935,7 @@ parse_string_or_char (const char *tokptr, const char **outptr, struct token { - char *operator; + const char *oper; int token; enum exp_opcode opcode; }; @@ -1041,39 +1001,41 @@ static int saw_name_at_eof; do field name completion. */ static int last_was_structop; +/* Depth of parentheses. */ +static int paren_depth; + /* Read one token, getting characters through lexptr. */ static int -lex_one_token (void) +lex_one_token (struct parser_state *par_state) { int c; int namelen; unsigned int i; const char *tokstart; int saw_structop = last_was_structop; - char *copy; last_was_structop = 0; retry: - prev_lexptr = lexptr; + par_state->prev_lexptr = par_state->lexptr; - tokstart = lexptr; + tokstart = par_state->lexptr; /* See if it is a special token of length 3. */ for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++) - if (strncmp (tokstart, tokentab3[i].operator, 3) == 0) + if (strncmp (tokstart, tokentab3[i].oper, 3) == 0) { - lexptr += 3; + par_state->lexptr += 3; yylval.opcode = tokentab3[i].opcode; return tokentab3[i].token; } /* See if it is a special token of length 2. */ for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++) - if (strncmp (tokstart, tokentab2[i].operator, 2) == 0) + if (strncmp (tokstart, tokentab2[i].oper, 2) == 0) { - lexptr += 2; + par_state->lexptr += 2; yylval.opcode = tokentab2[i].opcode; /* NOTE: -> doesn't exist in Go, so we don't need to watch for setting last_was_structop here. */ @@ -1096,13 +1058,13 @@ lex_one_token (void) case ' ': case '\t': case '\n': - lexptr++; + par_state->lexptr++; goto retry; case '[': case '(': paren_depth++; - lexptr++; + par_state->lexptr++; return c; case ']': @@ -1110,25 +1072,25 @@ lex_one_token (void) if (paren_depth == 0) return 0; paren_depth--; - lexptr++; + par_state->lexptr++; return c; case ',': - if (comma_terminates + if (pstate->comma_terminates && paren_depth == 0) return 0; - lexptr++; + par_state->lexptr++; return c; case '.': /* Might be a floating point number. */ - if (lexptr[1] < '0' || lexptr[1] > '9') + if (par_state->lexptr[1] < '0' || par_state->lexptr[1] > '9') { - if (parse_completion) + if (pstate->parse_completion) last_was_structop = 1; goto symbol; /* Nope, must be a symbol. */ } - /* FALL THRU into number case. */ + /* FALL THRU. */ case '0': case '1': @@ -1175,7 +1137,8 @@ lex_one_token (void) && (*p < 'A' || *p > 'Z'))) break; } - toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval); + toktype = parse_number (par_state, tokstart, p - tokstart, + got_dot|got_e, &yylval); if (toktype == ERROR) { char *err_copy = (char *) alloca (p - tokstart + 1); @@ -1184,7 +1147,7 @@ lex_one_token (void) err_copy[p - tokstart] = 0; error (_("Invalid number \"%s\"."), err_copy); } - lexptr = p; + par_state->lexptr = p; return toktype; } @@ -1198,7 +1161,7 @@ lex_one_token (void) if (strncmp (p, "entry", len) == 0 && !isalnum (p[len]) && p[len] != '_') { - lexptr = &p[len]; + par_state->lexptr = &p[len]; return ENTRY; } } @@ -1221,7 +1184,7 @@ lex_one_token (void) case '{': case '}': symbol: - lexptr++; + par_state->lexptr++; return c; case '\'': @@ -1229,8 +1192,8 @@ lex_one_token (void) case '`': { int host_len; - int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval, - &host_len); + int result = parse_string_or_char (tokstart, &par_state->lexptr, + &yylval.tsval, &host_len); if (result == CHAR) { if (host_len == 0) @@ -1238,7 +1201,7 @@ lex_one_token (void) else if (host_len > 2 && c == '\'') { ++tokstart; - namelen = lexptr - tokstart - 1; + namelen = par_state->lexptr - tokstart - 1; goto tryname; } else if (host_len > 1) @@ -1291,7 +1254,7 @@ lex_one_token (void) return 0; } - lexptr += namelen; + par_state->lexptr += namelen; tryname: @@ -1299,9 +1262,9 @@ lex_one_token (void) yylval.sval.length = namelen; /* Catch specific keywords. */ - copy = copy_name (yylval.sval); + std::string copy = copy_name (yylval.sval); for (i = 0; i < sizeof (ident_tokens) / sizeof (ident_tokens[0]); i++) - if (strcmp (copy, ident_tokens[i].operator) == 0) + if (copy == ident_tokens[i].oper) { /* It is ok to always set this, even though we don't always strictly need to. */ @@ -1312,30 +1275,28 @@ lex_one_token (void) if (*tokstart == '$') return DOLLAR_VARIABLE; - if (parse_completion && *lexptr == '\0') + if (pstate->parse_completion && *par_state->lexptr == '\0') saw_name_at_eof = 1; return NAME; } /* An object of this type is pushed on a FIFO by the "outer" lexer. */ -typedef struct +struct token_and_value { int token; YYSTYPE value; -} token_and_value; - -DEF_VEC_O (token_and_value); +}; /* A FIFO of tokens that have been read but not yet returned to the parser. */ -static VEC (token_and_value) *token_fifo; +static std::vector token_fifo; /* Non-zero if the lexer should return tokens from the FIFO. */ static int popping; /* Temporary storage for yylex; this holds symbol names as they are built up. */ -static struct obstack name_obstack; +static auto_obstack name_obstack; /* Build "package.name" in name_obstack. For convenience of the caller, the name is NUL-terminated, @@ -1347,12 +1308,12 @@ build_packaged_name (const char *package, int package_len, { struct stoken result; - obstack_free (&name_obstack, obstack_base (&name_obstack)); + name_obstack.clear (); obstack_grow (&name_obstack, package, package_len); obstack_grow_str (&name_obstack, "."); obstack_grow (&name_obstack, name, name_len); obstack_grow (&name_obstack, "", 1); - result.ptr = obstack_base (&name_obstack); + result.ptr = (char *) obstack_base (&name_obstack); result.length = obstack_object_size (&name_obstack) - 1; return result; @@ -1368,7 +1329,7 @@ package_name_p (const char *name, const struct block *block) struct symbol *sym; struct field_of_this_result is_a_field_of_this; - sym = lookup_symbol (name, block, STRUCT_DOMAIN, &is_a_field_of_this); + sym = lookup_symbol (name, block, STRUCT_DOMAIN, &is_a_field_of_this).symbol; if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF @@ -1385,15 +1346,15 @@ package_name_p (const char *name, const struct block *block) static int classify_unsafe_function (struct stoken function_name) { - char *copy = copy_name (function_name); + std::string copy = copy_name (function_name); - if (strcmp (copy, "Sizeof") == 0) + if (copy == "Sizeof") { yylval.sval = function_name; return SIZEOF_KEYWORD; } - error (_("Unknown function in `unsafe' package: %s"), copy); + error (_("Unknown function in `unsafe' package: %s"), copy.c_str ()); } /* Classify token(s) "name1.name2" where name1 is known to be a package. @@ -1405,15 +1366,14 @@ classify_unsafe_function (struct stoken function_name) static int classify_packaged_name (const struct block *block) { - char *copy; - struct symbol *sym; + struct block_symbol sym; struct field_of_this_result is_a_field_of_this; - copy = copy_name (yylval.sval); + std::string copy = copy_name (yylval.sval); - sym = lookup_symbol (copy, block, VAR_DOMAIN, &is_a_field_of_this); + sym = lookup_symbol (copy.c_str (), block, VAR_DOMAIN, &is_a_field_of_this); - if (sym) + if (sym.symbol) { yylval.ssym.sym = sym; yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL; @@ -1431,18 +1391,18 @@ classify_packaged_name (const struct block *block) The result is one of NAME, NAME_OR_INT, or TYPENAME. */ static int -classify_name (const struct block *block) +classify_name (struct parser_state *par_state, const struct block *block) { struct type *type; - struct symbol *sym; - char *copy; + struct block_symbol sym; struct field_of_this_result is_a_field_of_this; - copy = copy_name (yylval.sval); + std::string copy = copy_name (yylval.sval); /* Try primitive types first so they win over bad/weird debug info. */ - type = language_lookup_primitive_type_by_name (parse_language, - parse_gdbarch, copy); + type = language_lookup_primitive_type (par_state->language (), + par_state->gdbarch (), + copy.c_str ()); if (type != NULL) { /* NOTE: We take advantage of the fact that yylval coming in was a @@ -1454,9 +1414,9 @@ classify_name (const struct block *block) /* TODO: What about other types? */ - sym = lookup_symbol (copy, block, VAR_DOMAIN, &is_a_field_of_this); + sym = lookup_symbol (copy.c_str (), block, VAR_DOMAIN, &is_a_field_of_this); - if (sym) + if (sym.symbol) { yylval.ssym.sym = sym; yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL; @@ -1476,12 +1436,12 @@ classify_name (const struct block *block) struct stoken sval = build_packaged_name (current_package_name, strlen (current_package_name), - copy, strlen (copy)); + copy.c_str (), copy.size ()); xfree (current_package_name); sym = lookup_symbol (sval.ptr, block, VAR_DOMAIN, &is_a_field_of_this); - if (sym) + if (sym.symbol) { yylval.ssym.stoken = sval; yylval.ssym.sym = sym; @@ -1498,16 +1458,19 @@ classify_name (const struct block *block) || (copy[0] >= 'A' && copy[0] < 'A' + input_radix - 10)) { YYSTYPE newlval; /* Its value is ignored. */ - int hextype = parse_number (copy, yylval.sval.length, 0, &newlval); + int hextype = parse_number (par_state, copy.c_str (), + yylval.sval.length, 0, &newlval); if (hextype == INT) { - yylval.ssym.sym = NULL; + yylval.ssym.sym.symbol = NULL; + yylval.ssym.sym.block = NULL; yylval.ssym.is_a_field_of_this = 0; return NAME_OR_INT; } } - yylval.ssym.sym = NULL; + yylval.ssym.sym.symbol = NULL; + yylval.ssym.sym.block = NULL; yylval.ssym.is_a_field_of_this = 0; return NAME; } @@ -1520,10 +1483,10 @@ yylex (void) { token_and_value current, next; - if (popping && !VEC_empty (token_and_value, token_fifo)) + if (popping && !token_fifo.empty ()) { - token_and_value tv = *VEC_index (token_and_value, token_fifo, 0); - VEC_ordered_remove (token_and_value, token_fifo, 0); + token_and_value tv = token_fifo[0]; + token_fifo.erase (token_fifo.begin ()); yylval = tv.value; /* There's no need to fall through to handle package.name as that can never happen here. In theory. */ @@ -1531,7 +1494,7 @@ yylex (void) } popping = 0; - current.token = lex_one_token (); + current.token = lex_one_token (pstate); /* TODO: Need a way to force specifying name1 as a package. .name1.name2 ? */ @@ -1542,83 +1505,79 @@ yylex (void) /* See if we have "name1 . name2". */ current.value = yylval; - next.token = lex_one_token (); + next.token = lex_one_token (pstate); next.value = yylval; if (next.token == '.') { token_and_value name2; - name2.token = lex_one_token (); + name2.token = lex_one_token (pstate); name2.value = yylval; if (name2.token == NAME) { /* Ok, we have "name1 . name2". */ - char *copy; - - copy = copy_name (current.value.sval); + std::string copy = copy_name (current.value.sval); - if (strcmp (copy, "unsafe") == 0) + if (copy == "unsafe") { popping = 1; return classify_unsafe_function (name2.value.sval); } - if (package_name_p (copy, expression_context_block)) + if (package_name_p (copy.c_str (), pstate->expression_context_block)) { popping = 1; yylval.sval = build_packaged_name (current.value.sval.ptr, current.value.sval.length, name2.value.sval.ptr, name2.value.sval.length); - return classify_packaged_name (expression_context_block); + return classify_packaged_name (pstate->expression_context_block); } } - VEC_safe_push (token_and_value, token_fifo, &next); - VEC_safe_push (token_and_value, token_fifo, &name2); + token_fifo.push_back (next); + token_fifo.push_back (name2); } else - { - VEC_safe_push (token_and_value, token_fifo, &next); - } + token_fifo.push_back (next); /* If we arrive here we don't have a package-qualified name. */ popping = 1; yylval = current.value; - return classify_name (expression_context_block); + return classify_name (pstate, pstate->expression_context_block); } int -go_parse (void) +go_parse (struct parser_state *par_state) { - int result; - struct cleanup *back_to = make_cleanup (null_cleanup, NULL); + /* Setting up the parser state. */ + scoped_restore pstate_restore = make_scoped_restore (&pstate); + gdb_assert (par_state != NULL); + pstate = par_state; - make_cleanup_restore_integer (&yydebug); - yydebug = parser_debug; + scoped_restore restore_yydebug = make_scoped_restore (&yydebug, + parser_debug); /* Initialize some state used by the lexer. */ last_was_structop = 0; saw_name_at_eof = 0; + paren_depth = 0; - VEC_free (token_and_value, token_fifo); + token_fifo.clear (); popping = 0; - obstack_init (&name_obstack); - make_cleanup_obstack_free (&name_obstack); + name_obstack.clear (); - result = yyparse (); - do_cleanups (back_to); - return result; + return yyparse (); } -void -yyerror (char *msg) +static void +yyerror (const char *msg) { - if (prev_lexptr) - lexptr = prev_lexptr; + if (pstate->prev_lexptr) + pstate->lexptr = pstate->prev_lexptr; - error (_("A %s in expression, near `%s'."), (msg ? msg : "error"), lexptr); + error (_("A %s in expression, near `%s'."), msg, pstate->lexptr); }