]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Convert c-exp.y to use operations
authorTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:27:57 +0000 (07:27 -0700)
committerTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:28:38 +0000 (07:28 -0700)
This converts the C parser to generate operations rather than
exp_elements.

One test needed a tweak in order to handle the different debugging
output.

gdb/ChangeLog
2021-03-08  Tom Tromey  <tom@tromey.com>

* objc-lang.c (end_msglist): Create operations.
* c-exp.y: Change parser to create operations.
(write_destructor_name): Remove.
(c_parse): Update.

gdb/testsuite/ChangeLog
2021-03-08  Tom Tromey  <tom@tromey.com>

* gdb.base/debug-expr.exp: Update expected dump output.

gdb/ChangeLog
gdb/c-exp.y
gdb/objc-lang.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/debug-expr.exp

index 765dd9c0eed25de74655d498f1c7edf23bee2e44..2e271e03628515836b8b589d27612855fe1692ad 100644 (file)
@@ -1,3 +1,10 @@
+2021-03-08  Tom Tromey  <tom@tromey.com>
+
+       * objc-lang.c (end_msglist): Create operations.
+       * c-exp.y: Change parser to create operations.
+       (write_destructor_name): Remove.
+       (c_parse): Update.
+
 2021-03-08  Tom Tromey  <tom@tromey.com>
 
        * rust-exp.y: Create operations.
index 13b06f39bbf02f3f1fa341f17f68d98540d151e2..ad26a7cd2c5ce92a1b8243cdecaee3f69ff5e8b6 100644 (file)
@@ -55,6 +55,7 @@
 #include "cp-abi.h"
 #include "type-stack.h"
 #include "target-float.h"
+#include "c-exp.h"
 
 #define parse_type(ps) builtin_type (ps->gdbarch ())
 
@@ -123,6 +124,7 @@ static void yyerror (const char *);
 
 static int type_aggregate_p (struct type *);
 
+using namespace expr;
 %}
 
 /* Although the yacc "value" of an expression is not used,
@@ -164,8 +166,6 @@ static int parse_number (struct parser_state *par_state,
 static struct stoken operator_stoken (const char *);
 static struct stoken typename_stoken (const char *);
 static void check_parameter_typelist (std::vector<struct type *> *);
-static void write_destructor_name (struct parser_state *par_state,
-                                  struct stoken);
 
 #ifdef YYBISON
 static void c_print_token (FILE *file, int type, YYSTYPE value);
@@ -282,190 +282,213 @@ 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<type_operation> ($1);
+                       }
        |       TYPEOF '(' exp ')'
                        {
-                         write_exp_elt_opcode (pstate, OP_TYPEOF);
+                         pstate->wrap<typeof_operation> ();
                        }
        |       TYPEOF '(' type ')'
                        {
-                         write_exp_elt_opcode (pstate, OP_TYPE);
-                         write_exp_elt_type (pstate, $3);
-                         write_exp_elt_opcode (pstate, OP_TYPE);
+                         pstate->push_new<type_operation> ($3);
                        }
        |       DECLTYPE '(' exp ')'
                        {
-                         write_exp_elt_opcode (pstate, OP_DECLTYPE);
+                         pstate->wrap<decltype_operation> ();
                        }
        ;
 
 /* Expressions, including the comma operator.  */
 exp1   :       exp
        |       exp1 ',' exp
-                       { write_exp_elt_opcode (pstate, BINOP_COMMA); }
+                       { pstate->wrap2<comma_operation> (); }
        ;
 
 /* Expressions, not including the comma operator.  */
 exp    :       '*' exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_IND); }
+                       { pstate->wrap<unop_ind_operation> (); }
        ;
 
 exp    :       '&' exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_ADDR); }
+                       { pstate->wrap<unop_addr_operation> (); }
        ;
 
 exp    :       '-' exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_NEG); }
+                       { pstate->wrap<unary_neg_operation> (); }
        ;
 
 exp    :       '+' exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_PLUS); }
+                       { pstate->wrap<unary_plus_operation> (); }
        ;
 
 exp    :       '!' exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap<opencl_not_operation> ();
+                         else
+                           pstate->wrap<unary_logical_not_operation> ();
+                       }
        ;
 
 exp    :       '~' exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_COMPLEMENT); }
+                       { pstate->wrap<unary_complement_operation> (); }
        ;
 
 exp    :       INCREMENT exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_PREINCREMENT); }
+                       { pstate->wrap<preinc_operation> (); }
        ;
 
 exp    :       DECREMENT exp    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_PREDECREMENT); }
+                       { pstate->wrap<predec_operation> (); }
        ;
 
 exp    :       exp INCREMENT    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_POSTINCREMENT); }
+                       { pstate->wrap<postinc_operation> (); }
        ;
 
 exp    :       exp DECREMENT    %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_POSTDECREMENT); }
