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 /libcc1/context.cc | |
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.
Diffstat (limited to 'libcc1/context.cc')
-rw-r--r-- | libcc1/context.cc | 171 |
1 files changed, 171 insertions, 0 deletions
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; +} |