This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PLUGIN_PRAGMAS event


>>
>> The patch still has PLUGIN_START_UNIT in plugin.c
>
> PLUGIN_START_UNIT seems to already be in the trunk rev 153950. I believe it
> was added by somebody else, and I strongly believe it should not be removed
> (that is, all plugin events should be kept).
> And the string "PLUGIN_ATTRIBUTES" seems to be missing in its plugin.c; I am
> correcting that also in the submitted patch here.

That is correct. I misread the first patch. Thanks.

> I tend to believe that we should have a plugin-events.def file containing
> the list of events like
>
> ÂPLUGIN_EVENT(PLUGIN_PASS_MANAGER_SETUP)
> ÂPLUGIN_EVENT(PLUGIN_FINISH_TYPE)
> ÂPLUGIN_EVENT(PLUGIN_FINISH_UNIT)
>
> and include it with various #define of PLUGIN_EVENT both in gcc-plugin.h &
> plugin.c. We could even generate some part of plugins.texi but I won't
> propose such a patch if people are not interested.
> Perhaps we should sort alphabetically the list of events there.

Should be good to have. Maybe in the next stage1?

> There is also a typo in the error message when the callback event is
> unknown.

Thanks for fixing.

> Back to PLUGIN_PRAGMAS.
>
>>
>> The test fails with:
>> Âerror: 'abort' was not declared in this scope
>
> I removed the use of abort. ÂI tried to reproduce the dg comments from other
> tests, but which the plugin_pragma.c does work as expected, the comments in
> gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C
> are not making dejagnu happy. Unfortunately I never understood dejagnu. But
> when the pragma_plugin.so is loaded, it works as I expect:
>
> /usr/src/Lang/gcc-trunk-bstarynk/gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C:5:28:
> warning: 'pragma GCCPLUGIN sayhello' outside of function: here
> /usr/src/Lang/gcc-trunk-bstarynk/gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C:
> In function 'int some_func(const char*)':
> /usr/src/Lang/gcc-trunk-bstarynk/gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C:11:28:
> warning: 'pragma GCCPLUGIN sayhello' from function 'some_func': at start
> /usr/src/Lang/gcc-trunk-bstarynk/gcc/testsuite/g++.dg/plugin/pragma_plugin-test-1.C:16:20:
> warning: 'pragma GCCPLUGIN sayhello' from function 'some_func': in block
>
> What are the comments needed in pragma_plugin-test-1.C to make dejagnu
> happy?

Looks like the problem is that the comments have to be in the same
line as the pragmas and that some single quotes were missing. I have
attached a fix.

I think the patch is OK. Richard, Diego, the impact is probably low,
OK during stage3?

> Respectful regards.
>
> --
> Basile STARYNKEVITCH Â Â Â Â http://starynkevitch.net/Basile/
> email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
> 8, rue de la Faiencerie, 92340 Bourg La Reine, France
> *** opinions {are only mines, sont seulement les miennes} ***
>

Cheers,
-- 
Rafael Ãvila de EspÃndola
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/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;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]