public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* plugin event for C/C++ declarations
@ 2009-12-22 18:42 Brian Hackett
  2009-12-22 18:45 ` H.J. Lu
  2009-12-22 21:01 ` Diego Novillo
  0 siblings, 2 replies; 42+ messages in thread
From: Brian Hackett @ 2009-12-22 18:42 UTC (permalink / raw)
  To: gcc-patches

Hi, this patch adds a new plugin event FINISH_DECL, which is invoked
at every finish_decl in the C and C++ frontends.  Previously there did
not seem to be a way for a plugin to see the definition for a global
that is never used in the input file, or the initializer for a global
which is declared before a function but defined after.  This event
isn't restricted to just globals though, but also locals, fields, and
parameters (C frontend only).

Brian



2009-12-22  Brian Hackett  <bhackett1024@gmail.com>

gcc/ChangeLog:

	* plugin.def: Add event for finish_decl.
	* plugin.c (register_callback, invoke_plugin_callbacks): Same.
	* c-decl.c (finish_decl): Invoke callbacks on above event.

gcc/cp/ChangeLog:

	* decl.c (cp_finish_decl): Invoke callbacks on finish_decl event.

gcc/testsuite/ChangeLog:

	* g++.dg/plugin/decl_plugin.c: New test plugin.
	* g++.dg/plugin/decl-plugin-test.C: Testcase for above plugin.
	* g++.dg/plugin/plugin.exp




Index: gcc/doc/plugins.texi
===================================================================
--- gcc/doc/plugins.texi	(revision 155401)
+++ gcc/doc/plugins.texi	(working copy)
@@ -146,6 +146,7 @@ enum plugin_event
   PLUGIN_FINISH_TYPE,           /* After finishing parsing a type.  */
   PLUGIN_FINISH_UNIT,           /* Useful for summary processing.  */
   PLUGIN_PRE_GENERICIZE,        /* Allows to see low level AST in C
and C++ frontends.  */
+  PLUGIN_FINISH_DECL,           /* Allows to see all declarations in
C and C++ frontends. */
   PLUGIN_FINISH,                /* Called before GCC exits.  */
   PLUGIN_INFO,                  /* Information about the plugin. */
   PLUGIN_GGC_START,		/* Called at start of GCC Garbage Collection. */
Index: gcc/plugin.def
===================================================================
--- gcc/plugin.def	(revision 155386)
+++ gcc/plugin.def	(working copy)
@@ -30,6 +30,9 @@ DEFEVENT (PLUGIN_FINISH_UNIT)
 /* Allows to see low level AST in C and C++ frontends. */
 DEFEVENT (PLUGIN_PRE_GENERICIZE)

+/* Allows to see all declarations in C and C++ frontends. */
+DEFEVENT (PLUGIN_FINISH_DECL)
+
 /* Called before GCC exits.  */
 DEFEVENT (PLUGIN_FINISH)

