]> git.ipfire.org Git - thirdparty/gcc.git/blob - libcc1/libcc1plugin.cc
expmed: TRUNCATE value1 if needed in store_bit_field_using_insv
[thirdparty/gcc.git] / libcc1 / libcc1plugin.cc
1 /* Library interface to C front end
2 Copyright (C) 2014-2019 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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 location_t get_location_t (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 location_t 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 \f
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 \f
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 \f
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 location_t loc = ctx->get_location_t (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_location_t (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_location_t (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 \f
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 }