[PING][PATCH] New plugin event when evaluating a constexpr call
Andres Tiraboschi
andres.tiraboschi@tallertechnologies.com
Fri May 6 14:23:00 GMT 2016
Hi
I made the corrections to the patch.
Changelog 2016-5-6 Andres Tiraboschi
<andres.tiraboschi@tallertechnologies.com>
*gcc/plugin.c (PLUGIN_EVAL_CALL_CONSTEXPR): New event.
*gcc/plugin.def (PLUGIN_EVAL_CALL_CONSTEXPR): New event.
*gcc/cp/constexpr.c (constexpr_fundef): Moved to gcc/cp/constexpr.h.
*gcc/cp/constexpr.c (constexpr_call): Ditto.
*gcc/cp/constexpr.c (constexpr_ctx): Ditto.
*gcc/cp/constexpr.c (eval_call_pugin_callback): New Function.
*gcc/cp/constexpr.c (cxx_eval_constant_expression): Added a call
to eval_call_pugin_callback.
*gcc/cp/constexpr.c (cxx_eval_constant_expression): Not static anymore.
*gcc/cp/constexpr.c (cxx_bind_parameters_in_call): Ditto.
*gcc/cp/constexpr.h: New file.
*gcc/cp/constexpr.h (constexpr_call_info): New Type.
*gcc/cp/constexpr.h (constexpr_fundef): Moved type from gcc/cp/constexpr.c.
*gcc/cp/constexpr.h (constexpr_call): Ditto.
*gcc/cp/constexpr.h (constexpr_ctx): Ditto.
*gcc/cp/constexpr.h (cxx_eval_constant_expression): Declared.
*gcc/cp/constexpr.h (cxx_bind_parameters_in_call): Declared
*gcc/cp/config-lang.in (gtfiles): Added \$(srcdir)/cp/constexpr.h
*gcc/cp/Make-lang.in (CP_PLUGIN_HEADERS): Added constexpr.h.
2016-05-05 10:29 GMT-03:00 Andres Tiraboschi
<andres.tiraboschi@tallertechnologies.com>:
> Hi,
> thanks for the feedback, I'll do the changes.
>
> 2016-05-04 13:16 GMT-03:00 Jason Merrill <jason@redhat.com>:
>> On 05/02/2016 03:28 PM, Andres Tiraboschi wrote:
>>>
>>> + constexpr_call_info call_info;
>>> + call_info.function = t;
>>> + call_info.call_stack = call_stack;
>>> + call_info.ctx = ctx;
>>> + call_info.lval_p = lval;
>>> + call_info.non_constant_p = non_constant_p;
>>> + call_info.overflow_p = overflow_p;
>>> + call_info.result = NULL_TREE;
>>> +
>>> + invoke_plugin_callbacks (PLUGIN_EVAL_CALL_CONSTEXPR, &call_info);
>>
>>
>> Let's move this into a separate function so that it doesn't increase the
>> stack footprint of cxx_eval_call_expression.
>>
>> Jason
>>
-------------- next part --------------
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 625a77c..025ebc1 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -39,7 +39,7 @@ CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
CXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo c++|sed '$(program_transform_name)')
GXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo g++|sed '$(program_transform_name)')
-CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h type-utils.h
+CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h type-utils.h constexpr.h
#
# Define the names for selecting c++ in LANGUAGES.
diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in
index 276fc1d..2ca4d03 100644
--- a/gcc/cp/config-lang.in
+++ b/gcc/cp/config-lang.in
@@ -29,4 +29,4 @@ compilers="cc1plus\$(exeext)"
target_libs="target-libstdc++-v3"
-gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.h \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c \$(srcdir)/cp/except.c \$(srcdir)/cp/vtable-class-hierarchy.c \$(srcdir)/cp/constexpr.c \$(srcdir)/cp/cp-gimplify.c"
+gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.h \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c \$(srcdir)/cp/except.c \$(srcdir)/cp/vtable-class-hierarchy.c \$(srcdir)/cp/constexpr.h \$(srcdir)/cp/constexpr.c \$(srcdir)/cp/cp-gimplify.c"
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 6054d1a..7c50b06 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -31,6 +31,9 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "tree-inline.h"
#include "ubsan.h"
+#include "constexpr.h"
+#include "plugin-api.h"
+#include "plugin.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@@ -112,13 +115,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_ptr_hash<constexpr_fundef>
{
static hashval_t hash (constexpr_fundef *);
@@ -856,70 +852,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_ptr_hash<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;
- /* SAVE_EXPRs that we've seen within the current LOOP_EXPR. NULL if we
- aren't inside a loop. */
- hash_set<tree> *save_exprs;
- /* 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
@@ -1167,7 +1110,7 @@ unshare_constructor (tree t)
all arguments and bind their values to correspondings
parameters, making up the NEW_CALL context. */
-static void
+void
cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
constexpr_call *new_call,
bool *non_constant_p, bool *overflow_p,
@@ -1255,6 +1198,24 @@ cx_error_context (void)
return r;
}
+static tree
+eval_call_plugin_callback (const constexpr_ctx *ctx, tree fun,
+ bool lval, bool *non_constant_p, bool *overflow_p)
+{
+ constexpr_call_info call_info;
+ call_info.function = fun;
+ call_info.call_stack = call_stack;
+ call_info.ctx = ctx;
+ call_info.lval_p = lval;
+ call_info.non_constant_p = non_constant_p;
+ call_info.overflow_p = overflow_p;
+ call_info.result = NULL_TREE;
+
+ invoke_plugin_callbacks (PLUGIN_EVAL_CALL_CONSTEXPR, &call_info);
+
+ return call_info.result;
+}
+
/* Subroutine of cxx_eval_constant_expression.
Evaluate the call expression tree T in the context of OLD_CALL expression
evaluation. */
@@ -1268,6 +1229,13 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
tree fun = get_function_named_in_call (t);
constexpr_call new_call = { NULL, NULL, NULL, 0 };
bool depth_ok;
+ const tree callback_result = eval_call_plugin_callback (ctx, t, lval,
+ non_constant_p,
+ overflow_p);
+
+ if (callback_result != NULL_TREE)
+ return callback_result;
+
if (fun == NULL_TREE)
switch (CALL_EXPR_IFN (t))
@@ -3461,7 +3429,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,
diff --git a/gcc/cp/constexpr.h b/gcc/cp/constexpr.h
new file mode 100644
index 0000000..411c57b
--- /dev/null
+++ b/gcc/cp/constexpr.h
@@ -0,0 +1,117 @@
+/* Structures and functions for constexpr processing.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC 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.
+
+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/>. */
+
+#ifndef GCC_CONSTEXPR_H
+#define GCC_CONSTEXPR_H
+
+#include "cp-tree.h"
+
+/* 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;
+ /* SAVE_EXPRs that we've seen within the current LOOP_EXPR. NULL if we
+ aren't inside a loop. */
+ hash_set<tree> *save_exprs;
+ /* 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;
+};
+
+/* This type represents a function call into a constant expression.*/
+struct constexpr_call_info
+{
+ /* Function named in call. */
+ tree function;
+ /* Current call stack.*/
+ vec<tree> call_stack;
+ /* constexpr expansion context. */
+ const constexpr_ctx* ctx;
+ bool lval_p;
+ /* Is constant. */
+ bool* non_constant_p;
+ bool* overflow_p;
+ /* Function call result. */
+ tree result;
+
+};
+
+
+/* Attempt to reduce the expression T to a constant value.
+ On failure, issue diagnostic and return error_mark_node. */
+tree cxx_eval_constant_expression (const constexpr_ctx *, tree,
+ bool, bool *, bool *, tree * = NULL);
+
+
+/* Subroutine of cxx_eval_call_expression.
+ We are processing a call expression (either CALL_EXPR or
+ AGGR_INIT_EXPR) in the context of CTX. Evaluate
+ all arguments and bind their values to correspondings
+ parameters, making up the NEW_CALL context. */
+void cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
+ constexpr_call *new_call,
+ bool *non_constant_p, bool *overflow_p,
+ bool *non_constant_args);
+
+#endif /* ! GCC_CONSTEXPR_H */
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 8cfee4f..b9e29cf 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "langhooks-def.h"
#include "cp-objcp-common.h"
+#include "constexpr.h"
enum c_language_kind c_language = clk_cxx;
static void cp_init_ts (void);
diff --git a/gcc/plugin.c b/gcc/plugin.c
index 60081a5..34c60ed 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -427,6 +427,7 @@ register_callback (const char *plugin_name,
return;
}
/* Fall through. */
+ case PLUGIN_EVAL_CALL_CONSTEXPR:
case PLUGIN_START_PARSE_FUNCTION:
case PLUGIN_FINISH_PARSE_FUNCTION:
case PLUGIN_FINISH_TYPE:
@@ -507,6 +508,7 @@ 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_EVAL_CALL_CONSTEXPR:
case PLUGIN_START_PARSE_FUNCTION:
case PLUGIN_FINISH_PARSE_FUNCTION:
case PLUGIN_FINISH_TYPE:
diff --git a/gcc/plugin.def b/gcc/plugin.def
index c926d41..824f807 100644
--- a/gcc/plugin.def
+++ b/gcc/plugin.def
@@ -17,6 +17,9 @@ 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/>. */
+/* Called when evaluating a constexpr call. */
+DEFEVENT (PLUGIN_EVAL_CALL_CONSTEXPR)
+
/* Called before parsing the body of a function. */
DEFEVENT (PLUGIN_START_PARSE_FUNCTION)
More information about the Gcc-patches
mailing list