public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PING][PATCH] New plugin event when evaluating a constexpr call
@ 2016-04-25 14:08 Andres Tiraboschi
  2016-04-25 19:21 ` Jason Merrill
  0 siblings, 1 reply; 8+ messages in thread
From: Andres Tiraboschi @ 2016-04-25 14:08 UTC (permalink / raw)
  To: GCC Patches

Hi
 This patch adds a plugin event when evaluating a call expression in constexpr.
 The goal of this patch is to allow the plugins to analyze and or
modify the evaluation of constant expressions.


Changelog 2016-4-25  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/cp-tree.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/pc/cp-tree.h (constexpr_call_info): New Type.
    *gcc/pc/cp-tree.h (constexpr_fundef): Moved type from gcc/cp/constexpr.c.
    *gcc/pc/cp-tree.h (constexpr_call): Ditto.
    *gcc/pc/cp-tree.h (constexpr_ctx): Ditto.
    *gcc/pc/cp-tree.h (cxx_eval_constant_expression): Declared.




diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 5f97c9d..5562e44 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -31,6 +31,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)                        \
@@ -112,13 +114,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,62 +851,12 @@ 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.  */

@@ -1303,6 +1248,22 @@ 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 call_info.result;
+    }
+
   if (*non_constant_p)
     return t;

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 15b004d..00856ec 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6946,6 +6946,77 @@ extern tree cp_ubsan_maybe_instrument_downcast
  (location_t, tree, tree, tree);
 extern tree cp_ubsan_maybe_instrument_cast_to_vbase (location_t, tree, tree);
 extern void cp_ubsan_maybe_initialize_vtbl_ptrs (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;
+  /* 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
+{
+    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;
+
 /* -- end of C++ */

 #endif /* ! GCC_CP_TREE_H */
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)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING][PATCH] New plugin event when evaluating a constexpr call
  2016-04-25 14:08 [PING][PATCH] New plugin event when evaluating a constexpr call Andres Tiraboschi
@ 2016-04-25 19:21 ` Jason Merrill
  2016-04-26 13:41   ` Andres Tiraboschi
  0 siblings, 1 reply; 8+ messages in thread
From: Jason Merrill @ 2016-04-25 19:21 UTC (permalink / raw)
  To: Andres Tiraboschi, GCC Patches

On 04/25/2016 10:08 AM, Andres Tiraboschi wrote:
>      *gcc/cp/constexpr.c (constexpr_fundef): Moved to gcc/cp/cp-tree.h.
>      *gcc/cp/constexpr.c (constexpr_call): Ditto.
>      *gcc/cp/constexpr.c (constexpr_ctx): Ditto.

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?

>     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 call_info.result;
> +    }
> +
>     if (*non_constant_p)
>       return t;

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?

Jason

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING][PATCH] New plugin event when evaluating a constexpr call
  2016-04-25 19:21 ` Jason Merrill
@ 2016-04-26 13:41   ` Andres Tiraboschi
  2016-05-02 19:28     ` Andres Tiraboschi
  0 siblings, 1 reply; 8+ messages in thread
From: Andres Tiraboschi @ 2016-04-26 13:41 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

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.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING][PATCH] New plugin event when evaluating a constexpr call
  2016-04-26 13:41   ` Andres Tiraboschi
@ 2016-05-02 19:28     ` Andres Tiraboschi
  2016-05-04 16:16       ` Jason Merrill
  0 siblings, 1 reply; 8+ messages in thread
From: Andres Tiraboschi @ 2016-05-02 19:28 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1818 bytes --]

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.

[-- Attachment #2: patchConstexpr.diff --]
[-- Type: text/plain, Size: 13451 bytes --]

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)
 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING][PATCH] New plugin event when evaluating a constexpr call
  2016-05-02 19:28     ` Andres Tiraboschi
@ 2016-05-04 16:16       ` Jason Merrill
  2016-05-05 13:29         ` Andres Tiraboschi
  0 siblings, 1 reply; 8+ messages in thread
From: Jason Merrill @ 2016-05-04 16:16 UTC (permalink / raw)
  To: Andres Tiraboschi; +Cc: GCC Patches

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING][PATCH] New plugin event when evaluating a constexpr call
  2016-05-04 16:16       ` Jason Merrill
@ 2016-05-05 13:29         ` Andres Tiraboschi
  2016-05-06 14:23           ` Andres Tiraboschi
  0 siblings, 1 reply; 8+ messages in thread
From: Andres Tiraboschi @ 2016-05-05 13:29 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

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
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING][PATCH] New plugin event when evaluating a constexpr call
  2016-05-05 13:29         ` Andres Tiraboschi
@ 2016-05-06 14:23           ` Andres Tiraboschi
  2016-05-19 16:08             ` Jason Merrill
  0 siblings, 1 reply; 8+ messages in thread
From: Andres Tiraboschi @ 2016-05-06 14:23 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 2038 bytes --]

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
>>

[-- Attachment #2: patch.diff --]
[-- Type: text/plain, Size: 13960 bytes --]

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
 
 #\f
 # 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)
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING][PATCH] New plugin event when evaluating a constexpr call
  2016-05-06 14:23           ` Andres Tiraboschi
@ 2016-05-19 16:08             ` Jason Merrill
  0 siblings, 0 replies; 8+ messages in thread
From: Jason Merrill @ 2016-05-19 16:08 UTC (permalink / raw)
  To: Andres Tiraboschi; +Cc: GCC Patches

On 05/06/2016 10:23 AM, Andres Tiraboschi wrote:
> +static tree
> +eval_call_plugin_callback (const constexpr_ctx *ctx, tree fun,
> +			   bool lval, bool *non_constant_p, bool *overflow_p)

This function needs a comment.

> -static void
> +void
>  cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,

Why expose this function?  If you want the reduced forms of the 
arguments in your plugin, can't you call cxx_eval_constant_expression on 
them directly?

Jason

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-05-19 16:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-25 14:08 [PING][PATCH] New plugin event when evaluating a constexpr call Andres Tiraboschi
2016-04-25 19:21 ` Jason Merrill
2016-04-26 13:41   ` Andres Tiraboschi
2016-05-02 19:28     ` Andres Tiraboschi
2016-05-04 16:16       ` Jason Merrill
2016-05-05 13:29         ` Andres Tiraboschi
2016-05-06 14:23           ` Andres Tiraboschi
2016-05-19 16:08             ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).