+                       { pstate->wrap<postdec_operation> (); }
        ;
 
 exp    :       TYPEID '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (pstate, OP_TYPEID); }
+                       { pstate->wrap<typeid_operation> (); }
        ;
 
 exp    :       TYPEID '(' type_exp ')' %prec UNARY
-                       { write_exp_elt_opcode (pstate, OP_TYPEID); }
+                       { pstate->wrap<typeid_operation> (); }
        ;
 
 exp    :       SIZEOF exp       %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_SIZEOF); }
+                       { pstate->wrap<unop_sizeof_operation> (); }
        ;
 
 exp    :       ALIGNOF '(' type_exp ')'        %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_ALIGNOF); }
+                       { pstate->wrap<unop_alignof_operation> (); }
        ;
 
 exp    :       exp ARROW field_name
-                       { write_exp_elt_opcode (pstate, STRUCTOP_PTR);
-                         write_exp_string (pstate, $3);
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
+                       {
+                         pstate->push_new<structop_ptr_operation>
+                           (pstate->pop (), copy_name ($3));
+                       }
        ;
 
 exp    :       exp ARROW field_name COMPLETE
-                       { pstate->mark_struct_expression ();
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR);
-                         write_exp_string (pstate, $3);
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
+                       {
+                         structop_base_operation *op
+                           = new structop_ptr_operation (pstate->pop (),
+                                                         copy_name ($3));
+                         pstate->mark_struct_expression (op);
+                         pstate->push (operation_up (op));
+                       }
        ;
 
 exp    :       exp ARROW COMPLETE
-                       { struct stoken s;
-                         pstate->mark_struct_expression ();
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR);
-                         s.ptr = "";
-                         s.length = 0;
-                         write_exp_string (pstate, s);
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
+                       {
+                         structop_base_operation *op
+                           = new structop_ptr_operation (pstate->pop (), "");
+                         pstate->mark_struct_expression (op);
+                         pstate->push (operation_up (op));
+                       }
        ;
 
 exp    :       exp ARROW '~' name
-                       { write_exp_elt_opcode (pstate, STRUCTOP_PTR);
-                         write_destructor_name (pstate, $4);
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
+                       {
+                         pstate->push_new<structop_ptr_operation>
+                           (pstate->pop (), "~" + copy_name ($4));
+                       }
        ;
 
 exp    :       exp ARROW '~' name COMPLETE
-                       { pstate->mark_struct_expression ();
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR);
-                         write_destructor_name (pstate, $4);
-                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
+                       {
+                         structop_base_operation *op
+                           = new structop_ptr_operation (pstate->pop (),
+                                                         "~" + copy_name ($4));
+                         pstate->mark_struct_expression (op);
+                         pstate->push (operation_up (op));
+                       }
        ;
 
 exp    :       exp ARROW qualified_name
                        { /* exp->type::name becomes exp->*(&type::name) */
                          /* Note: this doesn't work if name is a
                             static member!  FIXME */
-                         write_exp_elt_opcode (pstate, UNOP_ADDR);
-                         write_exp_elt_opcode (pstate, STRUCTOP_MPTR); }
+                         pstate->wrap<unop_addr_operation> ();
+                         pstate->wrap2<structop_mptr_operation> (); }
        ;
 
 exp    :       exp ARROW_STAR exp
-                       { write_exp_elt_opcode (pstate, STRUCTOP_MPTR); }
+                       { pstate->wrap2<structop_mptr_operation> (); }
        ;
 
 exp    :       exp '.' field_name
-                       { write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
-                         write_exp_string (pstate, $3);
-                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->push_new<opencl_structop_operation>
+                             (pstate->pop (), copy_name ($3));
+                         else
+                           pstate->push_new<structop_operation>
+                             (pstate->pop (), copy_name ($3));
+                       }
        ;
 
 exp    :       exp '.' field_name COMPLETE
-                       { pstate->mark_struct_expression ();
-                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
-                         write_exp_string (pstate, $3);
-                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
+                       {
+                         structop_base_operation *op
+                           = new structop_operation (pstate->pop (),
+                                                     copy_name ($3));
+                         pstate->mark_struct_expression (op);
+                         pstate->push (operation_up (op));
+                       }
        ;
 
 exp    :       exp '.' COMPLETE
-                       { struct stoken s;
-                         pstate->mark_struct_expression ();
-                         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 '.' '~' name
-                       { write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
-                         write_destructor_name (pstate, $4);
-                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
+                       {
+                         pstate->push_new<structop_operation>
+                           (pstate->pop (), "~" + copy_name ($4));
+                       }
        ;
 
 exp    :       exp '.' '~' name COMPLETE
-                       { pstate->mark_struct_expression ();
-                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
-                         write_destructor_name (pstate, $4);
-                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
+                       {
+                         structop_base_operation *op
+                           = new structop_operation (pstate->pop (),
+                                                     "~" + copy_name ($4));
+                         pstate->mark_struct_expression (op);
+                         pstate->push (operation_up (op));
+                       }
        ;
 
 exp    :       exp '.' qualified_name
                        { /* exp.type::name becomes exp.*(&type::name) */
                          /* Note: this doesn't work if name is a
                             static member!  FIXME */
-                         write_exp_elt_opcode (pstate, UNOP_ADDR);
-                         write_exp_elt_opcode (pstate, STRUCTOP_MEMBER); }
+                         pstate->wrap<unop_addr_operation> ();
+                         pstate->wrap2<structop_member_operation> (); }
        ;
 
 exp    :       exp DOT_STAR exp
-                       { write_exp_elt_opcode (pstate, STRUCTOP_MEMBER); }
+                       { pstate->wrap2<structop_member_operation> (); }
        ;
 
 exp    :       exp '[' exp1 ']'
-                       { write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); }
+                       { pstate->wrap2<subscript_operation> (); }
        ;
 
 exp    :       exp OBJC_LBRAC exp1 ']'
-                       { write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); }
+                       { pstate->wrap2<subscript_operation> (); }
        ;
 
 /*
@@ -483,43 +506,30 @@ exp       :       OBJC_LBRAC TYPENAME
                          if (theclass == 0)
                            error (_("%s is not an ObjC Class"),
                                   copy.c_str ());
-                         write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_type (pstate,
-                                             parse_type (pstate)->builtin_int);
-                         write_exp_elt_longcst (pstate, (LONGEST) theclass);
-                         write_exp_elt_opcode (pstate, OP_LONG);
+                         pstate->push_new<long_const_operation>
+                           (parse_type (pstate)->builtin_int,
+                            (LONGEST) theclass);
                          start_msglist();
                        }
                msglist ']'
-                       { write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
-                         end_msglist (pstate);
-                         write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
-                       }
+                       { end_msglist (pstate); }
        ;
 
 exp    :       OBJC_LBRAC CLASSNAME
                        {
-                         write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_type (pstate,
-                                           parse_type (pstate)->builtin_int);
-                         write_exp_elt_longcst (pstate, (LONGEST) $2.theclass);
-                         write_exp_elt_opcode (pstate, OP_LONG);
+                         pstate->push_new<long_const_operation>
+                           (parse_type (pstate)->builtin_int,
+                            (LONGEST) $2.theclass);
                          start_msglist();
                        }
                msglist ']'
-                       { write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
-                         end_msglist (pstate);
-                         write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
-                       }
+                       { end_msglist (pstate); }
        ;
 
 exp    :       OBJC_LBRAC exp
                        { start_msglist(); }
                msglist ']'
-                       { write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
-                         end_msglist (pstate);
-                         write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
-                       }
+                       { end_msglist (pstate); }
        ;
 
 msglist :      name
@@ -544,21 +554,22 @@ exp       :       exp '('
                           being accumulated by an outer function call.  */
                        { pstate->start_arglist (); }
                arglist ')'     %prec ARROW
-                       { write_exp_elt_opcode (pstate, OP_FUNCALL);
-                         write_exp_elt_longcst (pstate,
-                                                pstate->end_arglist ());
-                         write_exp_elt_opcode (pstate, OP_FUNCALL); }
+                       {
+                         std::vector<operation_up> args
+                           = pstate->pop_vector (pstate->end_arglist ());
+                         pstate->push_new<funcall_operation>
+                           (pstate->pop (), std::move (args));
+                       }
        ;
 
 /* This is here to disambiguate with the production for
    "func()::static_var" further below, which uses
    function_method_void.  */
 exp    :       exp '(' ')' %prec ARROW
-                       { pstate->start_arglist ();
-                         write_exp_elt_opcode (pstate, OP_FUNCALL);
-                         write_exp_elt_longcst (pstate,
-                                                pstate->end_arglist ());
-                         write_exp_elt_opcode (pstate, OP_FUNCALL); }
+                       {
+                         pstate->push_new<funcall_operation>
+                           (pstate->pop (), std::vector<operation_up> ());
+                       }
        ;
 
 
@@ -566,25 +577,18 @@ exp       :       UNKNOWN_CPP_NAME '('
                        {
                          /* This could potentially be a an argument defined
                             lookup function (Koenig).  */
-                         write_exp_elt_opcode (pstate, OP_ADL_FUNC);
-                         write_exp_elt_block
-                           (pstate, pstate->expression_context_block);
-                         write_exp_elt_sym (pstate,
-                                            NULL); /* Placeholder.  */
-                         write_exp_string (pstate, $1.stoken);
-                         write_exp_elt_opcode (pstate, OP_ADL_FUNC);
-
-                       /* This is to save the value of arglist_len
-                          being accumulated by an outer function call.  */
-
+                         /* This is to save the value of arglist_len
+                            being accumulated by an outer function call.  */
                          pstate->start_arglist ();
                        }
                arglist ')'     %prec ARROW
                        {
-                         write_exp_elt_opcode (pstate, OP_FUNCALL);
-                         write_exp_elt_longcst (pstate,
-                                                pstate->end_arglist ());
-                         write_exp_elt_opcode (pstate, OP_FUNCALL);
+                         std::vector<operation_up> args
+                           = pstate->pop_vector (pstate->end_arglist ());
+                         pstate->push_new<adl_func_operation>
+                           (copy_name ($1.stoken),
+                            pstate->expression_context_block,
+                            std::move (args));
                        }
        ;
 
@@ -606,33 +610,25 @@ arglist   :       arglist ',' exp   %prec ABOVE_COMMA
 function_method:       exp '(' parameter_typelist ')' const_or_volatile
                        {
                          std::vector<struct type *> *type_list = $3;
-                         LONGEST len = type_list->size ();
-
-                         write_exp_elt_opcode (pstate, TYPE_INSTANCE);
                          /* Save the const/volatile qualifiers as
                             recorded by the const_or_volatile
                             production's actions.  */
-                         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);
-                         write_exp_elt_longcst(pstate, len);
-                         write_exp_elt_opcode (pstate, TYPE_INSTANCE);
+                         type_instance_flags flags
+                           = (cpstate->type_stack
+                              .follow_type_instance_flags ());
+                         pstate->push_new<type_instance_operation>
+                           (flags, std::move (*type_list),
+                            pstate->pop ());
                        }
        ;
 
 function_method_void:      exp '(' ')' const_or_volatile
-                      { write_exp_elt_opcode (pstate, TYPE_INSTANCE);
-                        /* See above.  */
-                        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);
+                      {
+                         type_instance_flags flags
+                           = (cpstate->type_stack
+                              .follow_type_instance_flags ());
+                         pstate->push_new<type_instance_operation>
+                           (flags, std::vector<type *> (), pstate->pop ());
                       }
        ;
 
@@ -649,9 +645,8 @@ function_method_void_or_typelist: function_method
 
 exp     :       function_method_void_or_typelist COLONCOLON name
                        {
-                         write_exp_elt_opcode (pstate, OP_FUNC_STATIC_VAR);
-                         write_exp_string (pstate, $3);
-                         write_exp_elt_opcode (pstate, OP_FUNC_STATIC_VAR);
+                         pstate->push_new<func_static_var_operation>
+                           (pstate->pop (), copy_name ($3));
                        }
        ;
 
@@ -659,18 +654,26 @@ rcurly    :       '}'
                        { $$ = pstate->end_arglist () - 1; }
        ;
 exp    :       lcurly arglist rcurly   %prec ARROW
-                       { write_exp_elt_opcode (pstate, OP_ARRAY);
-                         write_exp_elt_longcst (pstate, (LONGEST) 0);
-                         write_exp_elt_longcst (pstate, (LONGEST) $3);
-                         write_exp_elt_opcode (pstate, OP_ARRAY); }
+                       {
+                         std::vector<operation_up> args
+                           = pstate->pop_vector ($3 + 1);
+                         pstate->push_new<array_operation> (0, $3,
+                                                            std::move (args));
+                       }
        ;
 
 exp    :       lcurly type_exp rcurly exp  %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_MEMVAL_TYPE); }
