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