From patchwork Thu Jun 9 09:00:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Vittet X-Patchwork-Id: 99678 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 5AFE6B6FC3 for ; Thu, 9 Jun 2011 19:00:32 +1000 (EST) Received: (qmail 9335 invoked by alias); 9 Jun 2011 09:00:30 -0000 Received: (qmail 9322 invoked by uid 22791); 9 Jun 2011 09:00:27 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from 97.mail-out.ovh.net (HELO 97.mail-out.ovh.net) (91.121.185.90) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 09 Jun 2011 09:00:10 +0000 Received: from mail618.ha.ovh.net (b6.ovh.net [213.186.33.56]) by 97.mail-out.ovh.net (Postfix) with SMTP id E09094AA2B3 for ; Thu, 9 Jun 2011 11:00:42 +0200 (CEST) Received: from b0.ovh.net (HELO queueout) (213.186.33.50) by b0.ovh.net with SMTP; 9 Jun 2011 11:00:09 +0200 Received: from unknown (HELO ?172.25.1.160?) (piervit@pvittet.com@193.52.208.97) by ns0.ovh.net with SMTP; 9 Jun 2011 11:00:07 +0200 Message-ID: <4DF08B94.1010804@pvittet.com> Date: Thu, 09 Jun 2011 11:00:04 +0200 From: Pierre Vittet User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100515 Lightning/1.0b1 Icedove/3.0.4 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org CC: tromey@redhat.com, joseph@codesourcery.com, Basile Starynkevitch Subject: Re: [PATCH] c-pragma: adding a data field to pragma_handler References: <4DE66ECE.5030102@laposte.net> <4DE8FE4D.6050404@pvittet.com> <4DEFE90F.5020607@pvittet.com> <20110609081635.6a3c0ad2.basile@starynkevitch.net> In-Reply-To: <20110609081635.6a3c0ad2.basile@starynkevitch.net> X-Ovh-Tracer-Id: 10058508293344788638 X-Ovh-Remote: 193.52.208.97 () X-Ovh-Local: 213.186.33.20 (ns0.ovh.net) X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -200 X-VR-SPAMCAUSE: Vade Retro 01.320.21 AV+AS Profile: OVH; Bailout: 300; @!Recipients (-100); (-100) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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);