public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c-pragma: adding a data field to pragma_handler
@ 2011-06-01 16:55 Pierre
  2011-06-01 17:54 ` Basile Starynkevitch
  2011-06-02 17:52 ` Tom Tromey
  0 siblings, 2 replies; 14+ messages in thread
From: Pierre @ 2011-06-01 16:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: joseph

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

This patch is about the pragmas.

In c-family/c-pragma.h, we declare a pragma_handler which is a function 
accepting cpp_reader as parameter.

I have changed this handler in order to accept a second parameter which 
is a void *, allowing to give extra datas to the handler. I think this 
data field might be of general use: we can have condition or data at 
register time that we want to express in the handler. I guess this is a 
common way to pass data to an handler function.

I would like your opinion on this patch! Thanks!

Pierre Vittet

Changelog

2011-06-01  Pierre Vittet  <piervit@pvittet.com>

* c-pragma.h (pragma_handler,internal_pragma_handler, c_register_pragma,
	c_register_pragma_with_expansion): create internal_pragma_handler, add a
	new void * data parameter.
	* c-pragma.c (handle_pragma_pack, handle_pragma_weak,
	handle_pragma_redefine_extname, handle_pragma_visibility,
	handle_pragma_diagnostic, handle_pragma_target, handle_pragma_optimize,
	handle_pragma_push_options, handle_pragma_pop_options,
	handle_pragma_reset_options, handle_pragma_message,
	handle_pragma_float_const_decimal64, registered_pragmas,
	c_register_pragma_1, c_register_pragma, c_register_pragma_with_expansion,
	init_pragma): add support of the void * data field.




[-- Attachment #2: addDataToPragmaHandler-174521.diff --]
[-- Type: text/plain, Size: 11914 bytes --]

Index: gcc/c-family/c-pragma.h
===================================================================
--- gcc/c-family/c-pragma.h	(revision 174521)
+++ gcc/c-family/c-pragma.h	(working copy)
@@ -84,10 +84,19 @@ extern bool pop_visibility (int);
 extern void init_pragma (void);
 
 /* Front-end wrappers for pragma registration.  */
-typedef void (*pragma_handler)(struct cpp_reader *);
-extern void c_register_pragma (const char *, const char *, pragma_handler);
-extern void c_register_pragma_with_expansion (const char *, const char *,
-					      pragma_handler);
+/* The void * allows to pass extra data to the handler.  */
+typedef void (*pragma_handler)(struct cpp_reader *, void * );
+/* Internally use to keep the data of the handler.  */
+struct internal_pragma_handler_d{
+  pragma_handler handler;
+  void * data; 
+};
+typedef struct internal_pragma_handler_d internal_pragma_handler;
+
+extern void c_register_pragma (const char * space, const char * name,
+                               pragma_handler handler, void * data);
+extern void c_register_pragma_with_expansion (const char * space, 
+                      const char * name,  pragma_handler handler , void * data);
 extern void c_invoke_pragma_handler (unsigned int);
 
 extern void maybe_apply_pragma_weak (tree);
Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -53,7 +53,7 @@ typedef struct GTY(()) align_stack {
 
 static GTY(()) struct align_stack * alignment_stack;
 
-static void handle_pragma_pack (cpp_reader *);
+static void handle_pragma_pack (cpp_reader *, void * data);
 
 /* If we have a "global" #pragma pack(<n>) in effect when the first
    #pragma pack(push,<n>) is encountered, this stores the value of
@@ -133,7 +133,7 @@ pop_alignment (tree id)
    #pragma pack (pop)
    #pragma pack (pop, ID) */
 static void
-handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy), void * ARG_UNUSED (data))
 {
   tree x, id = 0;
   int align = -1;
@@ -247,7 +247,7 @@ DEF_VEC_ALLOC_O(pending_weak,gc);
 static GTY(()) VEC(pending_weak,gc) *pending_weaks;
 
 static void apply_pragma_weak (tree, tree);
-static void handle_pragma_weak (cpp_reader *);
+static void handle_pragma_weak (cpp_reader *, void * data);
 
 static void
 apply_pragma_weak (tree decl, tree value)
@@ -334,7 +334,7 @@ maybe_apply_pending_pragma_weaks (void)
 
 /* #pragma weak name [= value] */
 static void
-handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy), void * ARG_UNUSED (data))
 {
   tree name, value, x, decl;
   enum cpp_ttype t;
@@ -411,11 +411,12 @@ DEF_VEC_ALLOC_O(pending_redefinition,gc);
 
 static GTY(()) VEC(pending_redefinition,gc) *pending_redefine_extname;
 
-static void handle_pragma_redefine_extname (cpp_reader *);
+static void handle_pragma_redefine_extname (cpp_reader *, void * data);
 
 /* #pragma redefine_extname oldname newname */
 static void
-handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy), 
+                                void * ARG_UNUSED (data))
 {
   tree oldname, newname, decl, x;
   enum cpp_ttype t;
@@ -481,7 +482,8 @@ static GTY(()) tree pragma_extern_prefix;
 
 /* #pragma extern_prefix "prefix" */
 static void
-handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy), 
+                             void * ARG_UNUSED (data))
 {
   tree prefix, x;
   enum cpp_ttype t;
@@ -594,7 +596,7 @@ maybe_apply_renaming_pragma (tree decl, tree asmna
 }
 
 
-static void handle_pragma_visibility (cpp_reader *);
+static void handle_pragma_visibility (cpp_reader *, void * data);
 
 static VEC (int, heap) *visstack;
 
@@ -644,7 +646,8 @@ pop_visibility (int kind)
    specified on the command line.  */
 
 static void
-handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
+handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED, 
+                          void * ARG_UNUSED (data))
 {
   /* Form is #pragma GCC visibility push(hidden)|pop */
   tree x;
@@ -687,7 +690,8 @@ static void
 }
 
 static void
-handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy), 
+                         void * ARG_UNUSED (data))
 {
   const char *kind_string, *option_string;
   unsigned int option_index;
@@ -738,7 +742,7 @@ static void
 
 /*  Parse #pragma GCC target (xxx) to set target specific options.  */
 static void
-handle_pragma_target(cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_target(cpp_reader *ARG_UNUSED(dummy), void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x;
@@ -806,7 +810,7 @@ static void
 
 /* Handle #pragma GCC optimize to set optimization options.  */
 static void
-handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy), void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x;
@@ -893,7 +897,8 @@ static GTY(()) struct opt_stack * options_stack;
    options.  */
 
 static void
-handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy), 
+                            void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x = 0;
@@ -923,7 +928,8 @@ static void
    optimization options from a previous push_options.  */
 
 static void
-handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy), 
+                           void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x = 0;
@@ -971,7 +977,8 @@ static void
    optimization options to the original options used on the command line.  */
 
 static void
-handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy), 
+                             void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x = 0;
@@ -1007,7 +1014,7 @@ static void
 /* Print a plain user-specified message.  */
 
 static void
-handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_message (cpp_reader *ARG_UNUSED(dummy), void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x, message = 0;
@@ -1110,7 +1117,8 @@ handle_stdc_pragma (const char *pname)
    #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
 
 static void
-handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy))
+handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy), 
+                                     void * ARG_UNUSED (data))
 {
   if (c_dialect_cxx ())
     {
@@ -1148,12 +1156,12 @@ static void
 }
 
 /* A vector of registered pragma callbacks.  */
+/*This is never freed as we need it during the whole execution */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
 
-DEF_VEC_O (pragma_handler);
-DEF_VEC_ALLOC_O (pragma_handler, heap);
+static VEC(internal_pragma_handler, heap) *registered_pragmas;
 
-static VEC(pragma_handler, heap) *registered_pragmas;
-
 typedef struct
 {
   const char *space;
@@ -1216,9 +1224,10 @@ c_pp_lookup_pragma (unsigned int id, const char **
 
 static void
 c_register_pragma_1 (const char *space, const char *name,
-		     pragma_handler handler, bool allow_expansion)
+		     pragma_handler handler, bool allow_expansion, void * data)
 {
   unsigned id;
+  internal_pragma_handler * ihandler;
 
   if (flag_preprocess_only)
     {
@@ -1229,14 +1238,18 @@ c_register_pragma_1 (const char *space, const char
 
       ns_name.space = space;
       ns_name.name = name;
+      
       VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas, &ns_name);
       id = VEC_length (pragma_ns_name, registered_pp_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
     }
   else
     {
-      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-      id = VEC_length (pragma_handler, registered_pragmas);
+      ihandler->handler = handler;
+      ihandler->data = data;
+      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
+                                                    &ihandler);
+      id = VEC_length (internal_pragma_handler, registered_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
 
       /* The C++ front end allocates 6 bits in cp_token; the C front end
@@ -1249,27 +1262,28 @@ c_register_pragma_1 (const char *space, const char
 }
 
 void
-c_register_pragma (const char *space, const char *name, pragma_handler handler)
+c_register_pragma (const char *space, const char *name, pragma_handler handler, 
+                   void * data)
 {
-  c_register_pragma_1 (space, name, handler, false);
+  c_register_pragma_1 (space, name, handler, false, data);
 }
 
 void
 c_register_pragma_with_expansion (const char *space, const char *name,
-				  pragma_handler handler)
+				  pragma_handler handler, void * data)
 {
-  c_register_pragma_1 (space, name, handler, true);
+  c_register_pragma_1 (space, name, handler, true, data);
 }
 
 void
 c_invoke_pragma_handler (unsigned int id)
 {
-  pragma_handler handler;
+  internal_pragma_handler * ihandler;
 
   id -= PRAGMA_FIRST_EXTERNAL;
-  handler = *VEC_index (pragma_handler, registered_pragmas, id);
-
-  handler (parse_in);
+  ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id);
+  pragma_handler handler = ihandler->handler;
+  handler (parse_in, ihandler->data);
 }
 
 /* Set up front-end pragmas.  */
@@ -1291,27 +1305,28 @@ init_pragma (void)
 				  PRAGMA_GCC_PCH_PREPROCESS, false, false);
 
 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
-  c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
+  c_register_pragma_with_expansion (0, "pack", handle_pragma_pack, NULL);
 #else
-  c_register_pragma (0, "pack", handle_pragma_pack);
+  c_register_pragma (0, "pack", handle_pragma_pack, NULL);
 #endif
-  c_register_pragma (0, "weak", handle_pragma_weak);
-  c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
+  c_register_pragma (0, "weak", handle_pragma_weak, NULL);
+  c_register_pragma ("GCC", "visibility", handle_pragma_visibility, NULL);
 
-  c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
-  c_register_pragma ("GCC", "target", handle_pragma_target);
-  c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
-  c_register_pragma ("GCC", "push_options", handle_pragma_push_options);
-  c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
-  c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
+  c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic, NULL);
+  c_register_pragma ("GCC", "target", handle_pragma_target, NULL);
+  c_register_pragma ("GCC", "optimize", handle_pragma_optimize, NULL);
+  c_register_pragma ("GCC", "push_options", handle_pragma_push_options, NULL);
+  c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options, NULL);
+  c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options, NULL);
 
   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
-		     handle_pragma_float_const_decimal64);
+		     handle_pragma_float_const_decimal64, NULL);
 
