summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortglek <tglek@138bc75d-0d04-0410-961f-82ee72b054a4>2009-05-14 01:38:33 +0000
committertglek <tglek@138bc75d-0d04-0410-961f-82ee72b054a4>2009-05-14 01:38:33 +0000
commite3fced1ac7503512a9ccdcb5da732f2513b7a2cd (patch)
tree79caa93c375ec4191d07fcb56826aa922c1e1518
parent9ee55131e58408014be9ee79da60968c264cc760 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/attribs.c20
-rw-r--r--gcc/doc/plugins.texi33
-rw-r--r--gcc/gcc-plugin.h1
-rw-r--r--gcc/plugin.c2
-rw-r--r--gcc/plugin.h6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C16
-rw-r--r--gcc/testsuite/g++.dg/plugin/attribute_plugin.c66
-rw-r--r--gcc/testsuite/g++.dg/plugin/dumb_plugin.c2
-rw-r--r--gcc/testsuite/g++.dg/plugin/plugin.exp1
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 } ]