1 /* Definitions for expressions in GDB
2
3 Copyright (C) 2020-2024 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 "c-lang.h"
24 #include "cp-abi.h"
25 #include "expression.h"
26 #include "language.h"
27 #include "objfiles.h"
28 #include "gdbsupport/traits.h"
29 #include "gdbsupport/enum-flags.h"
30
31 struct agent_expr;
32 struct axs_value;
33
34 extern 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);
38 extern 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 extern void gen_expr_unop (struct expression *exp,
44 enum exp_opcode op,
45 expr::operation *lhs,
46 struct agent_expr *ax, struct axs_value *value);
47
48 extern struct value *eval_op_scope (struct type *expect_type,
49 struct expression *exp,
50 enum noside noside,
51 struct type *type, const char *string);
52 extern struct value *eval_op_var_msym_value (struct type *expect_type,
53 struct expression *exp,
54 enum noside noside,
55 bool outermost_p,
56 bound_minimal_symbol msymbol);
57 extern struct value *eval_op_var_entry_value (struct type *expect_type,
58 struct expression *exp,
59 enum noside noside, symbol *sym);
60 extern struct value *eval_op_func_static_var (struct type *expect_type,
61 struct expression *exp,
62 enum noside noside,
63 value *func, const char *var);
64 extern struct value *eval_op_register (struct type *expect_type,
65 struct expression *exp,
66 enum noside noside, const char *name);
67 extern struct value *eval_op_structop_struct (struct type *expect_type,
68 struct expression *exp,
69 enum noside noside,
70 struct value *arg1,
71 const char *string);
72 extern struct value *eval_op_structop_ptr (struct type *expect_type,
73 struct expression *exp,
74 enum noside noside,
75 struct value *arg1,
76 const char *string);
77 extern struct value *eval_op_member (struct type *expect_type,
78 struct expression *exp,
79 enum noside noside,
80 struct value *arg1, struct value *arg2);
81 extern struct value *eval_op_add (struct type *expect_type,
82 struct expression *exp,
83 enum noside noside,
84 struct value *arg1, struct value *arg2);
85 extern struct value *eval_op_sub (struct type *expect_type,
86 struct expression *exp,
87 enum noside noside,
88 struct value *arg1, struct value *arg2);
89 extern struct value *eval_op_binary (struct type *expect_type,
90 struct expression *exp,
91 enum noside noside, enum exp_opcode op,
92 struct value *arg1, struct value *arg2);
93 extern struct value *eval_op_subscript (struct type *expect_type,
94 struct expression *exp,
95 enum noside noside, enum exp_opcode op,
96 struct value *arg1,
97 struct value *arg2);
98 extern struct value *eval_op_equal (struct type *expect_type,
99 struct expression *exp,
100 enum noside noside, enum exp_opcode op,
101 struct value *arg1,
102 struct value *arg2);
103 extern struct value *eval_op_notequal (struct type *expect_type,
104 struct expression *exp,
105 enum noside noside, enum exp_opcode op,
106 struct value *arg1,
107 struct value *arg2);
108 extern struct value *eval_op_less (struct type *expect_type,
109 struct expression *exp,
110 enum noside noside, enum exp_opcode op,
111 struct value *arg1,
112 struct value *arg2);
113 extern struct value *eval_op_gtr (struct type *expect_type,
114 struct expression *exp,
115 enum noside noside, enum exp_opcode op,
116 struct value *arg1,
117 struct value *arg2);
118 extern struct value *eval_op_geq (struct type *expect_type,
119 struct expression *exp,
120 enum noside noside, enum exp_opcode op,
121 struct value *arg1,
122 struct value *arg2);
123 extern struct value *eval_op_leq (struct type *expect_type,
124 struct expression *exp,
125 enum noside noside, enum exp_opcode op,
126 struct value *arg1,
127 struct value *arg2);
128 extern struct value *eval_op_repeat (struct type *expect_type,
129 struct expression *exp,
130 enum noside noside, enum exp_opcode op,
131 struct value *arg1,
132 struct value *arg2);
133 extern struct value *eval_op_plus (struct type *expect_type,
134 struct expression *exp,
135 enum noside noside, enum exp_opcode op,
136 struct value *arg1);
137 extern struct value *eval_op_neg (struct type *expect_type,
138 struct expression *exp,
139 enum noside noside, enum exp_opcode op,
140 struct value *arg1);
141 extern struct value *eval_op_complement (struct type *expect_type,
142 struct expression *exp,
143 enum noside noside,
144 enum exp_opcode op,
145 struct value *arg1);
146 extern struct value *eval_op_lognot (struct type *expect_type,
147 struct expression *exp,
148 enum noside noside,
149 enum exp_opcode op,
150 struct value *arg1);
151 extern struct value *eval_op_preinc (struct type *expect_type,
152 struct expression *exp,
153 enum noside noside,
154 enum exp_opcode op,
155 struct value *arg1);
156 extern struct value *eval_op_predec (struct type *expect_type,
157 struct expression *exp,
158 enum noside noside,
159 enum exp_opcode op,
160 struct value *arg1);
161 extern struct value *eval_op_postinc (struct type *expect_type,
162 struct expression *exp,
163 enum noside noside,
164 enum exp_opcode op,
165 struct value *arg1);
166 extern struct value *eval_op_postdec (struct type *expect_type,
167 struct expression *exp,
168 enum noside noside,
169 enum exp_opcode op,
170 struct value *arg1);
171 extern struct value *eval_op_ind (struct type *expect_type,
172 struct expression *exp,
173 enum noside noside,
174 struct value *arg1);
175 extern struct value *eval_op_type (struct type *expect_type,
176 struct expression *exp,
177 enum noside noside, struct type *type);
178 extern struct value *eval_op_alignof (struct type *expect_type,
179 struct expression *exp,
180 enum noside noside,
181 struct value *arg1);
182 extern struct value *eval_op_memval (struct type *expect_type,
183 struct expression *exp,
184 enum noside noside,
185 struct value *arg1, struct type *type);
186 extern struct value *eval_binop_assign_modify (struct type *expect_type,
187 struct expression *exp,
188 enum noside noside,
189 enum exp_opcode op,
190 struct value *arg1,
191 struct value *arg2);
192
193 namespace expr
194 {
195
196 class ada_component;
197
198 /* The check_objfile overloads are used to check whether a particular
199 component of some operation references an objfile. The passed-in
200 objfile will never be a debug objfile. */
201
202 /* See if EXP_OBJFILE matches OBJFILE. */
203 static inline bool
check_objfile(struct objfile * exp_objfile,struct objfile * objfile)204 check_objfile (struct objfile *exp_objfile, struct objfile *objfile)
205 {
206 if (exp_objfile->separate_debug_objfile_backlink)
207 exp_objfile = exp_objfile->separate_debug_objfile_backlink;
208 return exp_objfile == objfile;
209 }
210
211 static inline bool
check_objfile(struct type * type,struct objfile * objfile)212 check_objfile (struct type *type, struct objfile *objfile)
213 {
214 struct objfile *ty_objfile = type->objfile_owner ();
215 if (ty_objfile != nullptr)
216 return check_objfile (ty_objfile, objfile);
217 return false;
218 }
219
220 static inline bool
check_objfile(struct symbol * sym,struct objfile * objfile)221 check_objfile (struct symbol *sym, struct objfile *objfile)
222 {
223 return check_objfile (sym->objfile (), objfile);
224 }
225
226 extern bool check_objfile (const struct block *block,
227 struct objfile *objfile);
228
229 static inline bool
check_objfile(const block_symbol & sym,struct objfile * objfile)230 check_objfile (const block_symbol &sym, struct objfile *objfile)
231 {
232 return (check_objfile (sym.symbol, objfile)
233 || check_objfile (sym.block, objfile));
234 }
235
236 static inline bool
check_objfile(bound_minimal_symbol minsym,struct objfile * objfile)237 check_objfile (bound_minimal_symbol minsym, struct objfile *objfile)
238 {
239 return check_objfile (minsym.objfile, objfile);
240 }
241
242 static inline bool
check_objfile(internalvar * ivar,struct objfile * objfile)243 check_objfile (internalvar *ivar, struct objfile *objfile)
244 {
245 return false;
246 }
247
248 static inline bool
check_objfile(const std::string & str,struct objfile * objfile)249 check_objfile (const std::string &str, struct objfile *objfile)
250 {
251 return false;
252 }
253
254 static inline bool
check_objfile(const operation_up & op,struct objfile * objfile)255 check_objfile (const operation_up &op, struct objfile *objfile)
256 {
257 return op->uses_objfile (objfile);
258 }
259
260 static inline bool
check_objfile(enum exp_opcode val,struct objfile * objfile)261 check_objfile (enum exp_opcode val, struct objfile *objfile)
262 {
263 return false;
264 }
265
266 static inline bool
check_objfile(ULONGEST val,struct objfile * objfile)267 check_objfile (ULONGEST val, struct objfile *objfile)
268 {
269 return false;
270 }
271
272 static inline bool
check_objfile(const gdb_mpz & val,struct objfile * objfile)273 check_objfile (const gdb_mpz &val, struct objfile *objfile)
274 {
275 return false;
276 }
277
278 template<typename T>
279 static inline bool
check_objfile(enum_flags<T> val,struct objfile * objfile)280 check_objfile (enum_flags<T> val, struct objfile *objfile)
281 {
282 return false;
283 }
284
285 template<typename T>
286 static inline bool
check_objfile(const std::vector<T> & collection,struct objfile * objfile)287 check_objfile (const std::vector<T> &collection, struct objfile *objfile)
288 {
289 for (const auto &item : collection)
290 {
291 if (check_objfile (item, objfile))
292 return true;
293 }
294 return false;
295 }
296
297 template<typename S, typename T>
298 static inline bool
check_objfile(const std::pair<S,T> & item,struct objfile * objfile)299 check_objfile (const std::pair<S, T> &item, struct objfile *objfile)
300 {
301 return (check_objfile (item.first, objfile)
302 || check_objfile (item.second, objfile));
303 }
304
305 extern bool check_objfile (const std::unique_ptr<ada_component> &comp,
306 struct objfile *objfile);
307
308 static inline void
dump_for_expression(struct ui_file * stream,int depth,const operation_up & op)309 dump_for_expression (struct ui_file *stream, int depth,
310 const operation_up &op)
311 {
312 if (op == nullptr)
313 gdb_printf (stream, _("%*snullptr\n"), depth, "");
314 else
315 op->dump (stream, depth);
316 }
317
318 extern void dump_for_expression (struct ui_file *stream, int depth,
319 enum exp_opcode op);
320 extern void dump_for_expression (struct ui_file *stream, int depth,
321 const std::string &str);
322 extern void dump_for_expression (struct ui_file *stream, int depth,
323 struct type *type);
324 extern void dump_for_expression (struct ui_file *stream, int depth,
325 CORE_ADDR addr);
326 extern void dump_for_expression (struct ui_file *stream, int depth,
327 const gdb_mpz &addr);
328 extern void dump_for_expression (struct ui_file *stream, int depth,
329 internalvar *ivar);
330 extern void dump_for_expression (struct ui_file *stream, int depth,
331 symbol *sym);
332 extern void dump_for_expression (struct ui_file *stream, int depth,
333 const block_symbol &sym);
334 extern void dump_for_expression (struct ui_file *stream, int depth,
335 bound_minimal_symbol msym);
336 extern void dump_for_expression (struct ui_file *stream, int depth,
337 const block *bl);
338 extern void dump_for_expression (struct ui_file *stream, int depth,
339 type_instance_flags flags);
340 extern void dump_for_expression (struct ui_file *stream, int depth,
341 enum c_string_type_values flags);
342 extern void dump_for_expression (struct ui_file *stream, int depth,
343 enum range_flag flags);
344 extern void dump_for_expression (struct ui_file *stream, int depth,
345 const std::unique_ptr<ada_component> &comp);
346
347 template<typename T>
348 void
dump_for_expression(struct ui_file * stream,int depth,const std::vector<T> & vals)349 dump_for_expression (struct ui_file *stream, int depth,
350 const std::vector<T> &vals)
351 {
352 gdb_printf (stream, _("%*sVector:\n"), depth, "");
353 for (auto &item : vals)
354 dump_for_expression (stream, depth + 1, item);
355 }
356
357 template<typename X, typename Y>
358 void
dump_for_expression(struct ui_file * stream,int depth,const std::pair<X,Y> & vals)359 dump_for_expression (struct ui_file *stream, int depth,
360 const std::pair<X, Y> &vals)
361 {
362 dump_for_expression (stream, depth, vals.first);
363 dump_for_expression (stream, depth, vals.second);
364 }
365
366 /* Base class for most concrete operations. This class holds data,
367 specified via template parameters, and supplies generic
368 implementations of the 'dump' and 'uses_objfile' methods. */
369 template<typename... Arg>
370 class tuple_holding_operation : public operation
371 {
372 public:
373
tuple_holding_operation(Arg...args)374 explicit tuple_holding_operation (Arg... args)
375 : m_storage (std::forward<Arg> (args)...)
376 {
377 }
378
379 DISABLE_COPY_AND_ASSIGN (tuple_holding_operation);
380
uses_objfile(struct objfile * objfile)381 bool uses_objfile (struct objfile *objfile) const override
382 {
383 return do_check_objfile<0, Arg...> (objfile, m_storage);
384 }
385
dump(struct ui_file * stream,int depth)386 void dump (struct ui_file *stream, int depth) const override
387 {
388 dump_for_expression (stream, depth, opcode ());
389 do_dump<0, Arg...> (stream, depth + 1, m_storage);
390 }
391
392 protected:
393
394 /* Storage for the data. */
395 std::tuple<Arg...> m_storage;
396
397 private:
398
399 /* do_dump does the work of dumping the data. */
400 template<int I, typename... T>
401 typename std::enable_if<I == sizeof... (T), void>::type
do_dump(struct ui_file * stream,int depth,const std::tuple<T...> & value)402 do_dump (struct ui_file *stream, int depth, const std::tuple<T...> &value)
403 const
404 {
405 }
406
407 template<int I, typename... T>
408 typename std::enable_if<I < sizeof... (T), void>::type
409 do_dump (struct ui_file *stream, int depth, const std::tuple<T...> &value)
410 const
411 {
412 dump_for_expression (stream, depth, std::get<I> (value));
413 do_dump<I + 1, T...> (stream, depth, value);
414 }
415
416 /* do_check_objfile does the work of checking whether this object
417 refers to OBJFILE. */
418 template<int I, typename... T>
419 typename std::enable_if<I == sizeof... (T), bool>::type
do_check_objfile(struct objfile * objfile,const std::tuple<T...> & value)420 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
421 const
422 {
423 return false;
424 }
425
426 template<int I, typename... T>
427 typename std::enable_if<I < sizeof... (T), bool>::type
428 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
429 const
430 {
431 if (check_objfile (std::get<I> (value), objfile))
432 return true;
433 return do_check_objfile<I + 1, T...> (objfile, value);
434 }
435 };
436
437 /* The check_constant overloads are used to decide whether a given
438 concrete operation is a constant. This is done by checking the
439 operands. */
440
441 static inline bool
check_constant(const operation_up & item)442 check_constant (const operation_up &item)
443 {
444 return item->constant_p ();
445 }
446
447 static inline bool
check_constant(bound_minimal_symbol msym)448 check_constant (bound_minimal_symbol msym)
449 {
450 return false;
451 }
452
453 static inline bool
check_constant(struct type * type)454 check_constant (struct type *type)
455 {
456 return true;
457 }
458
459 static inline bool
check_constant(const struct block * block)460 check_constant (const struct block *block)
461 {
462 return true;
463 }
464
465 static inline bool
check_constant(const std::string & str)466 check_constant (const std::string &str)
467 {
468 return true;
469 }
470
471 static inline bool
check_constant(ULONGEST cst)472 check_constant (ULONGEST cst)
473 {
474 return true;
475 }
476
477 static inline bool
check_constant(const gdb_mpz & cst)478 check_constant (const gdb_mpz &cst)
479 {
480 return true;
481 }
482
483 static inline bool
check_constant(struct symbol * sym)484 check_constant (struct symbol *sym)
485 {
486 enum address_class sc = sym->aclass ();
487 return (sc == LOC_BLOCK
488 || sc == LOC_CONST
489 || sc == LOC_CONST_BYTES
490 || sc == LOC_LABEL);
491 }
492
493 static inline bool
check_constant(const block_symbol & sym)494 check_constant (const block_symbol &sym)
495 {
496 /* We know the block is constant, so we only need to check the
497 symbol. */
498 return check_constant (sym.symbol);
499 }
500
501 template<typename T>
502 static inline bool
check_constant(const std::vector<T> & collection)503 check_constant (const std::vector<T> &collection)
504 {
505 for (const auto &item : collection)
506 if (!check_constant (item))
507 return false;
508 return true;
509 }
510
511 template<typename S, typename T>
512 static inline bool
check_constant(const std::pair<S,T> & item)513 check_constant (const std::pair<S, T> &item)
514 {
515 return check_constant (item.first) && check_constant (item.second);
516 }
517
518 /* Base class for concrete operations. This class supplies an
519 implementation of 'constant_p' that works by checking the
520 operands. */
521 template<typename... Arg>
522 class maybe_constant_operation
523 : public tuple_holding_operation<Arg...>
524 {
525 public:
526
527 using tuple_holding_operation<Arg...>::tuple_holding_operation;
528
constant_p()529 bool constant_p () const override
530 {
531 return do_check_constant<0, Arg...> (this->m_storage);
532 }
533
534 private:
535
536 template<int I, typename... T>
537 typename std::enable_if<I == sizeof... (T), bool>::type
do_check_constant(const std::tuple<T...> & value)538 do_check_constant (const std::tuple<T...> &value) const
539 {
540 return true;
541 }
542
543 template<int I, typename... T>
544 typename std::enable_if<I < sizeof... (T), bool>::type
545 do_check_constant (const std::tuple<T...> &value) const
546 {
547 if (!check_constant (std::get<I> (value)))
548 return false;
549 return do_check_constant<I + 1, T...> (value);
550 }
551 };
552
553 /* A floating-point constant. The constant is encoded in the target
554 format. */
555
556 typedef std::array<gdb_byte, 16> float_data;
557
558 /* An operation that holds a floating-point constant of a given
559 type.
560
561 This does not need the facilities provided by
562 tuple_holding_operation, so it does not use it. */
563 class float_const_operation
564 : public operation
565 {
566 public:
567
float_const_operation(struct type * type,float_data data)568 float_const_operation (struct type *type, float_data data)
569 : m_type (type),
570 m_data (data)
571 {
572 }
573
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)574 value *evaluate (struct type *expect_type,
575 struct expression *exp,
576 enum noside noside) override
577 {
578 return value_from_contents (m_type, m_data.data ());
579 }
580
opcode()581 enum exp_opcode opcode () const override
582 { return OP_FLOAT; }
583
constant_p()584 bool constant_p () const override
585 { return true; }
586
587 void dump (struct ui_file *stream, int depth) const override;
588
589 private:
590
591 struct type *m_type;
592 float_data m_data;
593 };
594
595 class scope_operation
596 : public maybe_constant_operation<struct type *, std::string>
597 {
598 public:
599
600 using maybe_constant_operation::maybe_constant_operation;
601
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)602 value *evaluate (struct type *expect_type,
603 struct expression *exp,
604 enum noside noside) override
605 {
606 return eval_op_scope (expect_type, exp, noside,
607 std::get<0> (m_storage),
608 std::get<1> (m_storage).c_str ());
609 }
610
611 value *evaluate_for_address (struct expression *exp,
612 enum noside noside) override;
613
614 value *evaluate_funcall (struct type *expect_type,
615 struct expression *exp,
616 enum noside noside,
617 const std::vector<operation_up> &args) override;
618
opcode()619 enum exp_opcode opcode () const override
620 { return OP_SCOPE; }
621
622 protected:
623
624 void do_generate_ax (struct expression *exp,
625 struct agent_expr *ax,
626 struct axs_value *value,
627 struct type *cast_type)
628 override;
629 };
630
631 /* Compute the value of a variable. */
632 class var_value_operation
633 : public maybe_constant_operation<block_symbol>
634 {
635 public:
636
637 using maybe_constant_operation::maybe_constant_operation;
638
639 value *evaluate (struct type *expect_type,
640 struct expression *exp,
641 enum noside noside) override;
642
643 value *evaluate_with_coercion (struct expression *exp,
644 enum noside noside) override;
645
646 value *evaluate_for_sizeof (struct expression *exp, enum noside noside)
647 override;
648
649 value *evaluate_for_cast (struct type *expect_type,
650 struct expression *exp,
651 enum noside noside) override;
652
653 value *evaluate_for_address (struct expression *exp, enum noside noside)
654 override;
655
656 value *evaluate_funcall (struct type *expect_type,
657 struct expression *exp,
658 enum noside noside,
659 const std::vector<operation_up> &args) override;
660
opcode()661 enum exp_opcode opcode () const override
662 { return OP_VAR_VALUE; }
663
664 /* Return the symbol referenced by this object. */
get_symbol()665 symbol *get_symbol () const
666 {
667 return std::get<0> (m_storage).symbol;
668 }
669
670 protected:
671
672 void do_generate_ax (struct expression *exp,
673 struct agent_expr *ax,
674 struct axs_value *value,
675 struct type *cast_type)
676 override;
677 };
678
679 class long_const_operation
680 : public tuple_holding_operation<struct type *, gdb_mpz>
681 {
682 public:
683
684 using tuple_holding_operation::tuple_holding_operation;
685
long_const_operation(struct type * type,LONGEST val)686 long_const_operation (struct type *type, LONGEST val)
687 : long_const_operation (type, gdb_mpz (val))
688 { }
689
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)690 value *evaluate (struct type *expect_type,
691 struct expression *exp,
692 enum noside noside) override
693 {
694 return value_from_mpz (std::get<0> (m_storage), std::get<1> (m_storage));
695 }
696
opcode()697 enum exp_opcode opcode () const override
698 { return OP_LONG; }
699
constant_p()700 bool constant_p () const override
701 { return true; }
702
703 protected:
704
as_longest()705 LONGEST as_longest () const
706 { return std::get<1> (m_storage).as_integer_truncate<LONGEST> (); }
707
708 void do_generate_ax (struct expression *exp,
709 struct agent_expr *ax,
710 struct axs_value *value,
711 struct type *cast_type)
712 override;
713 };
714
715 class var_msym_value_operation
716 : public maybe_constant_operation<bound_minimal_symbol>
717 {
718 public:
719
720 using maybe_constant_operation::maybe_constant_operation;
721
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)722 value *evaluate (struct type *expect_type,
723 struct expression *exp,
724 enum noside noside) override
725 {
726 return eval_op_var_msym_value (expect_type, exp, noside, m_outermost,
727 std::get<0> (m_storage));
728 }
729
730 value *evaluate_for_sizeof (struct expression *exp, enum noside noside)
731 override;
732
733 value *evaluate_for_address (struct expression *exp, enum noside noside)
734 override;
735
736 value *evaluate_for_cast (struct type *expect_type,
737 struct expression *exp,
738 enum noside noside) override;
739
evaluate_funcall(struct type * expect_type,struct expression * exp,enum noside noside,const std::vector<operation_up> & args)740 value *evaluate_funcall (struct type *expect_type,
741 struct expression *exp,
742 enum noside noside,
743 const std::vector<operation_up> &args) override
744 {
745 const char *name = std::get<0> (m_storage).minsym->print_name ();
746 return operation::evaluate_funcall (expect_type, exp, noside, name, args);
747 }
748
opcode()749 enum exp_opcode opcode () const override
750 { return OP_VAR_MSYM_VALUE; }
751
set_outermost()752 void set_outermost () override
753 {
754 m_outermost = true;
755 }
756
757 protected:
758
759 /* True if this is the outermost operation in the expression. */
760 bool m_outermost = false;
761
762 void do_generate_ax (struct expression *exp,
763 struct agent_expr *ax,
764 struct axs_value *value,
765 struct type *cast_type)
766 override;
767 };
768
769 class var_entry_value_operation
770 : public tuple_holding_operation<symbol *>
771 {
772 public:
773
774 using tuple_holding_operation::tuple_holding_operation;
775
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)776 value *evaluate (struct type *expect_type,
777 struct expression *exp,
778 enum noside noside) override
779 {
780 return eval_op_var_entry_value (expect_type, exp, noside,
781 std::get<0> (m_storage));
782 }
783
opcode()784 enum exp_opcode opcode () const override
785 { return OP_VAR_ENTRY_VALUE; }
786 };
787
788 class func_static_var_operation
789 : public maybe_constant_operation<operation_up, std::string>
790 {
791 public:
792
793 using maybe_constant_operation::maybe_constant_operation;
794
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)795 value *evaluate (struct type *expect_type,
796 struct expression *exp,
797 enum noside noside) override
798 {
799 value *func = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
800 return eval_op_func_static_var (expect_type, exp, noside, func,
801 std::get<1> (m_storage).c_str ());
802 }
803
opcode()804 enum exp_opcode opcode () const override
805 { return OP_FUNC_STATIC_VAR; }
806 };
807
808 class last_operation
809 : public tuple_holding_operation<int>
810 {
811 public:
812
813 using tuple_holding_operation::tuple_holding_operation;
814
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)815 value *evaluate (struct type *expect_type,
816 struct expression *exp,
817 enum noside noside) override
818 {
819 return access_value_history (std::get<0> (m_storage));
820 }
821
opcode()822 enum exp_opcode opcode () const override
823 { return OP_LAST; }
824 };
825
826 class register_operation
827 : public tuple_holding_operation<std::string>
828 {
829 public:
830
831 using tuple_holding_operation::tuple_holding_operation;
832
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)833 value *evaluate (struct type *expect_type,
834 struct expression *exp,
835 enum noside noside) override
836 {
837 return eval_op_register (expect_type, exp, noside,
838 std::get<0> (m_storage).c_str ());
839 }
840
opcode()841 enum exp_opcode opcode () const override
842 { return OP_REGISTER; }
843
844 /* Return the name of the register. */
get_name()845 const char *get_name () const
846 {
847 return std::get<0> (m_storage).c_str ();
848 }
849
850 protected:
851
852 void do_generate_ax (struct expression *exp,
853 struct agent_expr *ax,
854 struct axs_value *value,
855 struct type *cast_type)
856 override;
857 };
858
859 class bool_operation
860 : public tuple_holding_operation<bool>
861 {
862 public:
863
864 using tuple_holding_operation::tuple_holding_operation;
865
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)866 value *evaluate (struct type *expect_type,
867 struct expression *exp,
868 enum noside noside) override
869 {
870 struct type *type = language_bool_type (exp->language_defn, exp->gdbarch);
871 return value_from_longest (type, std::get<0> (m_storage));
872 }
873
opcode()874 enum exp_opcode opcode () const override
875 { return OP_BOOL; }
876
constant_p()877 bool constant_p () const override
878 { return true; }
879 };
880
881 class internalvar_operation
882 : public tuple_holding_operation<internalvar *>
883 {
884 public:
885
886 using tuple_holding_operation::tuple_holding_operation;
887
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)888 value *evaluate (struct type *expect_type,
889 struct expression *exp,
890 enum noside noside) override
891 {
892 return value_of_internalvar (exp->gdbarch,
893 std::get<0> (m_storage));
894 }
895
get_internalvar()896 internalvar *get_internalvar () const
897 {
898 return std::get<0> (m_storage);
899 }
900
opcode()901 enum exp_opcode opcode () const override
902 { return OP_INTERNALVAR; }
903
904 protected:
905
906 void do_generate_ax (struct expression *exp,
907 struct agent_expr *ax,
908 struct axs_value *value,
909 struct type *cast_type)
910 override;
911 };
912
913 class string_operation
914 : public tuple_holding_operation<std::string>
915 {
916 public:
917
918 using tuple_holding_operation::tuple_holding_operation;
919
920 value *evaluate (struct type *expect_type,
921 struct expression *exp,
922 enum noside noside) override;
923
opcode()924 enum exp_opcode opcode () const override
925 { return OP_STRING; }
926 };
927
928 class ternop_slice_operation
929 : public maybe_constant_operation<operation_up, operation_up, operation_up>
930 {
931 public:
932
933 using maybe_constant_operation::maybe_constant_operation;
934
935 value *evaluate (struct type *expect_type,
936 struct expression *exp,
937 enum noside noside) override;
938
opcode()939 enum exp_opcode opcode () const override
940 { return TERNOP_SLICE; }
941 };
942
943 class ternop_cond_operation
944 : public maybe_constant_operation<operation_up, operation_up, operation_up>
945 {
946 public:
947
948 using maybe_constant_operation::maybe_constant_operation;
949
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)950 value *evaluate (struct type *expect_type,
951 struct expression *exp,
952 enum noside noside) override
953 {
954 struct value *val
955 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
956
957 if (value_logical_not (val))
958 return std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
959 return std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
960 }
961
opcode()962 enum exp_opcode opcode () const override
963 { return TERNOP_COND; }
964
965 protected:
966
967 void do_generate_ax (struct expression *exp,
968 struct agent_expr *ax,
969 struct axs_value *value,
970 struct type *cast_type)
971 override;
972 };
973
974 class complex_operation
975 : public maybe_constant_operation<operation_up, operation_up, struct type *>
976 {
977 public:
978
979 using maybe_constant_operation::maybe_constant_operation;
980
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)981 value *evaluate (struct type *expect_type,
982 struct expression *exp,
983 enum noside noside) override
984 {
985 value *real = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
986 value *imag = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
987 return value_literal_complex (real, imag,
988 std::get<2> (m_storage));
989 }
990
opcode()991 enum exp_opcode opcode () const override
992 { return OP_COMPLEX; }
993 };
994
995 class structop_base_operation
996 : public tuple_holding_operation<operation_up, std::string>
997 {
998 public:
999
1000 /* Used for completion. Return the field name. */
get_string()1001 const std::string &get_string () const
1002 {
1003 return std::get<1> (m_storage);
1004 }
1005
1006 value *evaluate_funcall (struct type *expect_type,
1007 struct expression *exp,
1008 enum noside noside,
1009 const std::vector<operation_up> &args) override;
1010
1011 /* Try to complete this operation in the context of EXP. TRACKER is
1012 the completion tracker to update. Return true if completion was
1013 possible, false otherwise. */
complete(struct expression * exp,completion_tracker & tracker)1014 virtual bool complete (struct expression *exp, completion_tracker &tracker)
1015 {
1016 return complete (exp, tracker, "");
1017 }
1018
1019 protected:
1020
1021 /* Do the work of the public 'complete' method. PREFIX is prepended
1022 to each result. */
1023 bool complete (struct expression *exp, completion_tracker &tracker,
1024 const char *prefix);
1025
1026 using tuple_holding_operation::tuple_holding_operation;
1027 };
1028
1029 class structop_operation
1030 : public structop_base_operation
1031 {
1032 public:
1033
1034 using structop_base_operation::structop_base_operation;
1035
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1036 value *evaluate (struct type *expect_type,
1037 struct expression *exp,
1038 enum noside noside) override
1039 {
1040 value *val =std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1041 return eval_op_structop_struct (expect_type, exp, noside, val,
1042 std::get<1> (m_storage).c_str ());
1043 }
1044
opcode()1045 enum exp_opcode opcode () const override
1046 { return STRUCTOP_STRUCT; }
1047
1048 protected:
1049
do_generate_ax(struct expression * exp,struct agent_expr * ax,struct axs_value * value,struct type * cast_type)1050 void do_generate_ax (struct expression *exp,
1051 struct agent_expr *ax,
1052 struct axs_value *value,
1053 struct type *cast_type)
1054 override
1055 {
1056 gen_expr_structop (exp, STRUCTOP_STRUCT,
1057 std::get<0> (this->m_storage).get (),
1058 std::get<1> (this->m_storage).c_str (),
1059 ax, value);
1060 }
1061 };
1062
1063 class structop_ptr_operation
1064 : public structop_base_operation
1065 {
1066 public:
1067
1068 using structop_base_operation::structop_base_operation;
1069
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1070 value *evaluate (struct type *expect_type,
1071 struct expression *exp,
1072 enum noside noside) override
1073 {
1074 value *val = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1075 return eval_op_structop_ptr (expect_type, exp, noside, val,
1076 std::get<1> (m_storage).c_str ());
1077 }
1078
opcode()1079 enum exp_opcode opcode () const override
1080 { return STRUCTOP_PTR; }
1081
1082 protected:
1083
do_generate_ax(struct expression * exp,struct agent_expr * ax,struct axs_value * value,struct type * cast_type)1084 void do_generate_ax (struct expression *exp,
1085 struct agent_expr *ax,
1086 struct axs_value *value,
1087 struct type *cast_type)
1088 override
1089 {
1090 gen_expr_structop (exp, STRUCTOP_PTR,
1091 std::get<0> (this->m_storage).get (),
1092 std::get<1> (this->m_storage).c_str (),
1093 ax, value);
1094 }
1095 };
1096
1097 class structop_member_base
1098 : public tuple_holding_operation<operation_up, operation_up>
1099 {
1100 public:
1101
1102 using tuple_holding_operation::tuple_holding_operation;
1103
1104 value *evaluate_funcall (struct type *expect_type,
1105 struct expression *exp,
1106 enum noside noside,
1107 const std::vector<operation_up> &args) override;
1108 };
1109
1110 class structop_member_operation
1111 : public structop_member_base
1112 {
1113 public:
1114
1115 using structop_member_base::structop_member_base;
1116
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1117 value *evaluate (struct type *expect_type,
1118 struct expression *exp,
1119 enum noside noside) override
1120 {
1121 value *lhs
1122 = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
1123 value *rhs
1124 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
1125 return eval_op_member (expect_type, exp, noside, lhs, rhs);
1126 }
1127
opcode()1128 enum exp_opcode opcode () const override
1129 { return STRUCTOP_MEMBER; }
1130 };
1131
1132 class structop_mptr_operation
1133 : public structop_member_base
1134 {
1135 public:
1136
1137 using structop_member_base::structop_member_base;
1138
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1139 value *evaluate (struct type *expect_type,
1140 struct expression *exp,
1141 enum noside noside) override
1142 {
1143 value *lhs
1144 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1145 value *rhs
1146 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
1147 return eval_op_member (expect_type, exp, noside, lhs, rhs);
1148 }
1149
opcode()1150 enum exp_opcode opcode () const override
1151 { return STRUCTOP_MPTR; }
1152 };
1153
1154 class concat_operation
1155 : public maybe_constant_operation<operation_up, operation_up>
1156 {
1157 public:
1158
1159 using maybe_constant_operation::maybe_constant_operation;
1160
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1161 value *evaluate (struct type *expect_type,
1162 struct expression *exp,
1163 enum noside noside) override
1164 {
1165 value *lhs
1166 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
1167 value *rhs
1168 = std::get<1> (m_storage)->evaluate_with_coercion (exp, noside);
1169 return value_concat (lhs, rhs);
1170 }
1171
opcode()1172 enum exp_opcode opcode () const override
1173 { return BINOP_CONCAT; }
1174 };
1175
1176 class add_operation
1177 : public maybe_constant_operation<operation_up, operation_up>
1178 {
1179 public:
1180
1181 using maybe_constant_operation::maybe_constant_operation;
1182
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1183 value *evaluate (struct type *expect_type,
1184 struct expression *exp,
1185 enum noside noside) override
1186 {
1187 value *lhs
1188 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
1189 value *rhs
1190 = std::get<1> (m_storage)->evaluate_with_coercion (exp, noside);
1191 return eval_op_add (expect_type, exp, noside, lhs, rhs);
1192 }
1193
opcode()1194 enum exp_opcode opcode () const override
1195 { return BINOP_ADD; }
1196
1197 protected:
1198
do_generate_ax(struct expression * exp,struct agent_expr * ax,struct axs_value * value,struct type * cast_type)1199 void do_generate_ax (struct expression *exp,
1200 struct agent_expr *ax,
1201 struct axs_value *value,
1202 struct type *cast_type)
1203 override
1204 {
1205 gen_expr_binop (exp, BINOP_ADD,
1206 std::get<0> (this->m_storage).get (),
1207 std::get<1> (this->m_storage).get (),
1208 ax, value);
1209 }
1210 };
1211
1212 class sub_operation
1213 : public maybe_constant_operation<operation_up, operation_up>
1214 {
1215 public:
1216
1217 using maybe_constant_operation::maybe_constant_operation;
1218
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1219 value *evaluate (struct type *expect_type,
1220 struct expression *exp,
1221 enum noside noside) override
1222 {
1223 value *lhs
1224 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
1225 value *rhs
1226 = std::get<1> (m_storage)->evaluate_with_coercion (exp, noside);
1227 return eval_op_sub (expect_type, exp, noside, lhs, rhs);
1228 }
1229
opcode()1230 enum exp_opcode opcode () const override
1231 { return BINOP_SUB; }
1232
1233 protected:
1234
do_generate_ax(struct expression * exp,struct agent_expr * ax,struct axs_value * value,struct type * cast_type)1235 void do_generate_ax (struct expression *exp,
1236 struct agent_expr *ax,
1237 struct axs_value *value,
1238 struct type *cast_type)
1239 override
1240 {
1241 gen_expr_binop (exp, BINOP_SUB,
1242 std::get<0> (this->m_storage).get (),
1243 std::get<1> (this->m_storage).get (),
1244 ax, value);
1245 }
1246 };
1247
1248 typedef struct value *binary_ftype (struct type *expect_type,
1249 struct expression *exp,
1250 enum noside noside, enum exp_opcode op,
1251 struct value *arg1, struct value *arg2);
1252
1253 template<enum exp_opcode OP, binary_ftype FUNC>
1254 class binop_operation
1255 : public maybe_constant_operation<operation_up, operation_up>
1256 {
1257 public:
1258
1259 using maybe_constant_operation::maybe_constant_operation;
1260
1261 value *evaluate (struct type *expect_type,
1262 struct expression *exp,
1263 enum noside noside) override
1264 {
1265 value *lhs
1266 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1267 value *rhs
1268 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
1269 return FUNC (expect_type, exp, noside, OP, lhs, rhs);
1270 }
1271
1272 enum exp_opcode opcode () const override
1273 { return OP; }
1274 };
1275
1276 template<enum exp_opcode OP, binary_ftype FUNC>
1277 class usual_ax_binop_operation
1278 : public binop_operation<OP, FUNC>
1279 {
1280 public:
1281
1282 using binop_operation<OP, FUNC>::binop_operation;
1283
1284 protected:
1285
1286 void do_generate_ax (struct expression *exp,
1287 struct agent_expr *ax,
1288 struct axs_value *value,
1289 struct type *cast_type)
1290 override
1291 {
1292 gen_expr_binop (exp, OP,
1293 std::get<0> (this->m_storage).get (),
1294 std::get<1> (this->m_storage).get (),
1295 ax, value);
1296 }
1297 };
1298
1299 using exp_operation = binop_operation<BINOP_EXP, eval_op_binary>;
1300 using intdiv_operation = binop_operation<BINOP_INTDIV, eval_op_binary>;
1301 using mod_operation = binop_operation<BINOP_MOD, eval_op_binary>;
1302
1303 using mul_operation = usual_ax_binop_operation<BINOP_MUL, eval_op_binary>;
1304 using div_operation = usual_ax_binop_operation<BINOP_DIV, eval_op_binary>;
1305 using rem_operation = usual_ax_binop_operation<BINOP_REM, eval_op_binary>;
1306 using lsh_operation = usual_ax_binop_operation<BINOP_LSH, eval_op_binary>;
1307 using rsh_operation = usual_ax_binop_operation<BINOP_RSH, eval_op_binary>;
1308 using bitwise_and_operation
1309 = usual_ax_binop_operation<BINOP_BITWISE_AND, eval_op_binary>;
1310 using bitwise_ior_operation
1311 = usual_ax_binop_operation<BINOP_BITWISE_IOR, eval_op_binary>;
1312 using bitwise_xor_operation
1313 = usual_ax_binop_operation<BINOP_BITWISE_XOR, eval_op_binary>;
1314
1315 class subscript_operation
1316 : public usual_ax_binop_operation<BINOP_SUBSCRIPT, eval_op_subscript>
1317 {
1318 public:
1319 using usual_ax_binop_operation<BINOP_SUBSCRIPT,
1320 eval_op_subscript>::usual_ax_binop_operation;
1321
1322 value *evaluate_for_sizeof (struct expression *exp,
1323 enum noside noside) override;
1324 };
1325
1326 /* Implementation of comparison operations. */
1327 template<enum exp_opcode OP, binary_ftype FUNC>
1328 class comparison_operation
1329 : public usual_ax_binop_operation<OP, FUNC>
1330 {
1331 public:
1332
1333 using usual_ax_binop_operation<OP, FUNC>::usual_ax_binop_operation;
1334
1335 value *evaluate (struct type *expect_type,
1336 struct expression *exp,
1337 enum noside noside) override
1338 {
1339 value *lhs
1340 = std::get<0> (this->m_storage)->evaluate (nullptr, exp, noside);
1341 value *rhs
1342 = std::get<1> (this->m_storage)->evaluate (lhs->type (), exp,
1343 noside);
1344 return FUNC (expect_type, exp, noside, OP, lhs, rhs);
1345 }
1346 };
1347
1348 class equal_operation
1349 : public comparison_operation<BINOP_EQUAL, eval_op_equal>
1350 {
1351 public:
1352
1353 using comparison_operation::comparison_operation;
1354
get_lhs()1355 operation *get_lhs () const
1356 {
1357 return std::get<0> (m_storage).get ();
1358 }
1359
get_rhs()1360 operation *get_rhs () const
1361 {
1362 return std::get<1> (m_storage).get ();
1363 }
1364 };
1365
1366 using notequal_operation
1367 = comparison_operation<BINOP_NOTEQUAL, eval_op_notequal>;
1368 using less_operation = comparison_operation<BINOP_LESS, eval_op_less>;
1369 using gtr_operation = comparison_operation<BINOP_GTR, eval_op_gtr>;
1370 using geq_operation = comparison_operation<BINOP_GEQ, eval_op_geq>;
1371 using leq_operation = comparison_operation<BINOP_LEQ, eval_op_leq>;
1372
1373 /* Implement the GDB '@' repeat operator. */
1374 class repeat_operation
1375 : public binop_operation<BINOP_REPEAT, eval_op_repeat>
1376 {
1377 using binop_operation<BINOP_REPEAT, eval_op_repeat>::binop_operation;
1378
1379 protected:
1380
1381 void do_generate_ax (struct expression *exp,
1382 struct agent_expr *ax,
1383 struct axs_value *value,
1384 struct type *cast_type)
1385 override;
1386 };
1387
1388 /* C-style comma operator. */
1389 class comma_operation
1390 : public maybe_constant_operation<operation_up, operation_up>
1391 {
1392 public:
1393
1394 using maybe_constant_operation::maybe_constant_operation;
1395
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1396 value *evaluate (struct type *expect_type,
1397 struct expression *exp,
1398 enum noside noside) override
1399 {
1400 /* The left-hand-side is only evaluated for side effects, so don't
1401 bother in other modes. */
1402 if (noside == EVAL_NORMAL)
1403 std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1404 return std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
1405 }
1406
opcode()1407 enum exp_opcode opcode () const override
1408 { return BINOP_COMMA; }
1409
1410 protected:
1411
1412 void do_generate_ax (struct expression *exp,
1413 struct agent_expr *ax,
1414 struct axs_value *value,
1415 struct type *cast_type)
1416 override;
1417 };
1418
1419 typedef struct value *unary_ftype (struct type *expect_type,
1420 struct expression *exp,
1421 enum noside noside, enum exp_opcode op,
1422 struct value *arg1);
1423
1424 /* Base class for unary operations. */
1425 template<enum exp_opcode OP, unary_ftype FUNC>
1426 class unop_operation
1427 : public maybe_constant_operation<operation_up>
1428 {
1429 public:
1430
1431 using maybe_constant_operation::maybe_constant_operation;
1432
1433 value *evaluate (struct type *expect_type,
1434 struct expression *exp,
1435 enum noside noside) override
1436 {
1437 value *val = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1438 return FUNC (expect_type, exp, noside, OP, val);
1439 }
1440
1441 enum exp_opcode opcode () const override
1442 { return OP; }
1443 };
1444
1445 /* Unary operations that can also be turned into agent expressions in
1446 the "usual" way. */
1447 template<enum exp_opcode OP, unary_ftype FUNC>
1448 class usual_ax_unop_operation
1449 : public unop_operation<OP, FUNC>
1450 {
1451 using unop_operation<OP, FUNC>::unop_operation;
1452
1453 protected:
1454
1455 void do_generate_ax (struct expression *exp,
1456 struct agent_expr *ax,
1457 struct axs_value *value,
1458 struct type *cast_type)
1459 override
1460 {
1461 gen_expr_unop (exp, OP,
1462 std::get<0> (this->m_storage).get (),
1463 ax, value);
1464 }
1465 };
1466
1467 using unary_plus_operation = usual_ax_unop_operation<UNOP_PLUS, eval_op_plus>;
1468 using unary_neg_operation = usual_ax_unop_operation<UNOP_NEG, eval_op_neg>;
1469 using unary_complement_operation
1470 = usual_ax_unop_operation<UNOP_COMPLEMENT, eval_op_complement>;
1471 using unary_logical_not_operation
1472 = usual_ax_unop_operation<UNOP_LOGICAL_NOT, eval_op_lognot>;
1473
1474 /* Handle pre- and post- increment and -decrement. */
1475 template<enum exp_opcode OP, unary_ftype FUNC>
1476 class unop_incr_operation
1477 : public tuple_holding_operation<operation_up>
1478 {
1479 public:
1480
1481 using tuple_holding_operation::tuple_holding_operation;
1482
1483 value *evaluate (struct type *expect_type,
1484 struct expression *exp,
1485 enum noside noside) override
1486 {
1487 value *val = std::get<0> (m_storage)->evaluate (expect_type, exp, noside);
1488 return FUNC (expect_type, exp, noside, OP, val);
1489 }
1490
1491 enum exp_opcode opcode () const override
1492 { return OP; }
1493 };
1494
1495 using preinc_operation
1496 = unop_incr_operation<UNOP_PREINCREMENT, eval_op_preinc>;
1497 using predec_operation
1498 = unop_incr_operation<UNOP_PREDECREMENT, eval_op_predec>;
1499 using postinc_operation
1500 = unop_incr_operation<UNOP_POSTINCREMENT, eval_op_postinc>;
1501 using postdec_operation
1502 = unop_incr_operation<UNOP_POSTDECREMENT, eval_op_postdec>;
1503
1504 /* Base class for implementations of UNOP_IND. */
1505 class unop_ind_base_operation
1506 : public tuple_holding_operation<operation_up>
1507 {
1508 public:
1509
1510 using tuple_holding_operation::tuple_holding_operation;
1511
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1512 value *evaluate (struct type *expect_type,
1513 struct expression *exp,
1514 enum noside noside) override
1515 {
1516 value *val
1517 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1518 return eval_op_ind (expect_type, exp, noside, val);
1519 }
1520
1521 value *evaluate_for_address (struct expression *exp,
1522 enum noside noside) override;
1523
1524 value *evaluate_for_sizeof (struct expression *exp,
1525 enum noside noside) override;
1526
opcode()1527 enum exp_opcode opcode () const override
1528 { return UNOP_IND; }
1529 };
1530
1531 /* Ordinary UNOP_IND implementation. */
1532 class unop_ind_operation
1533 : public unop_ind_base_operation
1534 {
1535 public:
1536
1537 using unop_ind_base_operation::unop_ind_base_operation;
1538
1539 protected:
1540
do_generate_ax(struct expression * exp,struct agent_expr * ax,struct axs_value * value,struct type * cast_type)1541 void do_generate_ax (struct expression *exp,
1542 struct agent_expr *ax,
1543 struct axs_value *value,
1544 struct type *cast_type)
1545 override
1546 {
1547 gen_expr_unop (exp, UNOP_IND,
1548 std::get<0> (this->m_storage).get (),
1549 ax, value);
1550 }
1551 };
1552
1553 /* Implement OP_TYPE. */
1554 class type_operation
1555 : public tuple_holding_operation<struct type *>
1556 {
1557 public:
1558
1559 using tuple_holding_operation::tuple_holding_operation;
1560
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1561 value *evaluate (struct type *expect_type,
1562 struct expression *exp,
1563 enum noside noside) override
1564 {
1565 return eval_op_type (expect_type, exp, noside, std::get<0> (m_storage));
1566 }
1567
opcode()1568 enum exp_opcode opcode () const override
1569 { return OP_TYPE; }
1570
constant_p()1571 bool constant_p () const override
1572 { return true; }
1573 };
1574
1575 /* Implement the "typeof" operation. */
1576 class typeof_operation
1577 : public maybe_constant_operation<operation_up>
1578 {
1579 public:
1580
1581 using maybe_constant_operation::maybe_constant_operation;
1582
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1583 value *evaluate (struct type *expect_type,
1584 struct expression *exp,
1585 enum noside noside) override
1586 {
1587 if (noside == EVAL_AVOID_SIDE_EFFECTS)
1588 return std::get<0> (m_storage)->evaluate (nullptr, exp,
1589 EVAL_AVOID_SIDE_EFFECTS);
1590 else
1591 error (_("Attempt to use a type as an expression"));
1592 }
1593
opcode()1594 enum exp_opcode opcode () const override
1595 { return OP_TYPEOF; }
1596 };
1597
1598 /* Implement 'decltype'. */
1599 class decltype_operation
1600 : public maybe_constant_operation<operation_up>
1601 {
1602 public:
1603
1604 using maybe_constant_operation::maybe_constant_operation;
1605
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1606 value *evaluate (struct type *expect_type,
1607 struct expression *exp,
1608 enum noside noside) override
1609 {
1610 if (noside == EVAL_AVOID_SIDE_EFFECTS)
1611 {
1612 value *result
1613 = std::get<0> (m_storage)->evaluate (nullptr, exp,
1614 EVAL_AVOID_SIDE_EFFECTS);
1615 enum exp_opcode sub_op = std::get<0> (m_storage)->opcode ();
1616 if (sub_op == BINOP_SUBSCRIPT
1617 || sub_op == STRUCTOP_MEMBER
1618 || sub_op == STRUCTOP_MPTR
1619 || sub_op == UNOP_IND
1620 || sub_op == STRUCTOP_STRUCT
1621 || sub_op == STRUCTOP_PTR
1622 || sub_op == OP_SCOPE)
1623 {
1624 struct type *type = result->type ();
1625
1626 if (!TYPE_IS_REFERENCE (type))
1627 {
1628 type = lookup_lvalue_reference_type (type);
1629 result = value::allocate (type);
1630 }
1631 }
1632
1633 return result;
1634 }
1635 else
1636 error (_("Attempt to use a type as an expression"));
1637 }
1638
opcode()1639 enum exp_opcode opcode () const override
1640 { return OP_DECLTYPE; }
1641 };
1642
1643 /* Implement 'typeid'. */
1644 class typeid_operation
1645 : public tuple_holding_operation<operation_up>
1646 {
1647 public:
1648
1649 using tuple_holding_operation::tuple_holding_operation;
1650
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1651 value *evaluate (struct type *expect_type,
1652 struct expression *exp,
1653 enum noside noside) override
1654 {
1655 enum exp_opcode sub_op = std::get<0> (m_storage)->opcode ();
1656 enum noside sub_noside
1657 = ((sub_op == OP_TYPE || sub_op == OP_DECLTYPE || sub_op == OP_TYPEOF)
1658 ? EVAL_AVOID_SIDE_EFFECTS
1659 : noside);
1660
1661 value *result = std::get<0> (m_storage)->evaluate (nullptr, exp,
1662 sub_noside);
1663 if (noside != EVAL_NORMAL)
1664 return value::allocate (cplus_typeid_type (exp->gdbarch));
1665 return cplus_typeid (result);
1666 }
1667
opcode()1668 enum exp_opcode opcode () const override
1669 { return OP_TYPEID; }
1670 };
1671
1672 /* Implement the address-of operation. */
1673 class unop_addr_operation
1674 : public maybe_constant_operation<operation_up>
1675 {
1676 public:
1677
1678 using maybe_constant_operation::maybe_constant_operation;
1679
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1680 value *evaluate (struct type *expect_type,
1681 struct expression *exp,
1682 enum noside noside) override
1683 {
1684 /* C++: check for and handle pointer to members. */
1685 return std::get<0> (m_storage)->evaluate_for_address (exp, noside);
1686 }
1687
opcode()1688 enum exp_opcode opcode () const override
1689 { return UNOP_ADDR; }
1690
1691 /* Return the subexpression. */
get_expression()1692 const operation_up &get_expression () const
1693 {
1694 return std::get<0> (m_storage);
1695 }
1696
1697 protected:
1698
do_generate_ax(struct expression * exp,struct agent_expr * ax,struct axs_value * value,struct type * cast_type)1699 void do_generate_ax (struct expression *exp,
1700 struct agent_expr *ax,
1701 struct axs_value *value,
1702 struct type *cast_type)
1703 override
1704 {
1705 gen_expr_unop (exp, UNOP_ADDR,
1706 std::get<0> (this->m_storage).get (),
1707 ax, value);
1708 }
1709 };
1710
1711 /* Implement 'sizeof'. */
1712 class unop_sizeof_operation
1713 : public maybe_constant_operation<operation_up>
1714 {
1715 public:
1716
1717 using maybe_constant_operation::maybe_constant_operation;
1718
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1719 value *evaluate (struct type *expect_type,
1720 struct expression *exp,
1721 enum noside noside) override
1722 {
1723 return std::get<0> (m_storage)->evaluate_for_sizeof (exp, noside);
1724 }
1725
opcode()1726 enum exp_opcode opcode () const override
1727 { return UNOP_SIZEOF; }
1728
1729 protected:
1730
1731 void do_generate_ax (struct expression *exp,
1732 struct agent_expr *ax,
1733 struct axs_value *value,
1734 struct type *cast_type)
1735 override;
1736 };
1737
1738 /* Implement 'alignof'. */
1739 class unop_alignof_operation
1740 : public maybe_constant_operation<operation_up>
1741 {
1742 public:
1743
1744 using maybe_constant_operation::maybe_constant_operation;
1745
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1746 value *evaluate (struct type *expect_type,
1747 struct expression *exp,
1748 enum noside noside) override
1749 {
1750 value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
1751 EVAL_AVOID_SIDE_EFFECTS);
1752 return eval_op_alignof (expect_type, exp, noside, val);
1753 }
1754
opcode()1755 enum exp_opcode opcode () const override
1756 { return UNOP_ALIGNOF; }
1757 };
1758
1759 /* Implement UNOP_MEMVAL. */
1760 class unop_memval_operation
1761 : public tuple_holding_operation<operation_up, struct type *>
1762 {
1763 public:
1764
1765 using tuple_holding_operation::tuple_holding_operation;
1766
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1767 value *evaluate (struct type *expect_type,
1768 struct expression *exp,
1769 enum noside noside) override
1770 {
1771 value *val = std::get<0> (m_storage)->evaluate (expect_type, exp, noside);
1772 return eval_op_memval (expect_type, exp, noside, val,
1773 std::get<1> (m_storage));
1774 }
1775
1776 value *evaluate_for_sizeof (struct expression *exp,
1777 enum noside noside) override;
1778
1779 value *evaluate_for_address (struct expression *exp,
1780 enum noside noside) override;
1781
opcode()1782 enum exp_opcode opcode () const override
1783 { return UNOP_MEMVAL; }
1784
1785 /* Return the type referenced by this object. */
get_type()1786 struct type *get_type () const
1787 {
1788 return std::get<1> (m_storage);
1789 }
1790
1791 protected:
1792
1793 void do_generate_ax (struct expression *exp,
1794 struct agent_expr *ax,
1795 struct axs_value *value,
1796 struct type *cast_type)
1797 override;
1798 };
1799
1800 /* Implement UNOP_MEMVAL_TYPE. */
1801 class unop_memval_type_operation
1802 : public tuple_holding_operation<operation_up, operation_up>
1803 {
1804 public:
1805
1806 using tuple_holding_operation::tuple_holding_operation;
1807
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1808 value *evaluate (struct type *expect_type,
1809 struct expression *exp,
1810 enum noside noside) override
1811 {
1812 value *typeval
1813 = std::get<0> (m_storage)->evaluate (expect_type, exp,
1814 EVAL_AVOID_SIDE_EFFECTS);
1815 struct type *type = typeval->type ();
1816 value *val = std::get<1> (m_storage)->evaluate (expect_type, exp, noside);
1817 return eval_op_memval (expect_type, exp, noside, val, type);
1818 }
1819
1820 value *evaluate_for_sizeof (struct expression *exp,
1821 enum noside noside) override;
1822
1823 value *evaluate_for_address (struct expression *exp,
1824 enum noside noside) override;
1825
opcode()1826 enum exp_opcode opcode () const override
1827 { return UNOP_MEMVAL_TYPE; }
1828
1829 protected:
1830
1831 void do_generate_ax (struct expression *exp,
1832 struct agent_expr *ax,
1833 struct axs_value *value,
1834 struct type *cast_type)
1835 override;
1836 };
1837
1838 /* Implement the 'this' expression. */
1839 class op_this_operation
1840 : public tuple_holding_operation<>
1841 {
1842 public:
1843
1844 using tuple_holding_operation::tuple_holding_operation;
1845
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1846 value *evaluate (struct type *expect_type,
1847 struct expression *exp,
1848 enum noside noside) override
1849 {
1850 return value_of_this (exp->language_defn);
1851 }
1852
opcode()1853 enum exp_opcode opcode () const override
1854 { return OP_THIS; }
1855
1856 protected:
1857
1858 void do_generate_ax (struct expression *exp,
1859 struct agent_expr *ax,
1860 struct axs_value *value,
1861 struct type *cast_type)
1862 override;
1863 };
1864
1865 /* Implement the "type instance" operation. */
1866 class type_instance_operation
1867 : public tuple_holding_operation<type_instance_flags, std::vector<type *>,
1868 operation_up>
1869 {
1870 public:
1871
1872 using tuple_holding_operation::tuple_holding_operation;
1873
1874 value *evaluate (struct type *expect_type,
1875 struct expression *exp,
1876 enum noside noside) override;
1877
opcode()1878 enum exp_opcode opcode () const override
1879 { return TYPE_INSTANCE; }
1880 };
1881
1882 /* The assignment operator. */
1883 class assign_operation
1884 : public tuple_holding_operation<operation_up, operation_up>
1885 {
1886 public:
1887
1888 using tuple_holding_operation::tuple_holding_operation;
1889
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1890 value *evaluate (struct type *expect_type,
1891 struct expression *exp,
1892 enum noside noside) override
1893 {
1894 value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
1895 /* Special-case assignments where the left-hand-side is a
1896 convenience variable -- in these, don't bother setting an
1897 expected type. This avoids a weird case where re-assigning a
1898 string or array to an internal variable could error with "Too
1899 many array elements". */
1900 struct type *xtype = (lhs->lval () == lval_internalvar
1901 ? nullptr
1902 : lhs->type ());
1903 value *rhs = std::get<1> (m_storage)->evaluate (xtype, exp, noside);
1904
1905 if (noside == EVAL_AVOID_SIDE_EFFECTS)
1906 return lhs;
1907 if (binop_user_defined_p (BINOP_ASSIGN, lhs, rhs))
1908 return value_x_binop (lhs, rhs, BINOP_ASSIGN, OP_NULL, noside);
1909 else
1910 return value_assign (lhs, rhs);
1911 }
1912
opcode()1913 enum exp_opcode opcode () const override
1914 { return BINOP_ASSIGN; }
1915
1916 /* Return the left-hand-side of the assignment. */
get_lhs()1917 operation *get_lhs () const
1918 {
1919 return std::get<0> (m_storage).get ();
1920 }
1921
1922 protected:
1923
1924 void do_generate_ax (struct expression *exp,
1925 struct agent_expr *ax,
1926 struct axs_value *value,
1927 struct type *cast_type)
1928 override;
1929 };
1930
1931 /* Assignment with modification, like "+=". */
1932 class assign_modify_operation
1933 : public tuple_holding_operation<exp_opcode, operation_up, operation_up>
1934 {
1935 public:
1936
1937 using tuple_holding_operation::tuple_holding_operation;
1938
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)1939 value *evaluate (struct type *expect_type,
1940 struct expression *exp,
1941 enum noside noside) override
1942 {
1943 value *lhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
1944 value *rhs = std::get<2> (m_storage)->evaluate (expect_type, exp, noside);
1945 return eval_binop_assign_modify (expect_type, exp, noside,
1946 std::get<0> (m_storage), lhs, rhs);
1947 }
1948
opcode()1949 enum exp_opcode opcode () const override
1950 { return BINOP_ASSIGN_MODIFY; }
1951
1952 protected:
1953
1954 void do_generate_ax (struct expression *exp,
1955 struct agent_expr *ax,
1956 struct axs_value *value,
1957 struct type *cast_type)
1958 override;
1959 };
1960
1961 /* Not a cast! Extract a value of a given type from the contents of a
1962 value. The new value is extracted from the least significant bytes
1963 of the old value. The new value's type must be no bigger than the
1964 old values type. */
1965 class unop_extract_operation
1966 : public maybe_constant_operation<operation_up, struct type *>
1967 {
1968 public:
1969
1970 using maybe_constant_operation::maybe_constant_operation;
1971
1972 value *evaluate (struct type *expect_type, struct expression *exp,
1973 enum noside noside) override;
1974
opcode()1975 enum exp_opcode opcode () const override
1976 { return UNOP_EXTRACT; }
1977
1978 /* Return the type referenced by this object. */
get_type()1979 struct type *get_type () const
1980 {
1981 return std::get<1> (m_storage);
1982 }
1983
1984 protected:
1985
1986 void do_generate_ax (struct expression *exp,
1987 struct agent_expr *ax,
1988 struct axs_value *value,
1989 struct type *cast_type) override;
1990 };
1991
1992 /* A type cast. */
1993 class unop_cast_operation
1994 : public maybe_constant_operation<operation_up, struct type *>
1995 {
1996 public:
1997
1998 using maybe_constant_operation::maybe_constant_operation;
1999
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)2000 value *evaluate (struct type *expect_type,
2001 struct expression *exp,
2002 enum noside noside) override
2003 {
2004 return std::get<0> (m_storage)->evaluate_for_cast (std::get<1> (m_storage),
2005 exp, noside);
2006 }
2007
opcode()2008 enum exp_opcode opcode () const override
2009 { return UNOP_CAST; }
2010
2011 /* Return the type referenced by this object. */
get_type()2012 struct type *get_type () const
2013 {
2014 return std::get<1> (m_storage);
2015 }
2016
2017 protected:
2018
2019 void do_generate_ax (struct expression *exp,
2020 struct agent_expr *ax,
2021 struct axs_value *value,
2022 struct type *cast_type)
2023 override;
2024 };
2025
2026 /* A cast, but the type comes from an expression, not a "struct
2027 type". */
2028 class unop_cast_type_operation
2029 : public maybe_constant_operation<operation_up, operation_up>
2030 {
2031 public:
2032
2033 using maybe_constant_operation::maybe_constant_operation;
2034
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)2035 value *evaluate (struct type *expect_type,
2036 struct expression *exp,
2037 enum noside noside) override
2038 {
2039 value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
2040 EVAL_AVOID_SIDE_EFFECTS);
2041 return std::get<1> (m_storage)->evaluate_for_cast (val->type (),
2042 exp, noside);
2043 }
2044
opcode()2045 enum exp_opcode opcode () const override
2046 { return UNOP_CAST_TYPE; }
2047
2048 protected:
2049
2050 void do_generate_ax (struct expression *exp,
2051 struct agent_expr *ax,
2052 struct axs_value *value,
2053 struct type *cast_type)
2054 override;
2055 };
2056
2057 typedef value *cxx_cast_ftype (struct type *, value *);
2058
2059 /* This implements dynamic_cast and reinterpret_cast. static_cast and
2060 const_cast are handled by the ordinary case operations. */
2061 template<exp_opcode OP, cxx_cast_ftype FUNC>
2062 class cxx_cast_operation
2063 : public maybe_constant_operation<operation_up, operation_up>
2064 {
2065 public:
2066
2067 using maybe_constant_operation::maybe_constant_operation;
2068
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)2069 value *evaluate (struct type *expect_type,
2070 struct expression *exp,
2071 enum noside noside) override
2072 {
2073 value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
2074 EVAL_AVOID_SIDE_EFFECTS);
2075 struct type *type = val->type ();
2076 value *rhs = std::get<1> (m_storage)->evaluate (type, exp, noside);
2077 return FUNC (type, rhs);
2078 }
2079
opcode()2080 enum exp_opcode opcode () const override
2081 { return OP; }
2082 };
2083
2084 using dynamic_cast_operation = cxx_cast_operation<UNOP_DYNAMIC_CAST,
2085 value_dynamic_cast>;
2086 using reinterpret_cast_operation = cxx_cast_operation<UNOP_REINTERPRET_CAST,
2087 value_reinterpret_cast>;
2088
2089 /* Multi-dimensional subscripting. */
2090 class multi_subscript_operation
2091 : public tuple_holding_operation<operation_up, std::vector<operation_up>>
2092 {
2093 public:
2094
2095 using tuple_holding_operation::tuple_holding_operation;
2096
2097 value *evaluate (struct type *expect_type,
2098 struct expression *exp,
2099 enum noside noside) override;
2100
opcode()2101 enum exp_opcode opcode () const override
2102 { return MULTI_SUBSCRIPT; }
2103 };
2104
2105 /* The "&&" operator. */
2106 class logical_and_operation
2107 : public maybe_constant_operation<operation_up, operation_up>
2108 {
2109 public:
2110
2111 using maybe_constant_operation::maybe_constant_operation;
2112
2113 value *evaluate (struct type *expect_type,
2114 struct expression *exp,
2115 enum noside noside) override;
2116
opcode()2117 enum exp_opcode opcode () const override
2118 { return BINOP_LOGICAL_AND; }
2119
2120 protected:
2121
2122 void do_generate_ax (struct expression *exp,
2123 struct agent_expr *ax,
2124 struct axs_value *value,
2125 struct type *cast_type)
2126 override;
2127 };
2128
2129 /* The "||" operator. */
2130 class logical_or_operation
2131 : public maybe_constant_operation<operation_up, operation_up>
2132 {
2133 public:
2134
2135 using maybe_constant_operation::maybe_constant_operation;
2136
2137 value *evaluate (struct type *expect_type,
2138 struct expression *exp,
2139 enum noside noside) override;
2140
opcode()2141 enum exp_opcode opcode () const override
2142 { return BINOP_LOGICAL_OR; }
2143
2144 protected:
2145
2146 void do_generate_ax (struct expression *exp,
2147 struct agent_expr *ax,
2148 struct axs_value *value,
2149 struct type *cast_type)
2150 override;
2151 };
2152
2153 /* This class implements ADL (aka Koenig) function calls for C++. It
2154 holds the name of the function to call, the block in which the
2155 lookup should be done, and a vector of arguments. */
2156 class adl_func_operation
2157 : public tuple_holding_operation<std::string, const block *,
2158 std::vector<operation_up>>
2159 {
2160 public:
2161
2162 using tuple_holding_operation::tuple_holding_operation;
2163
2164 value *evaluate (struct type *expect_type,
2165 struct expression *exp,
2166 enum noside noside) override;
2167
opcode()2168 enum exp_opcode opcode () const override
2169 { return OP_ADL_FUNC; }
2170 };
2171
2172 /* The OP_ARRAY operation. */
2173 class array_operation
2174 : public tuple_holding_operation<int, int, std::vector<operation_up>>
2175 {
2176 public:
2177
2178 using tuple_holding_operation::tuple_holding_operation;
2179
2180 value *evaluate (struct type *expect_type,
2181 struct expression *exp,
2182 enum noside noside) override;
2183
opcode()2184 enum exp_opcode opcode () const override
2185 { return OP_ARRAY; }
2186
2187 private:
2188
2189 struct value *evaluate_struct_tuple (struct value *struct_val,
2190 struct expression *exp,
2191 enum noside noside, int nargs);
2192 };
2193
2194 /* A function call. This holds the callee operation and the
2195 arguments. */
2196 class funcall_operation
2197 : public tuple_holding_operation<operation_up, std::vector<operation_up>>
2198 {
2199 public:
2200
2201 using tuple_holding_operation::tuple_holding_operation;
2202
evaluate(struct type * expect_type,struct expression * exp,enum noside noside)2203 value *evaluate (struct type *expect_type,
2204 struct expression *exp,
2205 enum noside noside) override
2206 {
2207 return std::get<0> (m_storage)->evaluate_funcall (expect_type, exp, noside,
2208 std::get<1> (m_storage));
2209 }
2210
opcode()2211 enum exp_opcode opcode () const override
2212 { return OP_FUNCALL; }
2213 };
2214
2215 } /* namespace expr */
2216
2217 #endif /* EXPOP_H */
2218