aboutsummaryrefslogtreecommitdiff
path: root/libcc1/context.cc
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2021-05-04 15:26:58 -0600
committerTom Tromey <tom@tromey.com>2021-05-05 00:06:17 -0600
commit0624823260f953050447a909da87f031488dba13 (patch)
tree0bfb6977bc5cc58a57f2d2df6f5dea9c0f477e82 /libcc1/context.cc
parent0ed83e1d03b4864b5f50b6a8735ed8e3a3635193 (diff)
downloadgcc-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.cc171
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;
+}