1 /* Generic plugin context
2 Copyright (C) 2020-2025 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"
42 #include "diagnostic-format-text.h"
44 #include "gcc-interface.h"
47 #include "marshall.hh"
52 #pragma GCC visibility push(default)
54 int plugin_is_GPL_compatible
;
56 #pragma GCC visibility pop
59 cc1_plugin::plugin_context
*cc1_plugin::current_context
;
63 // This is put into the lang hooks when the plugin starts.
66 plugin_print_error_function (diagnostic_text_output_format
&text_output
,
68 const diagnostic_info
*diagnostic
)
70 if (current_function_decl
!= NULL_TREE
71 && DECL_NAME (current_function_decl
) != NULL_TREE
72 && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl
)),
73 GCC_FE_WRAPPER_FUNCTION
) == 0)
75 lhd_print_error_function (text_output
, file
, diagnostic
);
81 cc1_plugin::plugin_context::get_location_t (const char *filename
,
82 unsigned int line_number
)
85 return UNKNOWN_LOCATION
;
87 filename
= intern_filename (filename
);
88 linemap_add (line_table
, LC_ENTER
, false, filename
, line_number
);
89 location_t loc
= linemap_line_start (line_table
, line_number
, 0);
90 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
94 // Add a file name to FILE_NAMES and return the canonical copy.
96 cc1_plugin::plugin_context::intern_filename (const char *filename
)
98 const char **slot
= file_names
.find_slot (filename
, INSERT
);
101 /* The file name must live as long as the line map, which
102 effectively means as long as this compilation. So, we copy
103 the string here but never free it. */
104 *slot
= xstrdup (filename
);
110 cc1_plugin::plugin_context::mark ()
112 for (const auto &item
: address_map
)
114 ggc_mark (item
->decl
);
115 ggc_mark (item
->address
);
118 for (const auto &item
: preserved
)
124 // Perform GC marking.
127 gc_mark (void *, void *)
129 if (cc1_plugin::current_context
!= NULL
)
130 cc1_plugin::current_context
->mark ();
134 cc1_plugin::generic_plugin_init (struct plugin_name_args
*plugin_info
,
135 unsigned int version
)
138 for (int i
= 0; i
< plugin_info
->argc
; ++i
)
140 if (strcmp (plugin_info
->argv
[i
].key
, "fd") == 0)
144 fd
= strtol (plugin_info
->argv
[i
].value
, &tail
, 0);
145 if (*tail
!= '\0' || errno
!= 0)
146 fatal_error (input_location
,
147 "%s: invalid file descriptor argument to plugin",
148 plugin_info
->base_name
);
153 fatal_error (input_location
,
154 "%s: required plugin argument %<fd%> is missing",
155 plugin_info
->base_name
);
157 current_context
= new plugin_context (fd
);
160 cc1_plugin::protocol_int h_version
;
161 if (!current_context
->require ('H')
162 || ! ::cc1_plugin::unmarshall (current_context
, &h_version
))
163 fatal_error (input_location
,
164 "%s: handshake failed", plugin_info
->base_name
);
165 if (h_version
!= version
)
166 fatal_error (input_location
,
167 "%s: unknown version in handshake", plugin_info
->base_name
);
169 register_callback (plugin_info
->base_name
, PLUGIN_GGC_MARKING
,
172 lang_hooks
.print_error_function
= plugin_print_error_function
;