diff options
author | Tom Tromey <tom@tromey.com> | 2021-05-04 15:26:58 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2021-05-05 00:06:17 -0600 |
commit | 0624823260f953050447a909da87f031488dba13 (patch) | |
tree | 0bfb6977bc5cc58a57f2d2df6f5dea9c0f477e82 | |
parent | 0ed83e1d03b4864b5f50b6a8735ed8e3a3635193 (diff) | |
download | gcc-0624823260f953050447a909da87f031488dba13.zip gcc-0624823260f953050447a909da87f031488dba13.tar.gz gcc-0624823260f953050447a909da87f031488dba13.tar.bz2 |
libcc1: share basic context code
Both plugins in libcc1 share a fair amount of boilerplate. They both
share error-emission code, context management code, and tree GC code.
This patch unifies these two bodies of code, avoiding needless
duplication.
libcc1
* libcc1plugin.cc: Move code to context.cc.
* libcp1plugin.cc: Move code to context.cc.
* context.hh: New file.
* context.cc: New file.
* Makefile.in: Rebuild.
* Makefile.am (AM_CPPFLAGS): Add more gcc flags.
(CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): Update.
(libcc1plugin_la_SOURCES): Add context.hh, context.cc.
(libcp1plugin_la_SOURCES): Likewise.
-rw-r--r-- | libcc1/Makefile.am | 15 | ||||
-rw-r--r-- | libcc1/Makefile.in | 27 | ||||
-rw-r--r-- | libcc1/context.cc | 171 | ||||
-rw-r--r-- | libcc1/context.hh | 121 | ||||
-rw-r--r-- | libcc1/libcc1plugin.cc | 204 | ||||
-rw-r--r-- | libcc1/libcp1plugin.cc | 203 |
6 files changed, 321 insertions, 420 deletions
diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am index 3f20513..9ec0210 100644 --- a/libcc1/Makefile.am +++ b/libcc1/Makefile.am @@ -19,11 +19,10 @@ ACLOCAL_AMFLAGS = -I .. -I ../config gcc_build_dir = ../gcc AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \ - -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) -CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \ - -I $(srcdir)/../libcpp/include -CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c -CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp + -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \ + -I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include +CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c +CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR) $(visibility) $(CET_HOST_FLAGS) if DARWIN_DYNAMIC_LOOKUP AM_CXXFLAGS += -Wl,-undefined,dynamic_lookup @@ -55,7 +54,8 @@ marshall_c_source = marshall-c.hh marshall_cxx_source = marshall-cp.hh libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym -libcc1plugin_la_SOURCES = libcc1plugin.cc $(shared_source) $(marshall_c_source) +libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_c_source) libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C) libcc1plugin_la_LIBADD = $(libiberty) libcc1plugin_la_DEPENDENCIES = $(libiberty_dep) @@ -64,7 +64,8 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@ libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym -libcp1plugin_la_SOURCES = libcp1plugin.cc $(shared_source) $(marshall_cxx_source) +libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_cxx_source) libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX) libcp1plugin_la_LIBADD = $(libiberty) libcp1plugin_la_DEPENDENCIES = $(libiberty_dep) diff --git a/libcc1/Makefile.in b/libcc1/Makefile.in index d76893e..395f01a 100644 --- a/libcc1/Makefile.in +++ b/libcc1/Makefile.in @@ -148,12 +148,12 @@ am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo compiler.lo \ names.lo $(am__objects_1) $(am__objects_2) $(am__objects_2) libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS) @ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir) -am_libcc1plugin_la_OBJECTS = libcc1plugin.lo $(am__objects_1) \ - $(am__objects_2) +am_libcc1plugin_la_OBJECTS = libcc1plugin.lo context.lo \ + $(am__objects_1) $(am__objects_2) libcc1plugin_la_OBJECTS = $(am_libcc1plugin_la_OBJECTS) @ENABLE_PLUGIN_TRUE@am_libcc1plugin_la_rpath = -rpath $(plugindir) -am_libcp1plugin_la_OBJECTS = libcp1plugin.lo $(am__objects_1) \ - $(am__objects_2) +am_libcp1plugin_la_OBJECTS = libcp1plugin.lo context.lo \ + $(am__objects_1) $(am__objects_2) libcp1plugin_la_OBJECTS = $(am_libcp1plugin_la_OBJECTS) @ENABLE_PLUGIN_TRUE@am_libcp1plugin_la_rpath = -rpath $(plugindir) AM_V_P = $(am__v_P_@AM_V@) @@ -379,13 +379,11 @@ visibility = @visibility@ ACLOCAL_AMFLAGS = -I .. -I ../config gcc_build_dir = ../gcc AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \ - -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) + -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \ + -I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include -CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \ - -I $(srcdir)/../libcpp/include - -CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c -CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp +CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c +CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR) $(visibility) $(CET_HOST_FLAGS) \ $(am__append_1) # Can be simplified when libiberty becomes a normal convenience library. @@ -408,7 +406,9 @@ shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \ marshall_c_source = marshall-c.hh marshall_cxx_source = marshall-cp.hh libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym -libcc1plugin_la_SOURCES = libcc1plugin.cc $(shared_source) $(marshall_c_source) +libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_c_source) + libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C) libcc1plugin_la_LIBADD = $(libiberty) libcc1plugin_la_DEPENDENCIES = $(libiberty_dep) @@ -417,7 +417,9 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@ libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym -libcp1plugin_la_SOURCES = libcp1plugin.cc $(shared_source) $(marshall_cxx_source) +libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_cxx_source) + libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX) libcp1plugin_la_LIBADD = $(libiberty) libcp1plugin_la_DEPENDENCIES = $(libiberty_dep) @@ -579,6 +581,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compiler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findcomp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1plugin.Plo@am__quote@ diff --git a/libcc1/context.cc b/libcc1/context.cc new file mode 100644 index 0000000..3d5ff92 --- /dev/null +++ b/libcc1/context.cc @@ -0,0 +1,171 @@ +/* Generic plugin context + Copyright (C) 2020 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include <cc1plugin-config.h> + +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + +#include "../gcc/config.h" + +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + +#include "gcc-plugin.h" +#include "system.h" +#include "coretypes.h" +#include "stringpool.h" +#include "hash-set.h" +#include "diagnostic.h" +#include "langhooks.h" +#include "langhooks-def.h" + +#include "gcc-interface.h" + +#include "context.hh" +#include "marshall.hh" + + + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +int plugin_is_GPL_compatible; +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +cc1_plugin::plugin_context *cc1_plugin::current_context; + + + +// This is put into the lang hooks when the plugin starts. + +static void +plugin_print_error_function (diagnostic_context *context, const char *file, + diagnostic_info *diagnostic) +{ + if (current_function_decl != NULL_TREE + && DECL_NAME (current_function_decl) != NULL_TREE + && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), + GCC_FE_WRAPPER_FUNCTION) == 0) + return; + lhd_print_error_function (context, file, diagnostic); +} + + + +location_t +cc1_plugin::plugin_context::get_location_t (const char *filename, + unsigned int line_number) +{ + if (filename == NULL) + return UNKNOWN_LOCATION; + + filename = intern_filename (filename); + linemap_add (line_table, LC_ENTER, false, filename, line_number); + location_t loc = linemap_line_start (line_table, line_number, 0); + linemap_add (line_table, LC_LEAVE, false, NULL, 0); + return loc; +} + +// Add a file name to FILE_NAMES and return the canonical copy. +const char * +cc1_plugin::plugin_context::intern_filename (const char *filename) +{ + const char **slot = file_names.find_slot (filename, INSERT); + if (*slot == NULL) + { + /* The file name must live as long as the line map, which + effectively means as long as this compilation. So, we copy + the string here but never free it. */ + *slot = xstrdup (filename); + } + return *slot; +} + +void +cc1_plugin::plugin_context::mark () +{ + for (const auto &item : address_map) + { + ggc_mark (item->decl); + ggc_mark (item->address); + } + + for (const auto &item : preserved) + ggc_mark (&item); +} + + + +// Perform GC marking. + +static void +gc_mark (void *, void *) +{ + if (cc1_plugin::current_context != NULL) + cc1_plugin::current_context->mark (); +} + +void +cc1_plugin::generic_plugin_init (struct plugin_name_args *plugin_info, + unsigned int version) +{ + long fd = -1; + for (int i = 0; i < plugin_info->argc; ++i) + { + if (strcmp (plugin_info->argv[i].key, "fd") == 0) + { + char *tail; + errno = 0; + fd = strtol (plugin_info->argv[i].value, &tail, 0); + if (*tail != '\0' || errno != 0) + fatal_error (input_location, + "%s: invalid file descriptor argument to plugin", + plugin_info->base_name); + break; + } + } + if (fd == -1) + fatal_error (input_location, + "%s: required plugin argument %<fd%> is missing", + plugin_info->base_name); + + current_context = new plugin_context (fd); + + // Handshake. + cc1_plugin::protocol_int h_version; + if (!current_context->require ('H') + || ! ::cc1_plugin::unmarshall (current_context, &h_version)) + fatal_error (input_location, + "%s: handshake failed", plugin_info->base_name); + if (h_version != version) + fatal_error (input_location, + "%s: unknown version in handshake", plugin_info->base_name); + + register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING, + gc_mark, NULL); + + lang_hooks.print_error_function = plugin_print_error_function; +} diff --git a/libcc1/context.hh b/libcc1/context.hh new file mode 100644 index 0000000..21a8262 --- /dev/null +++ b/libcc1/context.hh @@ -0,0 +1,121 @@ +/* Generic plugin context + Copyright (C) 2020 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef CC1_PLUGIN_CONTEXT_HH +#define CC1_PLUGIN_CONTEXT_HH + +#include "system.h" +#include "coretypes.h" +#include "tree.h" + +#include "connection.hh" + +namespace cc1_plugin +{ + static inline unsigned long long + convert_out (tree t) + { + return (unsigned long long) (uintptr_t) t; + } + + static inline tree + convert_in (unsigned long long v) + { + return (tree) (uintptr_t) v; + } + + struct decl_addr_value + { + tree decl; + tree address; + }; + + struct decl_addr_hasher : free_ptr_hash<decl_addr_value> + { + static hashval_t hash (const decl_addr_value *e) + { + return DECL_UID (e->decl); + } + + static bool equal (const decl_addr_value *p1, + const decl_addr_value *p2) + { + return p1->decl == p2->decl; + } + }; + + struct string_hasher : nofree_ptr_hash<const char> + { + static inline hashval_t hash (const char *s) + { + return htab_hash_string (s); + } + + static inline bool equal (const char *p1, const char *p2) + { + return strcmp (p1, p2) == 0; + } + }; + + struct plugin_context : public cc1_plugin::connection + { + plugin_context (int fd) + : cc1_plugin::connection (fd), + address_map (30), + preserved (30), + file_names (30) + { + } + + // Map decls to addresses. + hash_table<decl_addr_hasher> address_map; + + // A collection of trees that are preserved for the GC. + hash_table< nofree_ptr_hash<tree_node> > preserved; + + // File name cache. + hash_table<string_hasher> file_names; + + // Perform GC marking. + void mark (); + + // Preserve a tree during the plugin's operation. + tree preserve (tree t) + { + tree_node **slot = preserved.find_slot (t, INSERT); + *slot = t; + return t; + } + + location_t get_location_t (const char *filename, + unsigned int line_number); + + private: + + // Add a file name to FILE_NAMES and return the canonical copy. + const char *intern_filename (const char *filename); + }; + + extern plugin_context *current_context; + + void generic_plugin_init (struct plugin_name_args *plugin_info, + unsigned int version); +} + +#endif // CC1_PLUGIN_CONTEXT_HH diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc index 2a75fab..d6951ab 100644 --- a/libcc1/libcc1plugin.cc +++ b/libcc1/libcc1plugin.cc @@ -66,87 +66,11 @@ #include "marshall.hh" #include "rpc.hh" #include "gcc-c-interface.h" +#include "context.hh" #include <vector> -#ifdef __GNUC__ -#pragma GCC visibility push(default) -#endif -int plugin_is_GPL_compatible; -#ifdef __GNUC__ -#pragma GCC visibility pop -#endif - - - -// This is put into the lang hooks when the plugin starts. - -static void -plugin_print_error_function (diagnostic_context *context, const char *file, - diagnostic_info *diagnostic) -{ - if (current_function_decl != NULL_TREE - && DECL_NAME (current_function_decl) != NULL_TREE - && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), - GCC_FE_WRAPPER_FUNCTION) == 0) - return; - lhd_print_error_function (context, file, diagnostic); -} - - - -static unsigned long long -convert_out (tree t) -{ - return (unsigned long long) (uintptr_t) t; -} - -static tree -convert_in (unsigned long long v) -{ - return (tree) (uintptr_t) v; -} - - - -struct decl_addr_value -{ - tree decl; - tree address; -}; - -struct decl_addr_hasher : free_ptr_hash<decl_addr_value> -{ - static inline hashval_t hash (const decl_addr_value *); - static inline bool equal (const decl_addr_value *, const decl_addr_value *); -}; - -inline hashval_t -decl_addr_hasher::hash (const decl_addr_value *e) -{ - return IDENTIFIER_HASH_VALUE (DECL_NAME (e->decl)); -} - -inline bool -decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2) -{ - return p1->decl == p2->decl; -} - - - -struct string_hasher : nofree_ptr_hash<const char> -{ - static inline hashval_t hash (const char *s) - { - return htab_hash_string (s); - } - - static inline bool equal (const char *p1, const char *p2) - { - return strcmp (p1, p2) == 0; - } -}; +using namespace cc1_plugin; @@ -166,85 +90,6 @@ pushdecl_safe (tree decl) -struct plugin_context : public cc1_plugin::connection -{ - plugin_context (int fd); - - // Map decls to addresses. - hash_table<decl_addr_hasher> address_map; - - // A collection of trees that are preserved for the GC. - hash_table< nofree_ptr_hash<tree_node> > preserved; - - // File name cache. - hash_table<string_hasher> file_names; - - // Perform GC marking. - void mark (); - - // Preserve a tree during the plugin's operation. - tree preserve (tree t) - { - tree_node **slot = preserved.find_slot (t, INSERT); - *slot = t; - return t; - } - - location_t get_location_t (const char *filename, - unsigned int line_number) - { - if (filename == NULL) - return UNKNOWN_LOCATION; - - filename = intern_filename (filename); - linemap_add (line_table, LC_ENTER, false, filename, line_number); - location_t loc = linemap_line_start (line_table, line_number, 0); - linemap_add (line_table, LC_LEAVE, false, NULL, 0); - return loc; - } - -private: - - // Add a file name to FILE_NAMES and return the canonical copy. - const char *intern_filename (const char *filename) - { - const char **slot = file_names.find_slot (filename, INSERT); - if (*slot == NULL) - { - /* The file name must live as long as the line map, which - effectively means as long as this compilation. So, we copy - the string here but never free it. */ - *slot = xstrdup (filename); - } - return *slot; - } -}; - -static plugin_context *current_context; - - - -plugin_context::plugin_context (int fd) - : cc1_plugin::connection (fd), - address_map (30), - preserved (30), - file_names (30) -{ -} - -void -plugin_context::mark () -{ - for (const auto &item : address_map) - { - ggc_mark (item->decl); - ggc_mark (item->address); - } - - for (const auto &item : preserved) - ggc_mark (&item); -} - static void plugin_binding_oracle (enum c_oracle_request kind, tree identifier) { @@ -899,15 +744,6 @@ plugin_error (cc1_plugin::connection *, -// Perform GC marking. - -static void -gc_mark (void *, void *) -{ - if (current_context != NULL) - current_context->mark (); -} - #ifdef __GNUC__ #pragma GCC visibility push(default) #endif @@ -916,46 +752,12 @@ int plugin_init (struct plugin_name_args *plugin_info, struct plugin_gcc_version *) { - long fd = -1; - for (int i = 0; i < plugin_info->argc; ++i) - { - if (strcmp (plugin_info->argv[i].key, "fd") == 0) - { - char *tail; - errno = 0; - fd = strtol (plugin_info->argv[i].value, &tail, 0); - if (*tail != '\0' || errno != 0) - fatal_error (input_location, - "%s: invalid file descriptor argument to plugin", - plugin_info->base_name); - break; - } - } - if (fd == -1) - fatal_error (input_location, - "%s: required plugin argument %<fd%> is missing", - plugin_info->base_name); - - current_context = new plugin_context (fd); - - // Handshake. - cc1_plugin::protocol_int version; - if (!current_context->require ('H') - || ! ::cc1_plugin::unmarshall (current_context, &version)) - fatal_error (input_location, - "%s: handshake failed", plugin_info->base_name); - if (version != GCC_C_FE_VERSION_1) - fatal_error (input_location, - "%s: unknown version in handshake", plugin_info->base_name); + generic_plugin_init (plugin_info, GCC_C_FE_VERSION_1); register_callback (plugin_info->base_name, PLUGIN_PRAGMAS, plugin_init_extra_pragmas, NULL); register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE, rewrite_decls_to_addresses, NULL); - register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING, - gc_mark, NULL); - - lang_hooks.print_error_function = plugin_print_error_function; #define GCC_METHOD0(R, N) \ { \ diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc index ba6c5ef..64cde65 100644 --- a/libcc1/libcp1plugin.cc +++ b/libcc1/libcp1plugin.cc @@ -38,7 +38,6 @@ #include "stringpool.h" #include "gcc-interface.h" -#include "hash-set.h" #include "machmode.h" #include "vec.h" #include "double-int.h" @@ -69,172 +68,19 @@ #include "connection.hh" #include "marshall-cp.hh" #include "rpc.hh" +#include "context.hh" #include <vector> -#ifdef __GNUC__ -#pragma GCC visibility push(default) -#endif -int plugin_is_GPL_compatible; -#ifdef __GNUC__ -#pragma GCC visibility pop -#endif +using namespace cc1_plugin; static_assert (GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END, "GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END"); -// This is put into the lang hooks when the plugin starts. - -static void -plugin_print_error_function (diagnostic_context *context, const char *file, - diagnostic_info *diagnostic) -{ - if (current_function_decl != NULL_TREE - && DECL_NAME (current_function_decl) != NULL_TREE - && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), - GCC_FE_WRAPPER_FUNCTION) == 0) - return; - lhd_print_error_function (context, file, diagnostic); -} - -static unsigned long long -convert_out (tree t) -{ - return (unsigned long long) (uintptr_t) t; -} - -static tree -convert_in (unsigned long long v) -{ - return (tree) (uintptr_t) v; -} - - - -struct decl_addr_value -{ - tree decl; - tree address; -}; - -struct decl_addr_hasher : free_ptr_hash<decl_addr_value> -{ - static inline hashval_t hash (const decl_addr_value *); - static inline bool equal (const decl_addr_value *, const decl_addr_value *); -}; - -inline hashval_t -decl_addr_hasher::hash (const decl_addr_value *e) -{ - return DECL_UID (e->decl); -} - -inline bool -decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2) -{ - return p1->decl == p2->decl; -} - - - -struct string_hasher : nofree_ptr_hash<const char> -{ - static inline hashval_t hash (const char *s) - { - return htab_hash_string (s); - } - - static inline bool equal (const char *p1, const char *p2) - { - return strcmp (p1, p2) == 0; - } -}; - - - -struct plugin_context : public cc1_plugin::connection -{ - plugin_context (int fd); - - // Map decls to addresses. - hash_table<decl_addr_hasher> address_map; - - // A collection of trees that are preserved for the GC. - hash_table< nofree_ptr_hash<tree_node> > preserved; - - // File name cache. - hash_table<string_hasher> file_names; - - // Perform GC marking. - void mark (); - - // Preserve a tree during the plugin's operation. - tree preserve (tree t) - { - tree_node **slot = preserved.find_slot (t, INSERT); - *slot = t; - return t; - } - - location_t get_location_t (const char *filename, - unsigned int line_number) - { - if (filename == NULL) - return UNKNOWN_LOCATION; - - filename = intern_filename (filename); - linemap_add (line_table, LC_ENTER, false, filename, line_number); - location_t loc = linemap_line_start (line_table, line_number, 0); - linemap_add (line_table, LC_LEAVE, false, NULL, 0); - return loc; - } - -private: - - // Add a file name to FILE_NAMES and return the canonical copy. - const char *intern_filename (const char *filename) - { - const char **slot = file_names.find_slot (filename, INSERT); - if (*slot == NULL) - { - /* The file name must live as long as the line map, which - effectively means as long as this compilation. So, we copy - the string here but never free it. */ - *slot = xstrdup (filename); - } - return *slot; - } -}; - -static plugin_context *current_context; - - - -plugin_context::plugin_context (int fd) - : cc1_plugin::connection (fd), - address_map (30), - preserved (30), - file_names (30) -{ -} - -void -plugin_context::mark () -{ - for (const auto &item : address_map) - { - ggc_mark (item->decl); - ggc_mark (item->address); - } - - for (const auto &item : preserved) - ggc_mark (&item); -} - static void plugin_binding_oracle (enum cp_oracle_request kind, tree identifier) { @@ -3645,15 +3491,6 @@ plugin_add_static_assert (cc1_plugin::connection *self, -// Perform GC marking. - -static void -gc_mark (void *, void *) -{ - if (current_context != NULL) - current_context->mark (); -} - #ifdef __GNUC__ #pragma GCC visibility push(default) #endif @@ -3662,46 +3499,12 @@ int plugin_init (struct plugin_name_args *plugin_info, struct plugin_gcc_version *) { - long fd = -1; - for (int i = 0; i < plugin_info->argc; ++i) - { - if (strcmp (plugin_info->argv[i].key, "fd") == 0) - { - char *tail; - errno = 0; - fd = strtol (plugin_info->argv[i].value, &tail, 0); - if (*tail != '\0' || errno != 0) - fatal_error (input_location, - "%s: invalid file descriptor argument to plugin", - plugin_info->base_name); - break; - } - } - if (fd == -1) - fatal_error (input_location, - "%s: required plugin argument %<fd%> is missing", - plugin_info->base_name); - - current_context = new plugin_context (fd); - - // Handshake. - cc1_plugin::protocol_int version; - if (!current_context->require ('H') - || ! ::cc1_plugin::unmarshall (current_context, &version)) - fatal_error (input_location, - "%s: handshake failed", plugin_info->base_name); - if (version != GCC_CP_FE_VERSION_0) - fatal_error (input_location, - "%s: unknown version in handshake", plugin_info->base_name); + generic_plugin_init (plugin_info, GCC_CP_FE_VERSION_0); register_callback (plugin_info->base_name, PLUGIN_PRAGMAS, plugin_init_extra_pragmas, NULL); register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE, rewrite_decls_to_addresses, NULL); - register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING, - gc_mark, NULL); - - lang_hooks.print_error_function = plugin_print_error_function; #define GCC_METHOD0(R, N) \ { \ |