annotate libcc1/libcc1plugin.cc @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Library interface to C front end
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2014-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of GCC.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
9 version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
14 for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 #include <cc1plugin-config.h>
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #undef PACKAGE_NAME
kono
parents:
diff changeset
23 #undef PACKAGE_STRING
kono
parents:
diff changeset
24 #undef PACKAGE_TARNAME
kono
parents:
diff changeset
25 #undef PACKAGE_VERSION
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #include "../gcc/config.h"
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 #undef PACKAGE_NAME
kono
parents:
diff changeset
30 #undef PACKAGE_STRING
kono
parents:
diff changeset
31 #undef PACKAGE_TARNAME
kono
parents:
diff changeset
32 #undef PACKAGE_VERSION
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 #include "gcc-plugin.h"
kono
parents:
diff changeset
35 #include "system.h"
kono
parents:
diff changeset
36 #include "coretypes.h"
kono
parents:
diff changeset
37 #include "stringpool.h"
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 #include "gcc-interface.h"
kono
parents:
diff changeset
40 #include "hash-set.h"
kono
parents:
diff changeset
41 #include "machmode.h"
kono
parents:
diff changeset
42 #include "vec.h"
kono
parents:
diff changeset
43 #include "double-int.h"
kono
parents:
diff changeset
44 #include "input.h"
kono
parents:
diff changeset
45 #include "alias.h"
kono
parents:
diff changeset
46 #include "symtab.h"
kono
parents:
diff changeset
47 #include "options.h"
kono
parents:
diff changeset
48 #include "wide-int.h"
kono
parents:
diff changeset
49 #include "inchash.h"
kono
parents:
diff changeset
50 #include "tree.h"
kono
parents:
diff changeset
51 #include "fold-const.h"
kono
parents:
diff changeset
52 #include "stor-layout.h"
kono
parents:
diff changeset
53 #include "c-tree.h"
kono
parents:
diff changeset
54 #include "toplev.h"
kono
parents:
diff changeset
55 #include "timevar.h"
kono
parents:
diff changeset
56 #include "hash-table.h"
kono
parents:
diff changeset
57 #include "tm.h"
kono
parents:
diff changeset
58 #include "c-family/c-pragma.h"
kono
parents:
diff changeset
59 #include "c-lang.h"
kono
parents:
diff changeset
60 #include "diagnostic.h"
kono
parents:
diff changeset
61 #include "langhooks.h"
kono
parents:
diff changeset
62 #include "langhooks-def.h"
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 #include "callbacks.hh"
kono
parents:
diff changeset
65 #include "connection.hh"
kono
parents:
diff changeset
66 #include "marshall-c.hh"
kono
parents:
diff changeset
67 #include "rpc.hh"
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 #ifdef __GNUC__
kono
parents:
diff changeset
70 #pragma GCC visibility push(default)
kono
parents:
diff changeset
71 #endif
kono
parents:
diff changeset
72 int plugin_is_GPL_compatible;
kono
parents:
diff changeset
73 #ifdef __GNUC__
kono
parents:
diff changeset
74 #pragma GCC visibility pop
kono
parents:
diff changeset
75 #endif
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 // This is put into the lang hooks when the plugin starts.
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 static void
kono
parents:
diff changeset
82 plugin_print_error_function (diagnostic_context *context, const char *file,
kono
parents:
diff changeset
83 diagnostic_info *diagnostic)
kono
parents:
diff changeset
84 {
kono
parents:
diff changeset
85 if (current_function_decl != NULL_TREE
kono
parents:
diff changeset
86 && DECL_NAME (current_function_decl) != NULL_TREE
kono
parents:
diff changeset
87 && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
kono
parents:
diff changeset
88 GCC_FE_WRAPPER_FUNCTION) == 0)
kono
parents:
diff changeset
89 return;
kono
parents:
diff changeset
90 lhd_print_error_function (context, file, diagnostic);
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 static unsigned long long
kono
parents:
diff changeset
96 convert_out (tree t)
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 return (unsigned long long) (uintptr_t) t;
kono
parents:
diff changeset
99 }
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 static tree
kono
parents:
diff changeset
102 convert_in (unsigned long long v)
kono
parents:
diff changeset
103 {
kono
parents:
diff changeset
104 return (tree) (uintptr_t) v;
kono
parents:
diff changeset
105 }
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 struct decl_addr_value
kono
parents:
diff changeset
110 {
kono
parents:
diff changeset
111 tree decl;
kono
parents:
diff changeset
112 tree address;
kono
parents:
diff changeset
113 };
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
kono
parents:
diff changeset
116 {
kono
parents:
diff changeset
117 static inline hashval_t hash (const decl_addr_value *);
kono
parents:
diff changeset
118 static inline bool equal (const decl_addr_value *, const decl_addr_value *);
kono
parents:
diff changeset
119 };
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 inline hashval_t
kono
parents:
diff changeset
122 decl_addr_hasher::hash (const decl_addr_value *e)
kono
parents:
diff changeset
123 {
kono
parents:
diff changeset
124 return IDENTIFIER_HASH_VALUE (DECL_NAME (e->decl));
kono
parents:
diff changeset
125 }
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 inline bool
kono
parents:
diff changeset
128 decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2)
kono
parents:
diff changeset
129 {
kono
parents:
diff changeset
130 return p1->decl == p2->decl;
kono
parents:
diff changeset
131 }
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 struct string_hasher : nofree_ptr_hash<const char>
kono
parents:
diff changeset
136 {
kono
parents:
diff changeset
137 static inline hashval_t hash (const char *s)
kono
parents:
diff changeset
138 {
kono
parents:
diff changeset
139 return htab_hash_string (s);
kono
parents:
diff changeset
140 }
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 static inline bool equal (const char *p1, const char *p2)
kono
parents:
diff changeset
143 {
kono
parents:
diff changeset
144 return strcmp (p1, p2) == 0;
kono
parents:
diff changeset
145 }
kono
parents:
diff changeset
146 };
kono
parents:
diff changeset
147
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 // A wrapper for pushdecl that doesn't let gdb have a chance to
kono
parents:
diff changeset
151 // instantiate a symbol.
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 static void
kono
parents:
diff changeset
154 pushdecl_safe (tree decl)
kono
parents:
diff changeset
155 {
kono
parents:
diff changeset
156 void (*save) (enum c_oracle_request, tree identifier);
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 save = c_binding_oracle;
kono
parents:
diff changeset
159 c_binding_oracle = NULL;
kono
parents:
diff changeset
160 pushdecl (decl);
kono
parents:
diff changeset
161 c_binding_oracle = save;
kono
parents:
diff changeset
162 }
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 struct plugin_context : public cc1_plugin::connection
kono
parents:
diff changeset
167 {
kono
parents:
diff changeset
168 plugin_context (int fd);
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 // Map decls to addresses.
kono
parents:
diff changeset
171 hash_table<decl_addr_hasher> address_map;
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 // A collection of trees that are preserved for the GC.
kono
parents:
diff changeset
174 hash_table< nofree_ptr_hash<tree_node> > preserved;
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 // File name cache.
kono
parents:
diff changeset
177 hash_table<string_hasher> file_names;
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 // Perform GC marking.
kono
parents:
diff changeset
180 void mark ();
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 // Preserve a tree during the plugin's operation.
kono
parents:
diff changeset
183 tree preserve (tree t)
kono
parents:
diff changeset
184 {
kono
parents:
diff changeset
185 tree_node **slot = preserved.find_slot (t, INSERT);
kono
parents:
diff changeset
186 *slot = t;
kono
parents:
diff changeset
187 return t;
kono
parents:
diff changeset
188 }
kono
parents:
diff changeset
189
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
190 location_t get_location_t (const char *filename,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
191 unsigned int line_number)
111
kono
parents:
diff changeset
192 {
kono
parents:
diff changeset
193 if (filename == NULL)
kono
parents:
diff changeset
194 return UNKNOWN_LOCATION;
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 filename = intern_filename (filename);
kono
parents:
diff changeset
197 linemap_add (line_table, LC_ENTER, false, filename, line_number);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
198 location_t loc = linemap_line_start (line_table, line_number, 0);
111
kono
parents:
diff changeset
199 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
kono
parents:
diff changeset
200 return loc;
kono
parents:
diff changeset
201 }
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 private:
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 // Add a file name to FILE_NAMES and return the canonical copy.
kono
parents:
diff changeset
206 const char *intern_filename (const char *filename)
kono
parents:
diff changeset
207 {
kono
parents:
diff changeset
208 const char **slot = file_names.find_slot (filename, INSERT);
kono
parents:
diff changeset
209 if (*slot == NULL)
kono
parents:
diff changeset
210 {
kono
parents:
diff changeset
211 /* The file name must live as long as the line map, which
kono
parents:
diff changeset
212 effectively means as long as this compilation. So, we copy
kono
parents:
diff changeset
213 the string here but never free it. */
kono
parents:
diff changeset
214 *slot = xstrdup (filename);
kono
parents:
diff changeset
215 }
kono
parents:
diff changeset
216 return *slot;
kono
parents:
diff changeset
217 }
kono
parents:
diff changeset
218 };
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 static plugin_context *current_context;
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 plugin_context::plugin_context (int fd)
kono
parents:
diff changeset
225 : cc1_plugin::connection (fd),
kono
parents:
diff changeset
226 address_map (30),
kono
parents:
diff changeset
227 preserved (30),
kono
parents:
diff changeset
228 file_names (30)
kono
parents:
diff changeset
229 {
kono
parents:
diff changeset
230 }
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 void
kono
parents:
diff changeset
233 plugin_context::mark ()
kono
parents:
diff changeset
234 {
kono
parents:
diff changeset
235 for (hash_table<decl_addr_hasher>::iterator it = address_map.begin ();
kono
parents:
diff changeset
236 it != address_map.end ();
kono
parents:
diff changeset
237 ++it)
kono
parents:
diff changeset
238 {
kono
parents:
diff changeset
239 ggc_mark ((*it)->decl);
kono
parents:
diff changeset
240 ggc_mark ((*it)->address);
kono
parents:
diff changeset
241 }
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 for (hash_table< nofree_ptr_hash<tree_node> >::iterator
kono
parents:
diff changeset
244 it = preserved.begin (); it != preserved.end (); ++it)
kono
parents:
diff changeset
245 ggc_mark (&*it);
kono
parents:
diff changeset
246 }
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 static void
kono
parents:
diff changeset
249 plugin_binding_oracle (enum c_oracle_request kind, tree identifier)
kono
parents:
diff changeset
250 {
kono
parents:
diff changeset
251 enum gcc_c_oracle_request request;
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 gcc_assert (current_context != NULL);
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 switch (kind)
kono
parents:
diff changeset
256 {
kono
parents:
diff changeset
257 case C_ORACLE_SYMBOL:
kono
parents:
diff changeset
258 request = GCC_C_ORACLE_SYMBOL;
kono
parents:
diff changeset
259 break;
kono
parents:
diff changeset
260 case C_ORACLE_TAG:
kono
parents:
diff changeset
261 request = GCC_C_ORACLE_TAG;
kono
parents:
diff changeset
262 break;
kono
parents:
diff changeset
263 case C_ORACLE_LABEL:
kono
parents:
diff changeset
264 request = GCC_C_ORACLE_LABEL;
kono
parents:
diff changeset
265 break;
kono
parents:
diff changeset
266 default:
kono
parents:
diff changeset
267 abort ();
kono
parents:
diff changeset
268 }
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 int ignore;
kono
parents:
diff changeset
271 cc1_plugin::call (current_context, "binding_oracle", &ignore,
kono
parents:
diff changeset
272 request, IDENTIFIER_POINTER (identifier));
kono
parents:
diff changeset
273 }
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 static void
kono
parents:
diff changeset
276 plugin_pragma_user_expression (cpp_reader *)
kono
parents:
diff changeset
277 {
kono
parents:
diff changeset
278 c_binding_oracle = plugin_binding_oracle;
kono
parents:
diff changeset
279 }
kono
parents:
diff changeset
280
kono
parents:
diff changeset
281 static void
kono
parents:
diff changeset
282 plugin_init_extra_pragmas (void *, void *)
kono
parents:
diff changeset
283 {
kono
parents:
diff changeset
284 c_register_pragma ("GCC", "user_expression", plugin_pragma_user_expression);
kono
parents:
diff changeset
285 }
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 // Maybe rewrite a decl to its address.
kono
parents:
diff changeset
290 static tree
kono
parents:
diff changeset
291 address_rewriter (tree *in, int *walk_subtrees, void *arg)
kono
parents:
diff changeset
292 {
kono
parents:
diff changeset
293 plugin_context *ctx = (plugin_context *) arg;
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 if (!DECL_P (*in) || DECL_NAME (*in) == NULL_TREE)
kono
parents:
diff changeset
296 return NULL_TREE;
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 decl_addr_value value;
kono
parents:
diff changeset
299 value.decl = *in;
kono
parents:
diff changeset
300 decl_addr_value *found_value = ctx->address_map.find (&value);
kono
parents:
diff changeset
301 if (found_value != NULL)
kono
parents:
diff changeset
302 ;
kono
parents:
diff changeset
303 else if (DECL_IS_BUILTIN (*in))
kono
parents:
diff changeset
304 {
kono
parents:
diff changeset
305 gcc_address address;
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 if (!cc1_plugin::call (ctx, "address_oracle", &address,
kono
parents:
diff changeset
308 IDENTIFIER_POINTER (DECL_NAME (*in))))
kono
parents:
diff changeset
309 return NULL_TREE;
kono
parents:
diff changeset
310 if (address == 0)
kono
parents:
diff changeset
311 return NULL_TREE;
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 // Insert the decl into the address map in case it is referenced
kono
parents:
diff changeset
314 // again.
kono
parents:
diff changeset
315 value.address = build_int_cst_type (ptr_type_node, address);
kono
parents:
diff changeset
316 decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
kono
parents:
diff changeset
317 gcc_assert (*slot == NULL);
kono
parents:
diff changeset
318 *slot
kono
parents:
diff changeset
319 = static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
kono
parents:
diff changeset
320 **slot = value;
kono
parents:
diff changeset
321 found_value = *slot;
kono
parents:
diff changeset
322 }
kono
parents:
diff changeset
323 else
kono
parents:
diff changeset
324 return NULL_TREE;
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 if (found_value->address != error_mark_node)
kono
parents:
diff changeset
327 {
kono
parents:
diff changeset
328 // We have an address for the decl, so rewrite the tree.
kono
parents:
diff changeset
329 tree ptr_type = build_pointer_type (TREE_TYPE (*in));
kono
parents:
diff changeset
330 *in = fold_build1 (INDIRECT_REF, TREE_TYPE (*in),
kono
parents:
diff changeset
331 fold_build1 (CONVERT_EXPR, ptr_type,
kono
parents:
diff changeset
332 found_value->address));
kono
parents:
diff changeset
333 }
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 *walk_subtrees = 0;
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 return NULL_TREE;
kono
parents:
diff changeset
338 }
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 // When generating code for gdb, we want to be able to use absolute
kono
parents:
diff changeset
341 // addresses to refer to otherwise external objects that gdb knows
kono
parents:
diff changeset
342 // about. gdb passes in these addresses when building decls, and then
kono
parents:
diff changeset
343 // before gimplification we go through the trees, rewriting uses to
kono
parents:
diff changeset
344 // the equivalent of "*(TYPE *) ADDR".
kono
parents:
diff changeset
345 static void
kono
parents:
diff changeset
346 rewrite_decls_to_addresses (void *function_in, void *)
kono
parents:
diff changeset
347 {
kono
parents:
diff changeset
348 tree function = (tree) function_in;
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 // Do nothing if we're not in gdb.
kono
parents:
diff changeset
351 if (current_context == NULL)
kono
parents:
diff changeset
352 return;
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 walk_tree (&DECL_SAVED_TREE (function), address_rewriter, current_context,
kono
parents:
diff changeset
355 NULL);
kono
parents:
diff changeset
356 }
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359
kono
parents:
diff changeset
360 gcc_decl
kono
parents:
diff changeset
361 plugin_build_decl (cc1_plugin::connection *self,
kono
parents:
diff changeset
362 const char *name,
kono
parents:
diff changeset
363 enum gcc_c_symbol_kind sym_kind,
kono
parents:
diff changeset
364 gcc_type sym_type_in,
kono
parents:
diff changeset
365 const char *substitution_name,
kono
parents:
diff changeset
366 gcc_address address,
kono
parents:
diff changeset
367 const char *filename,
kono
parents:
diff changeset
368 unsigned int line_number)
kono
parents:
diff changeset
369 {
kono
parents:
diff changeset
370 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
371 tree identifier = get_identifier (name);
kono
parents:
diff changeset
372 enum tree_code code;
kono
parents:
diff changeset
373 tree decl;
kono
parents:
diff changeset
374 tree sym_type = convert_in (sym_type_in);
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 switch (sym_kind)
kono
parents:
diff changeset
377 {
kono
parents:
diff changeset
378 case GCC_C_SYMBOL_FUNCTION:
kono
parents:
diff changeset
379 code = FUNCTION_DECL;
kono
parents:
diff changeset
380 break;
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 case GCC_C_SYMBOL_VARIABLE:
kono
parents:
diff changeset
383 code = VAR_DECL;
kono
parents:
diff changeset
384 break;
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 case GCC_C_SYMBOL_TYPEDEF:
kono
parents:
diff changeset
387 code = TYPE_DECL;
kono
parents:
diff changeset
388 break;
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 case GCC_C_SYMBOL_LABEL:
kono
parents:
diff changeset
391 // FIXME: we aren't ready to handle labels yet.
kono
parents:
diff changeset
392 // It isn't clear how to translate them properly
kono
parents:
diff changeset
393 // and in any case a "goto" isn't likely to work.
kono
parents:
diff changeset
394 return convert_out (error_mark_node);
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 default:
kono
parents:
diff changeset
397 abort ();
kono
parents:
diff changeset
398 }
kono
parents:
diff changeset
399
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
400 location_t loc = ctx->get_location_t (filename, line_number);
111
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 decl = build_decl (loc, code, identifier, sym_type);
kono
parents:
diff changeset
403 TREE_USED (decl) = 1;
kono
parents:
diff changeset
404 TREE_ADDRESSABLE (decl) = 1;
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 if (sym_kind != GCC_C_SYMBOL_TYPEDEF)
kono
parents:
diff changeset
407 {
kono
parents:
diff changeset
408 decl_addr_value value;
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 DECL_EXTERNAL (decl) = 1;
kono
parents:
diff changeset
411 value.decl = decl;
kono
parents:
diff changeset
412 if (substitution_name != NULL)
kono
parents:
diff changeset
413 {
kono
parents:
diff changeset
414 // If the translator gave us a name without a binding,
kono
parents:
diff changeset
415 // we can just substitute error_mark_node, since we know the
kono
parents:
diff changeset
416 // translator will be reporting an error anyhow.
kono
parents:
diff changeset
417 value.address
kono
parents:
diff changeset
418 = lookup_name (get_identifier (substitution_name));
kono
parents:
diff changeset
419 if (value.address == NULL_TREE)
kono
parents:
diff changeset
420 value.address = error_mark_node;
kono
parents:
diff changeset
421 }
kono
parents:
diff changeset
422 else
kono
parents:
diff changeset
423 value.address = build_int_cst_type (ptr_type_node, address);
kono
parents:
diff changeset
424 decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
kono
parents:
diff changeset
425 gcc_assert (*slot == NULL);
kono
parents:
diff changeset
426 *slot
kono
parents:
diff changeset
427 = static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
kono
parents:
diff changeset
428 **slot = value;
kono
parents:
diff changeset
429 }
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 return convert_out (ctx->preserve (decl));
kono
parents:
diff changeset
432 }
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 int
kono
parents:
diff changeset
435 plugin_bind (cc1_plugin::connection *,
kono
parents:
diff changeset
436 gcc_decl decl_in, int is_global)
kono
parents:
diff changeset
437 {
kono
parents:
diff changeset
438 tree decl = convert_in (decl_in);
kono
parents:
diff changeset
439 c_bind (DECL_SOURCE_LOCATION (decl), decl, is_global);
kono
parents:
diff changeset
440 rest_of_decl_compilation (decl, is_global, 0);
kono
parents:
diff changeset
441 return 1;
kono
parents:
diff changeset
442 }
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 int
kono
parents:
diff changeset
445 plugin_tagbind (cc1_plugin::connection *self,
kono
parents:
diff changeset
446 const char *name, gcc_type tagged_type,
kono
parents:
diff changeset
447 const char *filename, unsigned int line_number)
kono
parents:
diff changeset
448 {
kono
parents:
diff changeset
449 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
450 tree t = convert_in (tagged_type), x;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
451 c_pushtag (ctx->get_location_t (filename, line_number),
111
kono
parents:
diff changeset
452 get_identifier (name), t);
kono
parents:
diff changeset
453
kono
parents:
diff changeset
454 /* Propagate the newly-added type name so that previously-created
kono
parents:
diff changeset
455 variant types are not disconnected from their main variants. */
kono
parents:
diff changeset
456 for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
kono
parents:
diff changeset
457 TYPE_NAME (x) = TYPE_NAME (t);
kono
parents:
diff changeset
458
kono
parents:
diff changeset
459 return 1;
kono
parents:
diff changeset
460 }
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 gcc_type
kono
parents:
diff changeset
463 plugin_build_pointer_type (cc1_plugin::connection *,
kono
parents:
diff changeset
464 gcc_type base_type)
kono
parents:
diff changeset
465 {
kono
parents:
diff changeset
466 // No need to preserve a pointer type as the base type is preserved.
kono
parents:
diff changeset
467 return convert_out (build_pointer_type (convert_in (base_type)));
kono
parents:
diff changeset
468 }
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 // TYPE_NAME needs to be a valid pointer, even if there is no name available.
kono
parents:
diff changeset
471
kono
parents:
diff changeset
472 static tree
kono
parents:
diff changeset
473 build_anonymous_node (enum tree_code code)
kono
parents:
diff changeset
474 {
kono
parents:
diff changeset
475 tree node = make_node (code);
kono
parents:
diff changeset
476 tree type_decl = build_decl (input_location, TYPE_DECL, NULL_TREE, node);
kono
parents:
diff changeset
477 TYPE_NAME (node) = type_decl;
kono
parents:
diff changeset
478 TYPE_STUB_DECL (node) = type_decl;
kono
parents:
diff changeset
479 return node;
kono
parents:
diff changeset
480 }
kono
parents:
diff changeset
481
kono
parents:
diff changeset
482 gcc_type
kono
parents:
diff changeset
483 plugin_build_record_type (cc1_plugin::connection *self)
kono
parents:
diff changeset
484 {
kono
parents:
diff changeset
485 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
486 return convert_out (ctx->preserve (build_anonymous_node (RECORD_TYPE)));
kono
parents:
diff changeset
487 }
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 gcc_type
kono
parents:
diff changeset
490 plugin_build_union_type (cc1_plugin::connection *self)
kono
parents:
diff changeset
491 {
kono
parents:
diff changeset
492 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
493 return convert_out (ctx->preserve (build_anonymous_node (UNION_TYPE)));
kono
parents:
diff changeset
494 }
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 int
kono
parents:
diff changeset
497 plugin_build_add_field (cc1_plugin::connection *,
kono
parents:
diff changeset
498 gcc_type record_or_union_type_in,
kono
parents:
diff changeset
499 const char *field_name,
kono
parents:
diff changeset
500 gcc_type field_type_in,
kono
parents:
diff changeset
501 unsigned long bitsize,
kono
parents:
diff changeset
502 unsigned long bitpos)
kono
parents:
diff changeset
503 {
kono
parents:
diff changeset
504 tree record_or_union_type = convert_in (record_or_union_type_in);
kono
parents:
diff changeset
505 tree field_type = convert_in (field_type_in);
kono
parents:
diff changeset
506
kono
parents:
diff changeset
507 gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
kono
parents:
diff changeset
508 || TREE_CODE (record_or_union_type) == UNION_TYPE);
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 /* Note that gdb does not preserve the location of field decls, so
kono
parents:
diff changeset
511 we can't provide a decent location here. */
kono
parents:
diff changeset
512 tree decl = build_decl (BUILTINS_LOCATION, FIELD_DECL,
kono
parents:
diff changeset
513 get_identifier (field_name), field_type);
kono
parents:
diff changeset
514 DECL_FIELD_CONTEXT (decl) = record_or_union_type;
kono
parents:
diff changeset
515
kono
parents:
diff changeset
516 if (TREE_CODE (field_type) == INTEGER_TYPE
kono
parents:
diff changeset
517 && TYPE_PRECISION (field_type) != bitsize)
kono
parents:
diff changeset
518 {
kono
parents:
diff changeset
519 DECL_BIT_FIELD_TYPE (decl) = field_type;
kono
parents:
diff changeset
520 TREE_TYPE (decl)
kono
parents:
diff changeset
521 = c_build_bitfield_integer_type (bitsize, TYPE_UNSIGNED (field_type));
kono
parents:
diff changeset
522 }
kono
parents:
diff changeset
523
kono
parents:
diff changeset
524 SET_DECL_MODE (decl, TYPE_MODE (TREE_TYPE (decl)));
kono
parents:
diff changeset
525
kono
parents:
diff changeset
526 // There's no way to recover this from DWARF.
kono
parents:
diff changeset
527 SET_DECL_OFFSET_ALIGN (decl, TYPE_PRECISION (pointer_sized_int_node));
kono
parents:
diff changeset
528
kono
parents:
diff changeset
529 tree pos = bitsize_int (bitpos);
kono
parents:
diff changeset
530 pos_from_bit (&DECL_FIELD_OFFSET (decl), &DECL_FIELD_BIT_OFFSET (decl),
kono
parents:
diff changeset
531 DECL_OFFSET_ALIGN (decl), pos);
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 DECL_SIZE (decl) = bitsize_int (bitsize);
kono
parents:
diff changeset
534 DECL_SIZE_UNIT (decl) = size_int ((bitsize + BITS_PER_UNIT - 1)
kono
parents:
diff changeset
535 / BITS_PER_UNIT);
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 DECL_CHAIN (decl) = TYPE_FIELDS (record_or_union_type);
kono
parents:
diff changeset
538 TYPE_FIELDS (record_or_union_type) = decl;
kono
parents:
diff changeset
539
kono
parents:
diff changeset
540 return 1;
kono
parents:
diff changeset
541 }
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 int
kono
parents:
diff changeset
544 plugin_finish_record_or_union (cc1_plugin::connection *,
kono
parents:
diff changeset
545 gcc_type record_or_union_type_in,
kono
parents:
diff changeset
546 unsigned long size_in_bytes)
kono
parents:
diff changeset
547 {
kono
parents:
diff changeset
548 tree record_or_union_type = convert_in (record_or_union_type_in);
kono
parents:
diff changeset
549
kono
parents:
diff changeset
550 gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
kono
parents:
diff changeset
551 || TREE_CODE (record_or_union_type) == UNION_TYPE);
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 /* We built the field list in reverse order, so fix it now. */
kono
parents:
diff changeset
554 TYPE_FIELDS (record_or_union_type)
kono
parents:
diff changeset
555 = nreverse (TYPE_FIELDS (record_or_union_type));
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 if (TREE_CODE (record_or_union_type) == UNION_TYPE)
kono
parents:
diff changeset
558 {
kono
parents:
diff changeset
559 /* Unions can just be handled by the generic code. */
kono
parents:
diff changeset
560 layout_type (record_or_union_type);
kono
parents:
diff changeset
561 }
kono
parents:
diff changeset
562 else
kono
parents:
diff changeset
563 {
kono
parents:
diff changeset
564 // FIXME there's no way to get this from DWARF,
kono
parents:
diff changeset
565 // or even, it seems, a particularly good way to deduce it.
kono
parents:
diff changeset
566 SET_TYPE_ALIGN (record_or_union_type,
kono
parents:
diff changeset
567 TYPE_PRECISION (pointer_sized_int_node));
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 TYPE_SIZE (record_or_union_type) = bitsize_int (size_in_bytes
kono
parents:
diff changeset
570 * BITS_PER_UNIT);
kono
parents:
diff changeset
571 TYPE_SIZE_UNIT (record_or_union_type) = size_int (size_in_bytes);
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 compute_record_mode (record_or_union_type);
kono
parents:
diff changeset
574 finish_bitfield_layout (record_or_union_type);
kono
parents:
diff changeset
575 // FIXME we have no idea about TYPE_PACKED
kono
parents:
diff changeset
576 }
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 tree t = record_or_union_type, x;
kono
parents:
diff changeset
579 for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
kono
parents:
diff changeset
580 {
kono
parents:
diff changeset
581 /* Like finish_struct, update the qualified variant types. */
kono
parents:
diff changeset
582 TYPE_FIELDS (x) = TYPE_FIELDS (t);
kono
parents:
diff changeset
583 TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
kono
parents:
diff changeset
584 C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
kono
parents:
diff changeset
585 C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
kono
parents:
diff changeset
586 C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
kono
parents:
diff changeset
587 /* We copy these fields too. */
kono
parents:
diff changeset
588 SET_TYPE_ALIGN (x, TYPE_ALIGN (t));
kono
parents:
diff changeset
589 TYPE_SIZE (x) = TYPE_SIZE (t);
kono
parents:
diff changeset
590 TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t);
kono
parents:
diff changeset
591 if (x != record_or_union_type)
kono
parents:
diff changeset
592 compute_record_mode (x);
kono
parents:
diff changeset
593 }
kono
parents:
diff changeset
594
kono
parents:
diff changeset
595 return 1;
kono
parents:
diff changeset
596 }
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 gcc_type
kono
parents:
diff changeset
599 plugin_build_enum_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
600 gcc_type underlying_int_type_in)
kono
parents:
diff changeset
601 {
kono
parents:
diff changeset
602 tree underlying_int_type = convert_in (underlying_int_type_in);
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 if (underlying_int_type == error_mark_node)
kono
parents:
diff changeset
605 return convert_out (error_mark_node);
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 tree result = build_anonymous_node (ENUMERAL_TYPE);
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 TYPE_PRECISION (result) = TYPE_PRECISION (underlying_int_type);
kono
parents:
diff changeset
610 TYPE_UNSIGNED (result) = TYPE_UNSIGNED (underlying_int_type);
kono
parents:
diff changeset
611
kono
parents:
diff changeset
612 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
613 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
614 }
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 int
kono
parents:
diff changeset
617 plugin_build_add_enum_constant (cc1_plugin::connection *,
kono
parents:
diff changeset
618 gcc_type enum_type_in,
kono
parents:
diff changeset
619 const char *name,
kono
parents:
diff changeset
620 unsigned long value)
kono
parents:
diff changeset
621 {
kono
parents:
diff changeset
622 tree cst, decl, cons;
kono
parents:
diff changeset
623 tree enum_type = convert_in (enum_type_in);
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 gcc_assert (TREE_CODE (enum_type) == ENUMERAL_TYPE);
kono
parents:
diff changeset
626
kono
parents:
diff changeset
627 cst = build_int_cst (enum_type, value);
kono
parents:
diff changeset
628 /* Note that gdb does not preserve the location of enum constants,
kono
parents:
diff changeset
629 so we can't provide a decent location here. */
kono
parents:
diff changeset
630 decl = build_decl (BUILTINS_LOCATION, CONST_DECL,
kono
parents:
diff changeset
631 get_identifier (name), enum_type);
kono
parents:
diff changeset
632 DECL_INITIAL (decl) = cst;
kono
parents:
diff changeset
633 pushdecl_safe (decl);
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 cons = tree_cons (DECL_NAME (decl), cst, TYPE_VALUES (enum_type));
kono
parents:
diff changeset
636 TYPE_VALUES (enum_type) = cons;
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 return 1;
kono
parents:
diff changeset
639 }
kono
parents:
diff changeset
640
kono
parents:
diff changeset
641 int
kono
parents:
diff changeset
642 plugin_finish_enum_type (cc1_plugin::connection *,
kono
parents:
diff changeset
643 gcc_type enum_type_in)
kono
parents:
diff changeset
644 {
kono
parents:
diff changeset
645 tree enum_type = convert_in (enum_type_in);
kono
parents:
diff changeset
646 tree minnode, maxnode, iter;
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 iter = TYPE_VALUES (enum_type);
kono
parents:
diff changeset
649 minnode = maxnode = TREE_VALUE (iter);
kono
parents:
diff changeset
650 for (iter = TREE_CHAIN (iter);
kono
parents:
diff changeset
651 iter != NULL_TREE;
kono
parents:
diff changeset
652 iter = TREE_CHAIN (iter))
kono
parents:
diff changeset
653 {
kono
parents:
diff changeset
654 tree value = TREE_VALUE (iter);
kono
parents:
diff changeset
655 if (tree_int_cst_lt (maxnode, value))
kono
parents:
diff changeset
656 maxnode = value;
kono
parents:
diff changeset
657 if (tree_int_cst_lt (value, minnode))
kono
parents:
diff changeset
658 minnode = value;
kono
parents:
diff changeset
659 }
kono
parents:
diff changeset
660 TYPE_MIN_VALUE (enum_type) = minnode;
kono
parents:
diff changeset
661 TYPE_MAX_VALUE (enum_type) = maxnode;
kono
parents:
diff changeset
662
kono
parents:
diff changeset
663 layout_type (enum_type);
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 return 1;
kono
parents:
diff changeset
666 }
kono
parents:
diff changeset
667
kono
parents:
diff changeset
668 gcc_type
kono
parents:
diff changeset
669 plugin_build_function_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
670 gcc_type return_type_in,
kono
parents:
diff changeset
671 const struct gcc_type_array *argument_types_in,
kono
parents:
diff changeset
672 int is_varargs)
kono
parents:
diff changeset
673 {
kono
parents:
diff changeset
674 tree *argument_types;
kono
parents:
diff changeset
675 tree return_type = convert_in (return_type_in);
kono
parents:
diff changeset
676 tree result;
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 argument_types = new tree[argument_types_in->n_elements];
kono
parents:
diff changeset
679 for (int i = 0; i < argument_types_in->n_elements; ++i)
kono
parents:
diff changeset
680 argument_types[i] = convert_in (argument_types_in->elements[i]);
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 if (is_varargs)
kono
parents:
diff changeset
683 result = build_varargs_function_type_array (return_type,
kono
parents:
diff changeset
684 argument_types_in->n_elements,
kono
parents:
diff changeset
685 argument_types);
kono
parents:
diff changeset
686 else
kono
parents:
diff changeset
687 result = build_function_type_array (return_type,
kono
parents:
diff changeset
688 argument_types_in->n_elements,
kono
parents:
diff changeset
689 argument_types);
kono
parents:
diff changeset
690
kono
parents:
diff changeset
691 delete[] argument_types;
kono
parents:
diff changeset
692
kono
parents:
diff changeset
693 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
694 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
695 }
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 /* Return a builtin type associated with BUILTIN_NAME. */
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 static tree
kono
parents:
diff changeset
700 safe_lookup_builtin_type (const char *builtin_name)
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 tree result = NULL_TREE;
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 if (!builtin_name)
kono
parents:
diff changeset
705 return result;
kono
parents:
diff changeset
706
kono
parents:
diff changeset
707 result = identifier_global_value (get_identifier (builtin_name));
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 if (!result)
kono
parents:
diff changeset
710 return result;
kono
parents:
diff changeset
711
kono
parents:
diff changeset
712 gcc_assert (TREE_CODE (result) == TYPE_DECL);
kono
parents:
diff changeset
713 result = TREE_TYPE (result);
kono
parents:
diff changeset
714 return result;
kono
parents:
diff changeset
715 }
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 static gcc_type
kono
parents:
diff changeset
718 plugin_int_check (cc1_plugin::connection *self,
kono
parents:
diff changeset
719 int is_unsigned, unsigned long size_in_bytes,
kono
parents:
diff changeset
720 tree result)
kono
parents:
diff changeset
721 {
kono
parents:
diff changeset
722 if (result == NULL_TREE)
kono
parents:
diff changeset
723 result = error_mark_node;
kono
parents:
diff changeset
724 else
kono
parents:
diff changeset
725 {
kono
parents:
diff changeset
726 gcc_assert (!TYPE_UNSIGNED (result) == !is_unsigned);
kono
parents:
diff changeset
727 gcc_assert (TREE_CODE (TYPE_SIZE (result)) == INTEGER_CST);
kono
parents:
diff changeset
728 gcc_assert (TYPE_PRECISION (result) == BITS_PER_UNIT * size_in_bytes);
kono
parents:
diff changeset
729
kono
parents:
diff changeset
730 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
731 ctx->preserve (result);
kono
parents:
diff changeset
732 }
kono
parents:
diff changeset
733 return convert_out (result);
kono
parents:
diff changeset
734 }
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 gcc_type
kono
parents:
diff changeset
737 plugin_int_type_v0 (cc1_plugin::connection *self,
kono
parents:
diff changeset
738 int is_unsigned, unsigned long size_in_bytes)
kono
parents:
diff changeset
739 {
kono
parents:
diff changeset
740 tree result = c_common_type_for_size (BITS_PER_UNIT * size_in_bytes,
kono
parents:
diff changeset
741 is_unsigned);
kono
parents:
diff changeset
742
kono
parents:
diff changeset
743 return plugin_int_check (self, is_unsigned, size_in_bytes, result);
kono
parents:
diff changeset
744 }
kono
parents:
diff changeset
745
kono
parents:
diff changeset
746 gcc_type
kono
parents:
diff changeset
747 plugin_int_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
748 int is_unsigned, unsigned long size_in_bytes,
kono
parents:
diff changeset
749 const char *builtin_name)
kono
parents:
diff changeset
750 {
kono
parents:
diff changeset
751 if (!builtin_name)
kono
parents:
diff changeset
752 return plugin_int_type_v0 (self, is_unsigned, size_in_bytes);
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 tree result = safe_lookup_builtin_type (builtin_name);
kono
parents:
diff changeset
755 gcc_assert (!result || TREE_CODE (result) == INTEGER_TYPE);
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 return plugin_int_check (self, is_unsigned, size_in_bytes, result);
kono
parents:
diff changeset
758 }
kono
parents:
diff changeset
759
kono
parents:
diff changeset
760 gcc_type
kono
parents:
diff changeset
761 plugin_char_type (cc1_plugin::connection *)
kono
parents:
diff changeset
762 {
kono
parents:
diff changeset
763 return convert_out (char_type_node);
kono
parents:
diff changeset
764 }
kono
parents:
diff changeset
765
kono
parents:
diff changeset
766 gcc_type
kono
parents:
diff changeset
767 plugin_float_type_v0 (cc1_plugin::connection *,
kono
parents:
diff changeset
768 unsigned long size_in_bytes)
kono
parents:
diff changeset
769 {
kono
parents:
diff changeset
770 if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (float_type_node))
kono
parents:
diff changeset
771 return convert_out (float_type_node);
kono
parents:
diff changeset
772 if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (double_type_node))
kono
parents:
diff changeset
773 return convert_out (double_type_node);
kono
parents:
diff changeset
774 if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (long_double_type_node))
kono
parents:
diff changeset
775 return convert_out (long_double_type_node);
kono
parents:
diff changeset
776 return convert_out (error_mark_node);
kono
parents:
diff changeset
777 }
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 gcc_type
kono
parents:
diff changeset
780 plugin_float_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
781 unsigned long size_in_bytes,
kono
parents:
diff changeset
782 const char *builtin_name)
kono
parents:
diff changeset
783 {
kono
parents:
diff changeset
784 if (!builtin_name)
kono
parents:
diff changeset
785 return plugin_float_type_v0 (self, size_in_bytes);
kono
parents:
diff changeset
786
kono
parents:
diff changeset
787 tree result = safe_lookup_builtin_type (builtin_name);
kono
parents:
diff changeset
788
kono
parents:
diff changeset
789 if (!result)
kono
parents:
diff changeset
790 return convert_out (error_mark_node);
kono
parents:
diff changeset
791
kono
parents:
diff changeset
792 gcc_assert (TREE_CODE (result) == REAL_TYPE);
kono
parents:
diff changeset
793 gcc_assert (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (result));
kono
parents:
diff changeset
794
kono
parents:
diff changeset
795 return convert_out (result);
kono
parents:
diff changeset
796 }
kono
parents:
diff changeset
797
kono
parents:
diff changeset
798 gcc_type
kono
parents:
diff changeset
799 plugin_void_type (cc1_plugin::connection *)
kono
parents:
diff changeset
800 {
kono
parents:
diff changeset
801 return convert_out (void_type_node);
kono
parents:
diff changeset
802 }
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 gcc_type
kono
parents:
diff changeset
805 plugin_bool_type (cc1_plugin::connection *)
kono
parents:
diff changeset
806 {
kono
parents:
diff changeset
807 return convert_out (boolean_type_node);
kono
parents:
diff changeset
808 }
kono
parents:
diff changeset
809
kono
parents:
diff changeset
810 gcc_type
kono
parents:
diff changeset
811 plugin_build_array_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
812 gcc_type element_type_in, int num_elements)
kono
parents:
diff changeset
813 {
kono
parents:
diff changeset
814 tree element_type = convert_in (element_type_in);
kono
parents:
diff changeset
815 tree result;
kono
parents:
diff changeset
816
kono
parents:
diff changeset
817 if (num_elements == -1)
kono
parents:
diff changeset
818 result = build_array_type (element_type, NULL_TREE);
kono
parents:
diff changeset
819 else
kono
parents:
diff changeset
820 result = build_array_type_nelts (element_type, num_elements);
kono
parents:
diff changeset
821
kono
parents:
diff changeset
822 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
823 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
824 }
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826 gcc_type
kono
parents:
diff changeset
827 plugin_build_vla_array_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
828 gcc_type element_type_in,
kono
parents:
diff changeset
829 const char *upper_bound_name)
kono
parents:
diff changeset
830 {
kono
parents:
diff changeset
831 tree element_type = convert_in (element_type_in);
kono
parents:
diff changeset
832 tree upper_bound = lookup_name (get_identifier (upper_bound_name));
kono
parents:
diff changeset
833 tree range = build_index_type (upper_bound);
kono
parents:
diff changeset
834
kono
parents:
diff changeset
835 tree result = build_array_type (element_type, range);
kono
parents:
diff changeset
836 C_TYPE_VARIABLE_SIZE (result) = 1;
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
839 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
840 }
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 gcc_type
kono
parents:
diff changeset
843 plugin_build_qualified_type (cc1_plugin::connection *,
kono
parents:
diff changeset
844 gcc_type unqualified_type_in,
kono
parents:
diff changeset
845 enum gcc_qualifiers qualifiers)
kono
parents:
diff changeset
846 {
kono
parents:
diff changeset
847 tree unqualified_type = convert_in (unqualified_type_in);
kono
parents:
diff changeset
848 int quals = 0;
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 if ((qualifiers & GCC_QUALIFIER_CONST) != 0)
kono
parents:
diff changeset
851 quals |= TYPE_QUAL_CONST;
kono
parents:
diff changeset
852 if ((qualifiers & GCC_QUALIFIER_VOLATILE) != 0)
kono
parents:
diff changeset
853 quals |= TYPE_QUAL_VOLATILE;
kono
parents:
diff changeset
854 if ((qualifiers & GCC_QUALIFIER_RESTRICT) != 0)
kono
parents:
diff changeset
855 quals |= TYPE_QUAL_RESTRICT;
kono
parents:
diff changeset
856
kono
parents:
diff changeset
857 return convert_out (build_qualified_type (unqualified_type, quals));
kono
parents:
diff changeset
858 }
kono
parents:
diff changeset
859
kono
parents:
diff changeset
860 gcc_type
kono
parents:
diff changeset
861 plugin_build_complex_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
862 gcc_type base_type)
kono
parents:
diff changeset
863 {
kono
parents:
diff changeset
864 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
865 return convert_out (ctx->preserve (build_complex_type (convert_in (base_type))));
kono
parents:
diff changeset
866 }
kono
parents:
diff changeset
867
kono
parents:
diff changeset
868 gcc_type
kono
parents:
diff changeset
869 plugin_build_vector_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
870 gcc_type base_type, int nunits)
kono
parents:
diff changeset
871 {
kono
parents:
diff changeset
872 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
873 return convert_out (ctx->preserve (build_vector_type (convert_in (base_type),
kono
parents:
diff changeset
874 nunits)));
kono
parents:
diff changeset
875 }
kono
parents:
diff changeset
876
kono
parents:
diff changeset
877 int
kono
parents:
diff changeset
878 plugin_build_constant (cc1_plugin::connection *self, gcc_type type_in,
kono
parents:
diff changeset
879 const char *name, unsigned long value,
kono
parents:
diff changeset
880 const char *filename, unsigned int line_number)
kono
parents:
diff changeset
881 {
kono
parents:
diff changeset
882 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
883 tree cst, decl;
kono
parents:
diff changeset
884 tree type = convert_in (type_in);
kono
parents:
diff changeset
885
kono
parents:
diff changeset
886 cst = build_int_cst (type, value);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
887 decl = build_decl (ctx->get_location_t (filename, line_number),
111
kono
parents:
diff changeset
888 CONST_DECL, get_identifier (name), type);
kono
parents:
diff changeset
889 DECL_INITIAL (decl) = cst;
kono
parents:
diff changeset
890 pushdecl_safe (decl);
kono
parents:
diff changeset
891
kono
parents:
diff changeset
892 return 1;
kono
parents:
diff changeset
893 }
kono
parents:
diff changeset
894
kono
parents:
diff changeset
895 gcc_type
kono
parents:
diff changeset
896 plugin_error (cc1_plugin::connection *,
kono
parents:
diff changeset
897 const char *message)
kono
parents:
diff changeset
898 {
kono
parents:
diff changeset
899 error ("%s", message);
kono
parents:
diff changeset
900 return convert_out (error_mark_node);
kono
parents:
diff changeset
901 }
kono
parents:
diff changeset
902
kono
parents:
diff changeset
903
kono
parents:
diff changeset
904
kono
parents:
diff changeset
905 // Perform GC marking.
kono
parents:
diff changeset
906
kono
parents:
diff changeset
907 static void
kono
parents:
diff changeset
908 gc_mark (void *, void *)
kono
parents:
diff changeset
909 {
kono
parents:
diff changeset
910 if (current_context != NULL)
kono
parents:
diff changeset
911 current_context->mark ();
kono
parents:
diff changeset
912 }
kono
parents:
diff changeset
913
kono
parents:
diff changeset
914 #ifdef __GNUC__
kono
parents:
diff changeset
915 #pragma GCC visibility push(default)
kono
parents:
diff changeset
916 #endif
kono
parents:
diff changeset
917
kono
parents:
diff changeset
918 int
kono
parents:
diff changeset
919 plugin_init (struct plugin_name_args *plugin_info,
kono
parents:
diff changeset
920 struct plugin_gcc_version *)
kono
parents:
diff changeset
921 {
kono
parents:
diff changeset
922 long fd = -1;
kono
parents:
diff changeset
923 for (int i = 0; i < plugin_info->argc; ++i)
kono
parents:
diff changeset
924 {
kono
parents:
diff changeset
925 if (strcmp (plugin_info->argv[i].key, "fd") == 0)
kono
parents:
diff changeset
926 {
kono
parents:
diff changeset
927 char *tail;
kono
parents:
diff changeset
928 errno = 0;
kono
parents:
diff changeset
929 fd = strtol (plugin_info->argv[i].value, &tail, 0);
kono
parents:
diff changeset
930 if (*tail != '\0' || errno != 0)
kono
parents:
diff changeset
931 fatal_error (input_location,
kono
parents:
diff changeset
932 "%s: invalid file descriptor argument to plugin",
kono
parents:
diff changeset
933 plugin_info->base_name);
kono
parents:
diff changeset
934 break;
kono
parents:
diff changeset
935 }
kono
parents:
diff changeset
936 }
kono
parents:
diff changeset
937 if (fd == -1)
kono
parents:
diff changeset
938 fatal_error (input_location,
kono
parents:
diff changeset
939 "%s: required plugin argument %<fd%> is missing",
kono
parents:
diff changeset
940 plugin_info->base_name);
kono
parents:
diff changeset
941
kono
parents:
diff changeset
942 current_context = new plugin_context (fd);
kono
parents:
diff changeset
943
kono
parents:
diff changeset
944 // Handshake.
kono
parents:
diff changeset
945 cc1_plugin::protocol_int version;
kono
parents:
diff changeset
946 if (!current_context->require ('H')
kono
parents:
diff changeset
947 || ! ::cc1_plugin::unmarshall (current_context, &version))
kono
parents:
diff changeset
948 fatal_error (input_location,
kono
parents:
diff changeset
949 "%s: handshake failed", plugin_info->base_name);
kono
parents:
diff changeset
950 if (version != GCC_C_FE_VERSION_1)
kono
parents:
diff changeset
951 fatal_error (input_location,
kono
parents:
diff changeset
952 "%s: unknown version in handshake", plugin_info->base_name);
kono
parents:
diff changeset
953
kono
parents:
diff changeset
954 register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
kono
parents:
diff changeset
955 plugin_init_extra_pragmas, NULL);
kono
parents:
diff changeset
956 register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
kono
parents:
diff changeset
957 rewrite_decls_to_addresses, NULL);
kono
parents:
diff changeset
958 register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
kono
parents:
diff changeset
959 gc_mark, NULL);
kono
parents:
diff changeset
960
kono
parents:
diff changeset
961 lang_hooks.print_error_function = plugin_print_error_function;
kono
parents:
diff changeset
962
kono
parents:
diff changeset
963 #define GCC_METHOD0(R, N) \
kono
parents:
diff changeset
964 { \
kono
parents:
diff changeset
965 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
966 = cc1_plugin::callback<R, plugin_ ## N>; \
kono
parents:
diff changeset
967 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
968 }
kono
parents:
diff changeset
969 #define GCC_METHOD1(R, N, A) \
kono
parents:
diff changeset
970 { \
kono
parents:
diff changeset
971 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
972 = cc1_plugin::callback<R, A, plugin_ ## N>; \
kono
parents:
diff changeset
973 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
974 }
kono
parents:
diff changeset
975 #define GCC_METHOD2(R, N, A, B) \
kono
parents:
diff changeset
976 { \
kono
parents:
diff changeset
977 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
978 = cc1_plugin::callback<R, A, B, plugin_ ## N>; \
kono
parents:
diff changeset
979 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
980 }
kono
parents:
diff changeset
981 #define GCC_METHOD3(R, N, A, B, C) \
kono
parents:
diff changeset
982 { \
kono
parents:
diff changeset
983 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
984 = cc1_plugin::callback<R, A, B, C, plugin_ ## N>; \
kono
parents:
diff changeset
985 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
986 }
kono
parents:
diff changeset
987 #define GCC_METHOD4(R, N, A, B, C, D) \
kono
parents:
diff changeset
988 { \
kono
parents:
diff changeset
989 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
990 = cc1_plugin::callback<R, A, B, C, D, \
kono
parents:
diff changeset
991 plugin_ ## N>; \
kono
parents:
diff changeset
992 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
993 }
kono
parents:
diff changeset
994 #define GCC_METHOD5(R, N, A, B, C, D, E) \
kono
parents:
diff changeset
995 { \
kono
parents:
diff changeset
996 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
997 = cc1_plugin::callback<R, A, B, C, D, E, \
kono
parents:
diff changeset
998 plugin_ ## N>; \
kono
parents:
diff changeset
999 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
1000 }
kono
parents:
diff changeset
1001 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
kono
parents:
diff changeset
1002 { \
kono
parents:
diff changeset
1003 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
1004 = cc1_plugin::callback<R, A, B, C, D, E, F, G, \
kono
parents:
diff changeset
1005 plugin_ ## N>; \
kono
parents:
diff changeset
1006 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
1007 }
kono
parents:
diff changeset
1008
kono
parents:
diff changeset
1009 #include "gcc-c-fe.def"
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 #undef GCC_METHOD0
kono
parents:
diff changeset
1012 #undef GCC_METHOD1
kono
parents:
diff changeset
1013 #undef GCC_METHOD2
kono
parents:
diff changeset
1014 #undef GCC_METHOD3
kono
parents:
diff changeset
1015 #undef GCC_METHOD4
kono
parents:
diff changeset
1016 #undef GCC_METHOD5
kono
parents:
diff changeset
1017 #undef GCC_METHOD7
kono
parents:
diff changeset
1018
kono
parents:
diff changeset
1019 return 0;
kono
parents:
diff changeset
1020 }