Introduce var_entry_value_operation
[deliverable/binutils-gdb.git] / gdb / expop.h
CommitLineData
e2803273
TT
1/* Definitions for expressions in GDB
2
3 Copyright (C) 2020 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#ifndef EXPOP_H
21#define EXPOP_H
22
23#include "block.h"
24#include "c-lang.h"
25#include "cp-abi.h"
26#include "expression.h"
27#include "objfiles.h"
28#include "gdbsupport/traits.h"
29#include "gdbsupport/enum-flags.h"
30
31struct agent_expr;
32struct axs_value;
33
75f9892d
TT
34extern void gen_expr_binop (struct expression *exp,
35 enum exp_opcode op,
36 expr::operation *lhs, expr::operation *rhs,
37 struct agent_expr *ax, struct axs_value *value);
38extern void gen_expr_structop (struct expression *exp,
39 enum exp_opcode op,
40 expr::operation *lhs,
41 const char *name,
42 struct agent_expr *ax, struct axs_value *value);
43
d5ab122c
TT
44extern struct value *eval_op_scope (struct type *expect_type,
45 struct expression *exp,
46 enum noside noside,
47 struct type *type, const char *string);
0c8effa3
TT
48extern struct value *eval_op_var_msym_value (struct type *expect_type,
49 struct expression *exp,
50 enum noside noside,
51 bool outermost_p,
52 minimal_symbol *msymbol,
53 struct objfile *objfile);
b5cc3923
TT
54extern struct value *eval_op_var_entry_value (struct type *expect_type,
55 struct expression *exp,
56 enum noside noside, symbol *sym);
d5ab122c 57
e2803273
TT
58namespace expr
59{
60
61/* The check_objfile overloads are used to check whether a particular
62 component of some operation references an objfile. The passed-in
63 objfile will never be a debug objfile. */
64
65/* See if EXP_OBJFILE matches OBJFILE. */
66static inline bool
67check_objfile (struct objfile *exp_objfile, struct objfile *objfile)
68{
69 if (exp_objfile->separate_debug_objfile_backlink)
70 exp_objfile = exp_objfile->separate_debug_objfile_backlink;
71 return exp_objfile == objfile;
72}
73
74static inline bool
75check_objfile (struct type *type, struct objfile *objfile)
76{
77 struct objfile *ty_objfile = type->objfile_owner ();
78 if (ty_objfile != nullptr)
79 return check_objfile (ty_objfile, objfile);
80 return false;
81}
82
83static inline bool
84check_objfile (struct symbol *sym, struct objfile *objfile)
85{
86 return check_objfile (symbol_objfile (sym), objfile);
87}
88
89static inline bool
90check_objfile (const struct block *block, struct objfile *objfile)
91{
92 return check_objfile (block_objfile (block), objfile);
93}
94
95static inline bool
96check_objfile (minimal_symbol *minsym, struct objfile *objfile)
97{
98 /* This may seem strange but minsyms are only used with an objfile
99 as well. */
100 return false;
101}
102
103static inline bool
104check_objfile (internalvar *ivar, struct objfile *objfile)
105{
106 return false;
107}
108
109static inline bool
110check_objfile (const std::string &str, struct objfile *objfile)
111{
112 return false;
113}
114
115static inline bool
116check_objfile (const operation_up &op, struct objfile *objfile)
117{
118 return op->uses_objfile (objfile);
119}
120
121static inline bool
122check_objfile (enum exp_opcode val, struct objfile *objfile)
123{
124 return false;
125}
126
127static inline bool
128check_objfile (ULONGEST val, struct objfile *objfile)
129{
130 return false;
131}
132
133template<typename T>
134static inline bool
135check_objfile (enum_flags<T> val, struct objfile *objfile)
136{
137 return false;
138}
139
140template<typename T>
141static inline bool
142check_objfile (const std::vector<T> &collection, struct objfile *objfile)
143{
144 for (const auto &item : collection)
145 {
146 if (check_objfile (item, objfile))
147 return true;
148 }
149 return false;
150}
151
152template<typename S, typename T>
153static inline bool
154check_objfile (const std::pair<S, T> &item, struct objfile *objfile)
155{
156 return (check_objfile (item.first, objfile)
157 || check_objfile (item.second, objfile));
158}
159
de401988
TT
160static inline void
161dump_for_expression (struct ui_file *stream, int depth,
162 const operation_up &op)
163{
164 op->dump (stream, depth);
165}
166
167extern void dump_for_expression (struct ui_file *stream, int depth,
168 enum exp_opcode op);
169extern void dump_for_expression (struct ui_file *stream, int depth,
170 const std::string &str);
171extern void dump_for_expression (struct ui_file *stream, int depth,
172 struct type *type);
173extern void dump_for_expression (struct ui_file *stream, int depth,
174 CORE_ADDR addr);
175extern void dump_for_expression (struct ui_file *stream, int depth,
176 internalvar *ivar);
177extern void dump_for_expression (struct ui_file *stream, int depth,
178 symbol *sym);
179extern void dump_for_expression (struct ui_file *stream, int depth,
180 minimal_symbol *msym);
181extern void dump_for_expression (struct ui_file *stream, int depth,
182 const block *bl);
183extern void dump_for_expression (struct ui_file *stream, int depth,
184 type_instance_flags flags);
185extern void dump_for_expression (struct ui_file *stream, int depth,
186 enum c_string_type_values flags);
187extern void dump_for_expression (struct ui_file *stream, int depth,
188 enum range_flag flags);
189extern void dump_for_expression (struct ui_file *stream, int depth,
190 objfile *objf);
191
192template<typename T>
193void
194dump_for_expression (struct ui_file *stream, int depth,
195 const std::vector<T> &vals)
196{
197 fprintf_filtered (stream, _("%*sVector:\n"), depth, "");
198 for (auto &item : vals)
199 dump_for_expression (stream, depth + 1, item);
200}
201
202template<typename X, typename Y>
203void
204dump_for_expression (struct ui_file *stream, int depth,
205 const std::pair<X, Y> &vals)
206{
207 dump_for_expression (stream, depth, vals.first);
208 dump_for_expression (stream, depth, vals.second);
209}
210
e2803273
TT
211/* Base class for most concrete operations. This class holds data,
212 specified via template parameters, and supplies generic
213 implementations of the 'dump' and 'uses_objfile' methods. */
214template<typename... Arg>
215class tuple_holding_operation : public operation
216{
217public:
218
219 explicit tuple_holding_operation (Arg... args)
220 : m_storage (std::forward<Arg> (args)...)
221 {
222 }
223
224 DISABLE_COPY_AND_ASSIGN (tuple_holding_operation);
225
226 bool uses_objfile (struct objfile *objfile) const override
227 {
228 return do_check_objfile<0, Arg...> (objfile, m_storage);
229 }
230
231 void dump (struct ui_file *stream, int depth) const override
232 {
de401988
TT
233 dump_for_expression (stream, depth, opcode ());
234 do_dump<0, Arg...> (stream, depth + 1, m_storage);
e2803273
TT
235 }
236
237protected:
238
239 /* Storage for the data. */
240 std::tuple<Arg...> m_storage;
241
242private:
243
244 /* do_dump does the work of dumping the data. */
245 template<int I, typename... T>
246 typename std::enable_if<I == sizeof... (T), void>::type
247 do_dump (struct ui_file *stream, int depth, const std::tuple<T...> &value)
248 const
249 {
250 }
251
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 {
de401988 257 dump_for_expression (stream, depth, std::get<I> (value));
e2803273
TT
258 do_dump<I + 1, T...> (stream, depth, value);
259 }
260
261 /* do_check_objfile does the work of checking whether this object
262 refers to OBJFILE. */
263 template<int I, typename... T>
264 typename std::enable_if<I == sizeof... (T), bool>::type
265 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
266 const
267 {
268 return false;
269 }
270
271 template<int I, typename... T>
272 typename std::enable_if<I < sizeof... (T), bool>::type
273 do_check_objfile (struct objfile *objfile, const std::tuple<T...> &value)
274 const
275 {
276 if (check_objfile (std::get<I> (value), objfile))
277 return true;
278 return do_check_objfile<I + 1, T...> (objfile, value);
279 }
280};
281
282/* The check_constant overloads are used to decide whether a given
283 concrete operation is a constant. This is done by checking the
284 operands. */
285
286static inline bool
287check_constant (const operation_up &item)
288{
289 return item->constant_p ();
290}
291
292static inline bool
293check_constant (struct minimal_symbol *msym)
294{
295 return false;
296}
297
298static inline bool
299check_constant (struct type *type)
300{
301 return true;
302}
303
304static inline bool
305check_constant (const struct block *block)
306{
307 return true;
308}
309
310static inline bool
311check_constant (const std::string &str)
312{
313 return true;
314}
315
316static inline bool
317check_constant (struct objfile *objfile)
318{
319 return true;
320}
321
322static inline bool
323check_constant (ULONGEST cst)
324{
325 return true;
326}
327
328static inline bool
329check_constant (struct symbol *sym)
330{
331 enum address_class sc = SYMBOL_CLASS (sym);
332 return (sc == LOC_BLOCK
333 || sc == LOC_CONST
334 || sc == LOC_CONST_BYTES
335 || sc == LOC_LABEL);
336}
337
338template<typename T>
339static inline bool
340check_constant (const std::vector<T> &collection)
341{
342 for (const auto &item : collection)
343 if (!check_constant (item))
344 return false;
345 return true;
346}
347
348template<typename S, typename T>
349static inline bool
350check_constant (const std::pair<S, T> &item)
351{
352 return check_constant (item.first) && check_constant (item.second);
353}
354
355/* Base class for concrete operations. This class supplies an
356 implementation of 'constant_p' that works by checking the
357 operands. */
358template<typename... Arg>
359class maybe_constant_operation
360 : public tuple_holding_operation<Arg...>
361{
362public:
363
364 using tuple_holding_operation<Arg...>::tuple_holding_operation;
365
366 bool constant_p () const override
367 {
368 return do_check_constant<0, Arg...> (this->m_storage);
369 }
370
371private:
372
373 template<int I, typename... T>
374 typename std::enable_if<I == sizeof... (T), bool>::type
375 do_check_constant (const std::tuple<T...> &value) const
376 {
377 return true;
378 }
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 if (!check_constant (std::get<I> (value)))
385 return false;
386 return do_check_constant<I + 1, T...> (value);
387 }
388};
389
cae26a0c
TT
390/* A floating-point constant. The constant is encoded in the target
391 format. */
392
393typedef std::array<gdb_byte, 16> float_data;
394
395/* An operation that holds a floating-point constant of a given
396 type.
397
398 This does not need the facilities provided by
399 tuple_holding_operation, so it does not use it. */
400class float_const_operation
401 : public operation
402{
403public:
404
405 float_const_operation (struct type *type, float_data data)
406 : m_type (type),
407 m_data (data)
408 {
409 }
410
411 value *evaluate (struct type *expect_type,
412 struct expression *exp,
413 enum noside noside) override
414 {
415 return value_from_contents (m_type, m_data.data ());
416 }
417
418 enum exp_opcode opcode () const override
419 { return OP_FLOAT; }
420
421 bool constant_p () const override
422 { return true; }
423
424 void dump (struct ui_file *stream, int depth) const override;
425
426private:
427
428 struct type *m_type;
429 float_data m_data;
430};
431
d5ab122c
TT
432class scope_operation
433 : public maybe_constant_operation<struct type *, std::string>
434{
435public:
436
437 using maybe_constant_operation::maybe_constant_operation;
438
439 value *evaluate (struct type *expect_type,
440 struct expression *exp,
441 enum noside noside) override
442 {
443 return eval_op_scope (expect_type, exp, noside,
444 std::get<0> (m_storage),
445 std::get<1> (m_storage).c_str ());
446 }
447
448 value *evaluate_for_address (struct expression *exp,
449 enum noside noside) override;
450
451 enum exp_opcode opcode () const override
452 { return OP_SCOPE; }
453
454protected:
455
456 void do_generate_ax (struct expression *exp,
457 struct agent_expr *ax,
458 struct axs_value *value,
459 struct type *cast_type)
460 override;
461};
462
d336c29e
TT
463class long_const_operation
464 : public tuple_holding_operation<struct type *, LONGEST>
465{
466public:
467
468 using tuple_holding_operation::tuple_holding_operation;
469
470 value *evaluate (struct type *expect_type,
471 struct expression *exp,
472 enum noside noside) override
473 {
474 return value_from_longest (std::get<0> (m_storage),
475 std::get<1> (m_storage));
476 }
477
478 enum exp_opcode opcode () const override
479 { return OP_LONG; }
480
481 bool constant_p () const override
482 { return true; }
483
484protected:
485
486 void do_generate_ax (struct expression *exp,
487 struct agent_expr *ax,
488 struct axs_value *value,
489 struct type *cast_type)
490 override;
491};
492
0c8effa3
TT
493class var_msym_value_operation
494 : public maybe_constant_operation<minimal_symbol *, struct objfile *>
495{
496public:
497
498 using maybe_constant_operation::maybe_constant_operation;
499
500 value *evaluate (struct type *expect_type,
501 struct expression *exp,
502 enum noside noside) override
503 {
504 return eval_op_var_msym_value (expect_type, exp, noside, m_outermost,
505 std::get<0> (m_storage),
506 std::get<1> (m_storage));
507 }
508
509 value *evaluate_for_sizeof (struct expression *exp, enum noside noside)
510 override;
511
512 value *evaluate_for_address (struct expression *exp, enum noside noside)
513 override;
514
515 value *evaluate_for_cast (struct type *expect_type,
516 struct expression *exp,
517 enum noside noside) override;
518
519 enum exp_opcode opcode () const override
520 { return OP_VAR_MSYM_VALUE; }
521
522 void set_outermost () override
523 {
524 m_outermost = true;
525 }
526
527protected:
528
529 /* True if this is the outermost operation in the expression. */
530 bool m_outermost = false;
531
532 void do_generate_ax (struct expression *exp,
533 struct agent_expr *ax,
534 struct axs_value *value,
535 struct type *cast_type)
536 override;
537};
538
b5cc3923
TT
539class var_entry_value_operation
540 : public tuple_holding_operation<symbol *>
541{
542public:
543
544 using tuple_holding_operation::tuple_holding_operation;
545
546 value *evaluate (struct type *expect_type,
547 struct expression *exp,
548 enum noside noside) override
549 {
550 return eval_op_var_entry_value (expect_type, exp, noside,
551 std::get<0> (m_storage));
552 }
553
554 enum exp_opcode opcode () const override
555 { return OP_VAR_ENTRY_VALUE; }
556};
557
e2803273
TT
558} /* namespace expr */
559
560#endif /* EXPOP_H */
This page took 0.047444 seconds and 4 git commands to generate.