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

From-SVN: r147516
This commit is contained in:
Taras Glek 2009-05-14 01:38:33 +00:00 committed by Taras Glek
parent 1806edae58
commit d1c8e08a0c
11 changed files with 155 additions and 6 deletions

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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. */
};

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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" }

View File

@ -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;
}

View File

@ -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)

View File

@ -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 } ]