+                       { pstate->wrap2<unop_memval_type_operation> (); }
        ;
 
 exp    :       '(' type_exp ')' exp  %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_cast_type_operation> ();
+                         else
+                           pstate->wrap2<unop_cast_type_operation> ();
+                       }
        ;
 
 exp    :       '(' exp1 ')'
@@ -680,116 +683,194 @@ exp     :       '(' exp1 ')'
 /* Binary operators in order of decreasing precedence.  */
 
 exp    :       exp '@' exp
-                       { write_exp_elt_opcode (pstate, BINOP_REPEAT); }
+                       { pstate->wrap2<repeat_operation> (); }
        ;
 
 exp    :       exp '*' exp
-                       { write_exp_elt_opcode (pstate, BINOP_MUL); }
+                       { pstate->wrap2<mul_operation> (); }
        ;
 
 exp    :       exp '/' exp
-                       { write_exp_elt_opcode (pstate, BINOP_DIV); }
+                       { pstate->wrap2<div_operation> (); }
        ;
 
 exp    :       exp '%' exp
-                       { write_exp_elt_opcode (pstate, BINOP_REM); }
+                       { pstate->wrap2<rem_operation> (); }
        ;
 
 exp    :       exp '+' exp
-                       { write_exp_elt_opcode (pstate, BINOP_ADD); }
+                       { pstate->wrap2<add_operation> (); }
        ;
 
 exp    :       exp '-' exp
