context.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* Generic plugin context
  2. Copyright (C) 2020-2022 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <cc1plugin-config.h>
  16. #undef PACKAGE_NAME
  17. #undef PACKAGE_STRING
  18. #undef PACKAGE_TARNAME
  19. #undef PACKAGE_VERSION
  20. #include "../gcc/config.h"
  21. #undef PACKAGE_NAME
  22. #undef PACKAGE_STRING
  23. #undef PACKAGE_TARNAME
  24. #undef PACKAGE_VERSION
  25. #include "gcc-plugin.h"
  26. #include "system.h"
  27. #include "coretypes.h"
  28. #include "stringpool.h"
  29. #include "hash-set.h"
  30. #include "diagnostic.h"
  31. #include "langhooks.h"
  32. #include "langhooks-def.h"
  33. #include "gcc-interface.h"
  34. #include "context.hh"
  35. #include "marshall.hh"
  36. #ifdef __GNUC__
  37. #pragma GCC visibility push(default)
  38. #endif
  39. int plugin_is_GPL_compatible;
  40. #ifdef __GNUC__
  41. #pragma GCC visibility pop
  42. #endif
  43. cc1_plugin::plugin_context *cc1_plugin::current_context;
  44. // This is put into the lang hooks when the plugin starts.
  45. static void
  46. plugin_print_error_function (diagnostic_context *context, const char *file,
  47. diagnostic_info *diagnostic)
  48. {
  49. if (current_function_decl != NULL_TREE
  50. && DECL_NAME (current_function_decl) != NULL_TREE
  51. && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
  52. GCC_FE_WRAPPER_FUNCTION) == 0)
  53. return;
  54. lhd_print_error_function (context, file, diagnostic);
  55. }
  56. location_t
  57. cc1_plugin::plugin_context::get_location_t (const char *filename,
  58. unsigned int line_number)
  59. {
  60. if (filename == NULL)
  61. return UNKNOWN_LOCATION;
  62. filename = intern_filename (filename);
  63. linemap_add (line_table, LC_ENTER, false, filename, line_number);
  64. location_t loc = linemap_line_start (line_table, line_number, 0);
  65. linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  66. return loc;
  67. }
  68. // Add a file name to FILE_NAMES and return the canonical copy.
  69. const char *
  70. cc1_plugin::plugin_context::intern_filename (const char *filename)
  71. {
  72. const char **slot = file_names.find_slot (filename, INSERT);
  73. if (*slot == NULL)
  74. {
  75. /* The file name must live as long as the line map, which
  76. effectively means as long as this compilation. So, we copy
  77. the string here but never free it. */
  78. *slot = xstrdup (filename);
  79. }
  80. return *slot;
  81. }
  82. void
  83. cc1_plugin::plugin_context::mark ()
  84. {
  85. for (const auto &item : address_map)
  86. {
  87. ggc_mark (item->decl);
  88. ggc_mark (item->address);
  89. }
  90. for (const auto &item : preserved)
  91. ggc_mark (&item);
  92. }
  93. // Perform GC marking.
  94. static void
  95. gc_mark (void *, void *)
  96. {
  97. if (cc1_plugin::current_context != NULL)
  98. cc1_plugin::current_context->mark ();
  99. }
  100. void
  101. cc1_plugin::generic_plugin_init (struct plugin_name_args *plugin_info,
  102. unsigned int version)
  103. {
  104. long fd = -1;
  105. for (int i = 0; i < plugin_info->argc; ++i)
  106. {
  107. if (strcmp (plugin_info->argv[i].key, "fd") == 0)
  108. {
  109. char *tail;
  110. errno = 0;
  111. fd = strtol (plugin_info->argv[i].value, &tail, 0);
  112. if (*tail != '\0' || errno != 0)
  113. fatal_error (input_location,
  114. "%s: invalid file descriptor argument to plugin",
  115. plugin_info->base_name);
  116. break;
  117. }
  118. }
  119. if (fd == -1)
  120. fatal_error (input_location,
  121. "%s: required plugin argument %<fd%> is missing",
  122. plugin_info->base_name);
  123. current_context = new plugin_context (fd);
  124. // Handshake.
  125. cc1_plugin::protocol_int h_version;
  126. if (!current_context->require ('H')
  127. || ! ::cc1_plugin::unmarshall (current_context, &h_version))
  128. fatal_error (input_location,
  129. "%s: handshake failed", plugin_info->base_name);
  130. if (h_version != version)
  131. fatal_error (input_location,
  132. "%s: unknown version in handshake", plugin_info->base_name);
  133. register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
  134. gc_mark, NULL);
  135. lang_hooks.print_error_function = plugin_print_error_function;
  136. }