-  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
-  c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
+  c_register_pragma_with_expansion (0, "redefine_extname",
+                                    handle_pragma_redefine_extname, NULL);
+  c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix, NULL);
 
-  c_register_pragma_with_expansion (0, "message", handle_pragma_message);
+  c_register_pragma_with_expansion (0, "message", handle_pragma_message, NULL);
 
 #ifdef REGISTER_TARGET_PRAGMAS
   REGISTER_TARGET_PRAGMAS ();

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-01 16:55 [PATCH] c-pragma: adding a data field to pragma_handler Pierre
@ 2011-06-01 17:54 ` Basile Starynkevitch
  2011-06-02 17:52 ` Tom Tromey
  1 sibling, 0 replies; 14+ messages in thread
From: Basile Starynkevitch @ 2011-06-01 17:54 UTC (permalink / raw)
  To: Pierre; +Cc: gcc-patches, joseph

On Wed, 01 Jun 2011 18:54:38 +0200
Pierre <p.vittet@laposte.net> wrote:

> This patch is about the pragmas.
> 
> In c-family/c-pragma.h, we declare a pragma_handler which is a function 
> accepting cpp_reader as parameter.
> 
> I have changed this handler in order to accept a second parameter which 
> is a void *, allowing to give extra datas to the handler. I think this 
> data field might be of general use: we can have condition or data at 
> register time that we want to express in the handler. I guess this is a 
> common way to pass data to an handler function.

I find this patch interesting and useful (& not only for MELT).

A general coding rule in C seems to be that every time function can be
variably called thru indirect pointers (which can have several
different functions as value), they better take an extra data argument.
This is the case, in particular, inside Glib & GTK, inside the Linux
kernel, and on several other occurrences in GCC.

A use case of such pragma handlers with data for pragmas would be a
plugin which permit some messages to other channels than stdout/stderr
(e.g. other files, or a pipe, or the D-Bus, or a widget, or a web
service...). Then the same routine would handle 
   #pragma GCCPLUGIN message_to_file "foo"
and 
   #pragma GCCPLUGIN message_to_pipe "bar"
and the data pointer would be different (an fopen-ed or popen-ed
FILE*, or even an std::ostream& if the plugin is coded in C++). 


I am not authorized to ok the patch (I believe the changelog had some
typos), but I hope someone will review & ok it.

Regards




-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mine, sont seulement les miennes} ***

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-01 16:55 [PATCH] c-pragma: adding a data field to pragma_handler Pierre
  2011-06-01 17:54 ` Basile Starynkevitch
@ 2011-06-02 17:52 ` Tom Tromey
  2011-06-03 15:32   ` Pierre Vittet
  1 sibling, 1 reply; 14+ messages in thread
From: Tom Tromey @ 2011-06-02 17:52 UTC (permalink / raw)
  To: Pierre; +Cc: gcc-patches, joseph

>>>>> "Pierre" == Pierre  <p.vittet@laposte.net> writes:

Pierre> I have changed this handler in order to accept a second parameter
Pierre> which is a void *, allowing to give extra datas to the handler. I
Pierre> think this data field might be of general use: we can have condition
Pierre> or data at register time that we want to express in the handler. I
Pierre> guess this is a common way to pass data to an handler function.

I can't approve or reject this patch, but the idea seems reasonable
enough to me.

Pierre> I would like your opinion on this patch! Thanks!

It has a number of formatting issues.

Pierre> +typedef void (*pragma_handler)(struct cpp_reader *, void * );

No space after the final "*".

Pierre> +/* Internally use to keep the data of the handler.  */
Pierre> +struct internal_pragma_handler_d{

Space before the "{".

Pierre> +  pragma_handler handler;
Pierre> +  void * data; 

No space.  Lots of instances of this.

Pierre>  /* A vector of registered pragma callbacks.  */
Pierre> +/*This is never freed as we need it during the whole execution */

Coalesce the two comments.  The comment formatting is wrong, see GNU
standards.

Pierre>        ns_name.space = space;
Pierre>        ns_name.name = name;
Pierre> +      
Pierre>        VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas, &ns_name);

Gratuitous newline addition.

Pierre> +      ihandler->handler = handler;
Pierre> +      ihandler->data = data;

I didn't see anything that initialized ihandler.

Pierre> +      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
Pierre> +                                                    &ihandler);

I think you wanted just `internal_pragma_handler ihandler', no "*", for
the definition.

Pierre> +c_register_pragma (const char *space, const char *name, pragma_handler handler, 
Pierre> +                   void * data)

There are lots of calls to this that you did not update.
Do a recursive grep to see.

One way to avoid a massive change is to add a new "overload" that passes
in the data to c_register_pragma_1; and then change the "legacy"
functions to pass NULL.

I don't know if that approach is ok (it is typical in gdb...), so if
not, you have to update all callers.

Tom

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-02 17:52 ` Tom Tromey
@ 2011-06-03 15:32   ` Pierre Vittet
  2011-06-03 15:48     ` Basile Starynkevitch
  2011-06-08 21:35     ` Pierre Vittet
  0 siblings, 2 replies; 14+ messages in thread
From: Pierre Vittet @ 2011-06-03 15:32 UTC (permalink / raw)
  To: gcc-patches, tromey; +Cc: joseph, Basile Starynkevitch

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

Thank you for your answer!

I send you a new patch
I have corrected the errors you raised.

I have make my patch compatible with the old use of c_register_pragma 
and c_register_pragma_with_expansion.

I don't know what is the best solution, maybe changing every call 
c_register_pragma allows to keep a more clear code. I can do it, if you 
think it is better.

I have successfully compiled gcc with my patch and I have tried it with 
a modified version of gcc/testsuite/g++.dg/plugin/pragma_plugin.c.

Pierre Vittet

