[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