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.vit...@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


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

Reply via email to