[PING][PATCH] New plugin event when evaluating a constexpr call
Andres Tiraboschi
andres.tiraboschi@tallertechnologies.com
Mon May 2 19:28:00 GMT 2016
2016-04-26 10:41 GMT-03:00 Andres Tiraboschi
<andres.tiraboschi@tallertechnologies.com>:
> Hi, thanks for answering,
>
> 2016-04-25 16:21 GMT-03:00 Jason Merrill <jason@redhat.com>:
>> Let's create a constexpr.h rather than expose constexpr internals to all of
>> the front end. Really, I'd prefer to avoid exposing them at all. Why does
>> what you want to do require all this implementation detail?
>
> Ok, you are right, I'll make a constexpr.h.
>
>> This is a curious place to invoke the callback. Why before the
>> *non_constant_p? More generally, why between evaluating the arguments and
>> evaluating the function body?
>
> That was because I was interested just in the functions and its
> arguments, but you are right, I'll do the callback at the beginning of
> the function.
>
> Regards,
> Andrés.
Hi
I made the the corrections to the patch.
Changelog 2016-5-2 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 (cxx_eval_constant_expression): Not static anymore.
*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/config-lang.in (gtfiles): Added \$(srcdir)/cp/constexpr.h
*gcc/cp/Make-lang.in (CP_PLUGIN_HEADERS): Added constexpr.h.
-------------- next part --------------
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 8770f6f..aa8811c 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..8b62d86 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,
@@ -1269,6 +1212,21 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
constexpr_call new_call = { NULL, NULL, NULL, 0 };
bool depth_ok;
+ 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);
+
+ if (call_info.result != NULL_TREE)
+ return call_info.result;
+
+
if (fun == NULL_TREE)
switch (CALL_EXPR_IFN (t))
{
@@ -3461,7 +3419,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..8212563
--- /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.*/
+typedef struct constexpr_call_info_st
+{
+ /* 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;
+
+} constexpr_call_info;
+
+
+/* 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