1 Date: Tue, 22 Dec 2009 10:00:29 -0800
2 Subject: plugin event for C/C++ declarations
3 From: Brian Hackett <bhackett1024 at gmail dot com>
4 To: gcc-patches at gcc dot gnu dot org
6 Hi, this patch adds a new plugin event FINISH_DECL, which is invoked
7 at every finish_decl in the C and C++ frontends. Previously there did
8 not seem to be a way for a plugin to see the definition for a global
9 that is never used in the input file, or the initializer for a global
10 which is declared before a function but defined after. This event
11 isn't restricted to just globals though, but also locals, fields, and
12 parameters (C frontend only).
14 Index: gcc/doc/plugins.texi
15 ===================================================================
16 --- gcc/doc/plugins.texi (revision 155401)
17 +++ gcc/doc/plugins.texi (working copy)
18 @@ -146,6 +146,7 @@ enum plugin_event
19 PLUGIN_FINISH_TYPE, /* After finishing parsing a type. */
20 PLUGIN_FINISH_UNIT, /* Useful for summary processing. */
21 PLUGIN_PRE_GENERICIZE, /* Allows to see low level AST in C and C++ frontends. */
22 + PLUGIN_FINISH_DECL, /* Allows to see all declarations in C and C++ frontends. */
23 PLUGIN_FINISH, /* Called before GCC exits. */
24 PLUGIN_INFO, /* Information about the plugin. */
25 PLUGIN_GGC_START, /* Called at start of GCC Garbage Collection. */
27 ===================================================================
28 --- gcc/plugin.def (revision 155386)
29 +++ gcc/plugin.def (working copy)
30 @@ -30,6 +30,9 @@ DEFEVENT (PLUGIN_FINISH_UNIT)
31 /* Allows to see low level AST in C and C++ frontends. */
32 DEFEVENT (PLUGIN_PRE_GENERICIZE)
34 +/* Allows to see all declarations in C and C++ frontends. */
35 +DEFEVENT (PLUGIN_FINISH_DECL)
37 /* Called before GCC exits. */
38 DEFEVENT (PLUGIN_FINISH)
40 Index: gcc/testsuite/g++.dg/plugin/plugin.exp
41 ===================================================================
42 --- gcc/testsuite/g++.dg/plugin/plugin.exp (revision 155401)
43 +++ gcc/testsuite/g++.dg/plugin/plugin.exp (working copy)
44 @@ -51,7 +51,8 @@ set plugin_test_list [list \
45 { pragma_plugin.c pragma_plugin-test-1.C } \
46 { selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \
47 { dumb_plugin.c dumb-plugin-test-1.C } \
48 - { header_plugin.c header-plugin-test.C } ]
49 + { header_plugin.c header-plugin-test.C } \
50 + { decl_plugin.c decl-plugin-test.C } ]
52 foreach plugin_test $plugin_test_list {
53 # Replace each source file with its full-path name
54 Index: gcc/testsuite/g++.dg/plugin/decl-plugin-test.C
55 ===================================================================
56 --- gcc/testsuite/g++.dg/plugin/decl-plugin-test.C (revision 0)
57 +++ gcc/testsuite/g++.dg/plugin/decl-plugin-test.C (revision 0)
61 +extern int global; // { dg-warning "Decl Global global" }
62 +int global_array[] = { 1, 2, 3 }; // { dg-warning "Decl Global global_array" }
64 +int takes_args(int arg1, int arg2)
66 + int local = arg1 + arg2 + global; // { dg-warning "Decl Local local" }
70 +int global = 12; // { dg-warning "Decl Global global" }
73 + int field; // { dg-warning "Decl Field field" }
77 + int class_field1; // { dg-warning "Decl Field class_field1" }
78 + int class_field2; // { dg-warning "Decl Field class_field2" }
80 + test_class() // { dg-warning "Decl Function test_class" }
81 + : class_field1(0), class_field2(0)
84 + void swap_fields(int bias) // { dg-warning "Decl Function swap_fields" }
86 + int temp = class_field1 + bias; // { dg-warning "Decl Local temp" }
87 + class_field1 = class_field2 - bias;
88 + class_field2 = temp;
91 Index: gcc/testsuite/g++.dg/plugin/decl_plugin.c
92 ===================================================================
93 --- gcc/testsuite/g++.dg/plugin/decl_plugin.c (revision 0)
94 +++ gcc/testsuite/g++.dg/plugin/decl_plugin.c (revision 0)
96 +/* A plugin example that shows which declarations are caught by FINISH_DECL */
98 +#include "gcc-plugin.h"
102 +#include "coretypes.h"
104 +#include "tree-pass.h"
107 +int plugin_is_GPL_compatible;
109 +/* Callback function to invoke after GCC finishes a declaration. */
111 +void plugin_finish_decl (void *event_data, void *data)
113 + tree decl = (tree) event_data;
115 + const char *kind = NULL;
116 + switch (TREE_CODE(decl)) {
117 + case FUNCTION_DECL:
118 + kind = "Function"; break;
120 + kind = "Parameter"; break;
122 + if (DECL_CONTEXT(decl) != NULL)
128 + kind = "Field"; break;
133 + warning (0, G_("Decl %s %s"),
134 + kind, IDENTIFIER_POINTER (DECL_NAME (decl)));
138 +plugin_init (struct plugin_name_args *plugin_info,
139 + struct plugin_gcc_version *version)
141 + const char *plugin_name = plugin_info->base_name;
143 + register_callback (plugin_name, PLUGIN_FINISH_DECL,
144 + plugin_finish_decl, NULL);
148 ===================================================================
149 --- gcc/cp/decl.c (revision 155386)
150 +++ gcc/cp/decl.c (working copy)
151 @@ -5949,6 +5949,8 @@ cp_finish_decl (tree decl, tree init, bo
152 /* If this was marked 'used', be sure it will be output. */
153 if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
154 mark_decl_referenced (decl);
156 + invoke_plugin_callbacks(PLUGIN_FINISH_DECL, decl);
159 /* Returns a declaration for a VAR_DECL as if:
161 ===================================================================
162 --- gcc/c-decl.c (revision 155386)
163 +++ gcc/c-decl.c (working copy)
164 @@ -4389,6 +4389,8 @@ finish_decl (tree decl, location_t init_
165 && DECL_INITIAL (decl) == NULL_TREE)
166 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
167 "uninitialized const %qD is invalid in C++", decl);
169 + invoke_plugin_callbacks(PLUGIN_FINISH_DECL, decl);
172 /* Given a parsed parameter declaration, decode it into a PARM_DECL. */
174 ===================================================================
175 --- gcc/plugin.c (revision 155386)
176 +++ gcc/plugin.c (working copy)
177 @@ -403,6 +403,7 @@ register_callback (const char *plugin_na
178 case PLUGIN_START_UNIT:
179 case PLUGIN_FINISH_UNIT:
180 case PLUGIN_PRE_GENERICIZE:
181 + case PLUGIN_FINISH_DECL:
182 case PLUGIN_GGC_START:
183 case PLUGIN_GGC_MARKING:
185 @@ -484,6 +485,7 @@ invoke_plugin_callbacks (int event, void
186 case PLUGIN_START_UNIT:
187 case PLUGIN_FINISH_UNIT:
188 case PLUGIN_PRE_GENERICIZE:
189 + case PLUGIN_FINISH_DECL:
190 case PLUGIN_ATTRIBUTES: