1 /* Generic plugin context
2 Copyright (C) 2020-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include <cc1plugin-config.h>
24 #undef PACKAGE_TARNAME
25 #undef PACKAGE_VERSION
27 #include "../gcc/config.h"
31 #undef PACKAGE_TARNAME
32 #undef PACKAGE_VERSION
34 #include "gcc-plugin.h"
36 #include "coretypes.h"
37 #include "stringpool.h"
39 #include "diagnostic.h"
40 #include "langhooks.h"
41 #include "langhooks-def.h"
43 #include "gcc-interface.h"
46 #include "marshall.hh"
51 #pragma GCC visibility push(default)
53 int plugin_is_GPL_compatible
;
55 #pragma GCC visibility pop
58 cc1_plugin::plugin_context
*cc1_plugin::current_context
;
62 // This is put into the lang hooks when the plugin starts.
65 plugin_print_error_function (diagnostic_context
*context
, const char *file
,
66 diagnostic_info
*diagnostic
)
68 if (current_function_decl
!= NULL_TREE
69 && DECL_NAME (current_function_decl
) != NULL_TREE
70 && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl
)),
71 GCC_FE_WRAPPER_FUNCTION
) == 0)
73 lhd_print_error_function (context
, file
, diagnostic
);
79 cc1_plugin::plugin_context::get_location_t (const char *filename
,
80 unsigned int line_number
)
83 return UNKNOWN_LOCATION
;
85 filename
= intern_filename (filename
);
86 linemap_add (line_table
, LC_ENTER
, false, filename
, line_number
);
87 location_t loc
= linemap_line_start (line_table
, line_number
, 0);
88 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
92 // Add a file name to FILE_NAMES and return the canonical copy.
94 cc1_plugin::plugin_context::intern_filename (const char *filename
)
96 const char **slot
= file_names
.find_slot (filename
, INSERT
);
99 /* The file name must live as long as the line map, which
100 effectively means as long as this compilation. So, we copy
101 the string here but never free it. */
102 *slot
= xstrdup (filename
);
108 cc1_plugin::plugin_context::mark ()
110 for (const auto &item
: address_map
)
112 ggc_mark (item
->decl
);
113 ggc_mark (item
->address
);
116 for (const auto &item
: preserved
)
122 // Perform GC marking.
125 gc_mark (void *, void *)
127 if (cc1_plugin::current_context
!= NULL
)
128 cc1_plugin::current_context
->mark ();
132 cc1_plugin::generic_plugin_init (struct plugin_name_args
*plugin_info
,
133 unsigned int version
)
136 for (int i
= 0; i
< plugin_info
->argc
; ++i
)
138 if (strcmp (plugin_info
->argv
[i
].key
, "fd") == 0)
142 fd
= strtol (plugin_info
->argv
[i
].value
, &tail
, 0);
143 if (*tail
!= '\0' || errno
!= 0)
144 fatal_error (input_location
,
145 "%s: invalid file descriptor argument to plugin",
146 plugin_info
->base_name
);
151 fatal_error (input_location
,
152 "%s: required plugin argument %<fd%> is missing",
153 plugin_info
->base_name
);
155 current_context
= new plugin_context (fd
);
158 cc1_plugin::protocol_int h_version
;
159 if (!current_context
->require ('H')
160 || ! ::cc1_plugin::unmarshall (current_context
, &h_version
))
161 fatal_error (input_location
,
162 "%s: handshake failed", plugin_info
->base_name
);
163 if (h_version
!= version
)
164 fatal_error (input_location
,
165 "%s: unknown version in handshake", plugin_info
->base_name
);
167 register_callback (plugin_info
->base_name
, PLUGIN_GGC_MARKING
,
170 lang_hooks
.print_error_function
= plugin_print_error_function
;