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