123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /* Generic plugin context
- Copyright (C) 2020-2022 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;
- }
|