-                       { write_exp_elt_opcode (pstate, BINOP_SUB); }
+                       { pstate->wrap2<sub_operation> (); }
        ;
 
 exp    :       exp LSH exp
-                       { write_exp_elt_opcode (pstate, BINOP_LSH); }
+                       { pstate->wrap2<lsh_operation> (); }
        ;
 
 exp    :       exp RSH exp
-                       { write_exp_elt_opcode (pstate, BINOP_RSH); }
+                       { pstate->wrap2<rsh_operation> (); }
        ;
 
 exp    :       exp EQUAL exp
-                       { write_exp_elt_opcode (pstate, BINOP_EQUAL); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_equal_operation> ();
+                         else
+                           pstate->wrap2<equal_operation> ();
+                       }
        ;
 
 exp    :       exp NOTEQUAL exp
-                       { write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_notequal_operation> ();
+                         else
+                           pstate->wrap2<notequal_operation> ();
+                       }
        ;
 
 exp    :       exp LEQ exp
-                       { write_exp_elt_opcode (pstate, BINOP_LEQ); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_leq_operation> ();
+                         else
+                           pstate->wrap2<leq_operation> ();
+                       }
        ;
 
 exp    :       exp GEQ exp
-                       { write_exp_elt_opcode (pstate, BINOP_GEQ); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_geq_operation> ();
+                         else
+                           pstate->wrap2<geq_operation> ();
+                       }
        ;
 
 exp    :       exp '<' exp
