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