Index: gcc/testsuite/g++.dg/plugin/plugin.exp
===================================================================
--- gcc/testsuite/g++.dg/plugin/plugin.exp	(revision 155401)
+++ gcc/testsuite/g++.dg/plugin/plugin.exp	(working copy)
@@ -51,7 +51,8 @@ set plugin_test_list [list \
     { pragma_plugin.c pragma_plugin-test-1.C } \
     { selfassign.c self-assign-test-1.C self-assign-test-2.C
self-assign-test-3.C } \
     { dumb_plugin.c dumb-plugin-test-1.C } \
-    { header_plugin.c header-plugin-test.C } ]
+    { header_plugin.c header-plugin-test.C } \
+    { decl_plugin.c decl-plugin-test.C } ]

 foreach plugin_test $plugin_test_list {
     # Replace each source file with its full-path name
Index: gcc/testsuite/g++.dg/plugin/decl-plugin-test.C
===================================================================
--- gcc/testsuite/g++.dg/plugin/decl-plugin-test.C	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/decl-plugin-test.C	(revision 0)
@@ -0,0 +1,32 @@
+
+
+extern int global; // { dg-warning "Decl Global global" }
+int global_array[] = { 1, 2, 3 }; // { dg-warning "Decl Global global_array" }
+
+int takes_args(int arg1, int arg2)
+{
+  int local = arg1 + arg2 + global; // { dg-warning "Decl Local local" }
+  return local + 1;
+}
+
+int global = 12; // { dg-warning "Decl Global global" }
+
+struct test_str {
+  int field; // { dg-warning "Decl Field field" }
+};
+
+class test_class {
+  int class_field1; // { dg-warning "Decl Field class_field1" }
+  int class_field2; // { dg-warning "Decl Field class_field2" }
+
+  test_class() // { dg-warning "Decl Function test_class" }
+    : class_field1(0), class_field2(0)
+  {}
+
+  void swap_fields(int bias) // { dg-warning "Decl Function swap_fields" }
+  {
+    int temp = class_field1 + bias; // { dg-warning "Decl Local temp" }
+    class_field1 = class_field2 - bias;
+    class_field2 = temp;
+  }
+};
Index: gcc/testsuite/g++.dg/plugin/decl_plugin.c
===================================================================
--- gcc/testsuite/g++.dg/plugin/decl_plugin.c	(revision 0)
+++ gcc/testsuite/g++.dg/plugin/decl_plugin.c	(revision 0)
@@ -0,0 +1,51 @@
+/* A plugin example that shows which declarations are caught by FINISH_DECL */
+
+#include "gcc-plugin.h"
+#include <stdlib.h>
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+
+int plugin_is_GPL_compatible;
+
+/* Callback function to invoke after GCC finishes a declaration. */
+
+void plugin_finish_decl (void *event_data, void *data)
+{
+  tree decl = (tree) event_data;
+
+  const char *kind = NULL;
+  switch (TREE_CODE(decl)) {
+  case FUNCTION_DECL:
+    kind = "Function"; break;
+  case PARM_DECL:
+    kind = "Parameter"; break;
+  case VAR_DECL:
+    if (DECL_CONTEXT(decl) != NULL)
+      kind = "Local";
+    else
+      kind = "Global";
+    break;
+  case FIELD_DECL:
+    kind = "Field"; break;
+  default:
+    kind = "Unknown";
+  }
+
+  warning (0, G_("Decl %s %s"),
+           kind, IDENTIFIER_POINTER (DECL_NAME (decl)));
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+             struct plugin_gcc_version *version)
+{
+  const char *plugin_name = plugin_info->base_name;
+
+  register_callback (plugin_name, PLUGIN_FINISH_DECL,
+                     plugin_finish_decl, NULL);
+  return 0;
+}
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 155386)
+++ gcc/cp/decl.c	(working copy)
@@ -5949,6 +5949,8 @@ cp_finish_decl (tree decl, tree init, bo
   /* If this was marked 'used', be sure it will be output.  */
   if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
     mark_decl_referenced (decl);
+
+  invoke_plugin_callbacks(PLUGIN_FINISH_DECL, decl);
 }

 /* Returns a declaration for a VAR_DECL as if:
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 155386)
+++ gcc/c-decl.c	(working copy)
@@ -4389,6 +4389,8 @@ finish_decl (tree decl, location_t init_
       && DECL_INITIAL (decl) == NULL_TREE)
     warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
 		"uninitialized const %qD is invalid in C++", decl);
+
+  invoke_plugin_callbacks(PLUGIN_FINISH_DECL, decl);
 }

 /* Given a parsed parameter declaration, decode it into a PARM_DECL.  */
