diff options
author | tglek <tglek@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-14 01:38:33 +0000 |
---|---|---|
committer | tglek <tglek@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-14 01:38:33 +0000 |
commit | e3fced1ac7503512a9ccdcb5da732f2513b7a2cd (patch) | |
tree | 79caa93c375ec4191d07fcb56826aa922c1e1518 /gcc | |
parent | 9ee55131e58408014be9ee79da60968c264cc760 (diff) | |
download | gcc-e3fced1ac7503512a9ccdcb5da732f2513b7a2cd.tar.gz |
2009-05-13 Taras Glek <tglek@mozilla.com>
gcc/
* attribs.c moved out attribute registration into register_attribute
* doc/plugins.texi Documented register_attribute and PLUGIN_ATTRIBUTES
* gcc-plugin.h Added forward decl for register_attribute
* plugin.c Added PLUGIN_ATTRIBUTES boilerplate
* plugin.h Added PLUGIN_ATTRIBUTES
gcc/testsuite/
* g++.dg/plugin/attribute_plugin-test-1.C Testcase input for custom attributes and decl smashing
* g++.dg/plugin/attribute_plugin.c Testcase plugin to test user attributes
* g++.dg/plugin/dumb_plugin.c Fixed typo
* g++.dg/plugin/plugin.exp Added attribute_plugin test
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147516 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/attribs.c | 20 | ||||
-rw-r--r-- | gcc/doc/plugins.texi | 33 | ||||
-rw-r--r-- | gcc/gcc-plugin.h | 1 | ||||
-rw-r--r-- | gcc/plugin.c | 2 | ||||
-rw-r--r-- | gcc/plugin.h | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/plugin/attribute_plugin.c | 66 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/plugin/dumb_plugin.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/plugin/plugin.exp | 1 |
11 files changed, 155 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea12e83dd2c..4b5637b6767 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-05-13 Taras Glek <tglek@mozilla.com> + + * attribs.c moved out attribute registration into register_attribute + * doc/plugins.texi Documented register_attribute and PLUGIN_ATTRIBUTES + * gcc-plugin.h Added forward decl for register_attribute + * plugin.c Added PLUGIN_ATTRIBUTES boilerplate + * plugin.h Added PLUGIN_ATTRIBUTES + 2009-05-14 Dave Korn <dave.korn.cygwin@gmail.com> * config/i386/msformat-c.c (ms_printf_length_specs): Use enumeration diff --git a/gcc/attribs.c b/gcc/attribs.c index df4ca73124d..a7f549e1dc8 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "langhooks.h" #include "hashtab.h" +#include "plugin.h" static void init_attributes (void); @@ -182,18 +183,27 @@ init_attributes (void) for (i = 0; i < ARRAY_SIZE (attribute_tables); i++) for (k = 0; attribute_tables[i][k].name != NULL; k++) { + register_attribute (&attribute_tables[i][k]); + } + invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL); + attributes_initialized = true; +} + +/* Insert a single ATTR into the attribute table. */ + +void +register_attribute (const struct attribute_spec *attr) +{ struct substring str; const void **slot; - str.str = attribute_tables[i][k].name; - str.length = strlen (attribute_tables[i][k].name); + str.str = attr->name; + str.length = strlen (str.str); slot = (const void **)htab_find_slot_with_hash (attribute_hash, &str, substring_hash (str.str, str.length), INSERT); gcc_assert (!*slot); - *slot = &attribute_tables[i][k]; - } - attributes_initialized = true; + *slot = attr; } /* Return the spec for the attribute named NAME. */ diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi index 7c3fbed354e..1710395b50d 100644 --- a/gcc/doc/plugins.texi +++ b/gcc/doc/plugins.texi @@ -71,6 +71,7 @@ enum plugin_event PLUGIN_FINISH_UNIT, /* Useful for summary processing. */ PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE. */ PLUGIN_FINISH, /* Called before GCC exits. */ + PLUGIN_ATTRIBUTES, /* Called during attribute registration */ PLUGIN_EVENT_LAST /* Dummy event used for indexing callback array. */ @}; @@ -135,3 +136,35 @@ plugin_init (const char *plugin_name, int argc, struct plugin_argument *argv) ... @} @end smallexample +@section Registering custom attributes + +For analysis purposes it is useful to be able to add custom attributes. + +The @code{PLUGIN_ATTRIBUTES} callback is called during attribute +registration. Use the @code{register_attribute} function to register +custom attributes. + +@smallexample +/* Attribute handler callback */ +static tree +handle_user_attribute (tree *node, tree name, tree args, + int flags, bool *no_add_attrs) +@{ + return NULL_TREE; +@} + +/* Attribute definition */ +static struct attribute_spec user_attr = + @{ "user", 1, 1, false, false, false, handle_user_attribute @}; + +/* Plugin callback called during attribute registration. +Registered with register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL) +*/ +static void +register_attributes (void *event_data, void *data) +@{ + warning (0, G_("Callback to register attributes")); + register_attribute (&user_attr); +@} + +@end smallexample diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h index 96c867d4bc6..ba20b42475c 100644 --- a/gcc/gcc-plugin.h +++ b/gcc/gcc-plugin.h @@ -29,6 +29,7 @@ enum plugin_event PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE. */ PLUGIN_FINISH, /* Called before GCC exits. */ PLUGIN_INFO, /* Information about the plugin */ + PLUGIN_ATTRIBUTES, /* Called during attribute registration. */ PLUGIN_EVENT_LAST /* Dummy event used for indexing callback array. */ }; diff --git a/gcc/plugin.c b/gcc/plugin.c index dec336d70b7..923f0add0cf 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -493,6 +493,7 @@ register_callback (const char *plugin_name, case PLUGIN_FINISH_TYPE: case PLUGIN_FINISH_UNIT: case PLUGIN_CXX_CP_PRE_GENERICIZE: + case PLUGIN_ATTRIBUTES: case PLUGIN_FINISH: { struct callback_info *new_callback; @@ -534,6 +535,7 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data) case PLUGIN_FINISH_TYPE: case PLUGIN_FINISH_UNIT: case PLUGIN_CXX_CP_PRE_GENERICIZE: + case PLUGIN_ATTRIBUTES: case PLUGIN_FINISH: { /* Iterate over every callback registered with this event and diff --git a/gcc/plugin.h b/gcc/plugin.h index c1f566ba80f..b610b23ed93 100644 --- a/gcc/plugin.h +++ b/gcc/plugin.h @@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see #include "gcc-plugin.h" +struct attribute_spec; + extern void add_new_plugin (const char *); extern void parse_plugin_arg_opt (const char *); extern void invoke_plugin_callbacks (enum plugin_event, void *); @@ -33,4 +35,8 @@ extern void print_plugins_versions (FILE *file, const char *indent); extern void print_plugins_help (FILE *file, const char *indent); extern void finalize_plugins (void); +/* In attribs.c. */ + +extern void register_attribute (const struct attribute_spec *attr); + #endif /* PLUGIN_H */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fe0bb0042d6..2775cdb3336 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-05-13 Taras Glek <tglek@mozilla.com> + * g++.dg/plugin/attribute_plugin-test-1.C Testcase input for custom attributes and decl smashing + * g++.dg/plugin/attribute_plugin.c Testcase plugin to test user attributes + * g++.dg/plugin/dumb_plugin.c Fixed typo + * g++.dg/plugin/plugin.exp Added attribute_plugin test + 2009-05-14 Jakub Jelinek <jakub@redhat.com> PR fortran/39865 diff --git a/gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C b/gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C new file mode 100644 index 00000000000..abb1328670a --- /dev/null +++ b/gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C @@ -0,0 +1,16 @@ +// { dg-warning "Callback to register attributes" } + +void normal_func (char c, char c2); +void normal_func (char __attribute__((user("param"))) c, char); +void normal_func (char c, char __attribute__((user("param"))) c2) +{ +} // { dg-warning "attribute 'user' on param 'c' of function normal_func" } +// { dg-warning "attribute 'user' on param 'c2' of function normal_func" "" { target *-*-* } 7 } + +class Foo { + void method (char __attribute__((user("param"))) c); +}; + +void Foo::method(char c) +{ +} // { dg-warning "attribute 'user' on param 'c' of function method" } diff --git a/gcc/testsuite/g++.dg/plugin/attribute_plugin.c b/gcc/testsuite/g++.dg/plugin/attribute_plugin.c new file mode 100644 index 00000000000..d071762102b --- /dev/null +++ b/gcc/testsuite/g++.dg/plugin/attribute_plugin.c @@ -0,0 +1,66 @@ +/* Demonstrates how to add custom attributes */ + +#include <stdlib.h> +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tree.h" +#include "tree-pass.h" +#include "intl.h" +#include "gcc-plugin.h" + +/* Attribute handler callback */ + +static tree +handle_user_attribute (tree *node, tree name, tree args, + int flags, bool *no_add_attrs) +{ + return NULL_TREE; +} + +/* Attribute definition */ + +static struct attribute_spec user_attr = + { "user", 1, 1, false, false, false, handle_user_attribute }; + +/* Plugin callback called during attribute registration */ + +static void +register_attributes (void *event_data, void *data) +{ + warning (0, G_("Callback to register attributes")); + register_attribute (&user_attr); +} + +/* Callback function to invoke before the function body is genericized. */ + +void +handle_pre_generic (void *event_data, void *data) +{ + tree fndecl = (tree) event_data; + tree arg; + for (arg = DECL_ARGUMENTS(fndecl); arg; arg = TREE_CHAIN (arg)) { + tree attr; + for (attr = DECL_ATTRIBUTES (arg); attr; attr = TREE_CHAIN (attr)) { + tree attrname = TREE_PURPOSE (attr); + tree attrargs = TREE_VALUE (attr); + warning (0, G_("attribute '%s' on param '%s' of function %s"), + IDENTIFIER_POINTER (attrname), + IDENTIFIER_POINTER (DECL_NAME (arg)), + IDENTIFIER_POINTER (DECL_NAME (fndecl)) + ); + } + } +} + +int +plugin_init (const char *plugin_name, + struct plugin_gcc_version *version, + int argc, struct plugin_argument *argv) +{ + register_callback (plugin_name, PLUGIN_CXX_CP_PRE_GENERICIZE, + handle_pre_generic, NULL); + + register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); + return 0; +} diff --git a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c index 0c62f89e109..839dc2b1c8a 100644 --- a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c +++ b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c @@ -21,7 +21,7 @@ handle_struct (void *event_data, void *data) IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); } -/* Callback function to invoke before the program is genericized. */ +/* Callback function to invoke before the function body is genericized. */ void handle_pre_generic (void *event_data, void *data) diff --git a/gcc/testsuite/g++.dg/plugin/plugin.exp b/gcc/testsuite/g++.dg/plugin/plugin.exp index e1f6d89ae28..eb019986ffe 100644 --- a/gcc/testsuite/g++.dg/plugin/plugin.exp +++ b/gcc/testsuite/g++.dg/plugin/plugin.exp @@ -47,6 +47,7 @@ load_lib plugin-support.exp # Specify the plugin source file and the associated test files in a list. # plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... } set plugin_test_list [list \ + { attribute_plugin.c attribute_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 } ] |