X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fc-exp.y;h=50a2eef98b58614bf41cafada3359167e92bae8f;hb=8db52437243e251c01e352cdb325bc9ace578e7c;hp=16b291f9c700ff9c8453a5d51357be9cad038bee;hpb=8621b685bfdcb8773b8177fb2b89e45499902868;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 16b291f9c7..50a2eef98b 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1,5 +1,5 @@ /* YACC parser for C expressions, for GDB. - Copyright (C) 1986-2019 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -53,6 +53,7 @@ #include "objc-lang.h" #include "typeprint.h" #include "cp-abi.h" +#include "type-stack.h" #define parse_type(ps) builtin_type (ps->gdbarch ()) @@ -104,6 +105,9 @@ struct c_parse_state token, we simply keep it all and delete it after parsing has completed. */ auto_obstack expansion_obstack; + + /* The type stack. */ + struct type_stack type_stack; }; /* This is set and cleared in c_parse. */ @@ -233,6 +237,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value); /* Special type cases, put in to allow the parser to distinguish different legal basetypes. */ %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD +%token RESTRICT ATOMIC %token DOLLAR_VARIABLE @@ -364,7 +369,7 @@ exp : exp ARROW field_name ; exp : exp ARROW field_name COMPLETE - { mark_struct_expression (pstate); + { pstate->mark_struct_expression (); write_exp_elt_opcode (pstate, STRUCTOP_PTR); write_exp_string (pstate, $3); write_exp_elt_opcode (pstate, STRUCTOP_PTR); } @@ -372,7 +377,7 @@ exp : exp ARROW field_name COMPLETE exp : exp ARROW COMPLETE { struct stoken s; - mark_struct_expression (pstate); + pstate->mark_struct_expression (); write_exp_elt_opcode (pstate, STRUCTOP_PTR); s.ptr = ""; s.length = 0; @@ -387,7 +392,7 @@ exp : exp ARROW '~' name ; exp : exp ARROW '~' name COMPLETE - { mark_struct_expression (pstate); + { pstate->mark_struct_expression (); write_exp_elt_opcode (pstate, STRUCTOP_PTR); write_destructor_name (pstate, $4); write_exp_elt_opcode (pstate, STRUCTOP_PTR); } @@ -412,7 +417,7 @@ exp : exp '.' field_name ; exp : exp '.' field_name COMPLETE - { mark_struct_expression (pstate); + { pstate->mark_struct_expression (); write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); write_exp_string (pstate, $3); write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } @@ -420,7 +425,7 @@ exp : exp '.' field_name COMPLETE exp : exp '.' COMPLETE { struct stoken s; - mark_struct_expression (pstate); + pstate->mark_struct_expression (); write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); s.ptr = ""; s.length = 0; @@ -435,7 +440,7 @@ exp : exp '.' '~' name ; exp : exp '.' '~' name COMPLETE - { mark_struct_expression (pstate); + { pstate->mark_struct_expression (); write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); write_destructor_name (pstate, $4); write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } @@ -470,14 +475,15 @@ exp : OBJC_LBRAC TYPENAME { CORE_ADDR theclass; + std::string copy = copy_name ($2.stoken); theclass = lookup_objc_class (pstate->gdbarch (), - copy_name ($2.stoken)); + copy.c_str ()); if (theclass == 0) error (_("%s is not an ObjC Class"), - copy_name ($2.stoken)); + copy.c_str ()); write_exp_elt_opcode (pstate, OP_LONG); write_exp_elt_type (pstate, - parse_type (pstate)->builtin_int); + parse_type (pstate)->builtin_int); write_exp_elt_longcst (pstate, (LONGEST) theclass); write_exp_elt_opcode (pstate, OP_LONG); start_msglist(); @@ -534,11 +540,11 @@ msgarg : name ':' exp 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 ARROW { write_exp_elt_opcode (pstate, OP_FUNCALL); write_exp_elt_longcst (pstate, - (LONGEST) end_arglist ()); + pstate->end_arglist ()); write_exp_elt_opcode (pstate, OP_FUNCALL); } ; @@ -546,10 +552,10 @@ exp : exp '(' "func()::static_var" further below, which uses function_method_void. */ exp : exp '(' ')' %prec ARROW - { start_arglist (); + { pstate->start_arglist (); write_exp_elt_opcode (pstate, OP_FUNCALL); write_exp_elt_longcst (pstate, - (LONGEST) end_arglist ()); + pstate->end_arglist ()); write_exp_elt_opcode (pstate, OP_FUNCALL); } ; @@ -569,30 +575,30 @@ exp : UNKNOWN_CPP_NAME '(' /* This is to save the value of arglist_len being accumulated by an outer function call. */ - start_arglist (); + pstate->start_arglist (); } arglist ')' %prec ARROW { write_exp_elt_opcode (pstate, OP_FUNCALL); write_exp_elt_longcst (pstate, - (LONGEST) end_arglist ()); + 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++; } ; function_method: exp '(' parameter_typelist ')' const_or_volatile @@ -604,8 +610,10 @@ function_method: exp '(' parameter_typelist ')' const_or_volatile /* Save the const/volatile qualifiers as recorded by the const_or_volatile production's actions. */ - write_exp_elt_longcst (pstate, - follow_type_instance_flags ()); + write_exp_elt_longcst + (pstate, + (cpstate->type_stack + .follow_type_instance_flags ())); write_exp_elt_longcst (pstate, len); for (type *type_elt : *type_list) write_exp_elt_type (pstate, type_elt); @@ -617,8 +625,9 @@ function_method: exp '(' parameter_typelist ')' const_or_volatile function_method_void: exp '(' ')' const_or_volatile { write_exp_elt_opcode (pstate, TYPE_INSTANCE); /* See above. */ - write_exp_elt_longcst (pstate, - follow_type_instance_flags ()); + write_exp_elt_longcst + (pstate, + cpstate->type_stack.follow_type_instance_flags ()); write_exp_elt_longcst (pstate, 0); write_exp_elt_longcst (pstate, 0); write_exp_elt_opcode (pstate, TYPE_INSTANCE); @@ -645,7 +654,7 @@ exp : function_method_void_or_typelist COLONCOLON name ; rcurly : '}' - { $$ = end_arglist () - 1; } + { $$ = pstate->end_arglist () - 1; } ; exp : lcurly arglist rcurly %prec ARROW { write_exp_elt_opcode (pstate, OP_ARRAY); @@ -816,7 +825,6 @@ exp : SIZEOF '(' type ')' %prec UNARY write_exp_elt_opcode (pstate, OP_LONG); write_exp_elt_type (pstate, lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "int")); type = check_typedef (type); @@ -952,7 +960,7 @@ block : BLOCKNAME $$ = SYMBOL_BLOCK_VALUE ($1.sym.symbol); else error (_("No file or function \"%s\"."), - copy_name ($1.stoken)); + copy_name ($1.stoken).c_str ()); } | FILENAME { @@ -961,13 +969,15 @@ block : BLOCKNAME ; block : block COLONCOLON name - { struct symbol *tem - = lookup_symbol (copy_name ($3), $1, + { + std::string copy = copy_name ($3); + struct symbol *tem + = lookup_symbol (copy.c_str (), $1, VAR_DOMAIN, NULL).symbol; if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) error (_("No function \"%s\" in specified context."), - copy_name ($3)); + copy.c_str ()); $$ = SYMBOL_BLOCK_VALUE (tem); } ; @@ -978,7 +988,7 @@ variable: name_not_typename ENTRY || !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); @@ -987,16 +997,17 @@ variable: name_not_typename ENTRY ; variable: block COLONCOLON name - { struct block_symbol sym - = lookup_symbol (copy_name ($3), $1, + { + std::string copy = copy_name ($3); + struct block_symbol sym + = lookup_symbol (copy.c_str (), $1, VAR_DOMAIN, NULL); if (sym.symbol == 0) error (_("No symbol \"%s\" in specified context."), - copy_name ($3)); + copy.c_str ()); if (symbol_read_needs_frame (sym.symbol)) - - innermost_block.update (sym); + pstate->block_tracker->update (sym); write_exp_elt_opcode (pstate, OP_VAR_VALUE); write_exp_elt_block (pstate, sym.block); @@ -1043,22 +1054,23 @@ qualified_name: TYPENAME COLONCOLON name } | TYPENAME COLONCOLON name COLONCOLON name { - char *copy = copy_name ($3); + std::string copy = copy_name ($3); error (_("No type \"%s\" within class " "or namespace \"%s\"."), - copy, TYPE_SAFE_NAME ($1.type)); + copy.c_str (), TYPE_SAFE_NAME ($1.type)); } ; variable: qualified_name | COLONCOLON name_not_typename { - char *name = copy_name ($2.stoken); + std::string name = copy_name ($2.stoken); struct symbol *sym; struct bound_minimal_symbol msymbol; sym - = lookup_symbol (name, (const struct block *) NULL, + = lookup_symbol (name.c_str (), + (const struct block *) NULL, VAR_DOMAIN, NULL).symbol; if (sym) { @@ -1069,13 +1081,14 @@ variable: qualified_name break; } - msymbol = lookup_bound_minimal_symbol (name); + msymbol = lookup_bound_minimal_symbol (name.c_str ()); if (msymbol.minsym != NULL) 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."), name); + error (_("No symbol \"%s\" in current context."), + name.c_str ()); } ; @@ -1085,7 +1098,7 @@ variable: name_not_typename if (sym.symbol) { if (symbol_read_needs_frame (sym.symbol)) - innermost_block.update (sym); + pstate->block_tracker->update (sym); /* If we found a function, see if it's an ifunc resolver that has the same @@ -1109,7 +1122,7 @@ variable: name_not_typename /* C++: it hangs off of `this'. Must not inadvertently convert from a method call to data ref. */ - innermost_block.update (sym); + pstate->block_tracker->update (sym); write_exp_elt_opcode (pstate, OP_THIS); write_exp_elt_opcode (pstate, OP_THIS); write_exp_elt_opcode (pstate, STRUCTOP_PTR); @@ -1118,17 +1131,17 @@ variable: name_not_typename } else { - char *arg = copy_name ($1.stoken); + std::string arg = copy_name ($1.stoken); bound_minimal_symbol msymbol - = lookup_bound_minimal_symbol (arg); + = lookup_bound_minimal_symbol (arg.c_str ()); if (msymbol.minsym == NULL) { 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 ()); } /* This minsym might be an alias for @@ -1157,52 +1170,62 @@ variable: name_not_typename } ; -space_identifier : '@' NAME - { insert_type_address_space (pstate, copy_name ($2.stoken)); } - ; - const_or_volatile: const_or_volatile_noopt | ; -cv_with_space_id : const_or_volatile space_identifier const_or_volatile +single_qualifier: + CONST_KEYWORD + { cpstate->type_stack.insert (tp_const); } + | VOLATILE_KEYWORD + { cpstate->type_stack.insert (tp_volatile); } + | ATOMIC + { cpstate->type_stack.insert (tp_atomic); } + | RESTRICT + { cpstate->type_stack.insert (tp_restrict); } + | '@' NAME + { + cpstate->type_stack.insert (pstate, + copy_name ($2.stoken).c_str ()); + } ; -const_or_volatile_or_space_identifier_noopt: cv_with_space_id - | const_or_volatile_noopt +qualifier_seq_noopt: + single_qualifier + | qualifier_seq single_qualifier ; -const_or_volatile_or_space_identifier: - const_or_volatile_or_space_identifier_noopt +qualifier_seq: + qualifier_seq_noopt | ; ptr_operator: ptr_operator '*' - { insert_type (tp_pointer); } - const_or_volatile_or_space_identifier + { cpstate->type_stack.insert (tp_pointer); } + qualifier_seq | '*' - { insert_type (tp_pointer); } - const_or_volatile_or_space_identifier + { cpstate->type_stack.insert (tp_pointer); } + qualifier_seq | '&' - { insert_type (tp_reference); } + { cpstate->type_stack.insert (tp_reference); } | '&' ptr_operator - { insert_type (tp_reference); } + { cpstate->type_stack.insert (tp_reference); } | ANDAND - { insert_type (tp_rvalue_reference); } + { cpstate->type_stack.insert (tp_rvalue_reference); } | ANDAND ptr_operator - { insert_type (tp_rvalue_reference); } + { cpstate->type_stack.insert (tp_rvalue_reference); } ; ptr_operator_ts: ptr_operator { - $$ = get_type_stack (); + $$ = cpstate->type_stack.create (); cpstate->type_stacks.emplace_back ($$); } ; abs_decl: ptr_operator_ts direct_abs_decl - { $$ = append_type_stack ($2, $1); } + { $$ = $2->append ($1); } | ptr_operator_ts | direct_abs_decl ; @@ -1211,31 +1234,31 @@ direct_abs_decl: '(' abs_decl ')' { $$ = $2; } | direct_abs_decl array_mod { - push_type_stack ($1); - push_type_int ($2); - push_type (tp_array); - $$ = get_type_stack (); + cpstate->type_stack.push ($1); + cpstate->type_stack.push ($2); + cpstate->type_stack.push (tp_array); + $$ = cpstate->type_stack.create (); cpstate->type_stacks.emplace_back ($$); } | array_mod { - push_type_int ($1); - push_type (tp_array); - $$ = get_type_stack (); + cpstate->type_stack.push ($1); + cpstate->type_stack.push (tp_array); + $$ = cpstate->type_stack.create (); cpstate->type_stacks.emplace_back ($$); } | direct_abs_decl func_mod { - push_type_stack ($1); - push_typelist ($2); - $$ = get_type_stack (); + cpstate->type_stack.push ($1); + cpstate->type_stack.push ($2); + $$ = cpstate->type_stack.create (); cpstate->type_stacks.emplace_back ($$); } | func_mod { - push_typelist ($1); - $$ = get_type_stack (); + cpstate->type_stack.push ($1); + $$ = cpstate->type_stack.create (); cpstate->type_stacks.emplace_back ($$); } ; @@ -1285,210 +1308,182 @@ typebase { $$ = $1.type; } | INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "int"); } | LONG { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long"); } | SHORT { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "short"); } | LONG INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long"); } | LONG SIGNED_KEYWORD INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long"); } | LONG SIGNED_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long"); } | SIGNED_KEYWORD LONG INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long"); } | UNSIGNED LONG INT_KEYWORD { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "long"); } | LONG UNSIGNED INT_KEYWORD { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "long"); } | LONG UNSIGNED { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "long"); } | LONG LONG { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | LONG LONG INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | LONG LONG SIGNED_KEYWORD INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | LONG LONG SIGNED_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | SIGNED_KEYWORD LONG LONG { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | SIGNED_KEYWORD LONG LONG INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | UNSIGNED LONG LONG { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | UNSIGNED LONG LONG INT_KEYWORD { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | LONG LONG UNSIGNED { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | LONG LONG UNSIGNED INT_KEYWORD { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "long long"); } | SHORT INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "short"); } | SHORT SIGNED_KEYWORD INT_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "short"); } | SHORT SIGNED_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "short"); } | UNSIGNED SHORT INT_KEYWORD { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "short"); } | SHORT UNSIGNED { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "short"); } | SHORT UNSIGNED INT_KEYWORD { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "short"); } | DOUBLE_KEYWORD { $$ = lookup_typename (pstate->language (), - pstate->gdbarch (), "double", NULL, 0); } | LONG DOUBLE_KEYWORD { $$ = lookup_typename (pstate->language (), - pstate->gdbarch (), "long double", NULL, 0); } | STRUCT name { $$ - = lookup_struct (copy_name ($2), + = lookup_struct (copy_name ($2).c_str (), pstate->expression_context_block); } | STRUCT COMPLETE { - mark_completion_tag (TYPE_CODE_STRUCT, "", 0); + pstate->mark_completion_tag (TYPE_CODE_STRUCT, + "", 0); $$ = NULL; } | STRUCT name COMPLETE { - mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr, - $2.length); + pstate->mark_completion_tag (TYPE_CODE_STRUCT, + $2.ptr, $2.length); $$ = NULL; } | CLASS name { $$ = lookup_struct - (copy_name ($2), pstate->expression_context_block); + (copy_name ($2).c_str (), + pstate->expression_context_block); } | CLASS COMPLETE { - mark_completion_tag (TYPE_CODE_STRUCT, "", 0); + pstate->mark_completion_tag (TYPE_CODE_STRUCT, + "", 0); $$ = NULL; } | CLASS name COMPLETE { - mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr, - $2.length); + pstate->mark_completion_tag (TYPE_CODE_STRUCT, + $2.ptr, $2.length); $$ = NULL; } | UNION name { $$ - = lookup_union (copy_name ($2), + = lookup_union (copy_name ($2).c_str (), pstate->expression_context_block); } | UNION COMPLETE { - mark_completion_tag (TYPE_CODE_UNION, "", 0); + pstate->mark_completion_tag (TYPE_CODE_UNION, + "", 0); $$ = NULL; } | UNION name COMPLETE { - mark_completion_tag (TYPE_CODE_UNION, $2.ptr, - $2.length); + pstate->mark_completion_tag (TYPE_CODE_UNION, + $2.ptr, $2.length); $$ = NULL; } | ENUM name - { $$ = lookup_enum (copy_name ($2), + { $$ = lookup_enum (copy_name ($2).c_str (), pstate->expression_context_block); } | ENUM COMPLETE { - mark_completion_tag (TYPE_CODE_ENUM, "", 0); + pstate->mark_completion_tag (TYPE_CODE_ENUM, "", 0); $$ = NULL; } | ENUM name COMPLETE { - mark_completion_tag (TYPE_CODE_ENUM, $2.ptr, - $2.length); + pstate->mark_completion_tag (TYPE_CODE_ENUM, $2.ptr, + $2.length); $$ = NULL; } | UNSIGNED type_name { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), TYPE_NAME($2.type)); } | UNSIGNED { $$ = lookup_unsigned_typename (pstate->language (), - pstate->gdbarch (), "int"); } | SIGNED_KEYWORD type_name { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), TYPE_NAME($2.type)); } | SIGNED_KEYWORD { $$ = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "int"); } /* It appears that this rule for templates is never reduced; template recognition happens by lookahead in the token processing code in yylex. */ | TEMPLATE name '<' type '>' { $$ = lookup_template_type - (copy_name($2), $4, + (copy_name($2).c_str (), $4, pstate->expression_context_block); } - | const_or_volatile_or_space_identifier_noopt typebase - { $$ = follow_types ($2); } - | typebase const_or_volatile_or_space_identifier_noopt - { $$ = follow_types ($1); } + | qualifier_seq_noopt typebase + { $$ = cpstate->type_stack.follow_types ($2); } + | typebase qualifier_seq_noopt + { $$ = cpstate->type_stack.follow_types ($1); } ; type_name: TYPENAME @@ -1497,7 +1492,6 @@ type_name: TYPENAME $$.stoken.ptr = "int"; $$.stoken.length = 3; $$.type = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "int"); } | LONG @@ -1505,7 +1499,6 @@ type_name: TYPENAME $$.stoken.ptr = "long"; $$.stoken.length = 4; $$.type = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "long"); } | SHORT @@ -1513,7 +1506,6 @@ type_name: TYPENAME $$.stoken.ptr = "short"; $$.stoken.length = 5; $$.type = lookup_signed_typename (pstate->language (), - pstate->gdbarch (), "short"); } ; @@ -1549,13 +1541,13 @@ nonempty_typelist ptype : typebase | ptype abs_decl { - push_type_stack ($2); - $$ = follow_types ($1); + cpstate->type_stack.push ($2); + $$ = cpstate->type_stack.follow_types ($1); } ; conversion_type_id: typebase conversion_declarator - { $$ = follow_types ($1); } + { $$ = cpstate->type_stack.follow_types ($1); } ; conversion_declarator: /* Nothing. */ @@ -1567,13 +1559,13 @@ const_and_volatile: CONST_KEYWORD VOLATILE_KEYWORD ; const_or_volatile_noopt: const_and_volatile - { insert_type (tp_const); - insert_type (tp_volatile); + { cpstate->type_stack.insert (tp_const); + cpstate->type_stack.insert (tp_volatile); } | CONST_KEYWORD - { insert_type (tp_const); } + { cpstate->type_stack.insert (tp_const); } | VOLATILE_KEYWORD - { insert_type (tp_volatile); } + { cpstate->type_stack.insert (tp_volatile); } ; oper: OPERATOR NEW @@ -2361,11 +2353,15 @@ enum token_flag FLAG_CXX = 1, + /* If this bit is set, the token is C-only. */ + + FLAG_C = 2, + /* If this bit is set, the token is conditional: if there is a symbol of the same name, then the token is a symbol; otherwise, the token is a keyword. */ - FLAG_SHADOW = 2 + FLAG_SHADOW = 4 }; DEF_ENUM_FLAGS_TYPE (enum token_flag, token_flags); @@ -2432,6 +2428,10 @@ static const struct token ident_tokens[] = {"union", UNION, OP_NULL, 0}, {"short", SHORT, OP_NULL, 0}, {"const", CONST_KEYWORD, OP_NULL, 0}, + {"restrict", RESTRICT, OP_NULL, FLAG_C | FLAG_SHADOW}, + {"__restrict__", RESTRICT, OP_NULL, 0}, + {"__restrict", RESTRICT, OP_NULL, 0}, + {"_Atomic", ATOMIC, OP_NULL, 0}, {"enum", ENUM, OP_NULL, 0}, {"long", LONG, OP_NULL, 0}, {"true", TRUEKEYWORD, OP_NULL, FLAG_CXX}, @@ -2470,21 +2470,20 @@ static const struct token ident_tokens[] = static void scan_macro_expansion (char *expansion) { - char *copy; + const char *copy; /* We'd better not be trying to push the stack twice. */ gdb_assert (! cpstate->macro_original_text); /* Copy to the obstack, and then free the intermediate expansion. */ - copy = (char *) obstack_copy0 (&cpstate->expansion_obstack, expansion, - strlen (expansion)); + copy = obstack_strdup (&cpstate->expansion_obstack, expansion); xfree (expansion); /* Save the old lexptr value, so we can return to it when we're done parsing the expanded text. */ - cpstate->macro_original_text = lexptr; - lexptr = copy; + cpstate->macro_original_text = pstate->lexptr; + pstate->lexptr = copy; } static int @@ -2500,7 +2499,7 @@ finished_macro_expansion (void) gdb_assert (cpstate->macro_original_text); /* Pop back to the original text. */ - lexptr = cpstate->macro_original_text; + pstate->lexptr = cpstate->macro_original_text; cpstate->macro_original_text = 0; } @@ -2540,7 +2539,6 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) unsigned int i; const char *tokstart; bool saw_structop = last_was_structop; - char *copy; last_was_structop = false; *is_quoted_name = false; @@ -2550,7 +2548,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) /* Check if this is a macro invocation that we need to expand. */ if (! scanning_macro_expansion ()) { - char *expanded = macro_expand_next (&lexptr, + char *expanded = macro_expand_next (&pstate->lexptr, standard_macro_lookup, expression_macro_scope); @@ -2558,9 +2556,9 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) scan_macro_expansion (expanded); } - prev_lexptr = lexptr; + pstate->prev_lexptr = pstate->lexptr; - tokstart = lexptr; + tokstart = pstate->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) @@ -2568,8 +2566,9 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if ((tokentab3[i].flags & FLAG_CXX) != 0 && par_state->language ()->la_language != language_cplus) break; + gdb_assert ((tokentab3[i].flags & FLAG_C) == 0); - lexptr += 3; + pstate->lexptr += 3; yylval.opcode = tokentab3[i].opcode; return tokentab3[i].token; } @@ -2581,8 +2580,9 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if ((tokentab2[i].flags & FLAG_CXX) != 0 && par_state->language ()->la_language != language_cplus) break; + gdb_assert ((tokentab3[i].flags & FLAG_C) == 0); - lexptr += 2; + pstate->lexptr += 2; yylval.opcode = tokentab2[i].opcode; if (tokentab2[i].token == ARROW) last_was_structop = 1; @@ -2608,7 +2608,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) saw_name_at_eof = 0; return COMPLETE; } - else if (parse_completion && saw_structop) + else if (par_state->parse_completion && saw_structop) return COMPLETE; else return 0; @@ -2616,13 +2616,13 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) case ' ': case '\t': case '\n': - lexptr++; + pstate->lexptr++; goto retry; case '[': case '(': paren_depth++; - lexptr++; + pstate->lexptr++; if (par_state->language ()->la_language == language_objc && c == '[') return OBJC_LBRAC; @@ -2633,7 +2633,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if (paren_depth == 0) return 0; paren_depth--; - lexptr++; + pstate->lexptr++; return c; case ',': @@ -2641,12 +2641,12 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) && paren_depth == 0 && ! scanning_macro_expansion ()) return 0; - lexptr++; + pstate->lexptr++; return c; case '.': /* Might be a floating point number. */ - if (lexptr[1] < '0' || lexptr[1] > '9') + if (pstate->lexptr[1] < '0' || pstate->lexptr[1] > '9') { last_was_structop = true; goto symbol; /* Nope, must be a symbol. */ @@ -2713,7 +2713,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) err_copy[p - tokstart] = 0; error (_("Invalid number \"%s\"."), err_copy); } - lexptr = p; + pstate->lexptr = p; return toktype; } @@ -2728,7 +2728,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if (strncmp (p, "selector", len) == 0 && (p[len] == '\0' || ISSPACE (p[len]))) { - lexptr = p + len; + pstate->lexptr = p + len; return SELECTOR; } else if (*p == '"') @@ -2741,7 +2741,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if (strncmp (p, "entry", len) == 0 && !c_ident_is_alnum (p[len]) && p[len] != '_') { - lexptr = &p[len]; + pstate->lexptr = &p[len]; return ENTRY; } } @@ -2764,7 +2764,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) case '{': case '}': symbol: - lexptr++; + pstate->lexptr++; return c; case 'L': @@ -2779,8 +2779,8 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) parse_string: { int host_len; - int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval, - &host_len); + int result = parse_string_or_char (tokstart, &pstate->lexptr, + &yylval.tsval, &host_len); if (result == CHAR) { if (host_len == 0) @@ -2788,7 +2788,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) else if (host_len > 2 && c == '\'') { ++tokstart; - namelen = lexptr - tokstart - 1; + namelen = pstate->lexptr - tokstart - 1; *is_quoted_name = true; goto tryname; @@ -2860,7 +2860,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) return 0; } - lexptr += namelen; + pstate->lexptr += namelen; tryname: @@ -2868,19 +2868,23 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) 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].oper) == 0) + if (copy == ident_tokens[i].oper) { if ((ident_tokens[i].flags & FLAG_CXX) != 0 && par_state->language ()->la_language != language_cplus) break; + if ((ident_tokens[i].flags & FLAG_C) != 0 + && par_state->language ()->la_language != language_c + && par_state->language ()->la_language != language_objc) + break; if ((ident_tokens[i].flags & FLAG_SHADOW) != 0) { struct field_of_this_result is_a_field_of_this; - if (lookup_symbol (copy, + if (lookup_symbol (copy.c_str (), pstate->expression_context_block, VAR_DOMAIN, (par_state->language ()->la_language @@ -2902,7 +2906,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if (*tokstart == '$') return DOLLAR_VARIABLE; - if (parse_completion && *lexptr == '\0') + if (pstate->parse_completion && *pstate->lexptr == '\0') saw_name_at_eof = 1; yylval.ssym.stoken = yylval.sval; @@ -2942,16 +2946,15 @@ classify_name (struct parser_state *par_state, const struct block *block, bool is_quoted_name, bool is_after_structop) { struct block_symbol bsym; - char *copy; struct field_of_this_result is_a_field_of_this; - copy = copy_name (yylval.sval); + std::string copy = copy_name (yylval.sval); /* Initialize this in case we *don't* use it in this call; that way we can refer to it unconditionally below. */ memset (&is_a_field_of_this, 0, sizeof (is_a_field_of_this)); - bsym = lookup_symbol (copy, block, VAR_DOMAIN, + bsym = lookup_symbol (copy.c_str (), block, VAR_DOMAIN, par_state->language ()->la_name_of_this ? &is_a_field_of_this : NULL); @@ -2974,7 +2977,7 @@ classify_name (struct parser_state *par_state, const struct block *block, { struct field_of_this_result inner_is_a_field_of_this; - bsym = lookup_symbol (copy, block, STRUCT_DOMAIN, + bsym = lookup_symbol (copy.c_str (), block, STRUCT_DOMAIN, &inner_is_a_field_of_this); if (bsym.symbol != NULL) { @@ -2994,7 +2997,7 @@ classify_name (struct parser_state *par_state, const struct block *block, /* See if it's a file name. */ struct symtab *symtab; - symtab = lookup_symtab (copy); + symtab = lookup_symtab (copy.c_str ()); if (symtab) { yylval.bval = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), @@ -3013,13 +3016,14 @@ classify_name (struct parser_state *par_state, const struct block *block, /* See if it's an ObjC classname. */ if (par_state->language ()->la_language == language_objc && !bsym.symbol) { - CORE_ADDR Class = lookup_objc_class (par_state->gdbarch (), copy); + CORE_ADDR Class = lookup_objc_class (par_state->gdbarch (), + copy.c_str ()); if (Class) { struct symbol *sym; yylval.theclass.theclass = Class; - sym = lookup_struct_typedef (copy, + sym = lookup_struct_typedef (copy.c_str (), par_state->expression_context_block, 1); if (sym) yylval.theclass.type = SYMBOL_TYPE (sym); @@ -3035,7 +3039,7 @@ 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, + int hextype = parse_number (par_state, copy.c_str (), yylval.sval.length, 0, &newlval); if (hextype == INT) @@ -3053,7 +3057,7 @@ classify_name (struct parser_state *par_state, const struct block *block, if (bsym.symbol == NULL && par_state->language ()->la_language == language_cplus && is_a_field_of_this.type == NULL - && lookup_minimal_symbol (copy, NULL, NULL).minsym == NULL) + && lookup_minimal_symbol (copy.c_str (), NULL, NULL).minsym == NULL) return UNKNOWN_CPP_NAME; return NAME; @@ -3068,7 +3072,6 @@ classify_inner_name (struct parser_state *par_state, const struct block *block, struct type *context) { struct type *type; - char *copy; if (context == NULL) return classify_name (par_state, block, false, false); @@ -3077,16 +3080,18 @@ classify_inner_name (struct parser_state *par_state, if (!type_aggregate_p (type)) return ERROR; - copy = copy_name (yylval.ssym.stoken); + std::string copy = copy_name (yylval.ssym.stoken); /* N.B. We assume the symbol can only be in VAR_DOMAIN. */ - yylval.ssym.sym = cp_lookup_nested_symbol (type, copy, block, VAR_DOMAIN); + yylval.ssym.sym = cp_lookup_nested_symbol (type, copy.c_str (), block, + VAR_DOMAIN); /* If no symbol was found, search for a matching base class named COPY. This will allow users to enter qualified names of class members relative to the `this' pointer. */ if (yylval.ssym.sym.symbol == NULL) { - struct type *base_type = cp_find_type_baseclass_by_name (type, copy); + struct type *base_type = cp_find_type_baseclass_by_name (type, + copy.c_str ()); if (base_type != NULL) { @@ -3105,7 +3110,8 @@ classify_inner_name (struct parser_state *par_state, named COPY when we really wanted a base class of the same name. Double-check this case by looking for a base class. */ { - struct type *base_type = cp_find_type_baseclass_by_name (type, copy); + struct type *base_type + = cp_find_type_baseclass_by_name (type, copy.c_str ()); if (base_type != NULL) { @@ -3271,9 +3277,9 @@ yylex (void) if (checkpoint > 0) { current.value.sval.ptr - = (const char *) obstack_copy0 (&cpstate->expansion_obstack, - current.value.sval.ptr, - current.value.sval.length); + = obstack_strndup (&cpstate->expansion_obstack, + current.value.sval.ptr, + current.value.sval.length); token_fifo[0] = current; if (checkpoint > 1) @@ -3357,13 +3363,13 @@ c_print_token (FILE *file, int type, YYSTYPE value) case NSSTRING: case DOLLAR_VARIABLE: - parser_fprintf (file, "sval<%s>", copy_name (value.sval)); + parser_fprintf (file, "sval<%s>", copy_name (value.sval).c_str ()); break; case TYPENAME: parser_fprintf (file, "tsym", TYPE_SAFE_NAME (value.tsym.type), - copy_name (value.tsym.stoken)); + copy_name (value.tsym.stoken).c_str ()); break; case NAME: @@ -3371,9 +3377,9 @@ c_print_token (FILE *file, int type, YYSTYPE value) case NAME_OR_INT: case BLOCKNAME: parser_fprintf (file, "ssym", - copy_name (value.ssym.stoken), + copy_name (value.ssym.stoken).c_str (), (value.ssym.sym.symbol == NULL - ? "(null)" : SYMBOL_PRINT_NAME (value.ssym.sym.symbol)), + ? "(null)" : value.ssym.sym.symbol->print_name ()), value.ssym.is_a_field_of_this); break; @@ -3388,8 +3394,8 @@ c_print_token (FILE *file, int type, YYSTYPE value) 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, lexptr); + error (_("A %s in expression, near `%s'."), msg, pstate->lexptr); }