1 /* Definitions for expressions in GDB
3 Copyright (C) 2020 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
26 #include "expression.h"
28 #include "gdbsupport/traits.h"
29 #include "gdbsupport/enum-flags.h"
34 extern void gen_expr_binop (struct expression
*exp
,
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
,
42 struct agent_expr
*ax
, struct axs_value
*value
);
44 extern struct value
*eval_op_scope (struct type
*expect_type
,
45 struct expression
*exp
,
47 struct type
*type
, const char *string
);
48 extern struct value
*eval_op_var_msym_value (struct type
*expect_type
,
49 struct expression
*exp
,
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
,
60 value
*func
, const char *var
);
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. */
69 /* See if EXP_OBJFILE matches OBJFILE. */
71 check_objfile (struct objfile
*exp_objfile
, struct objfile
*objfile
)
73 if (exp_objfile
->separate_debug_objfile_backlink
)
74 exp_objfile
= exp_objfile
->separate_debug_objfile_backlink
;
75 return exp_objfile
== objfile
;
79 check_objfile (struct type
*type
, struct objfile
*objfile
)
81 struct objfile
*ty_objfile
= type
->objfile_owner ();
82 if (ty_objfile
!= nullptr)
83 return check_objfile (ty_objfile
, objfile
);
88 check_objfile (struct symbol
*sym
, struct objfile
*objfile
)
90 return check_objfile (symbol_objfile (sym
), objfile
);
94 check_objfile (const struct block
*block
, struct objfile
*objfile
)
96 return check_objfile (block_objfile (block
), objfile
);
100 check_objfile (minimal_symbol
*minsym
, struct objfile
*objfile
)
102 /* This may seem strange but minsyms are only used with an objfile
108 check_objfile (internalvar
*ivar
, struct objfile
*objfile
)
114 check_objfile (const std::string
&str
, struct objfile
*objfile
)
120 check_objfile (const operation_up
&op
, struct objfile
*objfile
)
122 return op
->uses_objfile (objfile
);
126 check_objfile (enum exp_opcode val
, struct objfile
*objfile
)
132 check_objfile (ULONGEST val
, struct objfile
*objfile
)
139 check_objfile (enum_flags
<T
> val
, struct objfile
*objfile
)
146 check_objfile (const std::vector
<T
> &collection
, struct objfile
*objfile
)
148 for (const auto &item
: collection
)
150 if (check_objfile (item
, objfile
))
156 template<typename S
, typename T
>
158 check_objfile (const std::pair
<S
, T
> &item
, struct objfile
*objfile
)
160 return (check_objfile (item
.first
, objfile
)
161 || check_objfile (item
.second
, objfile
));
165 dump_for_expression (struct ui_file
*stream
, int depth
,
166 const operation_up
&op
)
168 op
->dump (stream
, depth
);
171 extern void dump_for_expression (struct ui_file
*stream
, int depth
,
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
,
177 extern void dump_for_expression (struct ui_file
*stream
, int depth
,
179 extern void dump_for_expression (struct ui_file
*stream
, int depth
,
181 extern void dump_for_expression (struct ui_file
*stream
, int depth
,
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
,
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
,
198 dump_for_expression (struct ui_file
*stream
, int depth
,
199 const std::vector
<T
> &vals
)
201 fprintf_filtered (stream
, _("%*sVector:\n"), depth
, "");
202 for (auto &item
: vals
)
203 dump_for_expression (stream
, depth
+ 1, item
);
206 template<typename X
, typename Y
>
208 dump_for_expression (struct ui_file
*stream
, int depth
,
209 const std::pair
<X
, Y
> &vals
)
211 dump_for_expression (stream
, depth
, vals
.first
);
212 dump_for_expression (stream
, depth
, vals
.second
);
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
223 explicit tuple_holding_operation (Arg
... args
)
224 : m_storage (std::forward
<Arg
> (args
)...)
228 DISABLE_COPY_AND_ASSIGN (tuple_holding_operation
);
230 bool uses_objfile (struct objfile
*objfile
) const override
232 return do_check_objfile
<0, Arg
...> (objfile
, m_storage
);
235 void dump (struct ui_file
*stream
, int depth
) const override
237 dump_for_expression (stream
, depth
, opcode ());
238 do_dump
<0, Arg
...> (stream
, depth
+ 1, m_storage
);
243 /* Storage for the data. */
244 std::tuple
<Arg
...> m_storage
;
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
)
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
)
261 dump_for_expression (stream
, depth
, std::get
<I
> (value
));
262 do_dump
<I
+ 1, T
...> (stream
, depth
, value
);
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
)
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
)
280 if (check_objfile (std::get
<I
> (value
), objfile
))
282 return do_check_objfile
<I
+ 1, T
...> (objfile
, value
);
286 /* The check_constant overloads are used to decide whether a given
287 concrete operation is a constant. This is done by checking the
291 check_constant (const operation_up
&item
)
293 return item
->constant_p ();
297 check_constant (struct minimal_symbol
*msym
)
303 check_constant (struct type
*type
)
309 check_constant (const struct block
*block
)
315 check_constant (const std::string
&str
)
321 check_constant (struct objfile
*objfile
)
327 check_constant (ULONGEST cst
)
333 check_constant (struct symbol
*sym
)
335 enum address_class sc
= SYMBOL_CLASS (sym
);
336 return (sc
== LOC_BLOCK
338 || sc
== LOC_CONST_BYTES
344 check_constant (const std::vector
<T
> &collection
)
346 for (const auto &item
: collection
)
347 if (!check_constant (item
))
352 template<typename S
, typename T
>
354 check_constant (const std::pair
<S
, T
> &item
)
356 return check_constant (item
.first
) && check_constant (item
.second
);
359 /* Base class for concrete operations. This class supplies an
360 implementation of 'constant_p' that works by checking the
362 template<typename
... Arg
>
363 class maybe_constant_operation
364 : public tuple_holding_operation
<Arg
...>
368 using tuple_holding_operation
<Arg
...>::tuple_holding_operation
;
370 bool constant_p () const override
372 return do_check_constant
<0, Arg
...> (this->m_storage
);
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
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
388 if (!check_constant (std::get
<I
> (value
)))
390 return do_check_constant
<I
+ 1, T
...> (value
);
394 /* A floating-point constant. The constant is encoded in the target
397 typedef std::array
<gdb_byte
, 16> float_data
;
399 /* An operation that holds a floating-point constant of a given
402 This does not need the facilities provided by
403 tuple_holding_operation, so it does not use it. */
404 class float_const_operation
409 float_const_operation (struct type
*type
, float_data data
)
415 value
*evaluate (struct type
*expect_type
,
416 struct expression
*exp
,
417 enum noside noside
) override
419 return value_from_contents (m_type
, m_data
.data ());
422 enum exp_opcode
opcode () const override
425 bool constant_p () const override
428 void dump (struct ui_file
*stream
, int depth
) const override
;
436 class scope_operation
437 : public maybe_constant_operation
<struct type
*, std::string
>
441 using maybe_constant_operation::maybe_constant_operation
;
443 value
*evaluate (struct type
*expect_type
,
444 struct expression
*exp
,
445 enum noside noside
) override
447 return eval_op_scope (expect_type
, exp
, noside
,
448 std::get
<0> (m_storage
),
449 std::get
<1> (m_storage
).c_str ());
452 value
*evaluate_for_address (struct expression
*exp
,
453 enum noside noside
) override
;
455 enum exp_opcode
opcode () const override
460 void do_generate_ax (struct expression
*exp
,
461 struct agent_expr
*ax
,
462 struct axs_value
*value
,
463 struct type
*cast_type
)
467 class long_const_operation
468 : public tuple_holding_operation
<struct type
*, LONGEST
>
472 using tuple_holding_operation::tuple_holding_operation
;
474 value
*evaluate (struct type
*expect_type
,
475 struct expression
*exp
,
476 enum noside noside
) override
478 return value_from_longest (std::get
<0> (m_storage
),
479 std::get
<1> (m_storage
));
482 enum exp_opcode
opcode () const override
485 bool constant_p () const override
490 void do_generate_ax (struct expression
*exp
,
491 struct agent_expr
*ax
,
492 struct axs_value
*value
,
493 struct type
*cast_type
)
497 class var_msym_value_operation
498 : public maybe_constant_operation
<minimal_symbol
*, struct objfile
*>
502 using maybe_constant_operation::maybe_constant_operation
;
504 value
*evaluate (struct type
*expect_type
,
505 struct expression
*exp
,
506 enum noside noside
) override
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
));
513 value
*evaluate_for_sizeof (struct expression
*exp
, enum noside noside
)
516 value
*evaluate_for_address (struct expression
*exp
, enum noside noside
)
519 value
*evaluate_for_cast (struct type
*expect_type
,
520 struct expression
*exp
,
521 enum noside noside
) override
;
523 enum exp_opcode
opcode () const override
524 { return OP_VAR_MSYM_VALUE
; }
526 void set_outermost () override
533 /* True if this is the outermost operation in the expression. */
534 bool m_outermost
= false;
536 void do_generate_ax (struct expression
*exp
,
537 struct agent_expr
*ax
,
538 struct axs_value
*value
,
539 struct type
*cast_type
)
543 class var_entry_value_operation
544 : public tuple_holding_operation
<symbol
*>
548 using tuple_holding_operation::tuple_holding_operation
;
550 value
*evaluate (struct type
*expect_type
,
551 struct expression
*exp
,
552 enum noside noside
) override
554 return eval_op_var_entry_value (expect_type
, exp
, noside
,
555 std::get
<0> (m_storage
));
558 enum exp_opcode
opcode () const override
559 { return OP_VAR_ENTRY_VALUE
; }
562 class func_static_var_operation
563 : public maybe_constant_operation
<operation_up
, std::string
>
567 using maybe_constant_operation::maybe_constant_operation
;
569 value
*evaluate (struct type
*expect_type
,
570 struct expression
*exp
,
571 enum noside noside
) override
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 ());
578 enum exp_opcode
opcode () const override
579 { return OP_FUNC_STATIC_VAR
; }
582 } /* namespace expr */