On 02/06/2011 19:51, Tom Tromey wrote:
>>>>>> "Pierre" == Pierre<p.vittet@laposte.net>  writes:
>
> Pierre>  I have changed this handler in order to accept a second parameter
> Pierre>  which is a void *, allowing to give extra datas to the handler. I
> Pierre>  think this data field might be of general use: we can have condition
> Pierre>  or data at register time that we want to express in the handler. I
> Pierre>  guess this is a common way to pass data to an handler function.
>
> I can't approve or reject this patch, but the idea seems reasonable
> enough to me.
>
> Pierre>  I would like your opinion on this patch! Thanks!
>
> It has a number of formatting issues.
>
> Pierre>  +typedef void (*pragma_handler)(struct cpp_reader *, void * );
>
> No space after the final "*".
>
> Pierre>  +/* Internally use to keep the data of the handler.  */
> Pierre>  +struct internal_pragma_handler_d{
>
> Space before the "{".
>
> Pierre>  +  pragma_handler handler;
> Pierre>  +  void * data;
>
> No space.  Lots of instances of this.
>
> Pierre>   /* A vector of registered pragma callbacks.  */
> Pierre>  +/*This is never freed as we need it during the whole execution */
>
> Coalesce the two comments.  The comment formatting is wrong, see GNU
> standards.
>
> Pierre>         ns_name.space = space;
> Pierre>         ns_name.name = name;
> Pierre>  +
> Pierre>         VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas,&ns_name);
>
> Gratuitous newline addition.
>
> Pierre>  +      ihandler->handler = handler;
> Pierre>  +      ihandler->data = data;
>
> I didn't see anything that initialized ihandler.
>
> Pierre>  +      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
> Pierre>  +&ihandler);
>
> I think you wanted just `internal_pragma_handler ihandler', no "*", for
> the definition.
>
> Pierre>  +c_register_pragma (const char *space, const char *name, pragma_handler handler,
> Pierre>  +                   void * data)
>
> There are lots of calls to this that you did not update.
> Do a recursive grep to see.
>
> One way to avoid a massive change is to add a new "overload" that passes
> in the data to c_register_pragma_1; and then change the "legacy"
> functions to pass NULL.
>
> I don't know if that approach is ok (it is typical in gdb...), so if
> not, you have to update all callers.
>
> Tom
>


[-- Attachment #2: addDataToPragmaHandler-174521.diff --]
[-- Type: text/plain, Size: 12979 bytes --]

Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -53,7 +53,7 @@ typedef struct GTY(()) align_stack {
 
 static GTY(()) struct align_stack * alignment_stack;
 
-static void handle_pragma_pack (cpp_reader *);
+static void handle_pragma_pack (cpp_reader *, void * data);
 
 /* If we have a "global" #pragma pack(<n>) in effect when the first
    #pragma pack(push,<n>) is encountered, this stores the value of
@@ -133,7 +133,7 @@ pop_alignment (tree id)
    #pragma pack (pop)
    #pragma pack (pop, ID) */
 static void
-handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy), void * ARG_UNUSED (data))
 {
   tree x, id = 0;
   int align = -1;
@@ -247,7 +247,7 @@ DEF_VEC_ALLOC_O(pending_weak,gc);
 static GTY(()) VEC(pending_weak,gc) *pending_weaks;
 
 static void apply_pragma_weak (tree, tree);
-static void handle_pragma_weak (cpp_reader *);
+static void handle_pragma_weak (cpp_reader *, void * data);
 
 static void
 apply_pragma_weak (tree decl, tree value)
@@ -334,7 +334,7 @@ maybe_apply_pending_pragma_weaks (void)
 
 /* #pragma weak name [= value] */
 static void
-handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy), void * ARG_UNUSED (data))
 {
   tree name, value, x, decl;
   enum cpp_ttype t;
@@ -411,11 +411,12 @@ DEF_VEC_ALLOC_O(pending_redefinition,gc);
 
 static GTY(()) VEC(pending_redefinition,gc) *pending_redefine_extname;
 
-static void handle_pragma_redefine_extname (cpp_reader *);
+static void handle_pragma_redefine_extname (cpp_reader *, void * data);
 
 /* #pragma redefine_extname oldname newname */
 static void
-handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy),
+                                void * ARG_UNUSED (data))
 {
   tree oldname, newname, decl, x;
   enum cpp_ttype t;
@@ -481,7 +482,8 @@ static GTY(()) tree pragma_extern_prefix;
 
 /* #pragma extern_prefix "prefix" */
 static void
-handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
+handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy),
+                             void * ARG_UNUSED (data))
 {
   tree prefix, x;
   enum cpp_ttype t;
@@ -594,7 +596,7 @@ maybe_apply_renaming_pragma (tree decl, tree asmna
 }
 
 
-static void handle_pragma_visibility (cpp_reader *);
+static void handle_pragma_visibility (cpp_reader *, void * data);
 
 static VEC (int, heap) *visstack;
 
@@ -644,7 +646,8 @@ pop_visibility (int kind)
    specified on the command line.  */
 
 static void
-handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
+handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED,
+                          void * ARG_UNUSED (data))
 {
   /* Form is #pragma GCC visibility push(hidden)|pop */
   tree x;
@@ -687,7 +690,8 @@ static void
 }
 
 static void
-handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy),
+                         void * ARG_UNUSED (data))
 {
   const char *kind_string, *option_string;
   unsigned int option_index;
@@ -738,7 +742,7 @@ static void
 
 /*  Parse #pragma GCC target (xxx) to set target specific options.  */
 static void
-handle_pragma_target(cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_target(cpp_reader *ARG_UNUSED(dummy), void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x;
@@ -806,7 +810,7 @@ static void
 
 /* Handle #pragma GCC optimize to set optimization options.  */
 static void
-handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy), void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x;
@@ -893,7 +897,8 @@ static GTY(()) struct opt_stack * options_stack;
    options.  */
 
 static void
-handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy),
+                            void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x = 0;
@@ -923,7 +928,8 @@ static void
    optimization options from a previous push_options.  */
 
 static void
-handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy),
+                           void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x = 0;
@@ -971,7 +977,8 @@ static void
    optimization options to the original options used on the command line.  */
 
 static void
-handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy),
+                             void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x = 0;
@@ -1007,7 +1014,7 @@ static void
 /* Print a plain user-specified message.  */
 
 static void
-handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_message (cpp_reader *ARG_UNUSED(dummy), void * ARG_UNUSED (data))
 {
   enum cpp_ttype token;
   tree x, message = 0;
@@ -1110,7 +1117,8 @@ handle_stdc_pragma (const char *pname)
    #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
 
 static void
-handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy))
+handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy),
+                                     void * ARG_UNUSED (data))
 {
   if (c_dialect_cxx ())
     {
@@ -1148,12 +1156,12 @@ static void
 }
 
 /* A vector of registered pragma callbacks.  */
+/* This is never freed as we need it during the whole execution.  */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
 
-DEF_VEC_O (pragma_handler);
-DEF_VEC_ALLOC_O (pragma_handler, heap);
+static VEC(internal_pragma_handler, heap) *registered_pragmas;
 
-static VEC(pragma_handler, heap) *registered_pragmas;
-
 typedef struct
 {
   const char *space;
@@ -1216,12 +1224,12 @@ c_pp_lookup_pragma (unsigned int id, const char **
 
 static void
 c_register_pragma_1 (const char *space, const char *name,
-		     pragma_handler handler, bool allow_expansion)
+		                 internal_pragma_handler ihandler, bool allow_expansion)
 {
   unsigned id;
 
   if (flag_preprocess_only)
-    {
+   {
       pragma_ns_name ns_name;
 
       if (!allow_expansion)
@@ -1235,8 +1243,9 @@ c_register_pragma_1 (const char *space, const char
     }
   else
     {
-      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-      id = VEC_length (pragma_handler, registered_pragmas);
+      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
+                     &ihandler);
+      id = VEC_length (internal_pragma_handler, registered_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
 
       /* The C++ front end allocates 6 bits in cp_token; the C front end
@@ -1248,28 +1257,90 @@ c_register_pragma_1 (const char *space, const char
 				allow_expansion, false);
 }
 
+/* Register a C pragma handler, using a space and a name.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
-c_register_pragma (const char *space, const char *name, pragma_handler handler)
+c_register_pragma (const char *space, const char *name,
+                   pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, false);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, false);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
+c_register_pragma_with_data (const char *space, const char *name,
+                             pragma_handler_2arg handler, void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, false);
+}
+
+/* Register a C pragma handler, using a space and a name.  It allows pragma
+expansion as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
+void
 c_register_pragma_with_expansion (const char *space, const char *name,
-				  pragma_handler handler)
+				  pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, true);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, true);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It allows pragma expansion
+as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
 void
+c_register_pragma_with_expansion_and_data (const char *space, const char *name,
+				                                   pragma_handler_2arg handler,
+                                           void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, true);
+}
+
+void
 c_invoke_pragma_handler (unsigned int id)
 {
-  pragma_handler handler;
+  internal_pragma_handler * ihandler;
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
 
   id -= PRAGMA_FIRST_EXTERNAL;
-  handler = *VEC_index (pragma_handler, registered_pragmas, id);
-
-  handler (parse_in);
+  ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id);
+  if (ihandler->extra_data)
+    {
+      handler_2arg = ihandler->handler.handler_2arg;
+      handler_2arg (parse_in, ihandler->data);
+    }
+  else
+    {
+      handler_1arg = ihandler->handler.handler_1arg;
+      handler_1arg (parse_in);
+    }
 }
 
 /* Set up front-end pragmas.  */
@@ -1308,7 +1379,8 @@ init_pragma (void)
   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
 		     handle_pragma_float_const_decimal64);
 
-  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
+  c_register_pragma_with_expansion (0, "redefine_extname",
+                                    handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
Index: gcc/c-family/c-pragma.h
===================================================================
--- gcc/c-family/c-pragma.h	(revision 174521)
+++ gcc/c-family/c-pragma.h	(working copy)
@@ -84,10 +84,39 @@ extern bool pop_visibility (int);
 extern void init_pragma (void);
 
 /* Front-end wrappers for pragma registration.  */
-typedef void (*pragma_handler)(struct cpp_reader *);
-extern void c_register_pragma (const char *, const char *, pragma_handler);
-extern void c_register_pragma_with_expansion (const char *, const char *,
-					      pragma_handler);
+typedef void (*pragma_handler_1arg)(struct cpp_reader *);
+/* A second pragma handler, which adds a void * argument allowing to pass extra
+data to the handler.  */
+typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
+
+/* This union permits abstact the different handlers.  */
+union gen_pragma_handler {
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
+};
+/* Internally use to keep the data of the handler.  The field extra_data permit
+to know if handler is a pragma_handler_1arg (extra_data is false), or a
+pragma_handler_2arg (extra_data is true).  */
+struct internal_pragma_handler_d {
+  union gen_pragma_handler handler;
+  bool extra_data;
+  void * data;
+};
+typedef struct internal_pragma_handler_d internal_pragma_handler;
+
+extern void c_register_pragma (const char * space, const char * name,
+                               pragma_handler_1arg handler);
+extern void c_register_pragma_with_data (const char * space, const char * name,
+                                         pragma_handler_2arg handler,
+                                         void * data);
+
+extern void c_register_pragma_with_expansion (const char * space,
+                                              const char * name,
+                                              pragma_handler_1arg handler);
+extern void c_register_pragma_with_expansion_and_data (const char * space,
+                                                       const char * name,
+                                                   pragma_handler_2arg handler,
+                                                       void * data);
 extern void c_invoke_pragma_handler (unsigned int);
 
 extern void maybe_apply_pragma_weak (tree);

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-03 15:32   ` Pierre Vittet
@ 2011-06-03 15:48     ` Basile Starynkevitch
  2011-06-03 20:25       ` Pierre Vittet
  2011-06-08 21:35     ` Pierre Vittet
  1 sibling, 1 reply; 14+ messages in thread
From: Basile Starynkevitch @ 2011-06-03 15:48 UTC (permalink / raw)
  To: Pierre Vittet; +Cc: gcc-patches, tromey, joseph

On Fri, 03 Jun 2011 17:31:25 +0200
Pierre Vittet <piervit@pvittet.com> wrote:

> Thank you for your answer!
> 
> I send you a new patch
> I have corrected the errors you raised.
> 
> I have make my patch compatible with the old use of c_register_pragma 
> and c_register_pragma_with_expansion.

I find the patch quite interesting, but I cannot approve it.

 void
+c_register_pragma_with_expansion_and_data (const char *space, const char *name,
+				                                   pragma_handler_2arg handler,
+                                           void * data)

Perhaps there are some spaces (vs tabs) issues here.

Cheers
-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mine, sont seulement les miennes} ***

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-03 15:48     ` Basile Starynkevitch
@ 2011-06-03 20:25       ` Pierre Vittet
  0 siblings, 0 replies; 14+ messages in thread
From: Pierre Vittet @ 2011-06-03 20:25 UTC (permalink / raw)
  To: Basile Starynkevitch, gcc-patches; +Cc: tromey, joseph

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

Hello,

I am sorry, my editor (vim) was not correctly configure (I used 
http://gcc.gnu.org/ml/gcc/2011-03/msg00425.html to improve it). I guess 
it is ok now.
If I still have issue, I will post on the mailing list if there is some 
tips for vim otherway I will use Emacs (I am not very comfortable with 
it for now ;).

Pierre Vittet

On 03/06/2011 17:47, Basile Starynkevitch wrote:
> On Fri, 03 Jun 2011 17:31:25 +0200
> Pierre Vittet<piervit@pvittet.com>  wrote:
>
>    
>> Thank you for your answer!
>>
>> I send you a new patch
>> I have corrected the errors you raised.
>>
>> I have make my patch compatible with the old use of c_register_pragma
>> and c_register_pragma_with_expansion.
>>      
> I find the patch quite interesting, but I cannot approve it.
>
>   void
> +c_register_pragma_with_expansion_and_data (const char *space, const char *name,
> +				                                   pragma_handler_2arg handler,
> +                                           void * data)
>
> Perhaps there are some spaces (vs tabs) issues here.
>
> Cheers
>    


[-- Attachment #2: addDataToPragmaHandler-174521.diff --]
[-- Type: text/plain, Size: 7632 bytes --]

Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -1148,12 +1148,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A
 }
 
 /* A vector of registered pragma callbacks.  */
+/* This is never freed as we need it during the whole execution.  */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
 
-DEF_VEC_O (pragma_handler);
-DEF_VEC_ALLOC_O (pragma_handler, heap);
+static VEC(internal_pragma_handler, heap) *registered_pragmas;
 
-static VEC(pragma_handler, heap) *registered_pragmas;
-
 typedef struct
 {
   const char *space;
@@ -1216,7 +1216,7 @@ c_pp_lookup_pragma (unsigned int id, const char **
 
 static void
 c_register_pragma_1 (const char *space, const char *name,
-		     pragma_handler handler, bool allow_expansion)
+                     internal_pragma_handler ihandler, bool allow_expansion)
 {
   unsigned id;
 
@@ -1235,8 +1235,9 @@ c_register_pragma_1 (const char *space, const char
     }
   else
     {
-      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-      id = VEC_length (pragma_handler, registered_pragmas);
+      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
+                     &ihandler);
+      id = VEC_length (internal_pragma_handler, registered_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
 
       /* The C++ front end allocates 6 bits in cp_token; the C front end
@@ -1248,28 +1249,90 @@ c_register_pragma_1 (const char *space, const char
 				allow_expansion, false);
 }
 
+/* Register a C pragma handler, using a space and a name.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
-c_register_pragma (const char *space, const char *name, pragma_handler handler)
+c_register_pragma (const char *space, const char *name,
+                   pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, false);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, false);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
+c_register_pragma_with_data (const char *space, const char *name,
+                             pragma_handler_2arg handler, void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, false);
+}
+
+/* Register a C pragma handler, using a space and a name.  It allows pragma
+expansion as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
+void
 c_register_pragma_with_expansion (const char *space, const char *name,
-				  pragma_handler handler)
+				  pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, true);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, true);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It allows pragma expansion
+as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
 void
+c_register_pragma_with_expansion_and_data (const char *space, const char *name,
+                                           pragma_handler_2arg handler,
+                                           void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, true);
+}
+
+void
 c_invoke_pragma_handler (unsigned int id)
 {
-  pragma_handler handler;
+  internal_pragma_handler * ihandler;
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
 
   id -= PRAGMA_FIRST_EXTERNAL;
-  handler = *VEC_index (pragma_handler, registered_pragmas, id);
-
-  handler (parse_in);
+  ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id);
+  if (ihandler->extra_data)
+    {
+      handler_2arg = ihandler->handler.handler_2arg;
+      handler_2arg (parse_in, ihandler->data);
+    }
+  else
+    {
+      handler_1arg = ihandler->handler.handler_1arg;
+      handler_1arg (parse_in);
+    }
 }
 
 /* Set up front-end pragmas.  */
@@ -1308,7 +1371,8 @@ init_pragma (void)
   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
 		     handle_pragma_float_const_decimal64);
 
-  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
+  c_register_pragma_with_expansion (0, "redefine_extname",
+                                    handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
Index: gcc/c-family/c-pragma.h
===================================================================
--- gcc/c-family/c-pragma.h	(revision 174521)
+++ gcc/c-family/c-pragma.h	(working copy)
@@ -84,10 +84,39 @@ extern bool pop_visibility (int);
 extern void init_pragma (void);
 
 /* Front-end wrappers for pragma registration.  */
-typedef void (*pragma_handler)(struct cpp_reader *);
-extern void c_register_pragma (const char *, const char *, pragma_handler);
-extern void c_register_pragma_with_expansion (const char *, const char *,
-					      pragma_handler);
+typedef void (*pragma_handler_1arg)(struct cpp_reader *);
+/* A second pragma handler, which adds a void * argument allowing to pass extra
+data to the handler.  */
+typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
+
+/* This union permits abstact the different handlers.  */
+union gen_pragma_handler {
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
+};
+/* Internally use to keep the data of the handler.  The field extra_data permit
+to know if handler is a pragma_handler_1arg (extra_data is false), or a
+pragma_handler_2arg (extra_data is true).  */
+struct internal_pragma_handler_d {
+  union gen_pragma_handler handler;
+  bool extra_data;
+  void * data;
+};
+typedef struct internal_pragma_handler_d internal_pragma_handler;
+
+extern void c_register_pragma (const char * space, const char * name,
+                               pragma_handler_1arg handler);
+extern void c_register_pragma_with_data (const char * space, const char * name,
+                                         pragma_handler_2arg handler,
+                                         void * data);
+
+extern void c_register_pragma_with_expansion (const char * space,
+                                              const char * name,
+                                              pragma_handler_1arg handler);
+extern void c_register_pragma_with_expansion_and_data (const char * space,
+                                                       const char * name,
+                                                   pragma_handler_2arg handler,
+                                                       void * data);
 extern void c_invoke_pragma_handler (unsigned int);
 
 extern void maybe_apply_pragma_weak (tree);

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-03 15:32   ` Pierre Vittet
  2011-06-03 15:48     ` Basile Starynkevitch
@ 2011-06-08 21:35     ` Pierre Vittet
  2011-06-09  7:21       ` Basile Starynkevitch
  1 sibling, 1 reply; 14+ messages in thread
From: Pierre Vittet @ 2011-06-08 21:35 UTC (permalink / raw)
  To: gcc-patches, tromey, joseph, Basile Starynkevitch

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

I have written a test for this patch and run it (it works correctly). I 
guess there is no reason why it should not be accepted now.
To recap, this patch add a void * data field to the pragma handler, 
allowing to pass extra data. If we want to use this field, we need to 
use the function c_register_pragma_with_data or 
c_register_pragma_with_expansion_and_data. The old 
c_register_pragma(_with_expansion) is kept compatible.

I give two diff and two ChangeLog, the first are for the patch itself, 
the second are for the test.

I have tried to make things as good as possible, if there is a remark, 
please, send me it. Especially, I am not sure about the format of my 
ChangeLog, if there is an issue, I am ready to change it.

Changelog gcc:

2011-06-08  Pierre Vittet  <piervit@pvittet.com>

         * c-pragma.h (pragma_handler_1arg, pragma_handler_2arg,
         gen_pragma_handler, internal_pragma_handler, c_register_pragma,
         c_register_pragma_with_data, c_register_pragma_with_expansion,
         c_register_pragma_with_expansion_and_data): allows to add data to a
         pragma handler using a new c_register. Old c_register keep old
         behaviour for compatibility.
         * c-pragma.c (registered_pragmas, c_register_pragma_1,
         c_register_pragma, c_register_pragma_with_data,
         c_register_pragma_with_expansion,
         c_register_pragma_with_expansion_and_data, c_invoke_pragma_handler,
         init_pragma): allows to add data to a pragma handler using a new
         c_register. Old registers keep old behaviour for compatibility.

Changelog testsuite

2011-06-08  Pierre Vittet  <piervit@pvittet.com>

         * g++.dg/plugin/pragma_plugin_with_data.c: New test.


Thanks!

Pierre Vittet

[-- Attachment #2: addDataToPragmaHandler-174521.diff --]
[-- Type: text/plain, Size: 7632 bytes --]

Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -1148,12 +1148,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A
 }
 
 /* A vector of registered pragma callbacks.  */
+/* This is never freed as we need it during the whole execution.  */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
 
-DEF_VEC_O (pragma_handler);
-DEF_VEC_ALLOC_O (pragma_handler, heap);
+static VEC(internal_pragma_handler, heap) *registered_pragmas;
 
-static VEC(pragma_handler, heap) *registered_pragmas;
-
 typedef struct
 {
   const char *space;
@@ -1216,7 +1216,7 @@ c_pp_lookup_pragma (unsigned int id, const char **
 
 static void
 c_register_pragma_1 (const char *space, const char *name,
-		     pragma_handler handler, bool allow_expansion)
+                     internal_pragma_handler ihandler, bool allow_expansion)
 {
   unsigned id;
 
@@ -1235,8 +1235,9 @@ c_register_pragma_1 (const char *space, const char
     }
   else
     {
-      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-      id = VEC_length (pragma_handler, registered_pragmas);
+      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
+                     &ihandler);
+      id = VEC_length (internal_pragma_handler, registered_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
 
       /* The C++ front end allocates 6 bits in cp_token; the C front end
@@ -1248,28 +1249,90 @@ c_register_pragma_1 (const char *space, const char
 				allow_expansion, false);
 }
 
+/* Register a C pragma handler, using a space and a name.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
-c_register_pragma (const char *space, const char *name, pragma_handler handler)
+c_register_pragma (const char *space, const char *name,
+                   pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, false);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, false);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
+c_register_pragma_with_data (const char *space, const char *name,
+                             pragma_handler_2arg handler, void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, false);
+}
+
+/* Register a C pragma handler, using a space and a name.  It allows pragma
+expansion as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
+void
 c_register_pragma_with_expansion (const char *space, const char *name,
-				  pragma_handler handler)
+				  pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, true);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, true);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It allows pragma expansion
+as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
 void
+c_register_pragma_with_expansion_and_data (const char *space, const char *name,
+                                           pragma_handler_2arg handler,
+                                           void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, true);
+}
+
+void
 c_invoke_pragma_handler (unsigned int id)
 {
-  pragma_handler handler;
+  internal_pragma_handler * ihandler;
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
 
   id -= PRAGMA_FIRST_EXTERNAL;
-  handler = *VEC_index (pragma_handler, registered_pragmas, id);
-
-  handler (parse_in);
+  ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id);
+  if (ihandler->extra_data)
+    {
+      handler_2arg = ihandler->handler.handler_2arg;
+      handler_2arg (parse_in, ihandler->data);
+    }
+  else
+    {
+      handler_1arg = ihandler->handler.handler_1arg;
+      handler_1arg (parse_in);
+    }
 }
 
 /* Set up front-end pragmas.  */
@@ -1308,7 +1371,8 @@ init_pragma (void)
   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
 		     handle_pragma_float_const_decimal64);
 
-  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
+  c_register_pragma_with_expansion (0, "redefine_extname",
+                                    handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
Index: gcc/c-family/c-pragma.h
===================================================================
--- gcc/c-family/c-pragma.h	(revision 174521)
+++ gcc/c-family/c-pragma.h	(working copy)
@@ -84,10 +84,39 @@ extern bool pop_visibility (int);
 extern void init_pragma (void);
 
 /* Front-end wrappers for pragma registration.  */
-typedef void (*pragma_handler)(struct cpp_reader *);
-extern void c_register_pragma (const char *, const char *, pragma_handler);
-extern void c_register_pragma_with_expansion (const char *, const char *,
-					      pragma_handler);
+typedef void (*pragma_handler_1arg)(struct cpp_reader *);
+/* A second pragma handler, which adds a void * argument allowing to pass extra
+data to the handler.  */
+typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
+
+/* This union permits abstact the different handlers.  */
+union gen_pragma_handler {
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
+};
+/* Internally use to keep the data of the handler.  The field extra_data permit
+to know if handler is a pragma_handler_1arg (extra_data is false), or a
+pragma_handler_2arg (extra_data is true).  */
+struct internal_pragma_handler_d {
+  union gen_pragma_handler handler;
+  bool extra_data;
+  void * data;
+};
+typedef struct internal_pragma_handler_d internal_pragma_handler;
+
+extern void c_register_pragma (const char * space, const char * name,
+                               pragma_handler_1arg handler);
+extern void c_register_pragma_with_data (const char * space, const char * name,
+                                         pragma_handler_2arg handler,
+                                         void * data);
+
+extern void c_register_pragma_with_expansion (const char * space,
+                                              const char * name,
+                                              pragma_handler_1arg handler);
+extern void c_register_pragma_with_expansion_and_data (const char * space,
+                                                       const char * name,
+                                                   pragma_handler_2arg handler,
+                                                       void * data);
 extern void c_invoke_pragma_handler (unsigned int);
 
 extern void maybe_apply_pragma_weak (tree);

[-- Attachment #3: addDataToPragmaHandler-test-174521.diff --]
[-- Type: text/plain, Size: 4466 bytes --]

Index: gcc/testsuite/g++.dg/plugin/plugin.exp
===================================================================
--- gcc/testsuite/g++.dg/plugin/plugin.exp	(revision 174521)
+++ gcc/testsuite/g++.dg/plugin/plugin.exp	(working copy)
@@ -49,6 +49,7 @@ load_lib plugin-support.exp
 set plugin_test_list [list \
     { attribute_plugin.c attribute_plugin-test-1.C } \
     { pragma_plugin.c pragma_plugin-test-1.C } \
+    { pragma_plugin_with_data.c pragma_plugin_with_data-test-1.C } \
     { selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \
     { dumb_plugin.c dumb-plugin-test-1.C } \
     { header_plugin.c header-plugin-test.C } ]
Index: gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c
===================================================================
--- gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c	(revision 0)
@@ -0,0 +1,102 @@
+/* Test pragma adding using an extra data field. */
+
+#include "gcc-plugin.h"
+#include <stdlib.h>
+#include "function.h"
+#include "c-family/c-pragma.h"
+#include "intl.h"
+
+
+
+int plugin_is_GPL_compatible;
+
+
+
+#define GCC_PRAGMA_BAD(gmsgid) \
+  do { warning (OPT_Wpragmas, gmsgid); goto end; } while (0)
+
+/* handler of #pragma SPACE NAME command (arg1, arg2, ...) or of type 
+ * #pragma SPACE NAME command .
+ */
+
+static void
+handle_pragma_gen (cpp_reader *ARG_UNUSED(dummy), void * data)
+{
+  char * plugin_name = (char *) data;
+
+  warning (0, G_("The name of the pass: %s"),
+           plugin_name);
+
+  enum cpp_ttype token;
+  tree x;
+  const char * command;
+
+  token = pragma_lex (&x);
+  if(token != CPP_NAME)
+    GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+
+  command = IDENTIFIER_POINTER(x);
+  
+  /*If the pragma has the form #pragma SPACE NAME cmd (...) then command 
+  contains "cmd".
+  Next element should be a parenthese opening or an end of line */
+  token = pragma_lex (&x);
+  if (token != CPP_OPEN_PAREN)
+    {
+      if (token != CPP_EOF)
+      	GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+
+      else /* we have a pragma of the type '#pragma SPACE NAME command'  */
+	{
+	  /* We have recover our pragma.  */
+          warning (OPT_Wpragmas, "%<#pragma GCCPLUGIN newPragma%> a simple \
+instruction: %s", command);
+	  return;
+  	}	  
+    }
+  else
+    { /* opening parenthesis */
+      do 
+        {
+      	  token = pragma_lex (&x);
+      	  if(token != CPP_NAME && token != CPP_STRING && token != CPP_NUMBER)
+            GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+     
+      	  token = pragma_lex (&x);
+      
+        } while (token == CPP_COMMA);
+
+    if (token == CPP_CLOSE_PAREN && pragma_lex(&x) == CPP_EOF)
+      {
+        /* We have recover our pragma.  */
+        warning (OPT_Wpragmas, "%<#pragma GCCPLUGIN newPragma%> a more complex \
+instruction: %s", command);
+        return;
+      }
+    else
+      GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+    }
+end: return;
+}
+
+/* Plugin callback called during pragma registration */
+
+static void 
+register_my_pragma (void *event_data, void *data) 
+{
+  warning (0, G_("Callback to register pragmas"));
+  c_register_pragma_with_data ("GCCPLUGIN", "newPragma",
+			       handle_pragma_gen, data);
+}
+
+/* Init the plugin.  */
+int
+plugin_init (struct plugin_name_args *plugin_info,
+             struct plugin_gcc_version *version)
+{
+  const char *plugin_name = plugin_info->base_name;
+
+  register_callback (plugin_name, PLUGIN_PRAGMAS, register_my_pragma,
+	  	     (void *) plugin_name);
+  return 0;
+}
Index: gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C	(revision 0)
@@ -0,0 +1,8 @@
+// { dg-warning "Callback to register pragmas" "" { target *-*-* } 0 }
+// { dg-warning "The name of the pass: pragma_plugin_with_data" "" {target *-*-* } 5 }
+// { dg-warning "The name of the pass: pragma_plugin_with_data" "" {target *-*-* } 7 }
+
+#pragma GCCPLUGIN newPragma do_smt // { dg-warning "'#pragma GCCPLUGIN newPragma' a simple instruction: do_smt" }
+
+#pragma GCCPLUGIN newPragma do_smt_else (test ,"test", 2) // { dg-warning "'#pragma GCCPLUGIN newPragma' a more complex instruction: do_smt_else" }
+

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-08 21:35     ` Pierre Vittet
@ 2011-06-09  7:21       ` Basile Starynkevitch
  2011-06-09  9:08         ` Pierre Vittet
  0 siblings, 1 reply; 14+ messages in thread
