Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-22 Thread Dodji Seketeli
Hello Romain,

Sorry for my late reply to this thread.

Romain Geissler romain.geiss...@st.com a écrit:

 Just to be sure I understand, do you need to be notified about *uses* of
 types and decls as well?  If so, maybe a new kind of event should
 probably be defined, because PLUGIN_FINISH_DECL and PLUGIN_FINISH_TYPE
 seem to have more to do with declaring/defining decls and types than
 using them.


 Personally i don't need to catch all struct uses, but i need to catch struct 
 declarations.
 I want to apply some __attributes__ to a given struct type, for
 example let's say i need to mark *struct my_struct* as deprecated
 thanks to a plugin. I know how to apply some attributes to a type or a
 decl. See the plugin (test_plugin.c) and the test files attached.

 With test_pass.c, my_struct is declared first, then defined after,
 applying the deprecated attribute works.
 With test_fail.c, my_struct is declared and defined at the same time,
 applying the deprecated attribute doesn't work with the current trunk
 (and also with my patch).
 I got:
 test_fail.c:4:1: warning: type attributes ignored after type is already 
 defined [-Wattributes]

Right, you cannot use (cplus_)decl_attributes on type that is fully
created.  The function warns in that case.

 So i may need a PLUGIN_FINISH_TYPE_DECLARATION triggered when the type
 is declared but before it is finally defined.

Hmmh.  For this specific case, maybe just setting the TREE_DEPRECATED
flag on the tree node of type could do what you want?

-- 
Dodji


Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-22 Thread Dodji Seketeli
Romain Geissler romain.geiss...@gmail.com a écrit:

 I tried to fix PLUGIN_FINISH_DECL as well to include typedefs in C++.

 The followings does not currently trigger the PLUGIN_FINISH_DECL
 (or not in all cases), but should them ?
  - function parameters (in the function prototype)
  - definition (with a function body) of a top-level function (while the exact
same function definition enclosed in a class definition will trigger
PLUGIN_FINISH_DECL)
  - label declaration
  - constants defined by enums
  - namespace

Indeed.  finish_decl is not called in those cases.  As to if the
PLUGIN_FINISH_DECL event should be emitted for those, I'd say yes, at
least if I believe what the description in plugin.def says:

/* After finishing parsing a declaration. */
DEFEVENT (PLUGIN_FINISH_DECL)

But I'd rather ask what the maintainers think about it.

Jason, Diego?

-- 
Dodji


Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-22 Thread Diego Novillo

On 11-09-22 09:40 , Dodji Seketeli wrote:

Romain Geisslerromain.geiss...@gmail.com  a écrit:


I tried to fix PLUGIN_FINISH_DECL as well to include typedefs in C++.

The followings does not currently trigger the PLUGIN_FINISH_DECL
(or not in all cases), but should them ?
  - function parameters (in the function prototype)
  - definition (with a function body) of a top-level function (while the exact
same function definition enclosed in a class definition will trigger
PLUGIN_FINISH_DECL)
  - label declaration
  - constants defined by enums
  - namespace


Indeed.  finish_decl is not called in those cases.  As to if the
PLUGIN_FINISH_DECL event should be emitted for those, I'd say yes, at
least if I believe what the description in plugin.def says:

 /* After finishing parsing a declaration. */
 DEFEVENT (PLUGIN_FINISH_DECL)

But I'd rather ask what the maintainers think about it.

Jason, Diego?


Yes, those events should trigger a PLUGIN_FINISH_DECL call.


Diego.


Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-22 Thread Romain Geissler
Hello,

Le 22 sept. 2011 à 15:22, Dodji Seketeli a écrit :
 
 So i may need a PLUGIN_FINISH_TYPE_DECLARATION triggered when the type
 is declared but before it is finally defined.
 
 Hmmh.  For this specific case, maybe just setting the TREE_DEPRECATED
 flag on the tree node of type could do what you want


The deprecated attribute was just an example. I may need to apply any type 
attribute
when a new type is parsed, which is currently not possible with the current C++
front-end.

Romain


Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-22 Thread Romain Geissler

Le 22 sept. 2011 à 16:18, Diego Novillo a écrit :

 On 11-09-22 09:40 , Dodji Seketeli wrote:
 Romain Geisslerromain.geiss...@gmail.com  a écrit:
 
 I tried to fix PLUGIN_FINISH_DECL as well to include typedefs in C++.
 
 The followings does not currently trigger the PLUGIN_FINISH_DECL
 (or not in all cases), but should them ?
  - function parameters (in the function prototype)
  - definition (with a function body) of a top-level function (while the 
 exact
same function definition enclosed in a class definition will trigger
PLUGIN_FINISH_DECL)
  - label declaration
  - constants defined by enums
  - namespace
 
 Indeed.  finish_decl is not called in those cases.  As to if the
 PLUGIN_FINISH_DECL event should be emitted for those, I'd say yes, at
 least if I believe what the description in plugin.def says:
 
 /* After finishing parsing a declaration. */
 DEFEVENT (PLUGIN_FINISH_DECL)
 
 But I'd rather ask what the maintainers think about it.
 
 Jason, Diego?
 
 Yes, those events should trigger a PLUGIN_FINISH_DECL call.