-                       { write_exp_elt_opcode (pstate, BINOP_LESS); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_less_operation> ();
+                         else
+                           pstate->wrap2<less_operation> ();
+                       }
        ;
 
 exp    :       exp '>' exp
-                       { write_exp_elt_opcode (pstate, BINOP_GTR); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_gtr_operation> ();
+                         else
+                           pstate->wrap2<gtr_operation> ();
+                       }
        ;
 
 exp    :       exp '&' exp
-                       { write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); }
+                       { pstate->wrap2<bitwise_and_operation> (); }
        ;
 
 exp    :       exp '^' exp
-                       { write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); }
+                       { pstate->wrap2<bitwise_xor_operation> (); }
        ;
 
 exp    :       exp '|' exp
-                       { write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); }
+                       { pstate->wrap2<bitwise_ior_operation> (); }
        ;
 
 exp    :       exp ANDAND exp
-                       { write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           {
+                             operation_up rhs = pstate->pop ();
+                             operation_up lhs = pstate->pop ();
+                             pstate->push_new<opencl_logical_binop_operation>
+                               (BINOP_LOGICAL_AND, std::move (lhs),
+                                std::move (rhs));
+                           }
+                         else
+                           pstate->wrap2<logical_and_operation> ();
+                       }
        ;
 
 exp    :       exp OROR exp
-                       { write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           {
+                             operation_up rhs = pstate->pop ();
+                             operation_up lhs = pstate->pop ();
+                             pstate->push_new<opencl_logical_binop_operation>
+                               (BINOP_LOGICAL_OR, std::move (lhs),
+                                std::move (rhs));
+                           }
+                         else
+                           pstate->wrap2<logical_or_operation> ();
+                       }
        ;
 
 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 ();
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->push_new<opencl_ternop_cond_operation>
+                             (std::move (first), std::move (mid),
+                              std::move (last));
+                         else
+                           pstate->push_new<ternop_cond_operation>
+                             (std::move (first), std::move (mid),
+                              std::move (last));
+                       }
        ;
 
 exp    :       exp '=' exp
-                       { write_exp_elt_opcode (pstate, BINOP_ASSIGN); }
+                       {
+                         if (pstate->language ()->la_language
+                             == language_opencl)
+                           pstate->wrap2<opencl_assign_operation> ();
+                         else
+                           pstate->wrap2<assign_operation> ();
+                       }
        ;
 
 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<assign_modify_operation>
+                           ($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<long_const_operation>
+                           ($1.type, $1.val);
+                       }
        ;
 
 exp    :       COMPLEX_INT
                        {
-                         write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_type (pstate, TYPE_TARGET_TYPE ($1.type));
-                         write_exp_elt_longcst (pstate, 0);
-                         write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_type (pstate, TYPE_TARGET_TYPE ($1.type));
-                         write_exp_elt_longcst (pstate, (LONGEST) ($1.val));
-                         write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_opcode (pstate, OP_COMPLEX);
-                         write_exp_elt_type (pstate, $1.type);
-                         write_exp_elt_opcode (pstate, OP_COMPLEX);
+                         operation_up real
+                           = (make_operation<long_const_operation>
+                              (TYPE_TARGET_TYPE ($1.type), 0));
+                         operation_up imag
+                           = (make_operation<long_const_operation>
+                              (TYPE_TARGET_TYPE ($1.type), $1.val));
+                         pstate->push_new<complex_operation>
+                           (std::move (real), std::move (imag), $1.type);
                        }
        ;
 