From: Basile Starynkevitch @ 2011-06-09  7:21 UTC (permalink / raw)
  To: Pierre Vittet; +Cc: gcc-patches, tromey, joseph

On Wed, 08 Jun 2011 23:26:39 +0200
Pierre Vittet <piervit@pvittet.com> wrote:

> I have written a test for this patch and run it (it works correctly). I 
> guess there is no reason why it should not be accepted now.
> To recap, this patch add a void * data field to the pragma handler, 
> allowing to pass extra data. If we want to use this field, we need to 
> use the function c_register_pragma_with_data or 
> c_register_pragma_with_expansion_and_data. The old 
> c_register_pragma(_with_expansion) is kept compatible.


===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -1148,12 +1148,12 @@ handle_pragma_float_const_decimal64 (cpp_reader
*A }
 
 /* A vector of registered pragma callbacks.  */
+/* This is never freed as we need it during the whole execution.  */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);

Sorry to be picky Pierre, but that comment is not correct. It should be
instead.

/* A vector of registered pragma callbacks, which is never freed.   */

What I mean is that you are right that the vector is never freed, but
it is not because it is needed during the entire execution, since
middle-end and back-end passes don't know about pragmas.

I hope your patch will be ok-ed with that small change.

Perhaps a future patch would free that registered_pragmas vector, but I
feel that is not necessary, since it is not a big vector in practice.

