diff options
author | Basile Starynkevitch <basile@starynkevitch.net> | 2009-11-06 19:20:39 +0000 |
---|---|---|
committer | Rafael Espindola <espindola@gcc.gnu.org> | 2009-11-06 19:20:39 +0000 |
commit | 7ac8318c2daf09b9f2e1612b3add3584f58ac3b7 (patch) | |
tree | 9a9a21a6222d8d5e0d4faa8b2d2a263613b6cd83 | |
parent | 87e928642892922f18f1e652f41d8fc9169ae757 (diff) | |
download | gcc-7ac8318c2daf09b9f2e1612b3add3584f58ac3b7.zip gcc-7ac8318c2daf09b9f2e1612b3add3584f58ac3b7.tar.gz gcc-7ac8318c2daf09b9f2e1612b3add3584f58ac3b7.tar.bz2 |
plugins.texi (Plugin callbacks): added PLUGIN_PRAGMAS.
2009-11-06 Basile Starynkevitch <basile@starynkevitch.net>
* doc/plugins.texi (Plugin callbacks): added PLUGIN_PRAGMAS.
* c-pragma.c: Include "plugin.h".
(init_pragma): Invoke PLUGIN_PRAGMAS.
* gcc-plugin.h: Added PLUGIN_PRAGMAS.
* plugin.c (plugin_event_name): Added PLUGIN_PRAGMAS & the missing
PLUGIN_ATTRIBUTES.
(register_callback): Added PLUGIN_PRAGMAS. Fixed typo in message
error for unknown callback event.
(invoke_plugin_callbacks): Added PLUGIN_PRAGMAS.
* Makefile.in (c-pragma.o): Added dependency upon plugin.h.
(PLUGIN_HEADERS): added plugin.h.
2009-11-06 Basile Starynkevitch <basile@starynkevitch.net>
* g++.dg/plugin/pragma_plugin-test-1.C: new testcase for
PLUGIN_PRAGMAS.
* g++.dg/plugin/pragma_plugin.c: new test plugin for
PLUGIN_PRAGMAS.
* g++.dg/plugin/plugin.exp (plugin_test_list): Add pragma_plugin.c and
pragma_plugin-test-1.C.
From-SVN: r153975
-rw-r--r-- | gcc/Makefile.in | 7 | ||||
-rw-r--r-- | gcc/c-pragma.c | 4 | ||||
-rw-r--r-- | gcc/doc/plugins.texi | 6 | ||||
-rw-r--r-- | gcc/gcc-plugin.h | 1 | ||||
-rw-r--r-- | gcc/plugin.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/plugin/plugin.exp | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/plugin/pragma_plugin.c | 60 |
9 files changed, 109 insertions, 5 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 5dd47e5..f66f9ef 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1982,7 +1982,7 @@ c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FUNCTION_H) $(C_PRAGMA_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \ $(C_COMMON_H) $(TARGET_H) gt-c-pragma.h $(CPPLIB_H) $(FLAGS_H) $(DIAGNOSTIC_H) \ - opts.h + opts.h $(PLUGINS_H) graph.o: graph.c $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) $(FLAGS_H) output.h \ $(RTL_H) $(FUNCTION_H) hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(OBSTACK_H) \ $(CONFIG_H) @@ -4260,7 +4260,8 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \ intl.h $(PLUGIN_VERSION_H) $(DIAGNOSTIC_H) $(C_COMMON_H) $(C_PRETTY_PRINT_H) \ tree-iterator.h $(PLUGIN_H) $(TREE_FLOW_H) langhooks.h incpath.h \ - tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H) + tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H) \ + $(C_PRAGMA_H) $(CPPLIB_H) $(FUNCTION_H) # Install the headers needed to build a plugin. install-plugin: installdirs lang.install-plugin @@ -4524,7 +4525,7 @@ install-collect2: collect2 installdirs # Install lto-wrapper. install-lto-wrapper: lto-wrapper$(exeext) $(INSTALL_PROGRAM) lto-wrapper$(exeext) $(DESTDIR)$(libexecsubdir)/lto-wrapper$(exeext) - + # Cancel installation by deleting the installed files. uninstall: lang.uninstall -rm -rf $(DESTDIR)$(libsubdir) diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c index f281644..f71399f 100644 --- a/gcc/c-pragma.c +++ b/gcc/c-pragma.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "diagnostic.h" #include "opts.h" +#include "plugin.h" #define GCC_BAD(gmsgid) \ do { warning (OPT_Wpragmas, gmsgid); return; } while (0) @@ -1450,6 +1451,9 @@ init_pragma (void) #ifdef REGISTER_TARGET_PRAGMAS REGISTER_TARGET_PRAGMAS (); #endif + + /* Allow plugins to register their own pragmas. */ + invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL); } #include "gt-c-pragma.h" diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi index f784953..123f670 100644 --- a/gcc/doc/plugins.texi +++ b/gcc/doc/plugins.texi @@ -136,6 +136,7 @@ enum plugin_event PLUGIN_REGISTER_GGC_CACHES, /* Register an extra GGC cache table. */ PLUGIN_ATTRIBUTES, /* Called during attribute registration */ PLUGIN_START_UNIT, /* Called before processing a translation unit. */ + PLUGIN_PRAGMAS, /* Called during pragma registration. */ PLUGIN_EVENT_LAST /* Dummy event used for indexing callback array. */ @}; @@ -156,6 +157,11 @@ For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and PLUGIN_REGISTER_GGC_CACHES pseudo-events the @code{callback} should be null, and the @code{user_data} is specific. +When the PLUGIN_PRAGMAS event is triggered (with a null +pointer as data from GCC), plugins may register their own pragmas +using functions like @code{c_register_pragma} or +@code{c_register_pragma_with_expansion}. + @section Interacting with the pass manager There needs to be a way to add/reorder/remove passes dynamically. This diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h index 1792c03..2e36f48 100644 --- a/gcc/gcc-plugin.h +++ b/gcc/gcc-plugin.h @@ -43,6 +43,7 @@ enum plugin_event PLUGIN_REGISTER_GGC_CACHES, /* Register an extra GGC cache table. */ PLUGIN_ATTRIBUTES, /* Called during attribute registration. */ PLUGIN_START_UNIT, /* Called before processing a translation unit. */ + PLUGIN_PRAGMAS, /* Called during pragma registration. */ PLUGIN_EVENT_LAST /* Dummy event used for indexing callback array. */ }; diff --git a/gcc/plugin.c b/gcc/plugin.c index 18b7c8a..2d64422 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -58,7 +58,9 @@ const char *plugin_event_name[] = "PLUGIN_GGC_END", "PLUGIN_REGISTER_GGC_ROOTS", "PLUGIN_REGISTER_GGC_CACHES", - "PLUGIN_START_UNIT", + "PLUGIN_ATTRIBUTES", + "PLUGIN_START_UNIT", + "PLUGIN_PRAGMAS", "PLUGIN_EVENT_LAST" }; @@ -325,6 +327,7 @@ register_callback (const char *plugin_name, case PLUGIN_GGC_MARKING: case PLUGIN_GGC_END: case PLUGIN_ATTRIBUTES: + case PLUGIN_PRAGMAS: case PLUGIN_FINISH: { struct callback_info *new_callback; @@ -344,7 +347,7 @@ register_callback (const char *plugin_name, break; case PLUGIN_EVENT_LAST: default: - error ("Unkown callback event registered by plugin %s", + error ("Unknown callback event registered by plugin %s", plugin_name); } } @@ -368,6 +371,7 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data) case PLUGIN_FINISH_UNIT: case PLUGIN_CXX_CP_PRE_GENERICIZE: case PLUGIN_ATTRIBUTES: + case PLUGIN_PRAGMAS: case PLUGIN_FINISH: case PLUGIN_GGC_START: case PLUGIN_GGC_MARKING: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1c31757..bf74370 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2009-11-06 Basile Starynkevitch <basile@starynkevitch.net> + + * g++.dg/plugin/pragma_plugin-test-1.C: new testcase for + PLUGIN_PRAGMAS. + * g++.dg/plugin/pragma_plugin.c: new test plugin for + PLUGIN_PRAGMAS. + * g++.dg/plugin/plugin.exp (plugin_test_list): Add pragma_plugin.c and + pragma_plugin-test-1.C. + 2009-11-06 Andrew Pinski <andrew_pinski@playstation.sony.com> PR c++/41536 diff --git a/gcc/testsuite/g++.dg/plugin/plugin.exp b/gcc/testsuite/g++.dg/plugin/plugin.exp index 4ba73e5..72de92d 100644 --- a/gcc/testsuite/g++.dg/plugin/plugin.exp +++ b/gcc/testsuite/g++.dg/plugin/plugin.exp @@ -48,6 +48,7 @@ load_lib plugin-support.exp # plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... } set plugin_test_list [list \ { attribute_plugin.c attribute_plugin-test-1.C } \ + { 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 } ] diff --git a/gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C b/gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C new file mode 100644 index 0000000..3c08420 --- /dev/null +++ b/gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C @@ -0,0 +1,18 @@ +// { dg-warning "Callback to register pragmas" "" { target *-*-* } 0 } + +int some_func (int c); + +#pragma GCCPLUGIN sayhello "here" // { dg-warning "'pragma GCCPLUGIN sayhello' outside of function: here" } + +int some_func (const char* s) +{ +#pragma GCCPLUGIN sayhello "at start" // { dg-warning "'pragma GCCPLUGIN sayhello' from function 'some_func': at start" } + +#define DO_PRAGMA(x) _Pragma(#x) + if (!s) + { + DO_PRAGMA(GCCPLUGIN sayhello "in block"); // { dg-warning "'pragma GCCPLUGIN sayhello' from function 'some_func': in block" } + return 0; + } + return 1; +} diff --git a/gcc/testsuite/g++.dg/plugin/pragma_plugin.c b/gcc/testsuite/g++.dg/plugin/pragma_plugin.c new file mode 100644 index 0000000..237fcdd --- /dev/null +++ b/gcc/testsuite/g++.dg/plugin/pragma_plugin.c @@ -0,0 +1,60 @@ +/* Demonstrates how to add custom pragmas */ + +#include "gcc-plugin.h" +#include <stdlib.h> +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "tree.h" +#include "function.h" +#include "c-pragma.h" +#include "cpplib.h" +#include "tree-pass.h" +#include "intl.h" + +int plugin_is_GPL_compatible; + + +/* handler of #pragma GCCPLUGIN sayhello "message" is quite similar to + handler of #pragma GCC message...*/ + +static void +handle_pragma_sayhello (cpp_reader *dummy) +{ + tree message = 0; + if (pragma_lex (&message) != CPP_STRING) + { + warning (OPT_Wpragmas, "%<#pragma GCCPLUGIN sayhello%> is not a string"); + return; + } + if (TREE_STRING_LENGTH (message) > 1) + if (cfun) + warning (OPT_Wpragmas, + "%<pragma GCCPLUGIN sayhello%> from function %qE: %s", + cfun->decl, TREE_STRING_POINTER (message)); + else + warning (OPT_Wpragmas, + "%<pragma GCCPLUGIN sayhello%> outside of function: %s", + TREE_STRING_POINTER (message)); +} + +/* Plugin callback called during pragma registration */ + +static void +register_my_pragma (void *event_data, void *data) +{ + warning (0, G_("Callback to register pragmas")); + c_register_pragma ("GCCPLUGIN", "sayhello", handle_pragma_sayhello); +} + +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_PRAGMAS, register_my_pragma, NULL); + return 0; +} |