Introduce register_operation
[deliverable/binutils-gdb.git] / gdb / expop.h
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
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
44 extern struct value *eval_op_scope (struct type *expect_type,
45 struct expression *exp,
46 enum noside noside,
47 struct type *type, const char *string);
48 extern 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);
54 extern struct value *eval_op_var_entry_value (struct type *expect_type,
55 struct expression *exp,
56 enum noside noside, symbol *sym);
57 extern 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);
61 extern struct value *eval_op_register (struct type *expect_type,
62 struct expression *exp,
63 enum noside noside, const char *name);
64
65 namespace expr
66 {
67
68 /* The check_objfile overloads are used to check whether a particular
69 component of some operation references an objfile. The passed-in
70 objfile will never be a debug objfile. */
71
72 /* See if EXP_OBJFILE matches OBJFILE. */
73 static inline bool
74 check_objfile (struct objfile *exp_objfile, struct objfile *objfile)
75 {
76 if (exp_objfile->separate_debug_objfile_backlink)
77 exp_objfile = exp_objfile->separate_debug_objfile_backlink;
78 return exp_objfile == objfile;
79 }
80
81 static inline bool
82 check_objfile (struct type *type, struct objfile *objfile)
83 {
84 struct objfile *ty_objfile = type->objfile_owner ();
85 if (ty_objfile != nullptr)
86 return check_objfile (ty_objfile, objfile);
87 return false;
88 }
89
90 static inline bool
91 check_objfile (struct symbol *sym, struct objfile *objfile)
92 {
93 return check_objfile (symbol_objfile (sym), objfile);
94 }
95
96 static inline bool
97 check_objfile (const struct block *block, struct objfile *objfile)
98 {
99 return check_objfile (block_objfile (block), objfile);
100 }
101
102 static inline bool
103 check_objfile (minimal_symbol *minsym, struct objfile *objfile)
104 {
105 /* This may seem strange but minsyms are only used with an objfile
106 as well. */
107 return false;
108 }
109
110 static inline bool
111 check_objfile (internalvar *ivar, struct objfile *objfile)
112 {
113 return false;
114 }
115
116 static inline bool
117 check_objfile (const std::string &str, struct objfile *objfile)
118 {
119 return false;
120 }
121
122 static inline bool
123 check_objfile (const operation_up &op, struct objfile *objfile)
124 {
125 return op->uses_objfile (objfile);
126 }
127
128 static inline bool
129 check_objfile (enum exp_opcode val, struct objfile *objfile)
130 {
131 return false;
132 }
133
134 static inline bool
135 check_objfile (ULONGEST val, struct objfile *objfile)
136 {
137 return false;
138 }
139
140 template<typename T>
141 static inline bool
142 check_objfile (enum_flags<T> val, struct objfile *objfile)
143 {
144 return false;
145 }
146
147 template<typename T>
148 static inline bool
149 check_objfile (const std::vector<T> &collection, struct objfile *objfile)
150 {
151 for (const auto &item : collection)
152 {
153 if (check_objfile (item, objfile))
154 return true;
155 }
156 return false;
157 }
158
159 template<typename S, typename T>
160 static inline bool
161 check_objfile (const std::pair<S, T> &item, struct objfile *objfile)
162 {
163 return (check_objfile (item.first, objfile)
164 || check_objfile (item.second, objfile));
165 }
166
167 static inline void
168 dump_for_expression (struct ui_file *stream, int depth,
169 const operation_up &op)
170 {
171 op->dump (stream, depth);
172 }
173
174 extern void dump_for_expression (struct ui_file *stream, int depth,
175 enum exp_opcode op);
176 extern void dump_for_expression (struct ui_file *stream, int depth,
177 const std::string &str);
178 extern void dump_for_expression (struct ui_file *stream, int depth,
179 struct type *type);
180 extern void dump_for_expression (struct ui_file *stream, int depth,
181 CORE_ADDR addr);
182 extern void dump_for_expression (struct ui_file *stream, int depth,
183 internalvar *ivar);
184 extern void dump_for_expression (struct ui_file *stream, int depth,
185 symbol *sym);
186 extern void dump_for_expression (struct ui_file *stream, int depth,
187 minimal_symbol *msym);
188 extern void dump_for_expression (struct ui_file *stream, int depth,
189 const block *bl);
190 extern void dump_for_expression (struct ui_file *stream, int depth,
191 type_instance_flags flags);
192 extern void dump_for_expression (struct ui_file *stream, int depth,
193 enum c_string_type_values flags);
194 extern void dump_for_expression (struct ui_file *stream, int depth,
195 enum range_flag flags);
196 extern void dump_for_expression (struct ui_file *stream, int depth,
197 objfile *objf);
198
199 template<typename T>
200 void
201 dump_for_expression (struct ui_file *stream, int depth,
202 const std::vector<T> &vals)
203 {
204 fprintf_filtered (stream, _("%*sVector:\n"), depth, "");
205 for (auto &item : vals)
206 dump_for_expression (stream, depth + 1, item);
207 }
208
209 template<typename X, typename Y>
210 void
211 dump_for_expression (struct ui_file *stream, int depth,
212 const std::pair<X, Y> &vals)
213 {
214 dump_for_expression (stream, depth, vals.first);
215 dump_for_expression (stream, depth, vals.second);
216 }
217
218 /* Base class for most concrete operations. This class holds data,
219 specified via template parameters, and supplies generic
220 implementations of the 'dump' and 'uses_objfile' methods. */
221 template<typename... Arg>
222 class tuple_holding_operation : public operation
223 {
224 public:
225
226 explicit tuple_holding_operation (Arg... args)
227 : m_storage (std::forward<Arg> (args)...)
228 {
229 }
230
231 DISABLE_COPY_AND_ASSIGN (tuple_holding_operation);
232
233 bool uses_objfile (struct objfile *objfile) const override
234 {
235 return do_check_objfile<0, Arg...> (objfile, m_storage);
236 }
237
238 void dump (struct ui_file *stream, int depth) const override
239 {
240 dump_for_expression (stream, depth, opcode ());
241 do_dump<0, Arg...> (stream, depth + 1, m_storage);
242 }
243
244 protected:
245
246 /* Storage for the data. */
247 std::tuple<Arg...> m_storage;
248
249 private:
250
251 /* do_dump does the work of dumping the data. */
252 template<int I, typename... T>
253 typename std::enable_if<I == sizeof... (T), void>::type
254 do_dump (struct ui_file *stream, int depth, const std::tuple<T...> &value)
255 const
256 {
257 }
258
259 template<int I, typename... T>
260 typename std::enable_if<I < sizeof... (T), void>::type
261 do_dump (struct ui_file *stream, int depth, const std::tuple<T...> &value)
262 const
263 {
264 dump_for_expression (stream, depth, std::get<I> (value));
265 do_dump<I + 1, T...> (stream, depth, value);
266 }
267
268 /* do_check_objfile does the work of checking whether this object
269 refers to OBJFILE. */
270 template<int I, typename... T>
271 typename std::enable_if<I == sizeof... (T), bool>::type
272 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
273 const
274 {
275 return false;
276 }
277
278 template<int I, typename... T>
279 typename std::enable_if<I < sizeof... (T), bool>::type
280 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
281 const
282 {
283 if (check_objfile (std::get<I> (value), objfile))
284 return true;
285 return do_check_objfile<I + 1, T...> (objfile, value);
286 }
287 };
288
289 /* The check_constant overloads are used to decide whether a given
290 concrete operation is a constant. This is done by checking the
291 operands. */
292
293 static inline bool
294 check_constant (const operation_up &item)
295 {
296 return item->constant_p ();
297 }
298
299 static inline bool
300 check_constant (struct minimal_symbol *msym)
301 {
302 return false;
303 }
304
305 static inline bool
306 check_constant (struct type *type)
307 {
308 return true;
309 }
310
311 static inline bool
312 check_constant (const struct block *block)
313 {
314 return true;
315 }
316
317 static inline bool
318 check_constant (const std::string &str)
319 {
320 return true;
321 }
322
323 static inline bool
324 check_constant (struct objfile *objfile)
325 {
326 return true;
327 }
328
329 static inline bool
330 check_constant (ULONGEST cst)
331 {
332 return true;
333 }
334
335 static inline bool
336 check_constant (struct symbol *sym)
337 {
338 enum address_class sc = SYMBOL_CLASS (sym);
339 return (sc == LOC_BLOCK
340 || sc == LOC_CONST
341 || sc == LOC_CONST_BYTES
342 || sc == LOC_LABEL);
343 }
344
345 template<typename T>
346 static inline bool
347 check_constant (const std::vector<T> &collection)
348 {
349 for (const auto &item : collection)
350 if (!check_constant (item))
351 return false;
352 return true;
353 }
354
355 template<typename S, typename T>
356 static inline bool
357 check_constant (const std::pair<S, T> &item)
358 {
359 return check_constant (item.first) && check_constant (item.second);
360 }
361
362 /* Base class for concrete operations. This class supplies an
363 implementation of 'constant_p' that works by checking the
364 operands. */
365 template<typename... Arg>
366 class maybe_constant_operation
367 : public tuple_holding_operation<Arg...>
368 {
369 public:
370
371 using tuple_holding_operation<Arg...>::tuple_holding_operation;
372
373 bool constant_p () const override
374 {
375 return do_check_constant<0, Arg...> (this->m_storage);
376 }
377
378 private:
379
380 template<int I, typename... T>
381 typename std::enable_if<I == sizeof... (T), bool>::type
382 do_check_constant (const std::tuple<T...> &value) const
383 {
384 return true;
385 }
386
387 template<int I, typename... T>
388 typename std::enable_if<I < sizeof... (T), bool>::type
389 do_check_constant (const std::tuple<T...> &value) const
390 {
391 if (!check_constant (std::get<I> (value)))
392 return false;
393 return do_check_constant<I + 1, T...> (value);
394 }
395 };
396
397 /* A floating-point constant. The constant is encoded in the target
398 format. */
399
400 typedef std::array<gdb_byte, 16> float_data;
401
402 /* An operation that holds a floating-point constant of a given
403 type.
404
405 This does not need the facilities provided by
406 tuple_holding_operation, so it does not use it. */
407 class float_const_operation
408 : public operation
409 {
410 public:
411
412 float_const_operation (struct type *type, float_data data)
413 : m_type (type),
414 m_data (data)
415 {
416 }
417
418 value *evaluate (struct type *expect_type,
419 struct expression *exp,
420 enum noside noside) override
421 {
422 return value_from_contents (m_type, m_data.data ());
423 }
424
425 enum exp_opcode opcode () const override
426 { return OP_FLOAT; }
427
428 bool constant_p () const override
429 { return true; }
430
431 void dump (struct ui_file *stream, int depth) const override;
432
433 private:
434
435 struct type *m_type;
436 float_data m_data;
437 };
438
439 class scope_operation
440 : public maybe_constant_operation<struct type *, std::string>
441 {
442 public:
443
444 using maybe_constant_operation::maybe_constant_operation;
445
446 value *evaluate (struct type *expect_type,
447 struct expression *exp,
448 enum noside noside) override
449 {
450 return eval_op_scope (expect_type, exp, noside,
451 std::get<0> (m_storage),
452 std::get<1> (m_storage).c_str ());
453 }
454
455 value *evaluate_for_address (struct expression *exp,
456 enum noside noside) override;
457
458 enum exp_opcode opcode () const override
459 { return OP_SCOPE; }
460
461 protected:
462
463 void do_generate_ax (struct expression *exp,
464 struct agent_expr *ax,
465 struct axs_value *value,
466 struct type *cast_type)
467 override;
468 };
469
470 class long_const_operation
471 : public tuple_holding_operation<struct type *, LONGEST>
472 {
473 public:
474
475 using tuple_holding_operation::tuple_holding_operation;
476
477 value *evaluate (struct type *expect_type,
478 struct expression *exp,
479 enum noside noside) override
480 {
481 return value_from_longest (std::get<0> (m_storage),
482 std::get<1> (m_storage));
483 }
484
485 enum exp_opcode opcode () const override
486 { return OP_LONG; }
487
488 bool constant_p () const override
489 { return true; }
490
491 protected:
492
493 void do_generate_ax (struct expression *exp,
494 struct agent_expr *ax,
495 struct axs_value *value,
496 struct type *cast_type)
497 override;
498 };
499
500 class var_msym_value_operation
501 : public maybe_constant_operation<minimal_symbol *, struct objfile *>
502 {
503 public:
504
505 using maybe_constant_operation::maybe_constant_operation;
506
507 value *evaluate (struct type *expect_type,
508 struct expression *exp,
509 enum noside noside) override
510 {
511 return eval_op_var_msym_value (expect_type, exp, noside, m_outermost,
512 std::get<0> (m_storage),
513 std::get<1> (m_storage));
514 }
515
516 value *evaluate_for_sizeof (struct expression *exp, enum noside noside)
517 override;
518
519 value *evaluate_for_address (struct expression *exp, enum noside noside)
520 override;
521
522 value *evaluate_for_cast (struct type *expect_type,
523 struct expression *exp,
524 enum noside noside) override;
525
526 enum exp_opcode opcode () const override
527 { return OP_VAR_MSYM_VALUE; }
528
529 void set_outermost () override
530 {
531 m_outermost = true;
532 }
533
534 protected:
535
536 /* True if this is the outermost operation in the expression. */
537 bool m_outermost = false;
538
539 void do_generate_ax (struct expression *exp,
540 struct agent_expr *ax,
541 struct axs_value *value,
542 struct type *cast_type)
543 override;
544 };
545
546 class var_entry_value_operation
547 : public tuple_holding_operation<symbol *>
548 {
549 public:
550
551 using tuple_holding_operation::tuple_holding_operation;
552
553 value *evaluate (struct type *expect_type,
554 struct expression *exp,
555 enum noside noside) override
556 {
557 return eval_op_var_entry_value (expect_type, exp, noside,
558 std::get<0> (m_storage));
559 }
560
561 enum exp_opcode opcode () const override
562 { return OP_VAR_ENTRY_VALUE; }
563 };
564
565 class func_static_var_operation
566 : public maybe_constant_operation<operation_up, std::string>
567 {
568 public:
569
570 using maybe_constant_operation::maybe_constant_operation;
571
572 value *evaluate (struct type *expect_type,
573 struct expression *exp,
574 enum noside noside) override
575 {
576 value *func = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
577 return eval_op_func_static_var (expect_type, exp, noside, func,
578 std::get<1> (m_storage).c_str ());
579 }
580
581 enum exp_opcode opcode () const override
582 { return OP_FUNC_STATIC_VAR; }
583 };
584
585 class last_operation
586 : public tuple_holding_operation<int>
587 {
588 public:
589
590 using tuple_holding_operation::tuple_holding_operation;
591
592 value *evaluate (struct type *expect_type,
593 struct expression *exp,
594 enum noside noside) override
595 {
596 return access_value_history (std::get<0> (m_storage));
597 }
598
599 enum exp_opcode opcode () const override
600 { return OP_LAST; }
601 };
602
603 class register_operation
604 : public tuple_holding_operation<std::string>
605 {
606 public:
607
608 using tuple_holding_operation::tuple_holding_operation;
609
610 value *evaluate (struct type *expect_type,
611 struct expression *exp,
612 enum noside noside) override
613 {
614 return eval_op_register (expect_type, exp, noside,
615 std::get<0> (m_storage).c_str ());
616 }
617
618 enum exp_opcode opcode () const override
619 { return OP_REGISTER; }
620
621 protected:
622
623 void do_generate_ax (struct expression *exp,
624 struct agent_expr *ax,
625 struct axs_value *value,
626 struct type *cast_type)
627 override;
628 };
629
630 } /* namespace expr */
631
632 #endif /* EXPOP_H */
This page took 0.043618 seconds and 5 git commands to generate.