Regards.

-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mine, sont seulement les miennes} ***

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-09  7:21       ` Basile Starynkevitch
@ 2011-06-09  9:08         ` Pierre Vittet
  2011-06-09 14:53           ` Joseph S. Myers
  0 siblings, 1 reply; 14+ messages in thread
From: Pierre Vittet @ 2011-06-09  9:08 UTC (permalink / raw)
  To: gcc-patches; +Cc: tromey, joseph, Basile Starynkevitch

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

You are right, the new version is in the diff.
The diff for the test hasn't changed and is in the previous mail.

In the previous version of the file, the registered_pragmas was not 
better freed. I don't know if it is really important (it would need a 
callback at the end of the front-end passes).

Thanks.



On 09/06/2011 08:16, Basile Starynkevitch wrote:
> On Wed, 08 Jun 2011 23:26:39 +0200
> Pierre Vittet<piervit@pvittet.com>  wrote:
>
>    
>> I have written a test for this patch and run it (it works correctly). I
>> guess there is no reason why it should not be accepted now.
>> To recap, this patch add a void * data field to the pragma handler,
>> allowing to pass extra data. If we want to use this field, we need to
>> use the function c_register_pragma_with_data or
>> c_register_pragma_with_expansion_and_data. The old
>> c_register_pragma(_with_expansion) is kept compatible.
>>      
>
> ===================================================================
> --- gcc/c-family/c-pragma.c	(revision 174521)
> +++ gcc/c-family/c-pragma.c	(working copy)
> @@ -1148,12 +1148,12 @@ handle_pragma_float_const_decimal64 (cpp_reader
> *A }
>
>   /* A vector of registered pragma callbacks.  */
> +/* This is never freed as we need it during the whole execution.  */
> +DEF_VEC_O (internal_pragma_handler);
> +DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
>
> Sorry to be picky Pierre, but that comment is not correct. It should be
> instead.
>
> /* A vector of registered pragma callbacks, which is never freed.   */
>
> What I mean is that you are right that the vector is never freed, but
> it is not because it is needed during the entire execution, since
> middle-end and back-end passes don't know about pragmas.
>
> I hope your patch will be ok-ed with that small change.
>
> Perhaps a future patch would free that registered_pragmas vector, but I
> feel that is not necessary, since it is not a big vector in practice.
>
> Regards.
>
>    


[-- Attachment #2: addDataToPragmaHandler-174521.diff --]
[-- Type: text/plain, Size: 7641 bytes --]

Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -1147,13 +1147,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A
     }
 }
 
-/* A vector of registered pragma callbacks.  */
+/* A vector of registered pragma callbacks, which is never freed.   */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
 
-DEF_VEC_O (pragma_handler);
-DEF_VEC_ALLOC_O (pragma_handler, heap);
+static VEC(internal_pragma_handler, heap) *registered_pragmas;
 
-static VEC(pragma_handler, heap) *registered_pragmas;
-
 typedef struct
 {
   const char *space;
@@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char **
 
 static void
 c_register_pragma_1 (const char *space, const char *name,
-		     pragma_handler handler, bool allow_expansion)
+                     internal_pragma_handler ihandler, bool allow_expansion)
 {
   unsigned id;
 
@@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char
     }
   else
     {
-      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-      id = VEC_length (pragma_handler, registered_pragmas);
+      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
+                     &ihandler);
+      id = VEC_length (internal_pragma_handler, registered_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
 
       /* The C++ front end allocates 6 bits in cp_token; the C front end
@@ -1248,28 +1248,90 @@ c_register_pragma_1 (const char *space, const char
 				allow_expansion, false);
 }
 
+/* Register a C pragma handler, using a space and a name.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
-c_register_pragma (const char *space, const char *name, pragma_handler handler)
+c_register_pragma (const char *space, const char *name,
+                   pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, false);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, false);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It disallows pragma
+expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
+c_register_pragma_with_data (const char *space, const char *name,
+                             pragma_handler_2arg handler, void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, false);
+}
+
+/* Register a C pragma handler, using a space and a name.  It allows pragma
+expansion as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
+void
 c_register_pragma_with_expansion (const char *space, const char *name,
-				  pragma_handler handler)
+				  pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, true);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, true);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+extra data field which can be used by the handler.  It allows pragma expansion
+as in the following exemple:
+  #define NUMBER 10
+  #pragma count (NUMBER)
+Name expansion is still disallowed.  */
 void
+c_register_pragma_with_expansion_and_data (const char *space, const char *name,
+                                           pragma_handler_2arg handler,
+                                           void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, true);
+}
+
+void
 c_invoke_pragma_handler (unsigned int id)
 {
-  pragma_handler handler;
+  internal_pragma_handler * ihandler;
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
 
   id -= PRAGMA_FIRST_EXTERNAL;
-  handler = *VEC_index (pragma_handler, registered_pragmas, id);
-
-  handler (parse_in);
+  ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id);
+  if (ihandler->extra_data)
+    {
+      handler_2arg = ihandler->handler.handler_2arg;
+      handler_2arg (parse_in, ihandler->data);
+    }
+  else
+    {
+      handler_1arg = ihandler->handler.handler_1arg;
+      handler_1arg (parse_in);
+    }
 }
 
 /* Set up front-end pragmas.  */
@@ -1308,7 +1370,8 @@ init_pragma (void)
   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
 		     handle_pragma_float_const_decimal64);
 
-  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
+  c_register_pragma_with_expansion (0, "redefine_extname",
+                                    handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
Index: gcc/c-family/c-pragma.h
===================================================================
--- gcc/c-family/c-pragma.h	(revision 174521)
+++ gcc/c-family/c-pragma.h	(working copy)
@@ -84,10 +84,39 @@ extern bool pop_visibility (int);
 extern void init_pragma (void);
 
 /* Front-end wrappers for pragma registration.  */
-typedef void (*pragma_handler)(struct cpp_reader *);
-extern void c_register_pragma (const char *, const char *, pragma_handler);
-extern void c_register_pragma_with_expansion (const char *, const char *,
-					      pragma_handler);
+typedef void (*pragma_handler_1arg)(struct cpp_reader *);
+/* A second pragma handler, which adds a void * argument allowing to pass extra
+data to the handler.  */
+typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
+
+/* This union permits abstact the different handlers.  */
+union gen_pragma_handler {
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
+};
+/* Internally use to keep the data of the handler.  The field extra_data permit
+to know if handler is a pragma_handler_1arg (extra_data is false), or a
+pragma_handler_2arg (extra_data is true).  */
+struct internal_pragma_handler_d {
+  union gen_pragma_handler handler;
+  bool extra_data;
+  void * data;
+};
+typedef struct internal_pragma_handler_d internal_pragma_handler;
+
+extern void c_register_pragma (const char * space, const char * name,
+                               pragma_handler_1arg handler);
+extern void c_register_pragma_with_data (const char * space, const char * name,
+                                         pragma_handler_2arg handler,
+                                         void * data);
+
+extern void c_register_pragma_with_expansion (const char * space,
+                                              const char * name,
+                                              pragma_handler_1arg handler);
+extern void c_register_pragma_with_expansion_and_data (const char * space,
+                                                       const char * name,
+                                                   pragma_handler_2arg handler,
+                                                       void * data);
 extern void c_invoke_pragma_handler (unsigned int);
 
 extern void maybe_apply_pragma_weak (tree);

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-09  9:08         ` Pierre Vittet
@ 2011-06-09 14:53           ` Joseph S. Myers
  2011-06-10  9:17             ` Pierre Vittet
  0 siblings, 1 reply; 14+ messages in thread