Ok, i've already implemented it in the C front-end. I'll post the whole patch 
soon.

Romain



Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-22 Thread Dodji Seketeli
Romain Geissler romain.geiss...@gmail.com a écrit:

 The deprecated attribute was just an example. I may need to apply any type 
 attribute
 when a new type is parsed, which is currently not possible with the current 
 C++
 front-end.

So then it seems to me like you might need to emit an event when a new
declared named is about to be put in the symbol table for a given
scope.  For the c++ FE, that would be in pushdecl_maybe_friend.  That
way, you can see the DECL even for the declaration of a type, before the
type is fully parsed.

-- 
Dodji


Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-13 Thread Romain Geissler

Hi

2011/9/12 Dodji Seketeli do...@seketeli.org:
 Romain Geissler romain.geiss...@gmail.com a écrit:
 When i recontributed the PLUGIN_FINISH_DECL patch from the original
 Brian Hackett, i didn't exactly checked  what may or may not trigger
 this new event. I know for example that declaring a function triggers
 this event, but defining it does not.

 I don't really know when those event should be triggered, we should
 clarify the meaning of those.

 According to me:
 PLUGIN_FINISH_DECL should be triggered anytime the parser parse a
 declaration (which includes declaration + definition of function,
 typedef definition, namespaces, ..., all DECL_P trees built by the
 parser).

 The general idea sounds sensible, IMHO.  However, we must keep in mind
 that there are cases like, e.g, 'struct C;' where G++ creates a typedef
 'typedef struct C C;' so that you can name that type 'C' instead of
 having to type struct C' all the time.  For these cases, I don't think
 the PLUGIN_FINISH_DECL event should be emitted.

I agree.


 For, PLUGIN_FINISH_TYPE i don't really know it means a new type
 declaration (or declaration + definition) or if it means usage of a
 type (in a function prototype, the type of a local variable.

 I'd say it's a definition of a new type, IMHO.

Ok, so it only involves struct, unions, enum and class declaration / 
definitions.


 I would rather vote for new type definition (including typedefs)

 My understanding is that a typedef declaration doesn't define a new
 type.  Rather, it declares an alias for an existing type.  As such, I
 would think that notifying typedef declarations via PLUGIN_FINISH_DECL
 would be the way to go.

Ok


 but for special cases of struct, you can declare and use them at the
 same time:

 Just to be sure I understand, do you need to be notified about *uses* of
 types and decls as well?  If so, maybe a new kind of event should
 probably be defined, because PLUGIN_FINISH_DECL and PLUGIN_FINISH_TYPE
 seem to have more to do with declaring/defining decls and types than
 using them.


Personally i don't need to catch all struct uses, but i need to catch struct 
declarations.
I want to apply some __attributes__ to a given struct type, for example let's say i need 
to mark *struct my_struct* as deprecated thanks to a plugin. I know how to apply some 
attributes to a type or a decl. See the plugin (test_plugin.c) and the test files attached.


With test_pass.c, my_struct is declared first, then defined after, applying the deprecated 
attribute works.
With test_fail.c, my_struct is declared and defined at the same time, applying the 
deprecated attribute doesn't work with the current trunk (and also with my patch).

I got:
test_fail.c:4:1: warning: type attributes ignored after type is already defined 
[-Wattributes]

So i may need a PLUGIN_FINISH_TYPE_DECLARATION triggered when the type is declared but 
before it is finally defined.


Does two different events PLUGIN_FINISH_TYPE_DECLARATION and PLUGIN_FINISH_TYPE_DEFINITION 
make sens to you ?


 --
Dodji


Romain Geissler
struct my_struct {
int field_1;
int field_2;
};

struct my_struct *my_function();

struct my_struct x = {1, 2};

struct my_struct *my_function(){
return x;
}
struct my_struct *my_function();

struct my_struct {
int field_1;
int field_2;
};

struct my_struct x = {1, 2};

struct my_struct *my_function(){
return x;
}
#include gcc-plugin.h
#include plugin-version.h
#include tree.h
#include cp/cp-tree.h

#pragma weak cplus_decl_attributes

bool my_struct_found = false;
void finish_type_callback (void *gcc_data, void *data ATTRIBUTE_UNUSED) {
tree type = (tree)gcc_data;
const char *type_name;

if (my_struct_found || type == error_mark_node || DECL_P (type)) {
//current PLUGIN_FINISH_TYPE is buggy in C++
//and my current patch may return TYPE_DECL for typedefs

return;
}

if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) {
type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
} else {
type_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
}

if (strcmp (type_name, my_struct)) {
//only affect my_struct type
return;
}

my_struct_found = true;
tree deprecated_attribute = tree_cons (get_identifier (deprecated), 
NULL_TREE, NULL_TREE);
inform(input_location,  my_struct found);


//apply the deprecated attribute to the my_struct type.
if (cplus_decl_attributes) {
cplus_decl_attributes (type, deprecated_attribute, 
ATTR_FLAG_TYPE_IN_PLACE);
} else {
decl_attributes (type, deprecated_attribute, 
ATTR_FLAG_TYPE_IN_PLACE);
}
}