@@ -798,7 +879,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);
                        }
        ;
 
@@ -806,20 +887,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<long_const_operation>
+                           (val.typed_val_int.type,
+                            val.typed_val_int.val);
                        }
        ;
 
 
 exp    :       FLOAT
-                       { 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); }
+                       {
+                         float_data data;
+                         std::copy (std::begin ($1.val), std::end ($1.val),
+                                    std::begin (data));
+                         pstate->push_new<float_const_operation> ($1.type, data);
+                       }
        ;
 
 exp    :       COMPLEX_FLOAT
@@ -827,19 +908,22 @@ exp       :       COMPLEX_FLOAT
                          struct type *underlying
                            = TYPE_TARGET_TYPE ($1.type);
 
-                         write_exp_elt_opcode (pstate, OP_FLOAT);
-                         write_exp_elt_type (pstate, underlying);
-                         gdb_byte val[16];
-                         target_float_from_host_double (val, underlying, 0);
-                         write_exp_elt_floatcst (pstate, val);
-                         write_exp_elt_opcode (pstate, OP_FLOAT);
-                         write_exp_elt_opcode (pstate, OP_FLOAT);
-                         write_exp_elt_type (pstate, underlying);
-                         write_exp_elt_floatcst (pstate, $1.val);
-                         write_exp_elt_opcode (pstate, OP_FLOAT);
-                         write_exp_elt_opcode (pstate, OP_COMPLEX);
-                         write_exp_elt_type (pstate, $1.type);
-                         write_exp_elt_opcode (pstate, OP_COMPLEX);
+                         float_data val;
+                         target_float_from_host_double (val.data (),
+                                                        underlying, 0);
+                         operation_up real
+                           = (make_operation<float_const_operation>
+                              (underlying, val));
+
+                         std::copy (std::begin ($1.val), std::end ($1.val),
+                                    std::begin (val));
+                         operation_up imag
+                           = (make_operation<float_const_operation>
+                              (underlying, val));
+
+                         pstate->push_new<complex_operation>
+                           (std::move (real), std::move (imag),
+                            $1.type);
                        }
        ;
 
@@ -848,23 +932,22 @@ exp       :       variable
 
 exp    :       DOLLAR_VARIABLE
                        {
-                         write_dollar_variable (pstate, $1);
+                         pstate->push_dollar ($1);
                        }
        ;
 
 exp    :       SELECTOR '(' name ')'
                        {
-                         write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR);
-                         write_exp_string (pstate, $3);
-                         write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR); }
+                         pstate->push_new<objc_selector_operation>
+                           (copy_name ($3));
+                       }
        ;
 
 exp    :       SIZEOF '(' type ')'     %prec UNARY
                        { struct type *type = $3;
-                         write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_type (pstate, lookup_signed_typename
-                                             (pstate->language (),
-                                              "int"));
+                         struct type *int_type
+                           = lookup_signed_typename (pstate->language (),
+                                                     "int");
                          type = check_typedef (type);
 
                            /* $5.3.3/2 of the C++ Standard (n3290 draft)
@@ -873,28 +956,27 @@ exp       :       SIZEOF '(' type ')'     %prec UNARY
                               the referenced type."  */
                          if (TYPE_IS_REFERENCE (type))
                            type = check_typedef (TYPE_TARGET_TYPE (type));
-                         write_exp_elt_longcst (pstate,
-                                                (LONGEST) TYPE_LENGTH (type));
-                         write_exp_elt_opcode (pstate, OP_LONG); }
+                         pstate->push_new<long_const_operation>
+                           (int_type, TYPE_LENGTH (type));
+                       }
        ;
 
 exp    :       REINTERPRET_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (pstate,
-                                               UNOP_REINTERPRET_CAST); }
+                       { pstate->wrap2<reinterpret_cast_operation> (); }
        ;
 
 exp    :       STATIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); }
+                       { pstate->wrap2<unop_cast_type_operation> (); }
        ;
 
 exp    :       DYNAMIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (pstate, UNOP_DYNAMIC_CAST); }
+                       { pstate->wrap2<dynamic_cast_operation> (); }
        ;
 
 exp    :       CONST_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
                        { /* We could do more error checking here, but
                             it doesn't seem worthwhile.  */
-                         write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); }
+                         pstate->wrap2<unop_cast_type_operation> (); }
        ;
 
 string_exp:
@@ -959,7 +1041,7 @@ exp        :       string_exp
                                }
                            }
 
-                         write_exp_string_vector (pstate, type, &$1);
+                         pstate->push_c_string (type, &$1);
                          for (i = 0; i < $1.len; ++i)
                            free ($1.tokens[i].ptr);
                          free ($1.tokens);
@@ -969,26 +1051,23 @@ exp      :       string_exp
 exp     :      NSSTRING        /* ObjC NextStep NSString constant
                                 * of the form '@' '"' string '"'.
                                 */
