X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fgo-exp.y;h=f786ec201714a92e6719815258d55d0f427fe9d9;hb=2ab317fb8290ea96bdb446957d2e221634fd25c8;hp=4e017fe3dce52b6929e491431f7603993825f28d;hpb=63e43d3aedb8b1112899c2d0ad74cbbee687e5d6;p=binutils-gdb.git diff --git a/gdb/go-exp.y b/gdb/go-exp.y index 4e017fe3dce..f786ec20171 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-2015 Free Software Foundation, Inc. + Copyright (C) 2012-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -64,62 +64,14 @@ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ #include "charset.h" #include "block.h" +#include "expop.h" -#define parse_type(ps) builtin_type (parse_gdbarch (ps)) - -/* 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. */ @@ -130,7 +82,7 @@ int yyparse (void); static int yylex (void); -void yyerror (char *); +static void yyerror (const char *); %} @@ -146,7 +98,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; @@ -164,8 +116,8 @@ void yyerror (char *); /* YYSTYPE gets defined by %union. */ static int parse_number (struct parser_state *, const char *, int, int, YYSTYPE *); -static int parse_go_float (struct gdbarch *gdbarch, const char *p, int len, - DOUBLEST *d, struct type **t); + +using namespace expr; %} %type exp exp1 type_exp start variable lcurly @@ -244,119 +196,124 @@ start : exp1 ; type_exp: type - { write_exp_elt_opcode (pstate, OP_TYPE); - write_exp_elt_type (pstate, $1); - write_exp_elt_opcode (pstate, OP_TYPE); } + { pstate->push_new ($1); } ; /* Expressions, including the comma operator. */ exp1 : exp | exp1 ',' exp - { write_exp_elt_opcode (pstate, BINOP_COMMA); } + { pstate->wrap2 (); } ; /* Expressions, not including the comma operator. */ exp : '*' exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_IND); } + { pstate->wrap (); } ; exp : '&' exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_ADDR); } + { pstate->wrap (); } ; exp : '-' exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_NEG); } + { pstate->wrap (); } ; exp : '+' exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_PLUS); } + { pstate->wrap (); } ; exp : '!' exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); } + { pstate->wrap (); } ; exp : '^' exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_COMPLEMENT); } + { pstate->wrap (); } ; exp : exp INCREMENT %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_POSTINCREMENT); } + { pstate->wrap (); } ; exp : exp DECREMENT %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_POSTDECREMENT); } + { pstate->wrap (); } ; /* foo->bar is not in Go. May want as a gdb extension. Later. */ exp : exp '.' name_not_typename - { write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); - write_exp_string (pstate, $3.stoken); - write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } + { + pstate->push_new + (pstate->pop (), copy_name ($3.stoken)); + } ; exp : exp '.' name_not_typename COMPLETE - { mark_struct_expression (pstate); - write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); - write_exp_string (pstate, $3.stoken); - write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } + { + structop_base_operation *op + = new structop_operation (pstate->pop (), + copy_name ($3.stoken)); + pstate->mark_struct_expression (op); + pstate->push (operation_up (op)); + } ; exp : exp '.' COMPLETE - { struct stoken s; - mark_struct_expression (pstate); - write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); - s.ptr = ""; - s.length = 0; - write_exp_string (pstate, s); - write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } + { + structop_base_operation *op + = new structop_operation (pstate->pop (), ""); + pstate->mark_struct_expression (op); + pstate->push (operation_up (op)); + } ; exp : exp '[' exp1 ']' - { write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); } + { pstate->wrap2 (); } ; 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 (pstate, OP_FUNCALL); - write_exp_elt_longcst (pstate, - (LONGEST) end_arglist ()); - write_exp_elt_opcode (pstate, OP_FUNCALL); } + { + std::vector args + = pstate->pop_vector (pstate->end_arglist ()); + pstate->push_new + (pstate->pop (), std::move (args)); + } ; 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 (pstate, UNOP_MEMVAL); - write_exp_elt_type (pstate, $2); - write_exp_elt_opcode (pstate, UNOP_MEMVAL); } + { + pstate->push_new + (pstate->pop (), $2); + } ; exp : type '(' exp ')' %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_CAST); - write_exp_elt_type (pstate, $1); - write_exp_elt_opcode (pstate, UNOP_CAST); } + { + pstate->push_new + (pstate->pop (), $1); + } ; exp : '(' exp1 ')' @@ -366,100 +323,110 @@ exp : '(' exp1 ')' /* Binary operators in order of decreasing precedence. */ exp : exp '@' exp - { write_exp_elt_opcode (pstate, BINOP_REPEAT); } + { pstate->wrap2 (); } ; exp : exp '*' exp - { write_exp_elt_opcode (pstate, BINOP_MUL); } + { pstate->wrap2 (); } ; exp : exp '/' exp - { write_exp_elt_opcode (pstate, BINOP_DIV); } + { pstate->wrap2 (); } ; exp : exp '%' exp - { write_exp_elt_opcode (pstate, BINOP_REM); } + { pstate->wrap2 (); } ; exp : exp '+' exp - { write_exp_elt_opcode (pstate, BINOP_ADD); } + { pstate->wrap2 (); } ; exp : exp '-' exp - { write_exp_elt_opcode (pstate, BINOP_SUB); } + { pstate->wrap2 (); } ; exp : exp LSH exp - { write_exp_elt_opcode (pstate, BINOP_LSH); } + { pstate->wrap2 (); } ; exp : exp RSH exp - { write_exp_elt_opcode (pstate, BINOP_RSH); } + { pstate->wrap2 (); } ; exp : exp EQUAL exp - { write_exp_elt_opcode (pstate, BINOP_EQUAL); } + { pstate->wrap2 (); } ; exp : exp NOTEQUAL exp - { write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); } + { pstate->wrap2 (); } ; exp : exp LEQ exp - { write_exp_elt_opcode (pstate, BINOP_LEQ); } + { pstate->wrap2 (); } ; exp : exp GEQ exp - { write_exp_elt_opcode (pstate, BINOP_GEQ); } + { pstate->wrap2 (); } ; exp : exp '<' exp - { write_exp_elt_opcode (pstate, BINOP_LESS); } + { pstate->wrap2 (); } ; exp : exp '>' exp - { write_exp_elt_opcode (pstate, BINOP_GTR); } + { pstate->wrap2 (); } ; exp : exp '&' exp - { write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); } + { pstate->wrap2 (); } ; exp : exp '^' exp - { write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); } + { pstate->wrap2 (); } ; exp : exp '|' exp - { write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); } + { pstate->wrap2 (); } ; exp : exp ANDAND exp - { write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); } + { pstate->wrap2 (); } ; exp : exp OROR exp - { write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); } + { pstate->wrap2 (); } ; exp : exp '?' exp ':' exp %prec '?' - { write_exp_elt_opcode (pstate, TERNOP_COND); } + { + operation_up last = pstate->pop (); + operation_up mid = pstate->pop (); + operation_up first = pstate->pop (); + pstate->push_new + (std::move (first), std::move (mid), + std::move (last)); + } ; exp : exp '=' exp - { write_exp_elt_opcode (pstate, BINOP_ASSIGN); } + { pstate->wrap2 (); } ; exp : exp ASSIGN_MODIFY exp - { write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode (pstate, $2); - write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY); } + { + operation_up rhs = pstate->pop (); + operation_up lhs = pstate->pop (); + pstate->push_new + ($2, std::move (lhs), std::move (rhs)); + } ; exp : INT - { 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); } + { + pstate->push_new + ($1.type, $1.val); + } ; exp : CHAR @@ -467,7 +434,7 @@ exp : CHAR struct stoken_vector vec; vec.len = 1; vec.tokens = &$1; - write_exp_string_vector (pstate, $1.type, &vec); + pstate->push_c_string ($1.type, &vec); } ; @@ -475,20 +442,20 @@ exp : NAME_OR_INT { YYSTYPE val; 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 (pstate, OP_LONG); + pstate->push_new + (val.typed_val_int.type, + val.typed_val_int.val); } ; exp : FLOAT - { write_exp_elt_opcode (pstate, OP_DOUBLE); - write_exp_elt_type (pstate, $1.type); - write_exp_elt_dblcst (pstate, $1.dval); - write_exp_elt_opcode (pstate, OP_DOUBLE); } + { + float_data data; + std::copy (std::begin ($1.val), std::end ($1.val), + std::begin (data)); + pstate->push_new ($1.type, data); + } ; exp : variable @@ -496,29 +463,26 @@ exp : variable exp : DOLLAR_VARIABLE { - write_dollar_variable (pstate, $1); + pstate->push_dollar ($1); } ; exp : SIZEOF_KEYWORD '(' type ')' %prec UNARY { /* TODO(dje): Go objects in structs. */ - write_exp_elt_opcode (pstate, OP_LONG); /* TODO(dje): What's the right type here? */ - write_exp_elt_type - (pstate, - parse_type (pstate)->builtin_unsigned_int); + struct type *size_type + = 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); + pstate->push_new + (size_type, (LONGEST) TYPE_LENGTH ($3)); } ; exp : SIZEOF_KEYWORD '(' exp ')' %prec UNARY { /* TODO(dje): Go objects in structs. */ - write_exp_elt_opcode (pstate, UNOP_SIZEOF); + pstate->wrap (); } string_exp: @@ -535,7 +499,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); } @@ -545,10 +509,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; @@ -561,8 +525,8 @@ exp : string_exp %prec ABOVE_COMMA { int i; - write_exp_string_vector (pstate, 0 /*always utf8*/, - &$1); + /* Always utf8. */ + pstate->push_c_string (0, &$1); for (i = 0; i < $1.len; ++i) free ($1.tokens[i].ptr); free ($1.tokens); @@ -570,30 +534,24 @@ exp : string_exp %prec ABOVE_COMMA ; exp : TRUE_KEYWORD - { write_exp_elt_opcode (pstate, OP_BOOL); - write_exp_elt_longcst (pstate, (LONGEST) $1); - write_exp_elt_opcode (pstate, OP_BOOL); } + { pstate->push_new ($1); } ; exp : FALSE_KEYWORD - { write_exp_elt_opcode (pstate, OP_BOOL); - write_exp_elt_longcst (pstate, (LONGEST) $1); - write_exp_elt_opcode (pstate, OP_BOOL); } + { pstate->push_new ($1); } ; variable: name_not_typename ENTRY { struct symbol *sym = $1.sym.symbol; if (sym == NULL - || !SYMBOL_IS_ARGUMENT (sym) + || !sym->is_argument () || !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 (pstate, OP_VAR_ENTRY_VALUE); - write_exp_elt_sym (pstate, sym); - write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE); + pstate->push_new (sym); } ; @@ -603,17 +561,9 @@ variable: name_not_typename if (sym.symbol) { if (symbol_read_needs_frame (sym.symbol)) - { - if (innermost_block == 0 - || contained_in (sym.block, - innermost_block)) - innermost_block = sym.block; - } - - 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); + pstate->block_tracker->update (sym); + + pstate->push_new (sym); } else if ($1.is_a_field_of_this) { @@ -624,19 +574,20 @@ 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 (pstate, msymbol); + pstate->push_new + (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 ()); } } ; @@ -659,7 +610,7 @@ type /* Implements (approximately): [*] type-specifier */ expression_context_block); } */ | BYTE_KEYWORD - { $$ = builtin_go_type (parse_gdbarch (pstate)) + { $$ = builtin_go_type (pstate->gdbarch ()) ->builtin_uint8; } ; @@ -683,24 +634,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. */ @@ -714,11 +647,8 @@ static int 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. */ - LONGEST n = 0; - LONGEST prevn = 0; - ULONGEST un; + ULONGEST n = 0; + ULONGEST prevn = 0; int i = 0; int c; @@ -731,21 +661,41 @@ parse_number (struct parser_state *par_state, /* We have found a "L" or "U" suffix. */ int found_suffix = 0; - ULONGEST high_bit; - struct type *signed_type; - struct type *unsigned_type; - if (parsed_float) { - if (! parse_go_float (parse_gdbarch (par_state), p, len, - &putithere->typed_val_float.dval, - &putithere->typed_val_float.type)) + 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; } /* Handle base-switching prefixes 0x, 0t, 0d, 0. */ - if (p[0] == '0') + if (p[0] == '0' && len > 1) switch (p[1]) { case 'x': @@ -822,18 +772,12 @@ parse_number (struct parser_state *par_state, if (i >= base) return ERROR; /* Invalid digit in this base. */ - /* Portably test for overflow (only works for nonzero values, so make - a second check for zero). FIXME: Can't we just make n and prevn - unsigned and avoid this? */ - if (c != 'l' && c != 'u' && (prevn >= n) && n != 0) - unsigned_p = 1; /* Try something unsigned. */ - - /* Portably test for unsigned overflow. - FIXME: This check is wrong; for example it doesn't find overflow - on 0x123456789 when LONGEST is 32 bits. */ - if (c != 'l' && c != 'u' && n != 0) + if (c != 'l' && c != 'u') { - if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n)) + /* Test for overflow. */ + if (n == 0 && prevn == 0) + ; + else if (prevn >= n) error (_("Numeric constant too large.")); } prevn = n; @@ -851,57 +795,31 @@ parse_number (struct parser_state *par_state, the case where it is we just always shift the value more than once, with fewer bits each time. */ - un = (ULONGEST)n >> 2; - if (long_p == 0 - && (un >> (gdbarch_int_bit (parse_gdbarch (par_state)) - 2)) == 0) - { - high_bit - = ((ULONGEST)1) << (gdbarch_int_bit (parse_gdbarch (par_state)) - 1); - - /* A large decimal (not hex or octal) constant (between INT_MAX - and UINT_MAX) is a long or unsigned long, according to ANSI, - never an unsigned int, but this code treats it as unsigned - int. This probably should be fixed. GCC gives a warning on - such constants. */ - - 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 (par_state)) - 2)) == 0) - { - high_bit - = ((ULONGEST)1) << (gdbarch_long_bit (parse_gdbarch (par_state)) - 1); - unsigned_type = parse_type (par_state)->builtin_unsigned_long; - signed_type = parse_type (par_state)->builtin_long; - } + int int_bits = gdbarch_int_bit (par_state->gdbarch ()); + int long_bits = gdbarch_long_bit (par_state->gdbarch ()); + int long_long_bits = gdbarch_long_long_bit (par_state->gdbarch ()); + bool have_signed = !unsigned_p; + bool have_int = long_p == 0; + bool have_long = long_p <= 1; + if (have_int && have_signed && fits_in_type (1, n, int_bits, true)) + putithere->typed_val_int.type = parse_type (par_state)->builtin_int; + else if (have_int && fits_in_type (1, n, int_bits, false)) + putithere->typed_val_int.type + = parse_type (par_state)->builtin_unsigned_int; + else if (have_long && have_signed && fits_in_type (1, n, long_bits, true)) + putithere->typed_val_int.type = parse_type (par_state)->builtin_long; + else if (have_long && fits_in_type (1, n, long_bits, false)) + putithere->typed_val_int.type + = parse_type (par_state)->builtin_unsigned_long; + else if (have_signed && fits_in_type (1, n, long_long_bits, true)) + putithere->typed_val_int.type + = parse_type (par_state)->builtin_long_long; + else if (fits_in_type (1, n, long_long_bits, false)) + putithere->typed_val_int.type + = parse_type (par_state)->builtin_unsigned_long_long; else - { - int shift; - if (sizeof (ULONGEST) * HOST_CHAR_BIT - < gdbarch_long_long_bit (parse_gdbarch (par_state))) - /* A long long does not fit in a LONGEST. */ - shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1); - else - shift = (gdbarch_long_long_bit (parse_gdbarch (par_state)) - 1); - high_bit = (ULONGEST) 1 << shift; - 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; - - /* If the high bit of the worked out type is set then this number - has to be unsigned. */ - - if (unsigned_p || (n & high_bit)) - { - putithere->typed_val_int.type = unsigned_type; - } - else - { - putithere->typed_val_int.type = signed_type; - } + error (_("Numeric constant too large.")); + putithere->typed_val_int.val = n; return INT; } @@ -974,8 +892,8 @@ 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->type = (int) C_STRING | (quote == '\'' ? C_CHAR : 0); /*FIXME*/ + value->ptr = (char *) obstack_base (&tempbuf); value->length = obstack_object_size (&tempbuf); *outptr = tokptr; @@ -985,7 +903,7 @@ parse_string_or_char (const char *tokptr, const char **outptr, struct token { - char *oper; + const char *oper; int token; enum exp_opcode opcode; }; @@ -1008,19 +926,19 @@ static const struct token tokentab2[] = {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR}, {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND}, {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR}, - {"++", INCREMENT, BINOP_END}, - {"--", DECREMENT, BINOP_END}, - /*{"->", RIGHT_ARROW, BINOP_END}, Doesn't exist in Go. */ - {"<-", LEFT_ARROW, BINOP_END}, - {"&&", ANDAND, BINOP_END}, - {"||", OROR, BINOP_END}, - {"<<", LSH, BINOP_END}, - {">>", RSH, BINOP_END}, - {"==", EQUAL, BINOP_END}, - {"!=", NOTEQUAL, BINOP_END}, - {"<=", LEQ, BINOP_END}, - {">=", GEQ, BINOP_END}, - /*{"&^", ANDNOT, BINOP_END}, TODO */ + {"++", INCREMENT, OP_NULL}, + {"--", DECREMENT, OP_NULL}, + /*{"->", RIGHT_ARROW, OP_NULL}, Doesn't exist in Go. */ + {"<-", LEFT_ARROW, OP_NULL}, + {"&&", ANDAND, OP_NULL}, + {"||", OROR, OP_NULL}, + {"<<", LSH, OP_NULL}, + {">>", RSH, OP_NULL}, + {"==", EQUAL, OP_NULL}, + {"!=", NOTEQUAL, OP_NULL}, + {"<=", LEQ, OP_NULL}, + {">=", GEQ, OP_NULL}, + /*{"&^", ANDNOT, OP_NULL}, TODO */ }; /* Identifier-like tokens. */ @@ -1051,6 +969,9 @@ 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 @@ -1058,36 +979,34 @@ 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].oper, 3) == 0) + for (const auto &token : tokentab3) + if (strncmp (tokstart, token.oper, 3) == 0) { - lexptr += 3; - yylval.opcode = tokentab3[i].opcode; - return tokentab3[i].token; + par_state->lexptr += 3; + yylval.opcode = token.opcode; + return token.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].oper, 2) == 0) + for (const auto &token : tokentab2) + if (strncmp (tokstart, token.oper, 2) == 0) { - lexptr += 2; - yylval.opcode = tokentab2[i].opcode; + par_state->lexptr += 2; + yylval.opcode = token.opcode; /* NOTE: -> doesn't exist in Go, so we don't need to watch for setting last_was_structop here. */ - return tokentab2[i].token; + return token.token; } switch (c = *tokstart) @@ -1101,18 +1020,18 @@ lex_one_token (struct parser_state *par_state) else if (saw_structop) return COMPLETE; else - return 0; + return 0; case ' ': case '\t': case '\n': - lexptr++; + par_state->lexptr++; goto retry; case '[': case '(': paren_depth++; - lexptr++; + par_state->lexptr++; return c; case ']': @@ -1120,25 +1039,25 @@ lex_one_token (struct parser_state *par_state) if (paren_depth == 0) return 0; paren_depth--; - lexptr++; + par_state->lexptr++; return c; case ',': - if (comma_terminates - && paren_depth == 0) + 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': @@ -1187,7 +1106,7 @@ lex_one_token (struct parser_state *par_state) } toktype = parse_number (par_state, tokstart, p - tokstart, got_dot|got_e, &yylval); - if (toktype == ERROR) + if (toktype == ERROR) { char *err_copy = (char *) alloca (p - tokstart + 1); @@ -1195,7 +1114,7 @@ lex_one_token (struct parser_state *par_state) err_copy[p - tokstart] = 0; error (_("Invalid number \"%s\"."), err_copy); } - lexptr = p; + par_state->lexptr = p; return toktype; } @@ -1209,7 +1128,7 @@ lex_one_token (struct parser_state *par_state) if (strncmp (p, "entry", len) == 0 && !isalnum (p[len]) && p[len] != '_') { - lexptr = &p[len]; + par_state->lexptr = &p[len]; return ENTRY; } } @@ -1232,7 +1151,7 @@ lex_one_token (struct parser_state *par_state) case '{': case '}': symbol: - lexptr++; + par_state->lexptr++; return c; case '\'': @@ -1240,8 +1159,8 @@ lex_one_token (struct parser_state *par_state) 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) @@ -1249,7 +1168,7 @@ lex_one_token (struct parser_state *par_state) else if (host_len > 2 && c == '\'') { ++tokstart; - namelen = lexptr - tokstart - 1; + namelen = par_state->lexptr - tokstart - 1; goto tryname; } else if (host_len > 1) @@ -1302,7 +1221,7 @@ lex_one_token (struct parser_state *par_state) return 0; } - lexptr += namelen; + par_state->lexptr += namelen; tryname: @@ -1310,43 +1229,41 @@ lex_one_token (struct parser_state *par_state) yylval.sval.length = namelen; /* Catch specific keywords. */ - copy = copy_name (yylval.sval); - for (i = 0; i < sizeof (ident_tokens) / sizeof (ident_tokens[0]); i++) - if (strcmp (copy, ident_tokens[i].oper) == 0) + std::string copy = copy_name (yylval.sval); + for (const auto &token : ident_tokens) + if (copy == token.oper) { /* It is ok to always set this, even though we don't always strictly need to. */ - yylval.opcode = ident_tokens[i].opcode; - return ident_tokens[i].token; + yylval.opcode = token.opcode; + return token.token; } 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, @@ -1358,12 +1275,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; @@ -1382,8 +1299,8 @@ package_name_p (const char *name, const struct block *block) sym = lookup_symbol (name, block, STRUCT_DOMAIN, &is_a_field_of_this).symbol; if (sym - && SYMBOL_CLASS (sym) == LOC_TYPEDEF - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_MODULE) + && sym->aclass () == LOC_TYPEDEF + && sym->type ()->code () == TYPE_CODE_MODULE) return 1; return 0; @@ -1396,15 +1313,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. @@ -1416,13 +1333,12 @@ classify_unsafe_function (struct stoken function_name) static int classify_packaged_name (const struct block *block) { - 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); - 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.symbol) { @@ -1446,15 +1362,14 @@ classify_name (struct parser_state *par_state, const struct block *block) { struct type *type; struct block_symbol sym; - char *copy; 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 (parse_language (par_state), - parse_gdbarch (par_state), - 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 @@ -1466,7 +1381,7 @@ classify_name (struct parser_state *par_state, 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.symbol) { @@ -1488,7 +1403,7 @@ classify_name (struct parser_state *par_state, 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, @@ -1510,8 +1425,8 @@ classify_name (struct parser_state *par_state, const struct block *block) || (copy[0] >= 'A' && copy[0] < 'A' + input_radix - 10)) { YYSTYPE newlval; /* Its value is ignored. */ - int hextype = parse_number (par_state, 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.symbol = NULL; @@ -1535,10 +1450,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. */ @@ -1570,77 +1485,71 @@ yylex (void) if (name2.token == NAME) { /* Ok, we have "name1 . name2". */ - char *copy; + std::string copy = copy_name (current.value.sval); - 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 (pstate, expression_context_block); + return classify_name (pstate, pstate->expression_context_block); } +/* See language.h. */ + int -go_parse (struct parser_state *par_state) +go_language::parser (struct parser_state *par_state) const { - int result; - struct cleanup *back_to; - /* Setting up the parser state. */ + scoped_restore pstate_restore = make_scoped_restore (&pstate); gdb_assert (par_state != NULL); pstate = par_state; - back_to = make_cleanup (null_cleanup, NULL); - - make_cleanup_restore_integer (&yydebug); - make_cleanup_clear_parser_state (&pstate); - 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); + int result = yyparse (); + if (!result) + pstate->set_operation (pstate->pop ()); return result; } -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); }