@@ -42,6 +42,8 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "tree-inline.h"
#include "ubsan.h"
+#include "plugin-api.h"
+#include "plugin.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@@ -123,13 +125,6 @@ ensure_literal_type_for_constexpr_object (tree decl)
return decl;
}
-/* Representation of entries in the constexpr function definition table. */
-
-struct GTY((for_user)) constexpr_fundef {
- tree decl;
- tree body;
-};
-
struct constexpr_fundef_hasher : ggc_hasher<constexpr_fundef *>
{
static hashval_t hash (constexpr_fundef *);
@@ -855,67 +850,17 @@ explain_invalid_constexpr_fn (tree fun)
input_location = save_loc;
}
-/* Objects of this type represent calls to constexpr functions
- along with the bindings of parameters to their arguments, for
- the purpose of compile time evaluation. */
-
-struct GTY((for_user)) constexpr_call {
- /* Description of the constexpr function definition. */
- constexpr_fundef *fundef;
- /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
- is a parameter _DECL and the TREE_VALUE is the value of the parameter.
- Note: This arrangement is made to accommodate the use of
- iterative_hash_template_arg (see pt.c). If you change this
- representation, also change the hash calculation in
- cxx_eval_call_expression. */
- tree bindings;
- /* Result of the call.
- NULL means the call is being evaluated.
- error_mark_node means that the evaluation was erroneous;
- otherwise, the actuall value of the call. */
- tree result;
- /* The hash of this call; we remember it here to avoid having to
- recalculate it when expanding the hash table. */
- hashval_t hash;
-};
-
struct constexpr_call_hasher : ggc_hasher<constexpr_call *>
{
static hashval_t hash (constexpr_call *);
static bool equal (constexpr_call *, constexpr_call *);
};
-/* The constexpr expansion context. CALL is the current function
- expansion, CTOR is the current aggregate initializer, OBJECT is the
- object being initialized by CTOR, either a VAR_DECL or a _REF. VALUES
- is a map of values of variables initialized within the expression. */
-
-struct constexpr_ctx {
- /* The innermost call we're evaluating. */
- constexpr_call *call;
- /* Values for any temporaries or local variables within the
- constant-expression. */
- hash_map<tree,tree> *values;
- /* The CONSTRUCTOR we're currently building up for an aggregate
- initializer. */
- tree ctor;
- /* The object we're building the CONSTRUCTOR for. */
- tree object;
- /* Whether we should error on a non-constant expression or fail quietly. */
- bool quiet;
- /* Whether we are strictly conforming to constant expression rules or
- trying harder to get a constant value. */
- bool strict;
-};
-
/* A table of all constexpr calls that have been evaluated by the
compiler in this translation unit. */
static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
-static tree cxx_eval_constant_expression (const constexpr_ctx *, tree,
- bool, bool *, bool *, tree * = NULL);
-
/* Compute a hash value for a constexpr call representation. */
inline hashval_t
@@ -1303,6 +1248,19 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
bool non_constant_args = false;
cxx_bind_parameters_in_call (ctx, t, &new_call,
non_constant_p, overflow_p, &non_constant_args);
+ constexpr_call_info call_info;
+ call_info.function = t;
+ call_info.lval = lval;
+ call_info.call = &new_call;
+ call_info.call_stack = call_stack;
+ call_info.non_constant_args = &non_constant_args;
+ call_info.non_const_p = non_constant_p;
+ call_info.ctx = ctx;
+ call_info.result = NULL_TREE;
+ invoke_plugin_callbacks (PLUGIN_EVAL_CALL_CONSTEXPR, &call_info);
+ if (call_info.result != NULL_TREE)
+ return unshare_expr (call_info.result);
+
if (*non_constant_p)
return t;
@@ -2636,6 +2594,19 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
target = cxx_eval_constant_expression (ctx, target,
true,
non_constant_p, overflow_p);
+
+ constexpr_modify_info mod_info;
+ mod_info.target = target;
+ mod_info.expr = t;
+ mod_info.ctx = ctx;
+ mod_info.init = init;
+ mod_info.overflow = overflow_p;
+ mod_info.non_constant_expr = non_constant_p;
+ mod_info.result = NULL_TREE;
+ invoke_plugin_callbacks (PLUGIN_MOD_CONSTEXPR, &mod_info);
+ if (mod_info.result != NULL_TREE)
+ return mod_info.result;
+
if (*non_constant_p)
return t;
@@ -3032,7 +3003,7 @@ cxx_eval_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
/* FIXME unify with c_fully_fold */
/* FIXME overflow_p is too global */
-static tree
+tree
cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
bool lval,
bool *non_constant_p, bool *overflow_p,
@@ -6426,6 +6426,96 @@ extern void cp_ubsan_instrument_member_accesses (tree *);
extern tree cp_ubsan_maybe_instrument_downcast (location_t, tree, tree);
extern tree cp_ubsan_maybe_instrument_cast_to_vbase (location_t, tree, tree);
+/* Representation of entries in the constexpr function definition table. */
+
+struct GTY((for_user)) constexpr_fundef {
+ tree decl;
+ tree body;
+};
+
+/* Objects of this type represent calls to constexpr functions
+ along with the bindings of parameters to their arguments, for
+ the purpose of compile time evaluation. */
+
+struct GTY((for_user)) constexpr_call {
+ /* Description of the constexpr function definition. */
+ constexpr_fundef *fundef;
+ /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
+ is a parameter _DECL and the TREE_VALUE is the value of the parameter.
+ Note: This arrangement is made to accommodate the use of
+ iterative_hash_template_arg (see pt.c). If you change this
+ representation, also change the hash calculation in
+ cxx_eval_call_expression. */
+ tree bindings;
+ /* Result of the call.
+ NULL means the call is being evaluated.
+ error_mark_node means that the evaluation was erroneous;
+ otherwise, the actuall value of the call. */
+ tree result;
+ /* The hash of this call; we remember it here to avoid having to
+ recalculate it when expanding the hash table. */
+ hashval_t hash;
+};
+
+/* The constexpr expansion context. CALL is the current function
+ expansion, CTOR is the current aggregate initializer, OBJECT is the
+ object being initialized by CTOR, either a VAR_DECL or a _REF. VALUES
+ is a map of values of variables initialized within the expression. */
+
+struct constexpr_ctx {
+ /* The innermost call we're evaluating. */
+ constexpr_call *call;
+ /* Values for any temporaries or local variables within the
+ constant-expression. */
+ hash_map<tree,tree> *values;
+ /* The CONSTRUCTOR we're currently building up for an aggregate
+ initializer. */
+ tree ctor;
+ /* The object we're building the CONSTRUCTOR for. */
+ tree object;
+ /* Whether we should error on a non-constant expression or fail quietly. */
+ bool quiet;
+ /* Whether we are strictly conforming to constant expression rules or
+ trying harder to get a constant value. */
+ bool strict;
+};
+
+tree cxx_eval_constant_expression (const constexpr_ctx *, tree, bool, bool *, bool *, tree * = NULL);
+
+/* This type represents a function call into a constant expression.*/
+typedef struct constexpr_call_info_st
+{
+ tree function; //Function named in call.
+ tree result; //Function call result.
+ vec<tree> call_stack; //Call stack.
+ bool lval;
+ bool* non_constant_args; //The function arguments are constant.
+ bool* non_const_p; //Is constant.
+ bool* overflow;
+ constexpr_call* call; //Call to the constexpr function.
+ const struct constexpr_ctx* ctx; //constexpr expansion context.
+} constexpr_call_info;
+
+/* This type represents the modification of an array into a constant expression*/
+typedef struct constexpr_modify_info_st
+{
+ tree expr;
+ tree target; //Array to be modified.
+ tree init; //Initialization.
+ tree result; //Result.
+ bool lval;
+ bool* overflow;
+ bool* non_constant_expr; //Wheter it's a constant expression.
+ const struct constexpr_ctx* ctx; //constexpr expansion context.
+} constexpr_modify_info;
+
+typedef struct literal_type_info_st
+{
+ tree expr;
+ bool modified;
+ tree result;
+} literal_type_info;
+
/* -- end of C++ */
#endif /* ! GCC_CP_TREE_H */
@@ -33225,6 +33225,7 @@ c_parse_file (void)
push_deferring_access_checks (flag_access_control
? dk_no_deferred : dk_no_check);
cp_parser_translation_unit (the_parser);
+ invoke_plugin_callbacks (PLUGIN_END_PARSE_FILE, NULL);
the_parser = NULL;
}
@@ -441,6 +441,9 @@ register_callback (const char *plugin_name,
return;
}
/* Fall through. */
+ case PLUGIN_END_PARSE_FILE:
+ case PLUGIN_MOD_CONSTEXPR:
+ case PLUGIN_EVAL_CALL_CONSTEXPR:
case PLUGIN_FINISH_TYPE:
case PLUGIN_FINISH_DECL:
case PLUGIN_START_UNIT:
@@ -519,6 +522,9 @@ invoke_plugin_callbacks_full (int event, void *gcc_data)
gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC);
gcc_assert (event < event_last);
/* Fall through. */
+ case PLUGIN_END_PARSE_FILE:
+ case PLUGIN_MOD_CONSTEXPR:
+ case PLUGIN_EVAL_CALL_CONSTEXPR:
case PLUGIN_FINISH_TYPE:
case PLUGIN_FINISH_DECL:
case PLUGIN_START_UNIT:
@@ -17,6 +17,14 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+/* After parsing a file*/
+DEFEVENT (PLUGIN_END_PARSE_FILE)
+
+/* Called when evaluating in constexpr an INIT_EXPR or a MODIFY_EXPR*/
+DEFEVENT (PLUGIN_MOD_CONSTEXPR)
+
+/* Called when evaluating a constexpr call*/
+DEFEVENT (PLUGIN_EVAL_CALL_CONSTEXPR)
/* To hook into pass manager. */
DEFEVENT (PLUGIN_PASS_MANAGER_SETUP)