1999-04-16 09:35:26 +08:00
|
|
|
/* Definitions for expressions stored in reversed prefix form, for GDB.
|
2003-01-13 Andrew Cagney <ac131313@redhat.com>
* ax-gdb.c, c-valprint.c, charset.c, corefile.c: Update copyright.
* demangle.c, disasm.c, dwarf2cfi.c, dwarfread.c: Update copyright.
* elfread.c, eval.c, expprint.c, expression.h: Update copyright.
* f-typeprint.c, findvar.c, gcore.c, gdb_mbuild.sh: Update copyright.
* gdbtypes.h, gnu-v2-abi.c, inferior.h, inftarg.c: Update copyright.
* language.c, language.h, m32r-tdep.c: Update copyright.
* mn10200-tdep.c, scm-lang.c, scm-lang.h: Update copyright.
* somsolib.c, somsolib.h, symfile.c, symtab.h: Update copyright.
* thread-db.c, typeprint.c, utils.c, valarith.c: Update copyright.
* values.c, win32-nat.c, x86-64-linux-nat.c: Update copyright.
* x86-64-linux-tdep.c, z8k-tdep.c: Update copyright.
* cli/cli-decode.h, config/h8500/tm-h8500.h: Update copyright.
Index: mi/ChangeLog
2003-01-13 Andrew Cagney <ac131313@redhat.com>
* mi-cmd-env.c: Update copyright.
2003-01-14 08:49:06 +08:00
|
|
|
|
2021-01-01 16:03:39 +08:00
|
|
|
Copyright (C) 1986-2021 Free Software Foundation, Inc.
|
1999-04-16 09:35:26 +08:00
|
|
|
|
1999-07-08 04:19:36 +08:00
|
|
|
This file is part of GDB.
|
1999-04-16 09:35:26 +08:00
|
|
|
|
1999-07-08 04:19:36 +08:00
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2007-08-24 02:08:50 +08:00
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
1999-07-08 04:19:36 +08:00
|
|
|
(at your option) any later version.
|
1999-04-16 09:35:26 +08:00
|
|
|
|
1999-07-08 04:19:36 +08:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
1999-04-16 09:35:26 +08:00
|
|
|
|
1999-07-08 04:19:36 +08:00
|
|
|
You should have received a copy of the GNU General Public License
|
2007-08-24 02:08:50 +08:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
1999-04-16 09:35:26 +08:00
|
|
|
|
|
|
|
#if !defined (EXPRESSION_H)
|
|
|
|
#define EXPRESSION_H 1
|
|
|
|
|
Don't include gdbarch.h from defs.h
I touched symtab.h and was surprised to see how many files were
rebuilt. I looked into it a bit, and found that defs.h includes
gdbarch.h, which in turn includes many things.
gdbarch.h is only needed by a minority ofthe files in gdb, so this
patch removes the include from defs.h and updates the fallout.
I did "wc -l" on the files in build/gdb/.deps; this patch reduces the
line count from 139935 to 137030; so there are definitely future
build-time savings here.
Note that while I configured with --enable-targets=all, it's possible
that some *-nat.c file needs an update. I could not test all of
these. The buildbot caught a few problems along these lines.
gdb/ChangeLog
2019-07-10 Tom Tromey <tom@tromey.com>
* defs.h: Don't include gdbarch.h.
* aarch64-ravenscar-thread.c, aarch64-tdep.c, alpha-bsd-tdep.h,
alpha-linux-tdep.c, alpha-mdebug-tdep.c, arch-utils.h, arm-tdep.h,
ax-general.c, btrace.c, buildsym-legacy.c, buildsym.h, c-lang.c,
cli/cli-decode.h, cli/cli-dump.c, cli/cli-script.h,
cli/cli-style.h, coff-pe-read.h, compile/compile-c-support.c,
compile/compile-cplus.h, compile/compile-loc2c.c, corefile.c,
cp-valprint.c, cris-linux-tdep.c, ctf.c, d-lang.c, d-namespace.c,
dcache.c, dicos-tdep.c, dictionary.c, disasm-selftests.c,
dummy-frame.c, dummy-frame.h, dwarf2-frame-tailcall.c,
dwarf2expr.c, expression.h, f-lang.c, frame-base.c,
frame-unwind.c, frv-linux-tdep.c, gdbarch-selftests.c, gdbtypes.h,
go-lang.c, hppa-nbsd-tdep.c, hppa-obsd-tdep.c, i386-dicos-tdep.c,
i386-tdep.h, ia64-vms-tdep.c, interps.h, language.c,
linux-record.c, location.h, m2-lang.c, m32r-linux-tdep.c,
mem-break.c, memattr.c, mn10300-linux-tdep.c, nios2-linux-tdep.c,
objfiles.h, opencl-lang.c, or1k-linux-tdep.c, p-lang.c,
parser-defs.h, ppc-tdep.h, probe.h, python/py-record-btrace.c,
record-btrace.c, record.h, regcache-dump.c, regcache.h,
riscv-fbsd-tdep.c, riscv-linux-tdep.c, rust-exp.y,
sh-linux-tdep.c, sh-nbsd-tdep.c, source-cache.c,
sparc-nbsd-tdep.c, sparc-obsd-tdep.c, sparc-ravenscar-thread.c,
sparc64-fbsd-tdep.c, std-regs.c, target-descriptions.h,
target-float.c, tic6x-linux-tdep.c, tilegx-linux-tdep.c, top.c,
tracefile.c, trad-frame.c, type-stack.h, ui-style.c, utils.c,
utils.h, valarith.c, valprint.c, varobj.c, x86-tdep.c,
xml-support.h, xtensa-linux-tdep.c, cli/cli-cmds.h: Update.
* s390-linux-nat.c, procfs.c, inf-ptrace.c: Likewise.
2019-06-10 05:21:02 +08:00
|
|
|
#include "gdbtypes.h"
|
|
|
|
|
2019-03-24 00:11:51 +08:00
|
|
|
/* While parsing expressions we need to track the innermost lexical block
|
|
|
|
that we encounter. In some situations we need to track the innermost
|
|
|
|
block just for symbols, and in other situations we want to track the
|
|
|
|
innermost block for symbols and registers. These flags are used by the
|
|
|
|
innermost block tracker to control which blocks we consider for the
|
|
|
|
innermost block. These flags can be combined together as needed. */
|
|
|
|
|
|
|
|
enum innermost_block_tracker_type
|
|
|
|
{
|
|
|
|
/* Track the innermost block for symbols within an expression. */
|
|
|
|
INNERMOST_BLOCK_FOR_SYMBOLS = (1 << 0),
|
|
|
|
|
|
|
|
/* Track the innermost block for registers within an expression. */
|
|
|
|
INNERMOST_BLOCK_FOR_REGISTERS = (1 << 1)
|
|
|
|
};
|
|
|
|
DEF_ENUM_FLAGS_TYPE (enum innermost_block_tracker_type,
|
|
|
|
innermost_block_tracker_types);
|
1999-04-16 09:35:26 +08:00
|
|
|
|
Avoid undefined behavior in expression dumping
-fsanitize=undefined pointed out undefined behavior in
dump_raw_expression like:
runtime error: load of value 2887952, which is not a valid value for type 'exp_opcode'
dump_raw_expression will try to print the opcode for each element of
the expression, even when it is not valid. To allow this, but have it
avoid undefined behavior, this patch sets the underlying type of enum
exp_opcode, and arranges for op_name to handle invalid opcodes more
nicely.
Before this patch, debug-expr.exp shows:
Dump of expression @ 0x60f000007750, before conversion to prefix form:
Language c, 8 elements, 16 bytes each.
Index Opcode Hex Value String Value
0 OP_TYPE 89 Y...............
<unknown 3851920> 107820862850704 ..:..b..........
2 OP_TYPE 89 Y...............
3 OP_VAR_VALUE 40 (...............
4 <unknown 2807568> 107820861806352 ..*..b..........
5 <unknown 2806368> 107820861805152 `.*..b..........
6 OP_VAR_VALUE 40 (...............
7 UNOP_MEMVAL_TYPE 57 9...............
Afterward, the output is:
Dump of expression @ 0x4820f90, before conversion to prefix form:
Language c, 8 elements, 16 bytes each.
Index Opcode Hex Value String Value
0 OP_TYPE 89 Y...............
1 unknown opcode: 176 75444400 .0..............
2 OP_TYPE 89 Y...............
3 OP_VAR_VALUE 40 (...............
4 OP_BOOL 74616912 P.r.............
5 unknown opcode: 128 74615680 ..r.............
6 OP_VAR_VALUE 40 (...............
7 UNOP_MEMVAL_TYPE 57 9...............
gdb/ChangeLog
2018-10-03 Tom Tromey <tom@tromey.com>
* expression.h (enum exp_opcode): Use uint8_t as base type.
* expprint.c (op_name): Handle invalid opcodes.
2018-08-18 10:34:40 +08:00
|
|
|
enum exp_opcode : uint8_t
|
1999-07-08 04:19:36 +08:00
|
|
|
{
|
2011-02-02 02:54:01 +08:00
|
|
|
#define OP(name) name ,
|
1999-04-16 09:35:26 +08:00
|
|
|
|
2011-02-02 02:54:01 +08:00
|
|
|
#include "std-operator.def"
|
1999-04-16 09:35:26 +08:00
|
|
|
|
2011-02-02 02:54:01 +08:00
|
|
|
#undef OP
|
1999-07-08 04:19:36 +08:00
|
|
|
};
|
1999-04-16 09:35:26 +08:00
|
|
|
|
2020-11-21 23:49:10 +08:00
|
|
|
/* Values of NOSIDE argument to eval_subexp. */
|
|
|
|
|
|
|
|
enum noside
|
|
|
|
{
|
|
|
|
EVAL_NORMAL,
|
|
|
|
EVAL_AVOID_SIDE_EFFECTS /* Don't modify any variables or
|
|
|
|
call any functions. The value
|
|
|
|
returned will have the correct
|
|
|
|
type, and will have an
|
|
|
|
approximately correct lvalue
|
|
|
|
type (inaccuracy: anything that is
|
|
|
|
listed as being in a register in
|
|
|
|
the function in which it was
|
|
|
|
declared will be lval_register).
|
|
|
|
Ideally this would not even read
|
|
|
|
target memory, but currently it
|
|
|
|
does in many situations. */
|
|
|
|
};
|
|
|
|
|
Introduce class operation
This patch introduces class operation, the new base class for all
expression operations.
In the new approach, an operation is simply a class that presents a
certain interface. Operations own their operands, and management is
done via unique_ptr.
The operation interface is largely ad hoc, based on the evolution of
expression handling in GDB. Parts (for example,
evaluate_with_coercion) are probably redundant; however I took this
approach to try to avoid mixing different kinds of refactorings.
In some specific situations, rather than add a generic method across
the entire operation class hierarchy, I chose instead to use
dynamic_cast and specialized methods on certain concrete subclasses.
This will appear in some subsequent patches.
One goal of this work is to avoid the kinds of easy-to-make errors
that affected the old implementation. To this end, some helper
subclasses are also added here. These helpers automate the
implementation of the 'dump', 'uses_objfile', and 'constant_p'
methods. Nearly every concrete operation that is subsequently added
will use these facilities. (Note that the 'dump' implementation is
only outlined here, the body appears in the next patch.)
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* expression.h (expr::operation): New class.
(expr::make_operation): New function.
(expr::operation_up): New typedef.
* expop.h: New file.
* eval.c (operation::evaluate_for_cast)
(operation::evaluate_for_address, operation::evaluate_for_sizeof):
New methods.
* ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
|
|
|
struct expression;
|
|
|
|
struct agent_expr;
|
|
|
|
struct axs_value;
|
|
|
|
struct type;
|
|
|
|
struct ui_file;
|
|
|
|
|
|
|
|
namespace expr
|
|
|
|
{
|
|
|
|
|
|
|
|
class operation;
|
|
|
|
typedef std::unique_ptr<operation> operation_up;
|
|
|
|
|
|
|
|
/* Base class for an operation. An operation is a single component of
|
|
|
|
an expression. */
|
|
|
|
|
|
|
|
class operation
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
|
|
|
|
operation () = default;
|
|
|
|
DISABLE_COPY_AND_ASSIGN (operation);
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
virtual ~operation () = default;
|
|
|
|
|
|
|
|
/* Evaluate this operation. */
|
|
|
|
virtual value *evaluate (struct type *expect_type,
|
|
|
|
struct expression *exp,
|
|
|
|
enum noside noside) = 0;
|
|
|
|
|
|
|
|
/* Evaluate this operation in a context where C-like coercion is
|
|
|
|
needed. */
|
|
|
|
virtual value *evaluate_with_coercion (struct expression *exp,
|
|
|
|
enum noside noside)
|
|
|
|
{
|
|
|
|
return evaluate (nullptr, exp, noside);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Evaluate this expression in the context of a cast to
|
|
|
|
EXPECT_TYPE. */
|
|
|
|
virtual value *evaluate_for_cast (struct type *expect_type,
|
|
|
|
struct expression *exp,
|
|
|
|
enum noside noside);
|
|
|
|
|
|
|
|
/* Evaluate this expression in the context of a sizeof
|
|
|
|
operation. */
|
|
|
|
virtual value *evaluate_for_sizeof (struct expression *exp,
|
|
|
|
enum noside noside);
|
|
|
|
|
|
|
|
/* Evaluate this expression in the context of an address-of
|
|
|
|
operation. Must return the address. */
|
|
|
|
virtual value *evaluate_for_address (struct expression *exp,
|
|
|
|
enum noside noside);
|
|
|
|
|
2021-03-08 22:27:57 +08:00
|
|
|
/* Evaluate a function call, with this object as the callee.
|
|
|
|
EXPECT_TYPE, EXP, and NOSIDE have the same meaning as in
|
|
|
|
'evaluate'. ARGS holds the operations that should be evaluated
|
|
|
|
to get the arguments to the call. */
|
|
|
|
virtual value *evaluate_funcall (struct type *expect_type,
|
|
|
|
struct expression *exp,
|
|
|
|
enum noside noside,
|
|
|
|
const std::vector<operation_up> &args)
|
|
|
|
{
|
|
|
|
/* Defer to the helper overload. */
|
|
|
|
return evaluate_funcall (expect_type, exp, noside, nullptr, args);
|
|
|
|
}
|
|
|
|
|
Introduce class operation
This patch introduces class operation, the new base class for all
expression operations.
In the new approach, an operation is simply a class that presents a
certain interface. Operations own their operands, and management is
done via unique_ptr.
The operation interface is largely ad hoc, based on the evolution of
expression handling in GDB. Parts (for example,
evaluate_with_coercion) are probably redundant; however I took this
approach to try to avoid mixing different kinds of refactorings.
In some specific situations, rather than add a generic method across
the entire operation class hierarchy, I chose instead to use
dynamic_cast and specialized methods on certain concrete subclasses.
This will appear in some subsequent patches.
One goal of this work is to avoid the kinds of easy-to-make errors
that affected the old implementation. To this end, some helper
subclasses are also added here. These helpers automate the
implementation of the 'dump', 'uses_objfile', and 'constant_p'
methods. Nearly every concrete operation that is subsequently added
will use these facilities. (Note that the 'dump' implementation is
only outlined here, the body appears in the next patch.)
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* expression.h (expr::operation): New class.
(expr::make_operation): New function.
(expr::operation_up): New typedef.
* expop.h: New file.
* eval.c (operation::evaluate_for_cast)
(operation::evaluate_for_address, operation::evaluate_for_sizeof):
New methods.
* ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
|
|
|
/* True if this is a constant expression. */
|
|
|
|
virtual bool constant_p () const
|
|
|
|
{ return false; }
|
|
|
|
|
|
|
|
/* Return true if this operation uses OBJFILE (and will become
|
|
|
|
dangling when OBJFILE is unloaded), otherwise return false.
|
|
|
|
OBJFILE must not be a separate debug info file. */
|
|
|
|
virtual bool uses_objfile (struct objfile *objfile) const
|
|
|
|
{ return false; }
|
|
|
|
|
|
|
|
/* Generate agent expression bytecodes for this operation. */
|
|
|
|
void generate_ax (struct expression *exp, struct agent_expr *ax,
|
|
|
|
struct axs_value *value,
|
|
|
|
struct type *cast_type = nullptr);
|
|
|
|
|
|
|
|
/* Return the opcode that is implemented by this operation. */
|
|
|
|
virtual enum exp_opcode opcode () const = 0;
|
|
|
|
|
|
|
|
/* Print this operation to STREAM. */
|
|
|
|
virtual void dump (struct ui_file *stream, int depth) const = 0;
|
|
|
|
|
2021-03-08 22:27:57 +08:00
|
|
|
/* Call to indicate that this is the outermost operation in the
|
|
|
|
expression. This should almost never be overridden. */
|
|
|
|
virtual void set_outermost () { }
|
|
|
|
|
Introduce class operation
This patch introduces class operation, the new base class for all
expression operations.
In the new approach, an operation is simply a class that presents a
certain interface. Operations own their operands, and management is
done via unique_ptr.
The operation interface is largely ad hoc, based on the evolution of
expression handling in GDB. Parts (for example,
evaluate_with_coercion) are probably redundant; however I took this
approach to try to avoid mixing different kinds of refactorings.
In some specific situations, rather than add a generic method across
the entire operation class hierarchy, I chose instead to use
dynamic_cast and specialized methods on certain concrete subclasses.
This will appear in some subsequent patches.
One goal of this work is to avoid the kinds of easy-to-make errors
that affected the old implementation. To this end, some helper
subclasses are also added here. These helpers automate the
implementation of the 'dump', 'uses_objfile', and 'constant_p'
methods. Nearly every concrete operation that is subsequently added
will use these facilities. (Note that the 'dump' implementation is
only outlined here, the body appears in the next patch.)
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* expression.h (expr::operation): New class.
(expr::make_operation): New function.
(expr::operation_up): New typedef.
* expop.h: New file.
* eval.c (operation::evaluate_for_cast)
(operation::evaluate_for_address, operation::evaluate_for_sizeof):
New methods.
* ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
|
|
|
protected:
|
|
|
|
|
2021-03-08 22:27:57 +08:00
|
|
|
/* A helper overload that wraps evaluate_subexp_do_call. */
|
|
|
|
value *evaluate_funcall (struct type *expect_type,
|
|
|
|
struct expression *exp,
|
|
|
|
enum noside noside,
|
|
|
|
const char *function_name,
|
|
|
|
const std::vector<operation_up> &args);
|
|
|
|
|
Introduce class operation
This patch introduces class operation, the new base class for all
expression operations.
In the new approach, an operation is simply a class that presents a
certain interface. Operations own their operands, and management is
done via unique_ptr.
The operation interface is largely ad hoc, based on the evolution of
expression handling in GDB. Parts (for example,
evaluate_with_coercion) are probably redundant; however I took this
approach to try to avoid mixing different kinds of refactorings.
In some specific situations, rather than add a generic method across
the entire operation class hierarchy, I chose instead to use
dynamic_cast and specialized methods on certain concrete subclasses.
This will appear in some subsequent patches.
One goal of this work is to avoid the kinds of easy-to-make errors
that affected the old implementation. To this end, some helper
subclasses are also added here. These helpers automate the
implementation of the 'dump', 'uses_objfile', and 'constant_p'
methods. Nearly every concrete operation that is subsequently added
will use these facilities. (Note that the 'dump' implementation is
only outlined here, the body appears in the next patch.)
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* expression.h (expr::operation): New class.
(expr::make_operation): New function.
(expr::operation_up): New typedef.
* expop.h: New file.
* eval.c (operation::evaluate_for_cast)
(operation::evaluate_for_address, operation::evaluate_for_sizeof):
New methods.
* ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
|
|
|
/* Called by generate_ax to do the work for this particular
|
|
|
|
operation. */
|
|
|
|
virtual void do_generate_ax (struct expression *exp,
|
|
|
|
struct agent_expr *ax,
|
|
|
|
struct axs_value *value,
|
|
|
|
struct type *cast_type)
|
|
|
|
{
|
|
|
|
error (_("Cannot translate to agent expression"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/* A helper function for creating an operation_up, given a type. */
|
|
|
|
template<typename T, typename... Arg>
|
|
|
|
operation_up
|
|
|
|
make_operation (Arg... args)
|
|
|
|
{
|
|
|
|
return operation_up (new T (std::forward<Arg> (args)...));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-04-16 09:35:26 +08:00
|
|
|
struct expression
|
2020-12-02 08:22:05 +08:00
|
|
|
{
|
2021-03-08 22:27:57 +08:00
|
|
|
expression (const struct language_defn *lang, struct gdbarch *arch)
|
|
|
|
: language_defn (lang),
|
|
|
|
gdbarch (arch)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-12-02 08:22:05 +08:00
|
|
|
DISABLE_COPY_AND_ASSIGN (expression);
|
|
|
|
|
2020-12-16 09:14:42 +08:00
|
|
|
/* Return the opcode for the outermost sub-expression of this
|
|
|
|
expression. */
|
|
|
|
enum exp_opcode first_opcode () const
|
|
|
|
{
|
Remove union exp_element
This removes union exp_element functions that either create such
elements or walk them. struct expression no longer holds
exp_elements. A couple of language_defn methods are also removed, as
they are obsolete.
Note that this patch also removes the print_expression code. The only
in-tree caller of this was from dump_prefix_expression, which is only
called when expression debugging is enabled. Implementing this would
involve a fair amount of code, and it seems to me that prefix dumping
is preferable anyway, as it is unambiguous. So, I have not
reimplemented this feature.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* value.h (evaluate_subexp_with_coercion): Don't declare.
* parse.c (exp_descriptor_standard): Remove.
(expr_builder::expr_builder, expr_builder::release): Update.
(expression::expression): Remove size_t parameter.
(expression::~expression): Simplify.
(expression::resize): Remove.
(write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym)
(write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile)
(write_exp_elt_longcst, write_exp_elt_floatcst)
(write_exp_elt_type, write_exp_elt_intern, write_exp_string)
(write_exp_string_vector, write_exp_bitstring): Remove.
* p-lang.h (class pascal_language) <opcode_print_table,
op_print_tab>: Remove.
* p-lang.c (pascal_language::op_print_tab): Remove.
* opencl-lang.c (class opencl_language) <opcode_print_table>:
Remove.
* objc-lang.c (objc_op_print_tab): Remove.
(class objc_language) <opcode_print_table>: Remove.
* m2-lang.h (class m2_language) <opcode_print_table,
op_print_tab>: Remove.
* m2-lang.c (m2_language::op_print_tab): Remove.
* language.h (struct language_defn) <post_parser, expression_ops,
opcode_print_table>: Remove.
* language.c (language_defn::expression_ops)
(auto_or_unknown_language::opcode_print_table): Remove.
* go-lang.h (class go_language) <opcode_print_table,
op_print_tab>: Remove.
* go-lang.c (go_language::op_print_tab): Remove.
* f-lang.h (class f_language) <opcode_print_table>: Remove
<op_print_tab>: Remove.
* f-lang.c (f_language::op_print_tab): Remove.
* expression.h (union exp_element): Remove.
(struct expression): Remove size_t parameter from constructor.
<resize>: Remove.
<first_opcode>: Update.
<nelts, elts>: Remove.
(EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove.
(evaluate_subexp_standard, print_expression, op_string)
(dump_raw_expression): Don't declare.
* expprint.c (print_expression, print_subexp)
(print_subexp_funcall, print_subexp_standard, op_string)
(dump_raw_expression, dump_subexp, dump_subexp_body)
(dump_subexp_body_funcall, dump_subexp_body_standard): Remove.
(dump_prefix_expression): Update.
* eval.c (evaluate_subexp): Remove.
(evaluate_expression, evaluate_type): Update.
(evaluate_subexpression_type): Remove.
(fetch_subexp_value): Remove "pc" parameter. Update.
(extract_field_op, evaluate_struct_tuple, evaluate_funcall)
(evaluate_subexp_standard, evaluate_subexp_for_address)
(evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof)
(evaluate_subexp_for_cast): Remove.
(parse_and_eval_type): Update.
* dtrace-probe.c (dtrace_probe::compile_to_ax): Update.
* d-lang.c (d_op_print_tab): Remove.
(class d_language) <opcode_print_table>: Remove.
* c-lang.h (c_op_print_tab): Don't declare.
* c-lang.c (c_op_print_tab): Remove.
(class c_language, class cplus_language, class asm_language, class
minimal_language) <opcode_print_table>: Remove.
* breakpoint.c (update_watchpoint, watchpoint_check)
(watchpoint_exp_is_const, watch_command_1): Update.
* ax-gdb.h (union exp_element): Don't declare.
* ax-gdb.c (const_var_ref, const_expr, maybe_const_expr)
(gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr)
(gen_expr_binop_rest): Remove.
(gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update.
* ada-lang.c (ada_op_print_tab): Remove.
(class ada_language) <post_parser, opcode_print_table>: Remove.
2021-03-08 22:27:57 +08:00
|
|
|
return op->opcode ();
|
2020-12-16 09:14:42 +08:00
|
|
|
}
|
|
|
|
|
2021-02-19 02:23:33 +08:00
|
|
|
/* Evaluate the expression. EXPECT_TYPE is the context type of the
|
|
|
|
expression; normally this should be nullptr. NOSIDE controls how
|
|
|
|
evaluation is performed. */
|
|
|
|
struct value *evaluate (struct type *expect_type, enum noside noside);
|
|
|
|
|
2020-12-02 08:22:05 +08:00
|
|
|
/* Language it was entered in. */
|
|
|
|
const struct language_defn *language_defn;
|
|
|
|
/* Architecture it was parsed in. */
|
|
|
|
struct gdbarch *gdbarch;
|
Add an expr::operation_up to struct expression
This adds an expr::operation_up to struct expression, and then
modifies various parts of GDB to use this member when it is non-null.
The list of such spots was a bit surprising to me, and found only
after writing most of the code and then noticing what no longer
compiled.
In a few spots, new accessor methods are added to operation
subclasses, so that code that dissects an expression will work with
the new scheme.
After this change, code that constructs an expression can be switched
to the new form without breaking.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove;
now in superclass.
* value.h (fetch_subexp_value): Add "op" parameter.
* value.c (init_if_undefined_command): Update.
* tracepoint.c (validate_actionline, encode_actions_1): Update.
* stap-probe.c (stap_probe::compile_to_ax): Update.
* printcmd.c (set_command): Update.
* ppc-linux-nat.c (ppc_linux_nat_target::check_condition):
Update.
* parser-defs.h (struct expr_builder) <set_operation>: New
method.
* parse.c (parse_exp_in_context, exp_uses_objfile): Update.
* expression.h (struct expression) <first_opcode>: Update.
<op>: New member.
* expprint.c (dump_raw_expression, dump_prefix_expression):
Update.
* expop.h (class var_value_operation) <get_symbol>: New method.
(class register_operation) <get_name>: New method.
(class equal_operation): No longer a typedef, now a subclass.
(class unop_memval_operation) <get_type>: New method.
(class assign_operation) <get_lhs>: New method.
(class unop_cast_operation) <get_type>: New method.
* eval.c (evaluate_expression, evaluate_type)
(evaluate_subexpression_type): Update.
(fetch_subexp_value): Add "op" parameter.
(parse_and_eval_type): Update.
* dtrace-probe.c (dtrace_probe::compile_to_ax): Update.
* breakpoint.c (update_watchpoint, watchpoint_check)
(watchpoint_exp_is_const, watch_command_1): Update.
* ax-gdb.c (gen_trace_for_expr, gen_eval_for_expr, gen_printf):
Update.
2021-03-08 22:27:57 +08:00
|
|
|
expr::operation_up op;
|
2020-12-02 08:22:05 +08:00
|
|
|
};
|
1999-04-16 09:35:26 +08:00
|
|
|
|
2020-12-02 08:22:05 +08:00
|
|
|
typedef std::unique_ptr<expression> expression_up;
|
'struct expression *' -> gdb::unique_xmalloc_ptr<expression>
This patch makes parse_expression and friends return a unique_ptr
instead of raw pointer [1]:
typedef gdb::unique_malloc_ptr<expression> expression_up;
and then adjusts the codebase throughout to stop using cleanups to
manage lifetime of expression pointers.
Whenever I found a structure owning an expression pointer, I made it
store a unique_ptr instead of a raw pointer, which then requires using
new/delete of the holding structure, instead of XNEW/xfree.
[1] - I'd like to set the rule that types named with an "_up" suffix
are unique_ptr typedefs.
Note I used gdb::unique_xmalloc_ptr instead of gdb::unique_ptr, simply
because we still use xmalloc instead of new to allocate expression
objects. Once that's changed, all we need to do is change the
expression_up typedef and the smart pointer will then call delete
instead of xfree.
gdb/ChangeLog:
2016-11-08 Pedro Alves <palves@redhat.com>
* ada-lang.c (ada_read_renaming_var_value): Use expression_up.
(struct ada_catchpoint_location) <excep_cond_expr>: Now an
expression_up.
(ada_catchpoint_location_dtor): Reset excep_cond_expr instead of
using xfree.
(create_excep_cond_exprs): Use expression_up and gdb::move.
(allocate_location_exception): Use new instead of XNEW.
(should_stop_exception): Likewise. Adjust to use expression_up.
(create_ada_exception_catchpoint): Use new instead of XNEW.
* ax-gdb.c (agent_eval_command_one): Use expression_up instead of
cleanups.
(maint_agent_printf_command): Use expression_up.
* break-catch-sig.c (create_signal_catchpoint): Use new instead of
XNEW.
* break-catch-syscall.c (create_syscall_event_catchpoint):
Likewise.
* break-catch-throw.c (handle_gnu_v3_exceptions): Use new instead
of XCNEW. Use gdb::unique_ptr instead of cleanups.
* breakpoint.c (set_breakpoint_condition, update_watchpoint)
(parse_cmd_to_aexpr, watchpoint_check)
(bpstat_check_breakpoint_conditions, watchpoint_locations_match):
Adjust to use expression_up.
(init_bp_location): Adjust.
(free_bp_location): Use delete instead of xfree.
(set_raw_breakpoint_without_location, set_raw_breakpoint)
(add_solib_catchpoint, create_fork_vfork_event_catchpoint)
(new_single_step_breakpoint, create_breakpoint_sal): Use new
instead of XNEW.
(find_condition_and_thread): Adjust to use expression_up.
(create_breakpoint): Use new instead of XNEW.
(dtor_watchpoint): Don't xfree expression pointers, they're
unique_ptr's now.
(insert_watchpoint, remove_watchpoint): Adjust.
(watch_command_1): Use expression_up. Use new instead of XCNEW.
(catch_exec_command_1): Use new instead of XNEW.
(bp_location_dtor): Don't xfree expression pointers, they're
unique_ptr's now.
(base_breakpoint_allocate_location)
(strace_marker_create_breakpoints_sal): Use new instead of XNEW.
(delete_breakpoint): Use delete instead of xfree.
* breakpoint.h (struct bp_location) <cond>: Now an
unique_ptr<expression> instead of a raw pointer.
(struct watchpoint) <exp, cond_exp>: Likewise.
* cli/cli-script.c (execute_control_command): Use expression_up
instead of cleanups.
* dtrace-probe.c (dtrace_process_dof_probe): Use expression_up.
* eval.c (parse_and_eval_address, parse_and_eval_long)
(parse_and_eval, parse_to_comma_and_eval, parse_and_eval_type):
Use expression_up instead of cleanups.
* expression.h (expression_up): New typedef.
(parse_expression, parse_expression_with_language, parse_exp_1):
Change return type to expression_up.
* mi/mi-main.c (mi_cmd_data_evaluate_expression)
(print_variable_or_computed): Use expression_up.
* objc-lang.c (print_object_command): Use expression_up instead of
cleanups.
* parse.c (parse_exp_1, parse_exp_in_context)
(parse_exp_in_context_1, parse_expression)
(parse_expression_with_language): Return an expression_up instead
of a raw pointer.
(parse_expression_for_completion): Use expression_up.
* printcmd.c (struct display) <exp>: Now an expression_up instead
of a raw pointer.
(print_command_1, output_command_const, set_command, x_command):
Use expression_up instead of cleanups.
(display_command): Likewise. Use new instead of XNEW.
(free_display): Use delete instead of xfree.
(do_one_display): Adjust to use expression_up.
* remote.c (remote_download_tracepoint): Likewise.
* stack.c (return_command): Likewise.
* tracepoint.c (validate_actionline, encode_actions_1): Use
expression_up instead of cleanups.
* typeprint.c (whatis_exp, maintenance_print_type): Likewise.
* value.c (init_if_undefined_command): Likewise.
* varobj.c (struct varobj_root) <exp>: Now an expression_up
instead of a raw pointer.
(varobj_create): Adjust.
(varobj_set_value): Use an expression_up instead of cleanups.
(new_root_variable): Use new instead of XNEW.
(free_variable): Use delete instead of xfree.
(value_of_root_1): Use std::swap.
2016-11-08 23:26:43 +08:00
|
|
|
|
1999-04-16 09:35:26 +08:00
|
|
|
/* From parse.c */
|
|
|
|
|
2019-04-01 07:20:24 +08:00
|
|
|
class innermost_block_tracker;
|
|
|
|
extern expression_up parse_expression (const char *,
|
2021-01-09 03:20:12 +08:00
|
|
|
innermost_block_tracker * = nullptr,
|
|
|
|
bool void_context_p = false);
|
1999-04-16 09:35:26 +08:00
|
|
|
|
'struct expression *' -> gdb::unique_xmalloc_ptr<expression>
This patch makes parse_expression and friends return a unique_ptr
instead of raw pointer [1]:
typedef gdb::unique_malloc_ptr<expression> expression_up;
and then adjusts the codebase throughout to stop using cleanups to
manage lifetime of expression pointers.
Whenever I found a structure owning an expression pointer, I made it
store a unique_ptr instead of a raw pointer, which then requires using
new/delete of the holding structure, instead of XNEW/xfree.
[1] - I'd like to set the rule that types named with an "_up" suffix
are unique_ptr typedefs.
Note I used gdb::unique_xmalloc_ptr instead of gdb::unique_ptr, simply
because we still use xmalloc instead of new to allocate expression
objects. Once that's changed, all we need to do is change the
expression_up typedef and the smart pointer will then call delete
instead of xfree.
gdb/ChangeLog:
2016-11-08 Pedro Alves <palves@redhat.com>
* ada-lang.c (ada_read_renaming_var_value): Use expression_up.
(struct ada_catchpoint_location) <excep_cond_expr>: Now an
expression_up.
(ada_catchpoint_location_dtor): Reset excep_cond_expr instead of
using xfree.
(create_excep_cond_exprs): Use expression_up and gdb::move.
(allocate_location_exception): Use new instead of XNEW.
(should_stop_exception): Likewise. Adjust to use expression_up.
(create_ada_exception_catchpoint): Use new instead of XNEW.
* ax-gdb.c (agent_eval_command_one): Use expression_up instead of
cleanups.
(maint_agent_printf_command): Use expression_up.
* break-catch-sig.c (create_signal_catchpoint): Use new instead of
XNEW.
* break-catch-syscall.c (create_syscall_event_catchpoint):
Likewise.
* break-catch-throw.c (handle_gnu_v3_exceptions): Use new instead
of XCNEW. Use gdb::unique_ptr instead of cleanups.
* breakpoint.c (set_breakpoint_condition, update_watchpoint)
(parse_cmd_to_aexpr, watchpoint_check)
(bpstat_check_breakpoint_conditions, watchpoint_locations_match):
Adjust to use expression_up.
(init_bp_location): Adjust.
(free_bp_location): Use delete instead of xfree.
(set_raw_breakpoint_without_location, set_raw_breakpoint)
(add_solib_catchpoint, create_fork_vfork_event_catchpoint)
(new_single_step_breakpoint, create_breakpoint_sal): Use new
instead of XNEW.
(find_condition_and_thread): Adjust to use expression_up.
(create_breakpoint): Use new instead of XNEW.
(dtor_watchpoint): Don't xfree expression pointers, they're
unique_ptr's now.
(insert_watchpoint, remove_watchpoint): Adjust.
(watch_command_1): Use expression_up. Use new instead of XCNEW.
(catch_exec_command_1): Use new instead of XNEW.
(bp_location_dtor): Don't xfree expression pointers, they're
unique_ptr's now.
(base_breakpoint_allocate_location)
(strace_marker_create_breakpoints_sal): Use new instead of XNEW.
(delete_breakpoint): Use delete instead of xfree.
* breakpoint.h (struct bp_location) <cond>: Now an
unique_ptr<expression> instead of a raw pointer.
(struct watchpoint) <exp, cond_exp>: Likewise.
* cli/cli-script.c (execute_control_command): Use expression_up
instead of cleanups.
* dtrace-probe.c (dtrace_process_dof_probe): Use expression_up.
* eval.c (parse_and_eval_address, parse_and_eval_long)
(parse_and_eval, parse_to_comma_and_eval, parse_and_eval_type):
Use expression_up instead of cleanups.
* expression.h (expression_up): New typedef.
(parse_expression, parse_expression_with_language, parse_exp_1):
Change return type to expression_up.
* mi/mi-main.c (mi_cmd_data_evaluate_expression)
(print_variable_or_computed): Use expression_up.
* objc-lang.c (print_object_command): Use expression_up instead of
cleanups.
* parse.c (parse_exp_1, parse_exp_in_context)
(parse_exp_in_context_1, parse_expression)
(parse_expression_with_language): Return an expression_up instead
of a raw pointer.
(parse_expression_for_completion): Use expression_up.
* printcmd.c (struct display) <exp>: Now an expression_up instead
of a raw pointer.
(print_command_1, output_command_const, set_command, x_command):
Use expression_up instead of cleanups.
(display_command): Likewise. Use new instead of XNEW.
(free_display): Use delete instead of xfree.
(do_one_display): Adjust to use expression_up.
* remote.c (remote_download_tracepoint): Likewise.
* stack.c (return_command): Likewise.
* tracepoint.c (validate_actionline, encode_actions_1): Use
expression_up instead of cleanups.
* typeprint.c (whatis_exp, maintenance_print_type): Likewise.
* value.c (init_if_undefined_command): Likewise.
* varobj.c (struct varobj_root) <exp>: Now an expression_up
instead of a raw pointer.
(varobj_create): Adjust.
(varobj_set_value): Use an expression_up instead of cleanups.
(new_root_variable): Use new instead of XNEW.
(free_variable): Use delete instead of xfree.
(value_of_root_1): Use std::swap.
2016-11-08 23:26:43 +08:00
|
|
|
extern expression_up parse_expression_with_language (const char *string,
|
|
|
|
enum language lang);
|
2015-03-27 02:14:03 +08:00
|
|
|
|
2018-02-16 13:41:03 +08:00
|
|
|
extern struct type *parse_expression_for_completion
|
|
|
|
(const char *, gdb::unique_xmalloc_ptr<char> *, enum type_code *);
|
2008-06-07 04:58:08 +08:00
|
|
|
|
2019-04-01 07:20:24 +08:00
|
|
|
class innermost_block_tracker;
|
'struct expression *' -> gdb::unique_xmalloc_ptr<expression>
This patch makes parse_expression and friends return a unique_ptr
instead of raw pointer [1]:
typedef gdb::unique_malloc_ptr<expression> expression_up;
and then adjusts the codebase throughout to stop using cleanups to
manage lifetime of expression pointers.
Whenever I found a structure owning an expression pointer, I made it
store a unique_ptr instead of a raw pointer, which then requires using
new/delete of the holding structure, instead of XNEW/xfree.
[1] - I'd like to set the rule that types named with an "_up" suffix
are unique_ptr typedefs.
Note I used gdb::unique_xmalloc_ptr instead of gdb::unique_ptr, simply
because we still use xmalloc instead of new to allocate expression
objects. Once that's changed, all we need to do is change the
expression_up typedef and the smart pointer will then call delete
instead of xfree.
gdb/ChangeLog:
2016-11-08 Pedro Alves <palves@redhat.com>
* ada-lang.c (ada_read_renaming_var_value): Use expression_up.
(struct ada_catchpoint_location) <excep_cond_expr>: Now an
expression_up.
(ada_catchpoint_location_dtor): Reset excep_cond_expr instead of
using xfree.
(create_excep_cond_exprs): Use expression_up and gdb::move.
(allocate_location_exception): Use new instead of XNEW.
(should_stop_exception): Likewise. Adjust to use expression_up.
(create_ada_exception_catchpoint): Use new instead of XNEW.
* ax-gdb.c (agent_eval_command_one): Use expression_up instead of
cleanups.
(maint_agent_printf_command): Use expression_up.
* break-catch-sig.c (create_signal_catchpoint): Use new instead of
XNEW.
* break-catch-syscall.c (create_syscall_event_catchpoint):
Likewise.
* break-catch-throw.c (handle_gnu_v3_exceptions): Use new instead
of XCNEW. Use gdb::unique_ptr instead of cleanups.
* breakpoint.c (set_breakpoint_condition, update_watchpoint)
(parse_cmd_to_aexpr, watchpoint_check)
(bpstat_check_breakpoint_conditions, watchpoint_locations_match):
Adjust to use expression_up.
(init_bp_location): Adjust.
(free_bp_location): Use delete instead of xfree.
(set_raw_breakpoint_without_location, set_raw_breakpoint)
(add_solib_catchpoint, create_fork_vfork_event_catchpoint)
(new_single_step_breakpoint, create_breakpoint_sal): Use new
instead of XNEW.
(find_condition_and_thread): Adjust to use expression_up.
(create_breakpoint): Use new instead of XNEW.
(dtor_watchpoint): Don't xfree expression pointers, they're
unique_ptr's now.
(insert_watchpoint, remove_watchpoint): Adjust.
(watch_command_1): Use expression_up. Use new instead of XCNEW.
(catch_exec_command_1): Use new instead of XNEW.
(bp_location_dtor): Don't xfree expression pointers, they're
unique_ptr's now.
(base_breakpoint_allocate_location)
(strace_marker_create_breakpoints_sal): Use new instead of XNEW.
(delete_breakpoint): Use delete instead of xfree.
* breakpoint.h (struct bp_location) <cond>: Now an
unique_ptr<expression> instead of a raw pointer.
(struct watchpoint) <exp, cond_exp>: Likewise.
* cli/cli-script.c (execute_control_command): Use expression_up
instead of cleanups.
* dtrace-probe.c (dtrace_process_dof_probe): Use expression_up.
* eval.c (parse_and_eval_address, parse_and_eval_long)
(parse_and_eval, parse_to_comma_and_eval, parse_and_eval_type):
Use expression_up instead of cleanups.
* expression.h (expression_up): New typedef.
(parse_expression, parse_expression_with_language, parse_exp_1):
Change return type to expression_up.
* mi/mi-main.c (mi_cmd_data_evaluate_expression)
(print_variable_or_computed): Use expression_up.
* objc-lang.c (print_object_command): Use expression_up instead of
cleanups.
* parse.c (parse_exp_1, parse_exp_in_context)
(parse_exp_in_context_1, parse_expression)
(parse_expression_with_language): Return an expression_up instead
of a raw pointer.
(parse_expression_for_completion): Use expression_up.
* printcmd.c (struct display) <exp>: Now an expression_up instead
of a raw pointer.
(print_command_1, output_command_const, set_command, x_command):
Use expression_up instead of cleanups.
(display_command): Likewise. Use new instead of XNEW.
(free_display): Use delete instead of xfree.
(do_one_display): Adjust to use expression_up.
* remote.c (remote_download_tracepoint): Likewise.
* stack.c (return_command): Likewise.
* tracepoint.c (validate_actionline, encode_actions_1): Use
expression_up instead of cleanups.
* typeprint.c (whatis_exp, maintenance_print_type): Likewise.
* value.c (init_if_undefined_command): Likewise.
* varobj.c (struct varobj_root) <exp>: Now an expression_up
instead of a raw pointer.
(varobj_create): Adjust.
(varobj_set_value): Use an expression_up instead of cleanups.
(new_root_variable): Use new instead of XNEW.
(free_variable): Use delete instead of xfree.
(value_of_root_1): Use std::swap.
2016-11-08 23:26:43 +08:00
|
|
|
extern expression_up parse_exp_1 (const char **, CORE_ADDR pc,
|
2019-03-24 00:11:51 +08:00
|
|
|
const struct block *, int,
|
2019-04-01 07:20:24 +08:00
|
|
|
innermost_block_tracker * = nullptr);
|
1999-04-16 09:35:26 +08:00
|
|
|
|
|
|
|
/* From eval.c */
|
|
|
|
|
2020-12-16 08:53:34 +08:00
|
|
|
/* Evaluate a function call. The function to be called is in CALLEE and
|
|
|
|
the arguments passed to the function are in ARGVEC.
|
2020-05-07 23:27:16 +08:00
|
|
|
FUNCTION_NAME is the name of the function, if known.
|
|
|
|
DEFAULT_RETURN_TYPE is used as the function's return type if the return
|
|
|
|
type is unknown. */
|
|
|
|
|
|
|
|
extern struct value *evaluate_subexp_do_call (expression *exp,
|
|
|
|
enum noside noside,
|
2020-12-16 08:53:34 +08:00
|
|
|
value *callee,
|
|
|
|
gdb::array_view<value *> argvec,
|
2020-05-07 23:27:16 +08:00
|
|
|
const char *function_name,
|
|
|
|
type *default_return_type);
|
|
|
|
|
1999-04-16 09:35:26 +08:00
|
|
|
/* From expprint.c */
|
|
|
|
|
2020-11-30 16:37:10 +08:00
|
|
|
extern const char *op_name (enum exp_opcode opcode);
|
2012-03-21 23:16:24 +08:00
|
|
|
|
2003-09-24 16:29:42 +08:00
|
|
|
extern void dump_prefix_expression (struct expression *, struct ui_file *);
|
1999-04-16 09:35:26 +08:00
|
|
|
|
2016-04-28 00:28:56 +08:00
|
|
|
/* In an OP_RANGE expression, either bound could be empty, indicating
|
|
|
|
that its value is by default that of the corresponding bound of the
|
2018-03-30 04:14:07 +08:00
|
|
|
array or string. Also, the upper end of the range can be exclusive
|
|
|
|
or inclusive. So we have six sorts of subrange. This enumeration
|
|
|
|
type is to identify this. */
|
|
|
|
|
2020-09-26 07:09:25 +08:00
|
|
|
enum range_flag : unsigned
|
2018-03-30 04:14:07 +08:00
|
|
|
{
|
2020-05-05 23:03:53 +08:00
|
|
|
/* This is a standard range. Both the lower and upper bounds are
|
|
|
|
defined, and the bounds are inclusive. */
|
|
|
|
RANGE_STANDARD = 0,
|
|
|
|
|
|
|
|
/* The low bound was not given. */
|
|
|
|
RANGE_LOW_BOUND_DEFAULT = 1 << 0,
|
|
|
|
|
|
|
|
/* The high bound was not given. */
|
|
|
|
RANGE_HIGH_BOUND_DEFAULT = 1 << 1,
|
|
|
|
|
|
|
|
/* The high bound of this range is exclusive. */
|
|
|
|
RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
|
2020-10-08 23:34:58 +08:00
|
|
|
|
|
|
|
/* The range has a stride. */
|
|
|
|
RANGE_HAS_STRIDE = 1 << 3,
|
2018-03-30 04:14:07 +08:00
|
|
|
};
|
2016-04-28 00:28:56 +08:00
|
|
|
|
2020-09-26 07:09:25 +08:00
|
|
|
DEF_ENUM_FLAGS_TYPE (enum range_flag, range_flags);
|
2020-05-05 23:03:53 +08:00
|
|
|
|
1999-07-08 04:19:36 +08:00
|
|
|
#endif /* !defined (EXPRESSION_H) */
|