int plugin_is_GPL_compatible;

int plugin_init (struct plugin_name_args *plugin_info,
struct plugin_gcc_version *version ATTRIBUTE_UNUSED)
{

Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-12 Thread Dodji Seketeli
Hello Romain,

Romain Geissler romain.geiss...@st.com a écrit:

 This patch solves some lacks with the PLUGIN_FINISH_TYPE event
 triggering. For now, both C and C++ parser won't trigger it for enums or
 for typedef.

AFAICT, typedef declarations are reported by the PLUGIN_FINISH_DECL
event.  The predicate is_typedef_decl then returns TRUE when passed the
decl carried by the event.  Maybe the plugin's documentation could use
an addendum for this.

[...]

 gcc/cp/
 2011-09-12  Romain Geissler  romain.geiss...@gmail.com

   * decl.c (grokdeclarator): Trigger PLUGIN_FINISH_TYPE for typedefs.

[...]

 Index: gcc/cp/decl.c
 ===
 --- gcc/cp/decl.c (revision 178252)
 +++ gcc/cp/decl.c (working copy)
 @@ -9682,6 +9682,9 @@ grokdeclarator (const cp_declarator *dec
 memfn_quals != TYPE_UNQUALIFIED,
 inlinep, friendp, raises != NULL_TREE);
  
 +  if (TREE_TYPE (decl) != error_mark_node  !DECL_ARTIFICIAL (decl))
 +invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, decl);
 +
return decl;
  }
  

So I think this change is not necessary.

[...]


 Index: gcc/testsuite/gcc.dg/plugin/dumb-plugin-test-1.c
 ===
 --- gcc/testsuite/gcc.dg/plugin/dumb-plugin-test-1.c  (revision 0)
 +++ gcc/testsuite/gcc.dg/plugin/dumb-plugin-test-1.c  (revision 0)
 @@ -0,0 +1,56 @@
 +// Test case for the dumb plugin.
 +// { dg-do compile }
 +// { dg-options -O -fplugin-arg-dumb_plugin-ref-pass-name=ccp 
 -fplugin-arg-dumb_plugin-ref-pass-instance-num=1 }
 +

Here, it would be nice to add a comment saying which plugin acts on this
plugin's test and what the plugin does (what the output is supposed to
be).  That redundant information eases the review, at very least.

Thanks.

-- 
Dodji


Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-12 Thread Romain Geissler
Hi,

2011/9/12 Dodji Seketeli do...@seketeli.org:
 Hello Romain,

 Romain Geissler romain.geiss...@st.com a écrit:

 This patch solves some lacks with the PLUGIN_FINISH_TYPE event
 triggering. For now, both C and C++ parser won't trigger it for enums or
 for typedef.

 AFAICT, typedef declarations are reported by the PLUGIN_FINISH_DECL
 event.  The predicate is_typedef_decl then returns TRUE when passed the
 decl carried by the event.  Maybe the plugin's documentation could use
 an addendum for this.

I just checked again, and PLUGIN_FINISH_DECL is triggered for a
typedef in C mode, but not in C++ mode. I'll patch that.
When i recontributed the PLUGIN_FINISH_DECL patch from the original
Brian Hackett, i didn't exactly checked  what may or may not trigger
this new event. I know for example that declaring a function triggers
this event, but defining it does not.

I don't really know when those event should be triggered, we should
clarify the meaning of those.

