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


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

Reply via email to