1 /* Library interface to C front end
2    Copyright (C) 2014-2020 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
plugin_print_error_function(diagnostic_context * context,const char * file,diagnostic_info * diagnostic)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
convert_out(tree t)96 convert_out (tree t)
97 {
98   return (unsigned long long) (uintptr_t) t;
99 }
100 
101 static tree
convert_in(unsigned long long v)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
hash(const decl_addr_value * e)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
equal(const decl_addr_value * p1,const decl_addr_value * p2)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 {
hashstring_hasher137   static inline hashval_t hash (const char *s)
138   {
139     return htab_hash_string (s);
140   }
141 
equalstring_hasher142   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
pushdecl_safe(tree decl)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.
preserveplugin_context183   tree preserve (tree t)
184   {
185     tree_node **slot = preserved.find_slot (t, INSERT);
186     *slot = t;
187     return t;
188   }
189 
get_location_tplugin_context190   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.
intern_filenameplugin_context206   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 
plugin_context(int fd)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
mark()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
plugin_binding_oracle(enum c_oracle_request kind,tree identifier)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
plugin_pragma_user_expression(cpp_reader *)276 plugin_pragma_user_expression (cpp_reader *)
277 {
278   c_binding_oracle = plugin_binding_oracle;
279 }
280 
281 static void
plugin_init_extra_pragmas(void *,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
address_rewriter(tree * in,int * walk_subtrees,void * arg)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
rewrite_decls_to_addresses(void * function_in,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
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)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
plugin_bind(cc1_plugin::connection *,gcc_decl decl_in,int is_global)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
plugin_tagbind(cc1_plugin::connection * self,const char * name,gcc_type tagged_type,const char * filename,unsigned int line_number)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
plugin_build_pointer_type(cc1_plugin::connection *,gcc_type base_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
build_anonymous_node(enum tree_code code)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
plugin_build_record_type(cc1_plugin::connection * self)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
plugin_build_union_type(cc1_plugin::connection * self)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
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)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
plugin_finish_record_or_union(cc1_plugin::connection *,gcc_type record_or_union_type_in,unsigned long size_in_bytes)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
plugin_build_enum_type(cc1_plugin::connection * self,gcc_type underlying_int_type_in)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
plugin_build_add_enum_constant(cc1_plugin::connection *,gcc_type enum_type_in,const char * name,unsigned long value)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
plugin_finish_enum_type(cc1_plugin::connection *,gcc_type enum_type_in)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
plugin_build_function_type(cc1_plugin::connection * self,gcc_type return_type_in,const struct gcc_type_array * argument_types_in,int is_varargs)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
safe_lookup_builtin_type(const char * builtin_name)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
plugin_int_check(cc1_plugin::connection * self,int is_unsigned,unsigned long size_in_bytes,tree result)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
plugin_int_type_v0(cc1_plugin::connection * self,int is_unsigned,unsigned long size_in_bytes)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
plugin_int_type(cc1_plugin::connection * self,int is_unsigned,unsigned long size_in_bytes,const char * builtin_name)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
plugin_char_type(cc1_plugin::connection *)761 plugin_char_type (cc1_plugin::connection *)
762 {
763   return convert_out (char_type_node);
764 }
765 
766 gcc_type
plugin_float_type_v0(cc1_plugin::connection *,unsigned long size_in_bytes)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
plugin_float_type(cc1_plugin::connection * self,unsigned long size_in_bytes,const char * builtin_name)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
plugin_void_type(cc1_plugin::connection *)799 plugin_void_type (cc1_plugin::connection *)
800 {
801   return convert_out (void_type_node);
802 }
803 
804 gcc_type
plugin_bool_type(cc1_plugin::connection *)805 plugin_bool_type (cc1_plugin::connection *)
806 {
807   return convert_out (boolean_type_node);
808 }
809 
810 gcc_type
plugin_build_array_type(cc1_plugin::connection * self,gcc_type element_type_in,int num_elements)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
plugin_build_vla_array_type(cc1_plugin::connection * self,gcc_type element_type_in,const char * upper_bound_name)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
plugin_build_qualified_type(cc1_plugin::connection *,gcc_type unqualified_type_in,enum gcc_qualifiers qualifiers)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
plugin_build_complex_type(cc1_plugin::connection * self,gcc_type base_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
plugin_build_vector_type(cc1_plugin::connection * self,gcc_type base_type,int nunits)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
plugin_build_constant(cc1_plugin::connection * self,gcc_type type_in,const char * name,unsigned long value,const char * filename,unsigned int line_number)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
plugin_error(cc1_plugin::connection *,const char * message)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
gc_mark(void *,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
plugin_init(struct plugin_name_args * plugin_info,struct plugin_gcc_version *)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 }
1021