According to me:
PLUGIN_FINISH_DECL should be triggered anytime the parser parse a
declaration (which includes declaration + definition of function,
typedef definition, namespaces, ..., all DECL_P trees built by the
parser).
For, PLUGIN_FINISH_TYPE i don't really know it means a new type
declaration (or declaration + definition) or if it means usage of a
type (in a function prototype, the type of a local variable. I would
rather vote for new type definition (including typedefs) but for
special cases of struct, you can declare and use them at the same
time:

#include stdlib.h

struct my_struct x;
struct my_struct *my_function ();

struct my_struct {
  int field_1;
  int field_2;
};

struct my_struct *my_function () {
---return NULL;
}

which GCC accepts even with -pedantic.

That's why in this patch i launch a PLUGIN_FINISH_TYPE event every
time the parser meet the struct keyword.


So, what the real meaning of all those events ?


 [...]

 gcc/cp/
 2011-09-12  Romain Geissler  romain.geiss...@gmail.com

       * decl.c (grokdeclarator): Trigger PLUGIN_FINISH_TYPE for typedefs.

 [...]

 Index: gcc/cp/decl.c
 ===
 --- gcc/cp/decl.c     (revision 178252)
 +++ gcc/cp/decl.c     (working copy)
 @@ -9682,6 +9682,9 @@ grokdeclarator (const cp_declarator *dec
                     memfn_quals != TYPE_UNQUALIFIED,
                     inlinep, friendp, raises != NULL_TREE);

 +      if (TREE_TYPE (decl) != error_mark_node  !DECL_ARTIFICIAL (decl))
 +        invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, decl);
 +
        return decl;
      }


 So I think this change is not necessary.

 [...]


 Index: gcc/testsuite/gcc.dg/plugin/dumb-plugin-test-1.c
 ===
 --- gcc/testsuite/gcc.dg/plugin/dumb-plugin-test-1.c  (revision 0)
 +++ gcc/testsuite/gcc.dg/plugin/dumb-plugin-test-1.c  (revision 0)
 @@ -0,0 +1,56 @@
 +// Test case for the dumb plugin.
 +// { dg-do compile }
 +// { dg-options -O -fplugin-arg-dumb_plugin-ref-pass-name=ccp 
 -fplugin-arg-dumb_plugin-ref-pass-instance-num=1 }
 +

 Here, it would be nice to add a comment saying which plugin acts on this
 plugin's test and what the plugin does (what the output is supposed to
 be).  That redundant information eases the review, at very least.

Ok


 Thanks.

 --
                Dodji



Re: [PLUGIN] Fix PLUGIN_FINISH_TYPE

2011-09-12 Thread Dodji Seketeli
Romain Geissler romain.geiss...@gmail.com a écrit:

 I just checked again, and PLUGIN_FINISH_DECL is triggered for a
 typedef in C mode, but not in C++ mode. I'll patch that.

Correct.  This is because the event is emitted at the end of
cp_finish_decl, but that function has many return points.  Maybe
unifying all the those return points by replacing them with goto out;
and adding an out label right at the end, before emitting the event.

 When i recontributed the PLUGIN_FINISH_DECL patch from the original
 Brian Hackett, i didn't exactly checked  what may or may not trigger
 this new event. I know for example that declaring a function triggers
 this event, but defining it does not.

 I don't really know when those event should be triggered, we should
 clarify the meaning of those.

 According to me:
 PLUGIN_FINISH_DECL should be triggered anytime the parser parse a
 declaration (which includes declaration + definition of function,
 typedef definition, namespaces, ..., all DECL_P trees built by the
 parser).

The general idea sounds sensible, IMHO.  However, we must keep in mind
that there are cases like, e.g, 'struct C;' where G++ creates a typedef
'typedef struct C C;' so that you can name that type 'C' instead of
having to type struct C' all the time.  For these cases, I don't think
the PLUGIN_FINISH_DECL event should be emitted.

 For, PLUGIN_FINISH_TYPE i don't really know it means a new type
 declaration (or declaration + definition) or if it means usage of a
 type (in a function prototype, the type of a local variable.

I'd say it's a definition of a new type, IMHO.

 I would rather vote for new type definition (including typedefs)

My understanding is that a typedef declaration doesn't define a new
type.  Rather, it declares an alias for an existing type.  As such, I
would think that notifying typedef declarations via PLUGIN_FINISH_DECL
would be the way to go.

 but for special cases of struct, you can declare and use them at the
 same time:

Just to be sure I understand, do you need to be notified about *uses* of
types and decls as well?  If so, maybe a new kind of event should
probably be defined, because PLUGIN_FINISH_DECL and PLUGIN_FINISH_TYPE
seem to have more to do with declaring/defining decls and types than
using them.

 So, what the real meaning of all those events ?

From plugin.def, I read:

 /* After finishing parsing a type.  */
 DEFEVENT (PLUGIN_FINISH_TYPE)

 /* After finishing parsing a declaration. */
 DEFEVENT (PLUGIN_FINISH_DECL)

I agree that's rather terse, but it doesn't seem to be related to the
use of the type/decls.

-- 
Dodji