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