diff mbox

New plugin events when evaluating constexpr expressions.

Message ID CAJZwELnF97YAmsmkTrdHwyvnB9BZgWXh97VPtGS31UoVONprxg@mail.gmail.com
State New
Headers show

Commit Message

Andres Tiraboschi Nov. 3, 2015, 12:09 p.m. UTC
Hi
 This patch adds two plugins events when evaluated call expression and
an init or modify expression in constexpr.
 The goal of this patch is to allow the plugins to analyze and or
modify the evaluation of constant expressions.

 This patch also adds an event that is called when the parsing of a
file is finished.

Thanks,
Andrés.

Comments

Daniel Gutson Feb. 23, 2016, 7:46 p.m. UTC | #1
On Tue, Nov 3, 2015 at 9:09 AM, Andres Tiraboschi
<andres.tiraboschi@tallertechnologies.com> wrote:
>  Hi
>  This patch adds two plugins events when evaluated call expression and
> an init or modify expression in constexpr.
>  The goal of this patch is to allow the plugins to analyze and or
> modify the evaluation of constant expressions.
>
>  This patch also adds an event that is called when the parsing of a
> file is finished.

ping

Any update on this?

Thanks!

   Daniel.

>
> Thanks,
> Andrés.
diff mbox

Patch

diff --git a/gccOrig/gcc/cp/constexpr.c b/gccMod/gcc/cp/constexpr.c
index e250726..1c5431a 100644
--- a/gccOrig/gcc/cp/constexpr.c
+++ b/gccMod/gcc/cp/constexpr.c
@@ -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,
diff --git a/gccOrig/gcc/cp/cp-tree.h b/gccMod/gcc/cp/cp-tree.h
index 4e525e0..98b8dd1 100644
--- a/gccOrig/gcc/cp/cp-tree.h
+++ b/gccMod/gcc/cp/cp-tree.h
@@ -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 */
diff --git a/gccOrig/gcc/cp/parser.c b/gccMod/gcc/cp/parser.c
index db9301f..15dc98a 100644
--- a/gccOrig/gcc/cp/parser.c
+++ b/gccMod/gcc/cp/parser.c
@@ -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;
 }
 
diff --git a/gccOrig/gcc/plugin.c b/gccMod/gcc/plugin.c
index d924438..8b5d2a6 100644
--- a/gccOrig/gcc/plugin.c
+++ b/gccMod/gcc/plugin.c
@@ -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:
diff --git a/gccOrig/gcc/plugin.def b/gccMod/gcc/plugin.def
index 98c988a..e0d9ac8 100644
--- a/gccOrig/gcc/plugin.def
+++ b/gccMod/gcc/plugin.def
@@ -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)