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