Patchwork c-pragma: adding a data field to pragma_handler

login
register
mail settings
Submitter Pierre Vittet
Date June 3, 2011, 3:31 p.m.
Message ID <4DE8FE4D.6050404@pvittet.com>
Download mbox | patch
Permalink /patch/98597/
State New
Headers show

Comments

Pierre Vittet - June 3, 2011, 3:31 p.m.
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
>
Basile Starynkevitch - June 3, 2011, 3:47 p.m.
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

Patch

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