From: Joseph S. Myers @ 2011-06-09 14:53 UTC (permalink / raw)
  To: Pierre Vittet; +Cc: gcc-patches, tromey, Basile Starynkevitch

Thanks for this patch.  You need to adjust the formatting of the comments 
to match the existing style (in particular, indentation of second and 
subsequent lines of comments, and watch out for spelling errors (exemple, 
abstact).  For a struct, the explanations of individual fields should be 
in the comments on those fields rather than at the top of the struct.  The 
comment on c_register_pragma_with_data should refer to 
c_register_pragma_with_expansion_and_data rather than 
c_register_pragma_with_expansion.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-09 14:53           ` Joseph S. Myers
@ 2011-06-10  9:17             ` Pierre Vittet
  2011-06-10 14:02               ` Joseph S. Myers
  0 siblings, 1 reply; 14+ messages in thread
From: Pierre Vittet @ 2011-06-10  9:17 UTC (permalink / raw)
  To: gcc-patches; +Cc: joseph, tromey, Basile Starynkevitch

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

thanks!

I formatted as you requested.

I cannot commit myself as I haven't a  "write after approval" status, 
maye you can do it, or I can wait my GSOC mentor, Basile Starynkevitch 
to do this (He mights be busy for a few days).

Pierre Vittet


[-- Attachment #2: addDataToPragmaHandler-174521.diff --]
[-- Type: text/plain, Size: 7743 bytes --]

Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -1147,13 +1147,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A
     }
 }
 
-/* A vector of registered pragma callbacks.  */
+/* A vector of registered pragma callbacks, which is never freed.   */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
 
-DEF_VEC_O (pragma_handler);
-DEF_VEC_ALLOC_O (pragma_handler, heap);
+static VEC(internal_pragma_handler, heap) *registered_pragmas;
 
-static VEC(pragma_handler, heap) *registered_pragmas;
-
 typedef struct
 {
   const char *space;
@@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char **
 
 static void
 c_register_pragma_1 (const char *space, const char *name,
-		     pragma_handler handler, bool allow_expansion)
+                     internal_pragma_handler ihandler, bool allow_expansion)
 {
   unsigned id;
 
@@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char
     }
   else
     {
-      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-      id = VEC_length (pragma_handler, registered_pragmas);
+      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
+                     &ihandler);
+      id = VEC_length (internal_pragma_handler, registered_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
 
       /* The C++ front end allocates 6 bits in cp_token; the C front end
@@ -1248,28 +1248,95 @@ c_register_pragma_1 (const char *space, const char
 				allow_expansion, false);
 }
 
+/* Register a C pragma handler, using a space and a name.  It disallows pragma
+   expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
-c_register_pragma (const char *space, const char *name, pragma_handler handler)
+c_register_pragma (const char *space, const char *name,
+                   pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, false);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, false);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+   extra data field which can be used by the handler.  It disallows pragma
+   expansion (if you want it, use c_register_pragma_with_expansion_and_data
+   instead).  */
 void
+c_register_pragma_with_data (const char *space, const char *name,
+                             pragma_handler_2arg handler, void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, false);
+}
+
+/* Register a C pragma handler, using a space and a name.  It allows pragma
+   expansion as in the following example:
+
+   #define NUMBER 10
+   #pragma count (NUMBER)
+
+   Name expansion is still disallowed.  */
+void
 c_register_pragma_with_expansion (const char *space, const char *name,
-				  pragma_handler handler)
+				  pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, true);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, true);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+   extra data field which can be used by the handler.  It allows pragma
+   expansion as in the following example:
+
+   #define NUMBER 10
+   #pragma count (NUMBER)
+
+   Name expansion is still disallowed.  */
 void
+c_register_pragma_with_expansion_and_data (const char *space, const char *name,
+                                           pragma_handler_2arg handler,
+                                           void *data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, true);
+}
+
+void
 c_invoke_pragma_handler (unsigned int id)
 {
-  pragma_handler handler;
+  internal_pragma_handler *ihandler;
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
 
   id -= PRAGMA_FIRST_EXTERNAL;
-  handler = *VEC_index (pragma_handler, registered_pragmas, id);
-
-  handler (parse_in);
+  ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id);
+  if (ihandler->extra_data)
+    {
+      handler_2arg = ihandler->handler.handler_2arg;
+      handler_2arg (parse_in, ihandler->data);
+    }
+  else
+    {
+      handler_1arg = ihandler->handler.handler_1arg;
+      handler_1arg (parse_in);
+    }
 }
 
 /* Set up front-end pragmas.  */
@@ -1308,7 +1375,8 @@ init_pragma (void)
   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
 		     handle_pragma_float_const_decimal64);
 
-  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
+  c_register_pragma_with_expansion (0, "redefine_extname",
+                                    handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
Index: gcc/c-family/c-pragma.h
===================================================================
--- gcc/c-family/c-pragma.h	(revision 174521)
+++ gcc/c-family/c-pragma.h	(working copy)
@@ -84,10 +84,40 @@ extern bool pop_visibility (int);
 extern void init_pragma (void);
 
 /* Front-end wrappers for pragma registration.  */
-typedef void (*pragma_handler)(struct cpp_reader *);
-extern void c_register_pragma (const char *, const char *, pragma_handler);
-extern void c_register_pragma_with_expansion (const char *, const char *,
-					      pragma_handler);
+typedef void (*pragma_handler_1arg)(struct cpp_reader *);
+/* A second pragma handler, which adds a void * argument allowing to pass extra
+   data to the handler.  */
+typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
+
+/* This union allows to abstract the different handlers.  */
+union gen_pragma_handler {
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
+};
+/* Internally used to keep the data of the handler.  */
+struct internal_pragma_handler_d {
+  union gen_pragma_handler handler;
+  /* Permits to know if handler is a pragma_handler_1arg (extra_data is false)
+     or a pragma_handler_2arg (extra_data is true).  */
+  bool extra_data;
+  /* A data field which can be used when extra_data is true.  */
+  void * data;
+};
+typedef struct internal_pragma_handler_d internal_pragma_handler;
+
+extern void c_register_pragma (const char *space, const char *name,
+                               pragma_handler_1arg handler);
+extern void c_register_pragma_with_data (const char *space, const char *name,
+                                         pragma_handler_2arg handler,
+                                         void *data);
+
+extern void c_register_pragma_with_expansion (const char *space,
+                                              const char *name,
+                                              pragma_handler_1arg handler);
+extern void c_register_pragma_with_expansion_and_data (const char *space,
+                                                       const char *name,
+                                                   pragma_handler_2arg handler,
+                                                       void *data);
 extern void c_invoke_pragma_handler (unsigned int);
 
 extern void maybe_apply_pragma_weak (tree);

[-- Attachment #3: addDataToPragmaHandler-test-174521.diff --]
[-- Type: text/plain, Size: 4485 bytes --]

Index: gcc/testsuite/g++.dg/plugin/plugin.exp
===================================================================
--- gcc/testsuite/g++.dg/plugin/plugin.exp	(revision 174521)
+++ gcc/testsuite/g++.dg/plugin/plugin.exp	(working copy)
@@ -49,6 +49,7 @@ load_lib plugin-support.exp
 set plugin_test_list [list \
     { attribute_plugin.c attribute_plugin-test-1.C } \
     { pragma_plugin.c pragma_plugin-test-1.C } \
+    { pragma_plugin_with_data.c pragma_plugin_with_data-test-1.C } \
     { selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \
     { dumb_plugin.c dumb-plugin-test-1.C } \
     { header_plugin.c header-plugin-test.C } ]
Index: gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c
===================================================================
--- gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c	(revision 0)
@@ -0,0 +1,100 @@
+/* Test pragma adding using an extra data field.  */
+
+#include "gcc-plugin.h"
+#include <stdlib.h>
+#include "function.h"
+#include "c-family/c-pragma.h"
+#include "intl.h"
+
+
+
+int plugin_is_GPL_compatible;
+
+
+
+#define GCC_PRAGMA_BAD (gmsgid) \
+  do { warning (OPT_Wpragmas, gmsgid); goto end; } while (0)
+
+/* handler of #pragma SPACE NAME command (arg1, arg2, ...) or of type
+   #pragma SPACE NAME command.  */
+static void
+handle_pragma_gen (cpp_reader *ARG_UNUSED (dummy), void *data)
+{
+  char *plugin_name = (char *) data;
+
+  warning (0, G_("The name of the pass: %s"),
+           plugin_name);
+
+  enum cpp_ttype token;
+  tree x;
+  const char *command;
+
+  token = pragma_lex (&x);
+  if (token != CPP_NAME)
+    GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+
+  command = IDENTIFIER_POINTER (x);
+
+  /* If the pragma has the form #pragma SPACE NAME cmd (...) then command
+     contains "cmd".  Next element should be a parenthese opening or an end of
+     line.  */
+  token = pragma_lex (&x);
+  if (token != CPP_OPEN_PAREN)
+    {
+      if (token != CPP_EOF)
+      	GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+
+      else /* we have a pragma of the type '#pragma SPACE NAME command'.  */
+	{
+	  /* We have recovered our pragma.  */
+          warning (OPT_Wpragmas, "%<#pragma GCCPLUGIN newPragma%> a simple \
+instruction: %s", command);
+	  return;
+  	}
+    }
+  else
+    { /* opening parenthesis.  */
+      do
+        {
+      	  token = pragma_lex (&x);
+      	  if (token != CPP_NAME && token != CPP_STRING && token != CPP_NUMBER)
+            GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+      	  token = pragma_lex (&x);
+        } while (token == CPP_COMMA);
+
+    if (token == CPP_CLOSE_PAREN && pragma_lex (&x) == CPP_EOF)
+      {
+        /* We have recovered our pragma.  */
+        warning (OPT_Wpragmas, "%<#pragma GCCPLUGIN newPragma%> a more complex \
+instruction: %s", command);
+        return;
+      }
+    else
+      GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+    }
+end: return;
+}
+
+/* Plugin callback called during pragma registration.  */
+
+static void
+register_my_pragma (void *event_data, void *data)
+{
+  warning (0, G_("Callback to register pragmas"));
+  c_register_pragma_with_data ("GCCPLUGIN", "newPragma",
+			       handle_pragma_gen, data);
+}
+
+/* Init the plugin.  */
+int
+plugin_init (struct plugin_name_args *plugin_info,
+             struct plugin_gcc_version *version)
+{
+  const char *plugin_name = plugin_info->base_name;
+
+  register_callback (plugin_name, PLUGIN_PRAGMAS, register_my_pragma,
+	  	     (void *) plugin_name);
+  return 0;
+}
+
+#undef GCC_PRAGMA_BAD
Index: gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C	(revision 0)
@@ -0,0 +1,8 @@
+// { dg-warning "Callback to register pragmas" "" { target *-*-* } 0 }
+// { dg-warning "The name of the pass: pragma_plugin_with_data" "" {target *-*-* } 5 }
+// { dg-warning "The name of the pass: pragma_plugin_with_data" "" {target *-*-* } 7 }
+
+#pragma GCCPLUGIN newPragma do_smt // { dg-warning "'#pragma GCCPLUGIN newPragma' a simple instruction: do_smt" }
+
+#pragma GCCPLUGIN newPragma do_smt_else (test ,"test", 2) // { dg-warning "'#pragma GCCPLUGIN newPragma' a more complex instruction: do_smt_else" }
+

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-10  9:17             ` Pierre Vittet
@ 2011-06-10 14:02               ` Joseph S. Myers
  2011-06-10 16:15                 ` Pierre Vittet
  0 siblings, 1 reply; 14+ messages in thread
From: Joseph S. Myers @ 2011-06-10 14:02 UTC (permalink / raw)
  To: Pierre Vittet; +Cc: gcc-patches, tromey, Basile Starynkevitch

Please make sure that with each revision you include *both* the patch 
*and* the ChangeLog entries so they can be reviewed together.  The last 
version of the ChangeLog entries that I saw still needed more work to 
follow the normal style for ChangeLog entries.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-10 14:02               ` Joseph S. Myers
@ 2011-06-10 16:15                 ` Pierre Vittet
  2011-06-15 15:10                   ` Joseph S. Myers
  0 siblings, 1 reply; 14+ messages in thread
From: Pierre Vittet @ 2011-06-10 16:15 UTC (permalink / raw)
  To: gcc-patches; +Cc: joseph, Basile Starynkevitch

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

I guess this is better now.

Changelog (gcc/c-family):

2011-06-10  Pierre Vittet <piervit@pvittet.com>

     * c-pragma.h (pragma_handler_1arg, pragma_handler_2arg): New handler.
     (gen_pragma_handler): New union.
     (internal_pragma_handler): New type.
     (c_register_pragma_with_data,
     c_register_pragma_with_expansion_and_data): New functions.
     * c-pragma.c (registered_pragmas, c_register_pragma_1,
     c_register_pragma, c_register_pragma_with_expansion,
     c_invoke_pragma_handler): Changed to work with internal_pragma_handler.
     (c_register_pragma_with_data,
     c_register_pragma_with_expansion_and_data): New functions.

Changelog (gcc/testsuite):

2011-06-10  Pierre Vittet <piervit@pvittet.com>

     * g++.dg/plugin/pragma_plugin_with_data.c: New test file.
     * g++.dg/plugin/pragma_plugin_with_data-test-1.C: New test file.
     * g++.dg/plugin/plugin.exp (plugin_test_list): Add the new test


[-- Attachment #2: addDataToPragmaHandler-174521.diff --]
[-- Type: text/plain, Size: 7743 bytes --]

Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 174521)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -1147,13 +1147,12 @@ handle_pragma_float_const_decimal64 (cpp_reader *A
     }
 }
 
-/* A vector of registered pragma callbacks.  */
+/* A vector of registered pragma callbacks, which is never freed.   */
+DEF_VEC_O (internal_pragma_handler);
+DEF_VEC_ALLOC_O (internal_pragma_handler, heap);
 
-DEF_VEC_O (pragma_handler);
-DEF_VEC_ALLOC_O (pragma_handler, heap);
+static VEC(internal_pragma_handler, heap) *registered_pragmas;
 
-static VEC(pragma_handler, heap) *registered_pragmas;
-
 typedef struct
 {
   const char *space;
@@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char **
 
 static void
 c_register_pragma_1 (const char *space, const char *name,
-		     pragma_handler handler, bool allow_expansion)
+                     internal_pragma_handler ihandler, bool allow_expansion)
 {
   unsigned id;
 
@@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char
     }
   else
     {
-      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-      id = VEC_length (pragma_handler, registered_pragmas);
+      VEC_safe_push (internal_pragma_handler, heap, registered_pragmas,
+                     &ihandler);
+      id = VEC_length (internal_pragma_handler, registered_pragmas);
       id += PRAGMA_FIRST_EXTERNAL - 1;
 
       /* The C++ front end allocates 6 bits in cp_token; the C front end
@@ -1248,28 +1248,95 @@ c_register_pragma_1 (const char *space, const char
 				allow_expansion, false);
 }
 
+/* Register a C pragma handler, using a space and a name.  It disallows pragma
+   expansion (if you want it, use c_register_pragma_with_expansion instead).  */
 void
-c_register_pragma (const char *space, const char *name, pragma_handler handler)
+c_register_pragma (const char *space, const char *name,
+                   pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, false);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, false);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+   extra data field which can be used by the handler.  It disallows pragma
+   expansion (if you want it, use c_register_pragma_with_expansion_and_data
+   instead).  */
 void
+c_register_pragma_with_data (const char *space, const char *name,
+                             pragma_handler_2arg handler, void * data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, false);
+}
+
+/* Register a C pragma handler, using a space and a name.  It allows pragma
+   expansion as in the following example:
+
+   #define NUMBER 10
+   #pragma count (NUMBER)
+
+   Name expansion is still disallowed.  */
+void
 c_register_pragma_with_expansion (const char *space, const char *name,
-				  pragma_handler handler)
+				  pragma_handler_1arg handler)
 {
-  c_register_pragma_1 (space, name, handler, true);
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_1arg = handler;
+  ihandler.extra_data = false;
+  ihandler.data = NULL;
+  c_register_pragma_1 (space, name, ihandler, true);
 }
 
+/* Register a C pragma handler, using a space and a name, it also carries an
+   extra data field which can be used by the handler.  It allows pragma
+   expansion as in the following example:
+
+   #define NUMBER 10
+   #pragma count (NUMBER)
+
+   Name expansion is still disallowed.  */
 void
+c_register_pragma_with_expansion_and_data (const char *space, const char *name,
+                                           pragma_handler_2arg handler,
+                                           void *data)
+{
+  internal_pragma_handler ihandler;
+
+  ihandler.handler.handler_2arg = handler;
+  ihandler.extra_data = true;
+  ihandler.data = data;
+  c_register_pragma_1 (space, name, ihandler, true);
+}
+
+void
 c_invoke_pragma_handler (unsigned int id)
 {
-  pragma_handler handler;
+  internal_pragma_handler *ihandler;
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
 
   id -= PRAGMA_FIRST_EXTERNAL;
-  handler = *VEC_index (pragma_handler, registered_pragmas, id);
-
-  handler (parse_in);
+  ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id);
+  if (ihandler->extra_data)
+    {
+      handler_2arg = ihandler->handler.handler_2arg;
+      handler_2arg (parse_in, ihandler->data);
+    }
+  else
+    {
+      handler_1arg = ihandler->handler.handler_1arg;
+      handler_1arg (parse_in);
+    }
 }
 
 /* Set up front-end pragmas.  */
@@ -1308,7 +1375,8 @@ init_pragma (void)
   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
 		     handle_pragma_float_const_decimal64);
 
-  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
+  c_register_pragma_with_expansion (0, "redefine_extname",
+                                    handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
Index: gcc/c-family/c-pragma.h
===================================================================
--- gcc/c-family/c-pragma.h	(revision 174521)
+++ gcc/c-family/c-pragma.h	(working copy)
@@ -84,10 +84,40 @@ extern bool pop_visibility (int);
 extern void init_pragma (void);
 
 /* Front-end wrappers for pragma registration.  */
-typedef void (*pragma_handler)(struct cpp_reader *);
-extern void c_register_pragma (const char *, const char *, pragma_handler);
-extern void c_register_pragma_with_expansion (const char *, const char *,
-					      pragma_handler);
+typedef void (*pragma_handler_1arg)(struct cpp_reader *);
+/* A second pragma handler, which adds a void * argument allowing to pass extra
+   data to the handler.  */
+typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
+
+/* This union allows to abstract the different handlers.  */
+union gen_pragma_handler {
+  pragma_handler_1arg handler_1arg;
+  pragma_handler_2arg handler_2arg;
+};
+/* Internally used to keep the data of the handler.  */
+struct internal_pragma_handler_d {
+  union gen_pragma_handler handler;
+  /* Permits to know if handler is a pragma_handler_1arg (extra_data is false)
+     or a pragma_handler_2arg (extra_data is true).  */
+  bool extra_data;
+  /* A data field which can be used when extra_data is true.  */
+  void * data;
+};
+typedef struct internal_pragma_handler_d internal_pragma_handler;
+
+extern void c_register_pragma (const char *space, const char *name,
+                               pragma_handler_1arg handler);
+extern void c_register_pragma_with_data (const char *space, const char *name,
+                                         pragma_handler_2arg handler,
+                                         void *data);
+
+extern void c_register_pragma_with_expansion (const char *space,
+                                              const char *name,
+                                              pragma_handler_1arg handler);
+extern void c_register_pragma_with_expansion_and_data (const char *space,
+                                                       const char *name,
+                                                   pragma_handler_2arg handler,
+                                                       void *data);
 extern void c_invoke_pragma_handler (unsigned int);
 
 extern void maybe_apply_pragma_weak (tree);

[-- Attachment #3: addDataToPragmaHandler-test-174521.diff --]
[-- Type: text/plain, Size: 4485 bytes --]

Index: gcc/testsuite/g++.dg/plugin/plugin.exp
===================================================================
--- gcc/testsuite/g++.dg/plugin/plugin.exp	(revision 174521)
+++ gcc/testsuite/g++.dg/plugin/plugin.exp	(working copy)
@@ -49,6 +49,7 @@ load_lib plugin-support.exp
 set plugin_test_list [list \
     { attribute_plugin.c attribute_plugin-test-1.C } \
     { pragma_plugin.c pragma_plugin-test-1.C } \
+    { pragma_plugin_with_data.c pragma_plugin_with_data-test-1.C } \
     { selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \
     { dumb_plugin.c dumb-plugin-test-1.C } \
     { header_plugin.c header-plugin-test.C } ]
Index: gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c
===================================================================
--- gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data.c	(revision 0)
@@ -0,0 +1,100 @@
+/* Test pragma adding using an extra data field.  */
+
+#include "gcc-plugin.h"
+#include <stdlib.h>
+#include "function.h"
+#include "c-family/c-pragma.h"
+#include "intl.h"
+
+
+
+int plugin_is_GPL_compatible;
+
+
+
+#define GCC_PRAGMA_BAD (gmsgid) \
+  do { warning (OPT_Wpragmas, gmsgid); goto end; } while (0)
+
+/* handler of #pragma SPACE NAME command (arg1, arg2, ...) or of type
+   #pragma SPACE NAME command.  */
+static void
+handle_pragma_gen (cpp_reader *ARG_UNUSED (dummy), void *data)
+{
+  char *plugin_name = (char *) data;
+
+  warning (0, G_("The name of the pass: %s"),
+           plugin_name);
+
+  enum cpp_ttype token;
+  tree x;
+  const char *command;
+
+  token = pragma_lex (&x);
+  if (token != CPP_NAME)
+    GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+
+  command = IDENTIFIER_POINTER (x);
+
+  /* If the pragma has the form #pragma SPACE NAME cmd (...) then command
+     contains "cmd".  Next element should be a parenthese opening or an end of
+     line.  */
+  token = pragma_lex (&x);
+  if (token != CPP_OPEN_PAREN)
+    {
+      if (token != CPP_EOF)
+      	GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+
+      else /* we have a pragma of the type '#pragma SPACE NAME command'.  */
+	{
+	  /* We have recovered our pragma.  */
+          warning (OPT_Wpragmas, "%<#pragma GCCPLUGIN newPragma%> a simple \
+instruction: %s", command);
+	  return;
+  	}
+    }
+  else
+    { /* opening parenthesis.  */
+      do
+        {
+      	  token = pragma_lex (&x);
+      	  if (token != CPP_NAME && token != CPP_STRING && token != CPP_NUMBER)
+            GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+      	  token = pragma_lex (&x);
+        } while (token == CPP_COMMA);
+
+    if (token == CPP_CLOSE_PAREN && pragma_lex (&x) == CPP_EOF)
+      {
+        /* We have recovered our pragma.  */
+        warning (OPT_Wpragmas, "%<#pragma GCCPLUGIN newPragma%> a more complex \
+instruction: %s", command);
+        return;
+      }
+    else
+      GCC_PRAGMA_BAD ("malformed #pragma melt, ignored");
+    }
+end: return;
+}
+
+/* Plugin callback called during pragma registration.  */
+
+static void
+register_my_pragma (void *event_data, void *data)
+{
+  warning (0, G_("Callback to register pragmas"));
+  c_register_pragma_with_data ("GCCPLUGIN", "newPragma",
+			       handle_pragma_gen, data);
+}
+
+/* Init the plugin.  */
+int
+plugin_init (struct plugin_name_args *plugin_info,
+             struct plugin_gcc_version *version)
+{
+  const char *plugin_name = plugin_info->base_name;
+
+  register_callback (plugin_name, PLUGIN_PRAGMAS, register_my_pragma,
+	  	     (void *) plugin_name);
+  return 0;
+}
+
+#undef GCC_PRAGMA_BAD
Index: gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C
===================================================================
--- gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/pragma_plugin_with_data-test-1.C	(revision 0)
@@ -0,0 +1,8 @@
+// { dg-warning "Callback to register pragmas" "" { target *-*-* } 0 }
+// { dg-warning "The name of the pass: pragma_plugin_with_data" "" {target *-*-* } 5 }
+// { dg-warning "The name of the pass: pragma_plugin_with_data" "" {target *-*-* } 7 }
+
+#pragma GCCPLUGIN newPragma do_smt // { dg-warning "'#pragma GCCPLUGIN newPragma' a simple instruction: do_smt" }
+
+#pragma GCCPLUGIN newPragma do_smt_else (test ,"test", 2) // { dg-warning "'#pragma GCCPLUGIN newPragma' a more complex instruction: do_smt_else" }
+

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

* Re: [PATCH] c-pragma: adding a data field to pragma_handler
  2011-06-10 16:15                 ` Pierre Vittet
@ 2011-06-15 15:10                   ` Joseph S. Myers
  0 siblings, 0 replies; 14+ messages in thread
From: Joseph S. Myers @ 2011-06-15 15:10 UTC (permalink / raw)
  To: Pierre Vittet; +Cc: gcc-patches, Basile Starynkevitch

On Fri, 10 Jun 2011, Pierre Vittet wrote:

> I guess this is better now.
> 
> Changelog (gcc/c-family):
> 
> 2011-06-10  Pierre Vittet <piervit@pvittet.com>
> 
>     * c-pragma.h (pragma_handler_1arg, pragma_handler_2arg): New handler.
>     (gen_pragma_handler): New union.
>     (internal_pragma_handler): New type.
>     (c_register_pragma_with_data,
>     c_register_pragma_with_expansion_and_data): New functions.
>     * c-pragma.c (registered_pragmas, c_register_pragma_1,
>     c_register_pragma, c_register_pragma_with_expansion,
>     c_invoke_pragma_handler): Changed to work with internal_pragma_handler.
>     (c_register_pragma_with_data,
>     c_register_pragma_with_expansion_and_data): New functions.

Thanks.  The c-family changes are OK if you remove the last patch hunk in 
c-pragma.c (which just reformats existing code); that hunk is OK as a 
separate commit with its own ChangeLog entry, since lines shouldn't be 
wider than 80 columns.  The testsuite changes will need to be approved by 
a plugin maintainer (or a global reviewer) if they haven't already been so 
approved.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

end of thread, other threads:[~2011-06-15 14:15 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-01 16:55 [PATCH] c-pragma: adding a data field to pragma_handler Pierre
2011-06-01 17:54 ` Basile Starynkevitch
2011-06-02 17:52 ` Tom Tromey
2011-06-03 15:32   ` Pierre Vittet
2011-06-03 15:48     ` Basile Starynkevitch
2011-06-03 20:25       ` Pierre Vittet
2011-06-08 21:35     ` Pierre Vittet
2011-06-09  7:21       ` Basile Starynkevitch
2011-06-09  9:08         ` Pierre Vittet
2011-06-09 14:53           ` Joseph S. Myers
2011-06-10  9:17             ` Pierre Vittet
2011-06-10 14:02               ` Joseph S. Myers
2011-06-10 16:15                 ` Pierre Vittet
2011-06-15 15:10                   ` Joseph S. Myers

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