-                       { write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING);
-                         write_exp_string (pstate, $1);
-                         write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING); }
+                       {
+                         pstate->push_new<objc_nsstring_operation>
+                           (copy_name ($1));
+                       }
        ;
 
 /* C++.  */
 exp     :       TRUEKEYWORD
-                       { write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_type (pstate,
-                                         parse_type (pstate)->builtin_bool);
-                         write_exp_elt_longcst (pstate, (LONGEST) 1);
-                         write_exp_elt_opcode (pstate, OP_LONG); }
+                       { pstate->push_new<long_const_operation>
+                           (parse_type (pstate)->builtin_bool, 1);
+                       }
        ;
 
 exp     :       FALSEKEYWORD
-                       { write_exp_elt_opcode (pstate, OP_LONG);
-                         write_exp_elt_type (pstate,
-                                         parse_type (pstate)->builtin_bool);
-                         write_exp_elt_longcst (pstate, (LONGEST) 0);
-                         write_exp_elt_opcode (pstate, OP_LONG); }
+                       { pstate->push_new<long_const_operation>
+                           (parse_type (pstate)->builtin_bool, 0);
+                       }
        ;
 
 /* end of C++.  */
@@ -1029,9 +1108,7 @@ variable: name_not_typename ENTRY
                                     "parameters, not for \"%s\""),
                                   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<var_entry_value_operation> (sym);
                        }
        ;
 
@@ -1048,10 +1125,9 @@ variable:        block COLONCOLON name
                          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); }
+                         pstate->push_new<var_value_operation> (sym.symbol,
+                                                                sym.block);
+                       }
        ;
 
 qualified_name:        TYPENAME COLONCOLON name
@@ -1062,34 +1138,24 @@ qualified_name: TYPENAME COLONCOLON name
                            error (_("`%s' is not defined as an aggregate type."),
                                   TYPE_SAFE_NAME (type));
 
-                         write_exp_elt_opcode (pstate, OP_SCOPE);
-                         write_exp_elt_type (pstate, type);
-                         write_exp_string (pstate, $3);
-                         write_exp_elt_opcode (pstate, OP_SCOPE);
+                         pstate->push_new<scope_operation> (type,
+                                                            copy_name ($3));
                        }
        |       TYPENAME COLONCOLON '~' name
                        {
                          struct type *type = $1.type;
-                         struct stoken tmp_token;
-                         char *buf;
 
                          type = check_typedef (type);
                          if (!type_aggregate_p (type))
                            error (_("`%s' is not defined as an aggregate type."),
                                   TYPE_SAFE_NAME (type));
-                         buf = (char *) alloca ($4.length + 2);
-                         tmp_token.ptr = buf;
-                         tmp_token.length = $4.length + 1;
-                         buf[0] = '~';
-                         memcpy (buf+1, $4.ptr, $4.length);
-                         buf[tmp_token.length] = 0;
+                         std::string name = "~" + std::string ($4.ptr,
+                                                               $4.length);
 
                          /* Check for valid destructor name.  */
-                         destructor_name_p (tmp_token.ptr, $1.type);
-                         write_exp_elt_opcode (pstate, OP_SCOPE);
-                         write_exp_elt_type (pstate, type);
-                         write_exp_string (pstate, tmp_token);
-                         write_exp_elt_opcode (pstate, OP_SCOPE);
+                         destructor_name_p (name.c_str (), $1.type);
+                         pstate->push_new<scope_operation> (type,
+                                                            std::move (name));
                        }
        |       TYPENAME COLONCOLON name COLONCOLON name
                        {
@@ -1108,8 +1174,7 @@ variable: qualified_name
                            = lookup_symbol (name.c_str (),
                                             (const struct block *) NULL,
                                             VAR_DOMAIN, NULL);
-                         write_exp_symbol_reference (pstate, name.c_str (),
-                                                     sym);
+                         pstate->push_symbol (name.c_str (), sym);
                        }
        ;
 
@@ -1129,14 +1194,11 @@ variable:       name_not_typename
                              bound_minimal_symbol resolver
                                = find_gnu_ifunc (sym.symbol);
                              if (resolver.minsym != NULL)
-                               write_exp_msymbol (pstate, resolver);
+                               pstate->push_new<var_msym_value_operation>
+                                 (resolver.minsym, resolver.objfile);
                              else
-                               {
-                                 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->push_new<var_value_operation>
+                                 (sym.symbol, sym.block);
                            }
                          else if ($1.is_a_field_of_this)
                            {
@@ -1144,11 +1206,10 @@ variable:       name_not_typename
                                 not inadvertently convert from a method call
                                 to data ref.  */
                              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);
