Introduce binop_operation
[deliverable/binutils-gdb.git] / gdb / expop.h
CommitLineData
e2803273
TT
1/* Definitions for expressions in GDB
2
3 Copyright (C) 2020 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#ifndef EXPOP_H
21#define EXPOP_H
22
23#include "block.h"
24#include "c-lang.h"
25#include "cp-abi.h"
26#include "expression.h"
27#include "objfiles.h"
28#include "gdbsupport/traits.h"
29#include "gdbsupport/enum-flags.h"
30
31struct agent_expr;
32struct axs_value;
33
75f9892d
TT
34extern void gen_expr_binop (struct expression *exp,
35 enum exp_opcode op,
36 expr::operation *lhs, expr::operation *rhs,
37 struct agent_expr *ax, struct axs_value *value);
38extern void gen_expr_structop (struct expression *exp,
39 enum exp_opcode op,
40 expr::operation *lhs,
41 const char *name,
42 struct agent_expr *ax, struct axs_value *value);
43
d5ab122c
TT
44extern struct value *eval_op_scope (struct type *expect_type,
45 struct expression *exp,
46 enum noside noside,
47 struct type *type, const char *string);
0c8effa3
TT
48extern struct value *eval_op_var_msym_value (struct type *expect_type,
49 struct expression *exp,
50 enum noside noside,
51 bool outermost_p,
52 minimal_symbol *msymbol,
53 struct objfile *objfile);
b5cc3923
TT
54extern struct value *eval_op_var_entry_value (struct type *expect_type,
55 struct expression *exp,
56 enum noside noside, symbol *sym);
17679395
TT
57extern struct value *eval_op_func_static_var (struct type *expect_type,
58 struct expression *exp,
59 enum noside noside,
60 value *func, const char *var);
55bdbff8
TT
61extern struct value *eval_op_register (struct type *expect_type,
62 struct expression *exp,
63 enum noside noside, const char *name);
b50db09f
TT
64extern struct value *eval_op_string (struct type *expect_type,
65 struct expression *exp,
66 enum noside noside, int len,
67 const char *string);
1594e0bb
TT
68extern struct value *eval_op_ternop (struct type *expect_type,
69 struct expression *exp,
70 enum noside noside,
71 struct value *array, struct value *low,
72 struct value *upper);
808b22cf
TT
73extern struct value *eval_op_structop_struct (struct type *expect_type,
74 struct expression *exp,
75 enum noside noside,
76 struct value *arg1,
77 const char *string);
ab0609be
TT
78extern struct value *eval_op_structop_ptr (struct type *expect_type,
79 struct expression *exp,
80 enum noside noside,
81 struct value *arg1,
82 const char *string);
07f724a8
TT
83extern struct value *eval_op_member (struct type *expect_type,
84 struct expression *exp,
85 enum noside noside,
86 struct value *arg1, struct value *arg2);
e51e26a0
TT
87extern struct value *eval_op_concat (struct type *expect_type,
88 struct expression *exp,
89 enum noside noside,
90 struct value *arg1, struct value *arg2);
a94323b6
TT
91extern struct value *eval_op_add (struct type *expect_type,
92 struct expression *exp,
93 enum noside noside,
94 struct value *arg1, struct value *arg2);
5133d78b
TT
95extern struct value *eval_op_sub (struct type *expect_type,
96 struct expression *exp,
97 enum noside noside,
98 struct value *arg1, struct value *arg2);
373907ff
TT
99extern struct value *eval_op_binary (struct type *expect_type,
100 struct expression *exp,
101 enum noside noside, enum exp_opcode op,
102 struct value *arg1, struct value *arg2);
d5ab122c 103
e2803273
TT
104namespace expr
105{
106
107/* The check_objfile overloads are used to check whether a particular
108 component of some operation references an objfile. The passed-in
109 objfile will never be a debug objfile. */
110
111/* See if EXP_OBJFILE matches OBJFILE. */
112static inline bool
113check_objfile (struct objfile *exp_objfile, struct objfile *objfile)
114{
115 if (exp_objfile->separate_debug_objfile_backlink)
116 exp_objfile = exp_objfile->separate_debug_objfile_backlink;
117 return exp_objfile == objfile;
118}
119
120static inline bool
121check_objfile (struct type *type, struct objfile *objfile)
122{
123 struct objfile *ty_objfile = type->objfile_owner ();
124 if (ty_objfile != nullptr)
125 return check_objfile (ty_objfile, objfile);
126 return false;
127}
128
129static inline bool
130check_objfile (struct symbol *sym, struct objfile *objfile)
131{
132 return check_objfile (symbol_objfile (sym), objfile);
133}
134
135static inline bool
136check_objfile (const struct block *block, struct objfile *objfile)
137{
138 return check_objfile (block_objfile (block), objfile);
139}
140
141static inline bool
142check_objfile (minimal_symbol *minsym, struct objfile *objfile)
143{
144 /* This may seem strange but minsyms are only used with an objfile
145 as well. */
146 return false;
147}
148
149static inline bool
150check_objfile (internalvar *ivar, struct objfile *objfile)
151{
152 return false;
153}
154
155static inline bool
156check_objfile (const std::string &str, struct objfile *objfile)
157{
158 return false;
159}
160
161static inline bool
162check_objfile (const operation_up &op, struct objfile *objfile)
163{
164 return op->uses_objfile (objfile);
165}
166
167static inline bool
168check_objfile (enum exp_opcode val, struct objfile *objfile)
169{
170 return false;
171}
172
173static inline bool
174check_objfile (ULONGEST val, struct objfile *objfile)
175{
176 return false;
177}
178
179template<typename T>
180static inline bool
181check_objfile (enum_flags<T> val, struct objfile *objfile)
182{
183 return false;
184}
185
186template<typename T>
187static inline bool
188check_objfile (const std::vector<T> &collection, struct objfile *objfile)
189{
190 for (const auto &item : collection)
191 {
192 if (check_objfile (item, objfile))
193 return true;
194 }
195 return false;
196}
197
198template<typename S, typename T>
199static inline bool
200check_objfile (const std::pair<S, T> &item, struct objfile *objfile)
201{
202 return (check_objfile (item.first, objfile)
203 || check_objfile (item.second, objfile));
204}
205
de401988
TT
206static inline void
207dump_for_expression (struct ui_file *stream, int depth,
208 const operation_up &op)
209{
210 op->dump (stream, depth);
211}
212
213extern void dump_for_expression (struct ui_file *stream, int depth,
214 enum exp_opcode op);
215extern void dump_for_expression (struct ui_file *stream, int depth,
216 const std::string &str);
217extern void dump_for_expression (struct ui_file *stream, int depth,
218 struct type *type);
219extern void dump_for_expression (struct ui_file *stream, int depth,
220 CORE_ADDR addr);
221extern void dump_for_expression (struct ui_file *stream, int depth,
222 internalvar *ivar);
223extern void dump_for_expression (struct ui_file *stream, int depth,
224 symbol *sym);
225extern void dump_for_expression (struct ui_file *stream, int depth,
226 minimal_symbol *msym);
227extern void dump_for_expression (struct ui_file *stream, int depth,
228 const block *bl);
229extern void dump_for_expression (struct ui_file *stream, int depth,
230 type_instance_flags flags);
231extern void dump_for_expression (struct ui_file *stream, int depth,
232 enum c_string_type_values flags);
233extern void dump_for_expression (struct ui_file *stream, int depth,
234 enum range_flag flags);
235extern void dump_for_expression (struct ui_file *stream, int depth,
236 objfile *objf);
237
238template<typename T>
239void
240dump_for_expression (struct ui_file *stream, int depth,
241 const std::vector<T> &vals)
242{
243 fprintf_filtered (stream, _("%*sVector:\n"), depth, "");
244 for (auto &item : vals)
245 dump_for_expression (stream, depth + 1, item);
246}
247
248template<typename X, typename Y>
249void
250dump_for_expression (struct ui_file *stream, int depth,
251 const std::pair<X, Y> &vals)
252{
253 dump_for_expression (stream, depth, vals.first);
254 dump_for_expression (stream, depth, vals.second);
255}
256
e2803273
TT
257/* Base class for most concrete operations. This class holds data,
258 specified via template parameters, and supplies generic
259 implementations of the 'dump' and 'uses_objfile' methods. */
260template<typename... Arg>
261class tuple_holding_operation : public operation
262{
263public:
264
265 explicit tuple_holding_operation (Arg... args)
266 : m_storage (std::forward<Arg> (args)...)
267 {
268 }
269
270 DISABLE_COPY_AND_ASSIGN (tuple_holding_operation);
271
272 bool uses_objfile (struct objfile *objfile) const override
273 {
274 return do_check_objfile<0, Arg...> (objfile, m_storage);
275 }
276
277 void dump (struct ui_file *stream, int depth) const override
278 {
de401988
TT
279 dump_for_expression (stream, depth, opcode ());
280 do_dump<0, Arg...> (stream, depth + 1, m_storage);
e2803273
TT
281 }
282
283protected:
284
285 /* Storage for the data. */
286 std::tuple<Arg...> m_storage;
287
288private:
289
290 /* do_dump does the work of dumping the data. */
291 template<int I, typename... T>
292 typename std::enable_if<I == sizeof... (T), void>::type
293 do_dump (struct ui_file *stream, int depth, const std::tuple<T...> &value)
294 const
295 {
296 }
297
298 template<int I, typename... T>
299 typename std::enable_if<I < sizeof... (T), void>::type
300 do_dump (struct ui_file *stream, int depth, const std::tuple<T...> &value)
301 const
302 {
de401988 303 dump_for_expression (stream, depth, std::get<I> (value));
e2803273
TT
304 do_dump<I + 1, T...> (stream, depth, value);
305 }
306
307 /* do_check_objfile does the work of checking whether this object
308 refers to OBJFILE. */
309 template<int I, typename... T>
310 typename std::enable_if<I == sizeof... (T), bool>::type
311 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
312 const
313 {
314 return false;
315 }
316
317 template<int I, typename... T>
318 typename std::enable_if<I < sizeof... (T), bool>::type
319 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
320 const
321 {
322 if (check_objfile (std::get<I> (value), objfile))
323 return true;
324 return do_check_objfile<I + 1, T...> (objfile, value);
325 }
326};
327
328/* The check_constant overloads are used to decide whether a given
329 concrete operation is a constant. This is done by checking the
330 operands. */
331
332static inline bool
333check_constant (const operation_up &item)
334{
335 return item->constant_p ();
336}
337
338static inline bool
339check_constant (struct minimal_symbol *msym)
340{
341 return false;
342}
343
344static inline bool
345check_constant (struct type *type)
346{
347 return true;
348}
349
350static inline bool
351check_constant (const struct block *block)
352{
353 return true;
354}
355
356static inline bool
357check_constant (const std::string &str)
358{
359 return true;
360}
361
362static inline bool
363check_constant (struct objfile *objfile)
364{
365 return true;
366}
367
368static inline bool
369check_constant (ULONGEST cst)
370{
371 return true;
372}
373
374static inline bool
375check_constant (struct symbol *sym)
376{
377 enum address_class sc = SYMBOL_CLASS (sym);
378 return (sc == LOC_BLOCK
379 || sc == LOC_CONST
380 || sc == LOC_CONST_BYTES
381 || sc == LOC_LABEL);
382}
383
384template<typename T>
385static inline bool
386check_constant (const std::vector<T> &collection)
387{
388 for (const auto &item : collection)
389 if (!check_constant (item))
390 return false;
391 return true;
392}
393
394template<typename S, typename T>
395static inline bool
396check_constant (const std::pair<S, T> &item)
397{
398 return check_constant (item.first) && check_constant (item.second);
399}
400
401/* Base class for concrete operations. This class supplies an
402 implementation of 'constant_p' that works by checking the
403 operands. */
404template<typename... Arg>
405class maybe_constant_operation
406 : public tuple_holding_operation<Arg...>
407{
408public:
409
410 using tuple_holding_operation<Arg...>::tuple_holding_operation;
411
412 bool constant_p () const override
413 {
414 return do_check_constant<0, Arg...> (this->m_storage);
415 }
416
417private:
418
419 template<int I, typename... T>
420 typename std::enable_if<I == sizeof... (T), bool>::type
421 do_check_constant (const std::tuple<T...> &value) const
422 {
423 return true;
424 }
425
426 template<int I, typename... T>
427 typename std::enable_if<I < sizeof... (T), bool>::type
428 do_check_constant (const std::tuple<T...> &value) const
429 {
430 if (!check_constant (std::get<I> (value)))
431 return false;
432 return do_check_constant<I + 1, T...> (value);
433 }
434};
435
cae26a0c
TT
436/* A floating-point constant. The constant is encoded in the target
437 format. */
438
439typedef std::array<gdb_byte, 16> float_data;
440
441/* An operation that holds a floating-point constant of a given
442 type.
443
444 This does not need the facilities provided by
445 tuple_holding_operation, so it does not use it. */
446class float_const_operation
447 : public operation
448{
449public:
450
451 float_const_operation (struct type *type, float_data data)
452 : m_type (type),
453 m_data (data)
454 {
455 }
456
457 value *evaluate (struct type *expect_type,
458 struct expression *exp,
459 enum noside noside) override
460 {
461 return value_from_contents (m_type, m_data.data ());
462 }
463
464 enum exp_opcode opcode () const override
465 { return OP_FLOAT; }
466
467 bool constant_p () const override
468 { return true; }
469
470 void dump (struct ui_file *stream, int depth) const override;
471
472private:
473
474 struct type *m_type;
475 float_data m_data;
476};
477
d5ab122c
TT
478class scope_operation
479 : public maybe_constant_operation<struct type *, std::string>
480{
481public:
482
483 using maybe_constant_operation::maybe_constant_operation;
484
485 value *evaluate (struct type *expect_type,
486 struct expression *exp,
487 enum noside noside) override
488 {
489 return eval_op_scope (expect_type, exp, noside,
490 std::get<0> (m_storage),
491 std::get<1> (m_storage).c_str ());
492 }
493
494 value *evaluate_for_address (struct expression *exp,
495 enum noside noside) override;
496
497 enum exp_opcode opcode () const override
498 { return OP_SCOPE; }
499
500protected:
501
502 void do_generate_ax (struct expression *exp,
503 struct agent_expr *ax,
504 struct axs_value *value,
505 struct type *cast_type)
506 override;
507};
508
d336c29e
TT
509class long_const_operation
510 : public tuple_holding_operation<struct type *, LONGEST>
511{
512public:
513
514 using tuple_holding_operation::tuple_holding_operation;
515
516 value *evaluate (struct type *expect_type,
517 struct expression *exp,
518 enum noside noside) override
519 {
520 return value_from_longest (std::get<0> (m_storage),
521 std::get<1> (m_storage));
522 }
523
524 enum exp_opcode opcode () const override
525 { return OP_LONG; }
526
527 bool constant_p () const override
528 { return true; }
529
530protected:
531
532 void do_generate_ax (struct expression *exp,
533 struct agent_expr *ax,
534 struct axs_value *value,
535 struct type *cast_type)
536 override;
537};
538
0c8effa3
TT
539class var_msym_value_operation
540 : public maybe_constant_operation<minimal_symbol *, struct objfile *>
541{
542public:
543
544 using maybe_constant_operation::maybe_constant_operation;
545
546 value *evaluate (struct type *expect_type,
547 struct expression *exp,
548 enum noside noside) override
549 {
550 return eval_op_var_msym_value (expect_type, exp, noside, m_outermost,
551 std::get<0> (m_storage),
552 std::get<1> (m_storage));
553 }
554
555 value *evaluate_for_sizeof (struct expression *exp, enum noside noside)
556 override;
557
558 value *evaluate_for_address (struct expression *exp, enum noside noside)
559 override;
560
561 value *evaluate_for_cast (struct type *expect_type,
562 struct expression *exp,
563 enum noside noside) override;
564
565 enum exp_opcode opcode () const override
566 { return OP_VAR_MSYM_VALUE; }
567
568 void set_outermost () override
569 {
570 m_outermost = true;
571 }
572
573protected:
574
575 /* True if this is the outermost operation in the expression. */
576 bool m_outermost = false;
577
578 void do_generate_ax (struct expression *exp,
579 struct agent_expr *ax,
580 struct axs_value *value,
581 struct type *cast_type)
582 override;
583};
584
b5cc3923
TT
585class var_entry_value_operation
586 : public tuple_holding_operation<symbol *>
587{
588public:
589
590 using tuple_holding_operation::tuple_holding_operation;
591
592 value *evaluate (struct type *expect_type,
593 struct expression *exp,
594 enum noside noside) override
595 {
596 return eval_op_var_entry_value (expect_type, exp, noside,
597 std::get<0> (m_storage));
598 }
599
600 enum exp_opcode opcode () const override
601 { return OP_VAR_ENTRY_VALUE; }
602};
603
17679395
TT
604class func_static_var_operation
605 : public maybe_constant_operation<operation_up, std::string>
606{
607public:
608
609 using maybe_constant_operation::maybe_constant_operation;
610
611 value *evaluate (struct type *expect_type,
612 struct expression *exp,
613 enum noside noside) override
614 {
615 value *func = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
616 return eval_op_func_static_var (expect_type, exp, noside, func,
617 std::get<1> (m_storage).c_str ());
618 }
619
620 enum exp_opcode opcode () const override
621 { return OP_FUNC_STATIC_VAR; }
622};
623
247d935b
TT
624class last_operation
625 : public tuple_holding_operation<int>
626{
627public:
628
629 using tuple_holding_operation::tuple_holding_operation;
630
631 value *evaluate (struct type *expect_type,
632 struct expression *exp,
633 enum noside noside) override
634 {
635 return access_value_history (std::get<0> (m_storage));
636 }
637
638 enum exp_opcode opcode () const override
639 { return OP_LAST; }
640};
641
55bdbff8
TT
642class register_operation
643 : public tuple_holding_operation<std::string>
644{
645public:
646
647 using tuple_holding_operation::tuple_holding_operation;
648
649 value *evaluate (struct type *expect_type,
650 struct expression *exp,
651 enum noside noside) override
652 {
653 return eval_op_register (expect_type, exp, noside,
654 std::get<0> (m_storage).c_str ());
655 }
656
657 enum exp_opcode opcode () const override
658 { return OP_REGISTER; }
659
660protected:
661
662 void do_generate_ax (struct expression *exp,
663 struct agent_expr *ax,
664 struct axs_value *value,
665 struct type *cast_type)
666 override;
667};
668
e6985c5e
TT
669class bool_operation
670 : public tuple_holding_operation<bool>
671{
672public:
673
674 using tuple_holding_operation::tuple_holding_operation;
675
676 value *evaluate (struct type *expect_type,
677 struct expression *exp,
678 enum noside noside) override
679 {
680 struct type *type = language_bool_type (exp->language_defn, exp->gdbarch);
681 return value_from_longest (type, std::get<0> (m_storage));
682 }
683
684 enum exp_opcode opcode () const override
685 { return OP_BOOL; }
686
687 bool constant_p () const override
688 { return true; }
689};
690
e6e01e16
TT
691class internalvar_operation
692 : public tuple_holding_operation<internalvar *>
693{
694public:
695
696 using tuple_holding_operation::tuple_holding_operation;
697
698 value *evaluate (struct type *expect_type,
699 struct expression *exp,
700 enum noside noside) override
701 {
702 return value_of_internalvar (exp->gdbarch,
703 std::get<0> (m_storage));
704 }
705
706 internalvar *get_internalvar () const
707 {
708 return std::get<0> (m_storage);
709 }
710
711 enum exp_opcode opcode () const override
712 { return OP_INTERNALVAR; }
713
714protected:
715
716 void do_generate_ax (struct expression *exp,
717 struct agent_expr *ax,
718 struct axs_value *value,
719 struct type *cast_type)
720 override;
721};
722
b50db09f
TT
723class string_operation
724 : public tuple_holding_operation<std::string>
725{
726public:
727
728 using tuple_holding_operation::tuple_holding_operation;
729
730 value *evaluate (struct type *expect_type,
731 struct expression *exp,
732 enum noside noside) override
733 {
734 const std::string &str = std::get<0> (m_storage);
735 return eval_op_string (expect_type, exp, noside,
736 str.size (), str.c_str ());
737 }
738
739 enum exp_opcode opcode () const override
740 { return OP_STRING; }
741};
742
1594e0bb
TT
743class ternop_slice_operation
744 : public maybe_constant_operation<operation_up, operation_up, operation_up>
745{
746public:
747
748 using maybe_constant_operation::maybe_constant_operation;
749
750 value *evaluate (struct type *expect_type,
751 struct expression *exp,
752 enum noside noside) override
753 {
754 struct value *array
755 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
756 struct value *low
757 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
758 struct value *upper
759 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
760 return eval_op_ternop (expect_type, exp, noside, array, low, upper);
761 }
762
763 enum exp_opcode opcode () const override
764 { return TERNOP_SLICE; }
765};
766
9186293f
TT
767class ternop_cond_operation
768 : public maybe_constant_operation<operation_up, operation_up, operation_up>
769{
770public:
771
772 using maybe_constant_operation::maybe_constant_operation;
773
774 value *evaluate (struct type *expect_type,
775 struct expression *exp,
776 enum noside noside) override
777 {
778 struct value *val
779 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
780
781 if (value_logical_not (val))
782 return std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
783 return std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
784 }
785
786 enum exp_opcode opcode () const override
787 { return TERNOP_COND; }
788
789protected:
790
791 void do_generate_ax (struct expression *exp,
792 struct agent_expr *ax,
793 struct axs_value *value,
794 struct type *cast_type)
795 override;
796};
797
8cfd3e95
TT
798class complex_operation
799 : public maybe_constant_operation<operation_up, operation_up, struct type *>
800{
801public:
802
803 using maybe_constant_operation::maybe_constant_operation;
804
805 value *evaluate (struct type *expect_type,
806 struct expression *exp,
807 enum noside noside) override
808 {
809 value *real = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
810 value *imag = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
811 return value_literal_complex (real, imag,
812 std::get<2> (m_storage));
813 }
814
815 enum exp_opcode opcode () const override
816 { return OP_COMPLEX; }
817};
818
808b22cf
TT
819class structop_base_operation
820 : public tuple_holding_operation<operation_up, std::string>
821{
822public:
823
824 /* Used for completion. Return the field name. */
825 const std::string &get_string () const
826 {
827 return std::get<1> (m_storage);
828 }
829
830 /* Used for completion. Evaluate the LHS for type. */
831 value *evaluate_lhs (struct expression *exp)
832 {
833 return std::get<0> (m_storage)->evaluate (nullptr, exp,
834 EVAL_AVOID_SIDE_EFFECTS);
835 }
836
837protected:
838
839 using tuple_holding_operation::tuple_holding_operation;
840};
841
842class structop_operation
843 : public structop_base_operation
844{
845public:
846
847 using structop_base_operation::structop_base_operation;
848
849 value *evaluate (struct type *expect_type,
850 struct expression *exp,
851 enum noside noside) override
852 {
853 value *val =std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
854 return eval_op_structop_struct (expect_type, exp, noside, val,
855 std::get<1> (m_storage).c_str ());
856 }
857
858 enum exp_opcode opcode () const override
859 { return STRUCTOP_STRUCT; }
860
861protected:
862
863 void do_generate_ax (struct expression *exp,
864 struct agent_expr *ax,
865 struct axs_value *value,
866 struct type *cast_type)
867 override
868 {
869 gen_expr_structop (exp, STRUCTOP_STRUCT,
870 std::get<0> (this->m_storage).get (),
871 std::get<1> (this->m_storage).c_str (),
872 ax, value);
873 }
874};
875
ab0609be
TT
876class structop_ptr_operation
877 : public structop_base_operation
878{
879public:
880
881 using structop_base_operation::structop_base_operation;
882
883 value *evaluate (struct type *expect_type,
884 struct expression *exp,
885 enum noside noside) override
886 {
887 value *val = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
888 return eval_op_structop_ptr (expect_type, exp, noside, val,
889 std::get<1> (m_storage).c_str ());
890 }
891
892 enum exp_opcode opcode () const override
893 { return STRUCTOP_PTR; }
894
895protected:
896
897 void do_generate_ax (struct expression *exp,
898 struct agent_expr *ax,
899 struct axs_value *value,
900 struct type *cast_type)
901 override
902 {
903 gen_expr_structop (exp, STRUCTOP_PTR,
904 std::get<0> (this->m_storage).get (),
905 std::get<1> (this->m_storage).c_str (),
906 ax, value);
907 }
908};
909
07f724a8
TT
910class structop_member_operation
911 : public tuple_holding_operation<operation_up, operation_up>
912{
913public:
914
915 using tuple_holding_operation::tuple_holding_operation;
916
917 value *evaluate (struct type *expect_type,
918 struct expression *exp,
919 enum noside noside) override
920 {
921 value *lhs
922 = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
923 value *rhs
924 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
925 return eval_op_member (expect_type, exp, noside, lhs, rhs);
926 }
927
928 enum exp_opcode opcode () const override
929 { return STRUCTOP_MEMBER; }
930};
931
932class structop_mptr_operation
933 : public tuple_holding_operation<operation_up, operation_up>
934{
935public:
936
937 using tuple_holding_operation::tuple_holding_operation;
938
939 value *evaluate (struct type *expect_type,
940 struct expression *exp,
941 enum noside noside) override
942 {
943 value *lhs
944 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
945 value *rhs
946 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
947 return eval_op_member (expect_type, exp, noside, lhs, rhs);
948 }
949
950 enum exp_opcode opcode () const override
951 { return STRUCTOP_MPTR; }
952};
953
e51e26a0
TT
954class concat_operation
955 : public maybe_constant_operation<operation_up, operation_up>
956{
957public:
958
959 using maybe_constant_operation::maybe_constant_operation;
960
961 value *evaluate (struct type *expect_type,
962 struct expression *exp,
963 enum noside noside) override
964 {
965 value *lhs
966 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
967 value *rhs
968 = std::get<1> (m_storage)->evaluate_with_coercion (exp, noside);
969 return eval_op_concat (expect_type, exp, noside, lhs, rhs);
970 }
971
972 enum exp_opcode opcode () const override
973 { return BINOP_CONCAT; }
974};
975
a94323b6
TT
976class add_operation
977 : public maybe_constant_operation<operation_up, operation_up>
978{
979public:
980
981 using maybe_constant_operation::maybe_constant_operation;
982
983 value *evaluate (struct type *expect_type,
984 struct expression *exp,
985 enum noside noside) override
986 {
987 value *lhs
988 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
989 value *rhs
990 = std::get<1> (m_storage)->evaluate_with_coercion (exp, noside);
991 return eval_op_add (expect_type, exp, noside, lhs, rhs);
992 }
993
994 enum exp_opcode opcode () const override
995 { return BINOP_ADD; }
996
997protected:
998
999 void do_generate_ax (struct expression *exp,
1000 struct agent_expr *ax,
1001 struct axs_value *value,
1002 struct type *cast_type)
1003 override
1004 {
1005 gen_expr_binop (exp, BINOP_ADD,
1006 std::get<0> (this->m_storage).get (),
1007 std::get<1> (this->m_storage).get (),
1008 ax, value);
1009 }
1010};
1011
5133d78b
TT
1012class sub_operation
1013 : public maybe_constant_operation<operation_up, operation_up>
1014{
1015public:
1016
1017 using maybe_constant_operation::maybe_constant_operation;
1018
1019 value *evaluate (struct type *expect_type,
1020 struct expression *exp,
1021 enum noside noside) override
1022 {
1023 value *lhs
1024 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
1025 value *rhs
1026 = std::get<1> (m_storage)->evaluate_with_coercion (exp, noside);
1027 return eval_op_sub (expect_type, exp, noside, lhs, rhs);
1028 }
1029
1030 enum exp_opcode opcode () const override
1031 { return BINOP_SUB; }
1032
1033protected:
1034
1035 void do_generate_ax (struct expression *exp,
1036 struct agent_expr *ax,
1037 struct axs_value *value,
1038 struct type *cast_type)
1039 override
1040 {
1041 gen_expr_binop (exp, BINOP_SUB,
1042 std::get<0> (this->m_storage).get (),
1043 std::get<1> (this->m_storage).get (),
1044 ax, value);
1045 }
1046};
1047
373907ff
TT
1048typedef struct value *binary_ftype (struct type *expect_type,
1049 struct expression *exp,
1050 enum noside noside, enum exp_opcode op,
1051 struct value *arg1, struct value *arg2);
1052
1053template<enum exp_opcode OP, binary_ftype FUNC>
1054class binop_operation
1055 : public maybe_constant_operation<operation_up, operation_up>
1056{
1057public:
1058
1059 using maybe_constant_operation::maybe_constant_operation;
1060
1061 value *evaluate (struct type *expect_type,
1062 struct expression *exp,
1063 enum noside noside) override
1064 {
1065 value *lhs
1066 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1067 value *rhs
1068 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
1069 return FUNC (expect_type, exp, noside, OP, lhs, rhs);
1070 }
1071
1072 enum exp_opcode opcode () const override
1073 { return OP; }
1074};
1075
1076template<enum exp_opcode OP, binary_ftype FUNC>
1077class usual_ax_binop_operation
1078 : public binop_operation<OP, FUNC>
1079{
1080public:
1081
1082 using binop_operation<OP, FUNC>::binop_operation;
1083
1084protected:
1085
1086 void do_generate_ax (struct expression *exp,
1087 struct agent_expr *ax,
1088 struct axs_value *value,
1089 struct type *cast_type)
1090 override
1091 {
1092 gen_expr_binop (exp, OP,
1093 std::get<0> (this->m_storage).get (),
1094 std::get<1> (this->m_storage).get (),
1095 ax, value);
1096 }
1097};
1098
1099using exp_operation = binop_operation<BINOP_EXP, eval_op_binary>;
1100using intdiv_operation = binop_operation<BINOP_INTDIV, eval_op_binary>;
1101using mod_operation = binop_operation<BINOP_MOD, eval_op_binary>;
1102
1103using mul_operation = usual_ax_binop_operation<BINOP_MUL, eval_op_binary>;
1104using div_operation = usual_ax_binop_operation<BINOP_DIV, eval_op_binary>;
1105using rem_operation = usual_ax_binop_operation<BINOP_REM, eval_op_binary>;
1106using lsh_operation = usual_ax_binop_operation<BINOP_LSH, eval_op_binary>;
1107using rsh_operation = usual_ax_binop_operation<BINOP_RSH, eval_op_binary>;
1108using bitwise_and_operation
1109 = usual_ax_binop_operation<BINOP_BITWISE_AND, eval_op_binary>;
1110using bitwise_ior_operation
1111 = usual_ax_binop_operation<BINOP_BITWISE_IOR, eval_op_binary>;
1112using bitwise_xor_operation
1113 = usual_ax_binop_operation<BINOP_BITWISE_XOR, eval_op_binary>;
1114
e2803273
TT
1115} /* namespace expr */
1116
1117#endif /* EXPOP_H */
This page took 0.100765 seconds and 4 git commands to generate.