Index: gcc/plugin.c
===================================================================
--- gcc/plugin.c	(revision 155386)
+++ gcc/plugin.c	(working copy)
@@ -403,6 +403,7 @@ register_callback (const char *plugin_na
       case PLUGIN_START_UNIT:
       case PLUGIN_FINISH_UNIT:
       case PLUGIN_PRE_GENERICIZE:
+      case PLUGIN_FINISH_DECL:
       case PLUGIN_GGC_START:
       case PLUGIN_GGC_MARKING:
       case PLUGIN_GGC_END:
@@ -484,6 +485,7 @@ invoke_plugin_callbacks (int event, void
       case PLUGIN_START_UNIT:
       case PLUGIN_FINISH_UNIT:
       case PLUGIN_PRE_GENERICIZE:
+      case PLUGIN_FINISH_DECL:
       case PLUGIN_ATTRIBUTES:
       case PLUGIN_PRAGMAS:
       case PLUGIN_FINISH:

^ permalink raw reply	[flat|nested] 42+ messages in thread
* Re: plugin event for C/C++ declarations
@ 2010-04-29 13:00 Dominique Dhumieres
  0 siblings, 0 replies; 42+ messages in thread
From: Dominique Dhumieres @ 2010-04-29 13:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: bhackett1024


This is likely the cause of pr43935.

Dominique

^ permalink raw reply	[flat|nested] 42+ messages in thread
* Re: plugin event for C/C++ declarations
@ 2011-07-07  9:09 Romain Geissler
  2011-07-07 12:19 ` Diego Novillo
  0 siblings, 1 reply; 42+ messages in thread
From: Romain Geissler @ 2011-07-07  9:09 UTC (permalink / raw)
  To: gcc-patches; +Cc: bhackett1024

> On Tue, Dec 22, 2009 at 11:45 AM, Diego Novillo <dnovillo@google.com> wrote:
>> On Tue, Dec 22, 2009 at 13:00, Brian Hackett <bhackett1024@gmail.com> wrote:
>>> Hi, this patch adds a new plugin event FINISH_DECL, which is invoked
>>> at every finish_decl in the C and C++ frontends. ?Previously there did
>>> not seem to be a way for a plugin to see the definition for a global
>>> that is never used in the input file, or the initializer for a global
>>> which is declared before a function but defined after. ?This event
>>> isn't restricted to just globals though, but also locals, fields, and
>>> parameters (C frontend only).
>>
>> Thanks for your patch. ?This will be great to fix
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41757 but we need to wait
>> for your copyright assignment to go through before we can accept it.
>
> Hi, this is a patch from a few months ago which I was not able to get
> an assignment for.  The FSF has a personal copyright assignment for
> me, but I could not get one from my employer at the time, Stanford
> (according to Stanford's policies they would not claim copyright on
> this patch).  I now work for Mozilla, which (I understand) has a
> company wide copyright assignment.  Are there issues if I from scratch
> rewrite and resubmit a new patch?
>
> Original patch (9 new lines of code, doc change and new regression):
>
> http://gcc.gnu.org/ml/gcc-patches/2009-12/msg01032.html
>
> Brian

Hi,

Once again, this is a ping for the long time proposed patch by Brian Hackett.
See last thread about this one here:
http://gcc.gnu.org/ml/gcc-patches/2010-04/msg00315.html

Find below the fixed patch for recent revision (changed
gcc/testsuite/g++.dg/plugin/decl_plugin.c global and local var
decl detection)

Romain Geissler

2011-07-07  Romain Geissler  <romain.geissler@gmail.com>
2010-04-14  Brian Hackett  <bhackett1024@gmail.com>

gcc/ChangeLog:

       * plugin.def: Add event for finish_decl.
       * plugin.c (register_callback, invoke_plugin_callbacks): Same.
       * c-decl.c (finish_decl): Invoke callbacks on above event.
       * doc/plugins.texi: Document above event.

gcc/cp/ChangeLog:

       * decl.c (cp_finish_decl): Invoke callbacks on finish_decl event.

gcc/testsuite/ChangeLog:

       * g++.dg/plugin/decl_plugin.c: New test plugin.
       * g++.dg/plugin/decl-plugin-test.C: Testcase for above plugin.
       * g++.dg/plugin/plugin.exp: Add above testcase.


Index: gcc/doc/plugins.texi
===================================================================
--- gcc/doc/plugins.texi        (revision 175907)
+++ gcc/doc/plugins.texi        (working copy)
@@ -151,6 +151,7 @@ enum plugin_event
 @{
   PLUGIN_PASS_MANAGER_SETUP,    /* To hook into pass manager.  */
   PLUGIN_FINISH_TYPE,           /* After finishing parsing a type.  */
+  PLUGIN_FINISH_DECL,           /* After finishing parsing a declaration. */
   PLUGIN_FINISH_UNIT,           /* Useful for summary processing.  */
   PLUGIN_PRE_GENERICIZE,        /* Allows to see low level AST in C
and C++ frontends.  */
   PLUGIN_FINISH,                /* Called before GCC exits.  */
Index: gcc/plugin.def
===================================================================
--- gcc/plugin.def      (revision 175907)
+++ gcc/plugin.def      (working copy)
@@ -24,6 +24,9 @@ DEFEVENT (PLUGIN_PASS_MANAGER_SETUP)
 /* After finishing parsing a type.  */
 DEFEVENT (PLUGIN_FINISH_TYPE)

+/* After finishing parsing a declaration. */
+DEFEVENT (PLUGIN_FINISH_DECL)
+
 /* Useful for summary processing.  */
 DEFEVENT (PLUGIN_FINISH_UNIT)

Index: gcc/testsuite/g++.dg/plugin/plugin.exp
===================================================================
--- gcc/testsuite/g++.dg/plugin/plugin.exp      (revision 175907)
+++ gcc/testsuite/g++.dg/plugin/plugin.exp      (working copy)
@@ -51,7 +51,8 @@ set plugin_test_list [list \
     { pragma_plugin.c pragma_plugin-test-1.C } \
     { selfassign.c self-assign-test-1.C self-assign-test-2.C
self-assign-test-3.C } \
     { dumb_plugin.c dumb-plugin-test-1.C } \
-    { header_plugin.c header-plugin-test.C } ]
+    { header_plugin.c header-plugin-test.C } \
+    { decl_plugin.c decl-plugin-test.C } ]

 foreach plugin_test $plugin_test_list {
     # Replace each source file with its full-path name
Index: gcc/testsuite/g++.dg/plugin/decl-plugin-test.C
===================================================================
--- gcc/testsuite/g++.dg/plugin/decl-plugin-test.C      (revision 0)
+++ gcc/testsuite/g++.dg/plugin/decl-plugin-test.C      (revision 0)
@@ -0,0 +1,32 @@
+
+
+extern int global; // { dg-warning "Decl Global global" }
+int global_array[] = { 1, 2, 3 }; // { dg-warning "Decl Global global_array" }
+
+int takes_args(int arg1, int arg2)
+{
+  int local = arg1 + arg2 + global; // { dg-warning "Decl Local local" }
+  return local + 1;
+}
+
+int global = 12; // { dg-warning "Decl Global global" }
+
+struct test_str {
+  int field; // { dg-warning "Decl Field field" }
+};
+
+class test_class {
+  int class_field1; // { dg-warning "Decl Field class_field1" }
+  int class_field2; // { dg-warning "Decl Field class_field2" }
+
+  test_class() // { dg-warning "Decl Function test_class" }
+    : class_field1(0), class_field2(0)
+  {}
+
+  void swap_fields(int bias) // { dg-warning "Decl Function swap_fields" }
+  {
+    int temp = class_field1 + bias; // { dg-warning "Decl Local temp" }
+    class_field1 = class_field2 - bias;
+    class_field2 = temp;
+  }
+};
Index: gcc/testsuite/g++.dg/plugin/decl_plugin.c
===================================================================
--- gcc/testsuite/g++.dg/plugin/decl_plugin.c   (revision 0)
+++ gcc/testsuite/g++.dg/plugin/decl_plugin.c   (revision 0)
@@ -0,0 +1,51 @@
+/* A plugin example that shows which declarations are caught by FINISH_DECL */
+
+#include "gcc-plugin.h"
+#include <stdlib.h>
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+
+int plugin_is_GPL_compatible;
+
+/* Callback function to invoke after GCC finishes a declaration. */
+
+void plugin_finish_decl (void *event_data, void *data)
+{
+  tree decl = (tree) event_data;
+
+  const char *kind = NULL;
+  switch (TREE_CODE(decl)) {
+  case FUNCTION_DECL:
+    kind = "Function"; break;
+  case PARM_DECL:
+    kind = "Parameter"; break;
+  case VAR_DECL:
+    if (DECL_FILE_SCOPE_P(decl))
+      kind = "Global";
+    else
+      kind = "Local";
+    break;
+  case FIELD_DECL:
+    kind = "Field"; break;
+  default:
+    kind = "Unknown";
+  }
+
+  warning (0, G_("Decl %s %s"),
+           kind, IDENTIFIER_POINTER (DECL_NAME (decl)));
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+             struct plugin_gcc_version *version)
+{
+  const char *plugin_name = plugin_info->base_name;
+
+  register_callback (plugin_name, PLUGIN_FINISH_DECL,
+                     plugin_finish_decl, NULL);
+  return 0;
+}
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c       (revision 175907)
+++ gcc/cp/decl.c       (working copy)
@@ -6298,6 +6298,8 @@ cp_finish_decl (tree decl, tree init, bo

   if (was_readonly)
     TREE_READONLY (decl) = 1;
+
+  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
 }

 /* Returns a declaration for a VAR_DECL as if:
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c        (revision 175907)
+++ gcc/c-decl.c        (working copy)
@@ -4464,6 +4464,8 @@ finish_decl (tree decl, location_t init_
               && C_TYPE_FIELDS_READONLY (type))
        diagnose_uninitialized_cst_member (decl, type);
     }
+
+    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
 }

 /* Given a parsed parameter declaration, decode it into a PARM_DECL.
Index: gcc/plugin.c
===================================================================
--- gcc/plugin.c        (revision 175907)
+++ gcc/plugin.c        (working copy)
@@ -420,6 +420,7 @@ register_callback (const char *plugin_na
          }
       /* Fall through.  */
       case PLUGIN_FINISH_TYPE:
+      case PLUGIN_FINISH_DECL:
       case PLUGIN_START_UNIT:
       case PLUGIN_FINISH_UNIT:
       case PLUGIN_PRE_GENERICIZE:
@@ -496,6 +497,7 @@ invoke_plugin_callbacks_full (int event,
        gcc_assert (event < event_last);
       /* Fall through.  */
       case PLUGIN_FINISH_TYPE:
+      case PLUGIN_FINISH_DECL:
       case PLUGIN_START_UNIT:
       case PLUGIN_FINISH_UNIT:
       case PLUGIN_PRE_GENERICIZE:

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2011-08-11 15:58 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-22 18:42 plugin event for C/C++ declarations Brian Hackett
2009-12-22 18:45 ` H.J. Lu
2009-12-22 18:46   ` Brian Hackett
2009-12-22 18:50     ` H.J. Lu
2009-12-22 19:04       ` Brian Hackett
2009-12-22 19:46         ` H.J. Lu
2009-12-22 20:37           ` Brian Hackett
2009-12-22 21:01 ` Diego Novillo
2010-04-07 18:30   ` Brian Hackett
2010-04-12 19:39     ` Diego Novillo
2010-04-12 19:54       ` Brian Hackett
2010-04-14 14:15         ` Brian Hackett
2010-04-27 15:09           ` Brian Hackett
2010-04-27 15:29             ` Diego Novillo
2010-04-27 15:31               ` Richard Guenther
2010-04-27 15:32                 ` Richard Guenther
2010-04-27 15:46                   ` Brian Hackett
2010-04-27 15:50                     ` Richard Guenther
2010-04-27 16:00                       ` Diego Novillo
2010-04-27 16:03                         ` Richard Guenther
2010-04-27 16:04                           ` Diego Novillo
2010-04-27 17:16                             ` Richard Guenther
2010-04-27 20:15                               ` Brian Hackett
2010-04-28 10:01                                 ` Richard Guenther
2010-04-28 14:34                                 ` Diego Novillo
2010-04-29  2:24                                   ` Brian Hackett
2010-04-29 10:02                                     ` Richard Guenther
2010-04-29 13:22                                     ` H.J. Lu
2010-04-29 14:03                                       ` Brian Hackett
2010-04-29 14:04                                         ` H.J. Lu
2010-04-29 14:37                                           ` Brian Hackett
2010-04-27 15:45                 ` Diego Novillo
2010-04-29 13:00 Dominique Dhumieres
2011-07-07  9:09 Romain Geissler
2011-07-07 12:19 ` Diego Novillo
2011-07-11  8:21   ` Romain Geissler
2011-07-18  9:28     ` Romain Geissler
2011-07-20 12:37       ` Diego Novillo
2011-08-08 12:13         ` Romain Geissler
2011-08-10 15:59           ` Diego Novillo
2011-08-11 13:37             ` Romain Geissler
2011-08-11 17:11               ` Diego Novillo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).