-                             write_exp_string (pstate, $1.stoken);
-                             write_exp_elt_opcode (pstate, STRUCTOP_PTR);
+                             operation_up thisop
+                               = make_operation<op_this_operation> ();
+                             pstate->push_new<structop_ptr_operation>
+                               (std::move (thisop), copy_name ($1.stoken));
                            }
                          else
                            {
@@ -1178,15 +1239,11 @@ variable:       name_not_typename
                                   ? find_function_alias_target (msymbol)
                                   : NULL);
                              if (alias_target != NULL)
-                               {
-                                 write_exp_elt_opcode (pstate, OP_VAR_VALUE);
-                                 write_exp_elt_block
-                                   (pstate, SYMBOL_BLOCK_VALUE (alias_target));
-                                 write_exp_elt_sym (pstate, alias_target);
-                                 write_exp_elt_opcode (pstate, OP_VAR_VALUE);
-                               }
+                               pstate->push_new<var_value_operation>
+                                 (alias_target, SYMBOL_BLOCK_VALUE (alias_target));
                              else
-                               write_exp_msymbol (pstate, msymbol);
+                               pstate->push_new<var_msym_value_operation>
+                                 (msymbol.minsym, msymbol.objfile);
                            }
                        }
        ;
@@ -1783,22 +1840,6 @@ name_not_typename :      NAME
 
 %%
 
-/* Like write_exp_string, but prepends a '~'.  */
-
-static void
-write_destructor_name (struct parser_state *par_state, struct stoken token)
-{
-  char *copy = (char *) alloca (token.length + 1);
-
-  copy[0] = '~';
-  memcpy (&copy[1], token.ptr, token.length);
-
-  token.ptr = copy;
-  ++token.length;
-
-  write_exp_string (par_state, token);
-}
-
 /* Returns a stoken of the operator name given by OP (which does not
    include the string "operator").  */
 
@@ -3393,7 +3434,10 @@ c_parse (struct parser_state *par_state)
   popping = 0;
   name_obstack.clear ();
 
-  return yyparse ();
+  int result = yyparse ();
+  if (!result)
+    pstate->set_operation (pstate->pop ());
+  return result;
 }
 
 #ifdef YYBISON
index 67896284720c552bd5cb391fcdcf70e79aae1df5..788fe0f3353cb9f809365d1cec75a3d4fbc8231a 100644 (file)
@@ -43,6 +43,7 @@
 #include "infcall.h"
 #include "valprint.h"
 #include "cli/cli-utils.h"
+#include "c-exp.h"
 
 #include <ctype.h>
 #include <algorithm>
@@ -507,15 +508,20 @@ end_msglist (struct parser_state *ps)
   char *p = msglist_sel;
   CORE_ADDR selid;
 
+  std::vector<expr::operation_up> args = ps->pop_vector (val);
+  expr::operation_up target = ps->pop ();
+
   selname_chain = sel->next;
   msglist_len = sel->msglist_len;
   msglist_sel = sel->msglist_sel;
   selid = lookup_child_selector (ps->gdbarch (), p);
   if (!selid)
     error (_("Can't find selector \"%s\""), p);
-  write_exp_elt_longcst (ps, selid);
+
+  ps->push_new<expr::objc_msgcall_operation> (selid, std::move (target),
+                                             std::move (args));
+
   xfree(p);
-  write_exp_elt_longcst (ps, val);     /* Number of args */
   xfree(sel);
 
   return val;
index ecbb768a423746e339e5ff20a8b95b81daf638a6..5b65aafe2e1059bedd1696e25f7fd5621533db49 100644 (file)
@@ -1,3 +1,7 @@
+2021-03-08  Tom Tromey  <tom@tromey.com>
+
+       * gdb.base/debug-expr.exp: Update expected dump output.
+
 2021-03-06  Tom Tromey  <tom@tromey.com>
 
        * lib/dwarf.exp (_handle_DW_FORM): Treat DW_FORM_GNU_ref_alt and
index 068c88a3e36b1409c5d7d6001bda1c253d424977..77cf030d9064aa0963b49b9447a0f7197efa78da 100644 (file)
@@ -45,10 +45,10 @@ gdb_test_debug_expr "print /x {char\[4\]} array" \
 
 # This caused gdb to output garbage and possibly segfault
 gdb_test_debug_expr "print \"hello\"" \
-    ".*OP_STRING\[^\r\n\]*Language-specific string type: 0.*\[\r\n\]\\$$decimal = \"hello\"" \
+    ".*OP_STRING\[^\r\n\]*.*: ordinary string.*\[\r\n\]\\$$decimal = \"hello\"" \
     "string evaluation with debug expr"
 
 # An expression using a function call.
 gdb_test_debug_expr "print call_me ( &val )" \
-    ".*OP_FUNCALL\[^\r\n\]*Number of args: 1.*\[\r\n\]\\$$decimal = 0.*" \
+    ".*OP_FUNCALL\[^\r\n\]*.*UNOP_ADDR.*\[\r\n\]\\$$decimal = 0.*" \
     "function call expression"