1 // go-gcc.cc -- Go frontend to gcc IR.
2 // Copyright (C) 2011-2018 Free Software Foundation, Inc.
3 // Contributed by Ian Lance Taylor, Google.
4 
5 // This file is part of GCC.
6 
7 // GCC is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3, or (at your option) any later
10 // version.
11 
12 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 // for more details.
16 
17 // You should have received a copy of the GNU General Public License
18 // along with GCC; see the file COPYING3.  If not see
19 // <http://www.gnu.org/licenses/>.
20 
21 #include "go-system.h"
22 
23 // This has to be included outside of extern "C", so we have to
24 // include it here before tree.h includes it later.
25 #include <gmp.h>
26 
27 #include "tree.h"
28 #include "fold-const.h"
29 #include "stringpool.h"
30 #include "stor-layout.h"
31 #include "varasm.h"
32 #include "tree-iterator.h"
33 #include "tm.h"
34 #include "function.h"
35 #include "cgraph.h"
36 #include "convert.h"
37 #include "gimple-expr.h"
38 #include "gimplify.h"
39 #include "langhooks.h"
40 #include "toplev.h"
41 #include "output.h"
42 #include "realmpfr.h"
43 #include "builtins.h"
44 
45 #include "go-c.h"
46 #include "go-gcc.h"
47 
48 #include "gogo.h"
49 #include "backend.h"
50 
51 // A class wrapping a tree.
52 
53 class Gcc_tree
54 {
55  public:
Gcc_tree(tree t)56   Gcc_tree(tree t)
57     : t_(t)
58   { }
59 
60   tree
get_tree() const61   get_tree() const
62   { return this->t_; }
63 
64   void
set_tree(tree t)65   set_tree(tree t)
66   { this->t_ = t; }
67 
68  private:
69   tree t_;
70 };
71 
72 // In gcc, types, expressions, and statements are all trees.
73 class Btype : public Gcc_tree
74 {
75  public:
Btype(tree t)76   Btype(tree t)
77     : Gcc_tree(t)
78   { }
79 };
80 
81 class Bexpression : public Gcc_tree
82 {
83  public:
Bexpression(tree t)84   Bexpression(tree t)
85     : Gcc_tree(t)
86   { }
87 };
88 
89 class Bstatement : public Gcc_tree
90 {
91  public:
Bstatement(tree t)92   Bstatement(tree t)
93     : Gcc_tree(t)
94   { }
95 };
96 
97 class Bfunction : public Gcc_tree
98 {
99  public:
Bfunction(tree t)100   Bfunction(tree t)
101     : Gcc_tree(t)
102   { }
103 };
104 
105 class Bblock : public Gcc_tree
106 {
107  public:
Bblock(tree t)108   Bblock(tree t)
109     : Gcc_tree(t)
110   { }
111 };
112 
113 class Blabel : public Gcc_tree
114 {
115  public:
Blabel(tree t)116   Blabel(tree t)
117     : Gcc_tree(t)
118   { }
119 };
120 
121 // Bvariable is a bit more complicated, because of zero-sized types.
122 // The GNU linker does not permit dynamic variables with zero size.
123 // When we see such a variable, we generate a version of the type with
124 // non-zero size.  However, when referring to the global variable, we
125 // want an expression of zero size; otherwise, if, say, the global
126 // variable is passed to a function, we will be passing a
127 // non-zero-sized value to a zero-sized value, which can lead to a
128 // miscompilation.
129 
130 class Bvariable
131 {
132  public:
Bvariable(tree t)133   Bvariable(tree t)
134     : t_(t), orig_type_(NULL)
135   { }
136 
Bvariable(tree t,tree orig_type)137   Bvariable(tree t, tree orig_type)
138     : t_(t), orig_type_(orig_type)
139   { }
140 
141   // Get the tree for use as an expression.
142   tree
143   get_tree(Location) const;
144 
145   // Get the actual decl;
146   tree
get_decl() const147   get_decl() const
148   { return this->t_; }
149 
150  private:
151   tree t_;
152   tree orig_type_;
153 };
154 
155 // Get the tree of a variable for use as an expression.  If this is a
156 // zero-sized global, create an expression that refers to the decl but
157 // has zero size.
158 tree
get_tree(Location location) const159 Bvariable::get_tree(Location location) const
160 {
161   if (this->orig_type_ == NULL
162       || this->t_ == error_mark_node
163       || TREE_TYPE(this->t_) == this->orig_type_)
164     return this->t_;
165   // Return *(orig_type*)&decl.  */
166   tree t = build_fold_addr_expr_loc(location.gcc_location(), this->t_);
167   t = fold_build1_loc(location.gcc_location(), NOP_EXPR,
168 		      build_pointer_type(this->orig_type_), t);
169   return build_fold_indirect_ref_loc(location.gcc_location(), t);
170 }
171 
172 // This file implements the interface between the Go frontend proper
173 // and the gcc IR.  This implements specific instantiations of
174 // abstract classes defined by the Go frontend proper.  The Go
175 // frontend proper class methods of these classes to generate the
176 // backend representation.
177 
178 class Gcc_backend : public Backend
179 {
180  public:
181   Gcc_backend();
182 
183   // Types.
184 
185   Btype*
error_type()186   error_type()
187   { return this->make_type(error_mark_node); }
188 
189   Btype*
void_type()190   void_type()
191   { return this->make_type(void_type_node); }
192 
193   Btype*
bool_type()194   bool_type()
195   { return this->make_type(boolean_type_node); }
196 
197   Btype*
198   integer_type(bool, int);
199 
200   Btype*
201   float_type(int);
202 
203   Btype*
204   complex_type(int);
205 
206   Btype*
207   pointer_type(Btype*);
208 
209   Btype*
210   function_type(const Btyped_identifier&,
211 		const std::vector<Btyped_identifier>&,
212 		const std::vector<Btyped_identifier>&,
213 		Btype*,
214 		const Location);
215 
216   Btype*
217   struct_type(const std::vector<Btyped_identifier>&);
218 
219   Btype*
220   array_type(Btype*, Bexpression*);
221 
222   Btype*
223   placeholder_pointer_type(const std::string&, Location, bool);
224 
225   bool
226   set_placeholder_pointer_type(Btype*, Btype*);
227 
228   bool
229   set_placeholder_function_type(Btype*, Btype*);
230 
231   Btype*
232   placeholder_struct_type(const std::string&, Location);
233 
234   bool
235   set_placeholder_struct_type(Btype* placeholder,
236 			      const std::vector<Btyped_identifier>&);
237 
238   Btype*
239   placeholder_array_type(const std::string&, Location);
240 
241   bool
242   set_placeholder_array_type(Btype*, Btype*, Bexpression*);
243 
244   Btype*
245   named_type(const std::string&, Btype*, Location);
246 
247   Btype*
248   circular_pointer_type(Btype*, bool);
249 
250   bool
251   is_circular_pointer_type(Btype*);
252 
253   int64_t
254   type_size(Btype*);
255 
256   int64_t
257   type_alignment(Btype*);
258 
259   int64_t
260   type_field_alignment(Btype*);
261 
262   int64_t
263   type_field_offset(Btype*, size_t index);
264 
265   // Expressions.
266 
267   Bexpression*
268   zero_expression(Btype*);
269 
270   Bexpression*
error_expression()271   error_expression()
272   { return this->make_expression(error_mark_node); }
273 
274   Bexpression*
nil_pointer_expression()275   nil_pointer_expression()
276   { return this->make_expression(null_pointer_node); }
277 
278   Bexpression*
279   var_expression(Bvariable* var, Location);
280 
281   Bexpression*
282   indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location);
283 
284   Bexpression*
285   named_constant_expression(Btype* btype, const std::string& name,
286 			    Bexpression* val, Location);
287 
288   Bexpression*
289   integer_constant_expression(Btype* btype, mpz_t val);
290 
291   Bexpression*
292   float_constant_expression(Btype* btype, mpfr_t val);
293 
294   Bexpression*
295   complex_constant_expression(Btype* btype, mpc_t val);
296 
297   Bexpression*
298   string_constant_expression(const std::string& val);
299 
300   Bexpression*
301   boolean_constant_expression(bool val);
302 
303   Bexpression*
304   real_part_expression(Bexpression* bcomplex, Location);
305 
306   Bexpression*
307   imag_part_expression(Bexpression* bcomplex, Location);
308 
309   Bexpression*
310   complex_expression(Bexpression* breal, Bexpression* bimag, Location);
311 
312   Bexpression*
313   convert_expression(Btype* type, Bexpression* expr, Location);
314 
315   Bexpression*
316   function_code_expression(Bfunction*, Location);
317 
318   Bexpression*
319   address_expression(Bexpression*, Location);
320 
321   Bexpression*
322   struct_field_expression(Bexpression*, size_t, Location);
323 
324   Bexpression*
325   compound_expression(Bstatement*, Bexpression*, Location);
326 
327   Bexpression*
328   conditional_expression(Bfunction*, Btype*, Bexpression*, Bexpression*,
329                          Bexpression*, Location);
330 
331   Bexpression*
332   unary_expression(Operator, Bexpression*, Location);
333 
334   Bexpression*
335   binary_expression(Operator, Bexpression*, Bexpression*, Location);
336 
337   Bexpression*
338   constructor_expression(Btype*, const std::vector<Bexpression*>&, Location);
339 
340   Bexpression*
341   array_constructor_expression(Btype*, const std::vector<unsigned long>&,
342                                const std::vector<Bexpression*>&, Location);
343 
344   Bexpression*
345   pointer_offset_expression(Bexpression* base, Bexpression* offset, Location);
346 
347   Bexpression*
348   array_index_expression(Bexpression* array, Bexpression* index, Location);
349 
350   Bexpression*
351   call_expression(Bfunction* caller, Bexpression* fn,
352                   const std::vector<Bexpression*>& args,
353                   Bexpression* static_chain, Location);
354 
355   Bexpression*
356   stack_allocation_expression(int64_t size, Location);
357 
358   // Statements.
359 
360   Bstatement*
error_statement()361   error_statement()
362   { return this->make_statement(error_mark_node); }
363 
364   Bstatement*
365   expression_statement(Bfunction*, Bexpression*);
366 
367   Bstatement*
368   init_statement(Bfunction*, Bvariable* var, Bexpression* init);
369 
370   Bstatement*
371   assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
372 		       Location);
373 
374   Bstatement*
375   return_statement(Bfunction*, const std::vector<Bexpression*>&,
376 		   Location);
377 
378   Bstatement*
379   if_statement(Bfunction*, Bexpression* condition, Bblock* then_block,
380 	       Bblock* else_block, Location);
381 
382   Bstatement*
383   switch_statement(Bfunction* function, Bexpression* value,
384 		   const std::vector<std::vector<Bexpression*> >& cases,
385 		   const std::vector<Bstatement*>& statements,
386 		   Location);
387 
388   Bstatement*
389   compound_statement(Bstatement*, Bstatement*);
390 
391   Bstatement*
392   statement_list(const std::vector<Bstatement*>&);
393 
394   Bstatement*
395   exception_handler_statement(Bstatement* bstat, Bstatement* except_stmt,
396                               Bstatement* finally_stmt, Location);
397 
398   // Blocks.
399 
400   Bblock*
401   block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
402 	Location, Location);
403 
404   void
405   block_add_statements(Bblock*, const std::vector<Bstatement*>&);
406 
407   Bstatement*
408   block_statement(Bblock*);
409 
410   // Variables.
411 
412   Bvariable*
error_variable()413   error_variable()
414   { return new Bvariable(error_mark_node); }
415 
416   Bvariable*
417   global_variable(const std::string& var_name,
418 		  const std::string& asm_name,
419 		  Btype* btype,
420 		  bool is_external,
421 		  bool is_hidden,
422 		  bool in_unique_section,
423 		  Location location);
424 
425   void
426   global_variable_set_init(Bvariable*, Bexpression*);
427 
428   Bvariable*
429   local_variable(Bfunction*, const std::string&, Btype*, Bvariable*, bool,
430 		 Location);
431 
432   Bvariable*
433   parameter_variable(Bfunction*, const std::string&, Btype*, bool,
434 		     Location);
435 
436   Bvariable*
437   static_chain_variable(Bfunction*, const std::string&, Btype*, Location);
438 
439   Bvariable*
440   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
441 		     Location, Bstatement**);
442 
443   Bvariable*
444   implicit_variable(const std::string&, const std::string&, Btype*,
445                     bool, bool, bool, int64_t);
446 
447   void
448   implicit_variable_set_init(Bvariable*, const std::string&, Btype*,
449 			     bool, bool, bool, Bexpression*);
450 
451   Bvariable*
452   implicit_variable_reference(const std::string&, const std::string&, Btype*);
453 
454   Bvariable*
455   immutable_struct(const std::string&, const std::string&,
456                    bool, bool, Btype*, Location);
457 
458   void
459   immutable_struct_set_init(Bvariable*, const std::string&, bool, bool, Btype*,
460 			    Location, Bexpression*);
461 
462   Bvariable*
463   immutable_struct_reference(const std::string&, const std::string&,
464                              Btype*, Location);
465 
466   // Labels.
467 
468   Blabel*
469   label(Bfunction*, const std::string& name, Location);
470 
471   Bstatement*
472   label_definition_statement(Blabel*);
473 
474   Bstatement*
475   goto_statement(Blabel*, Location);
476 
477   Bexpression*
478   label_address(Blabel*, Location);
479 
480   // Functions.
481 
482   Bfunction*
error_function()483   error_function()
484   { return this->make_function(error_mark_node); }
485 
486   Bfunction*
487   function(Btype* fntype, const std::string& name, const std::string& asm_name,
488            bool is_visible, bool is_declaration, bool is_inlinable,
489            bool disable_split_stack, bool does_not_return,
490 	   bool in_unique_section, Location);
491 
492   Bstatement*
493   function_defer_statement(Bfunction* function, Bexpression* undefer,
494                            Bexpression* defer, Location);
495 
496   bool
497   function_set_parameters(Bfunction* function, const std::vector<Bvariable*>&);
498 
499   bool
500   function_set_body(Bfunction* function, Bstatement* code_stmt);
501 
502   Bfunction*
503   lookup_builtin(const std::string&);
504 
505   void
506   write_global_definitions(const std::vector<Btype*>&,
507                            const std::vector<Bexpression*>&,
508                            const std::vector<Bfunction*>&,
509                            const std::vector<Bvariable*>&);
510 
511   void
512   write_export_data(const char* bytes, unsigned int size);
513 
514 
515  private:
516   // Make a Bexpression from a tree.
517   Bexpression*
make_expression(tree t)518   make_expression(tree t)
519   { return new Bexpression(t); }
520 
521   // Make a Bstatement from a tree.
522   Bstatement*
make_statement(tree t)523   make_statement(tree t)
524   { return new Bstatement(t); }
525 
526   // Make a Btype from a tree.
527   Btype*
make_type(tree t)528   make_type(tree t)
529   { return new Btype(t); }
530 
531   Bfunction*
make_function(tree t)532   make_function(tree t)
533   { return new Bfunction(t); }
534 
535   Btype*
536   fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
537 
538   Btype*
539   fill_in_array(Btype*, Btype*, Bexpression*);
540 
541   tree
542   non_zero_size_type(tree);
543 
544   tree
545   convert_tree(tree, tree, Location);
546 
547 private:
548   void
549   define_builtin(built_in_function bcode, const char* name, const char* libname,
550 		 tree fntype, bool const_p, bool noreturn_p);
551 
552   // A mapping of the GCC built-ins exposed to GCCGo.
553   std::map<std::string, Bfunction*> builtin_functions_;
554 };
555 
556 // A helper function to create a GCC identifier from a C++ string.
557 
558 static inline tree
get_identifier_from_string(const std::string & str)559 get_identifier_from_string(const std::string& str)
560 {
561   return get_identifier_with_length(str.data(), str.length());
562 }
563 
564 // Define the built-in functions that are exposed to GCCGo.
565 
Gcc_backend()566 Gcc_backend::Gcc_backend()
567 {
568   /* We need to define the fetch_and_add functions, since we use them
569      for ++ and --.  */
570   tree t = this->integer_type(true, BITS_PER_UNIT)->get_tree();
571   tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
572   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
573 		       NULL, build_function_type_list(t, p, t, NULL_TREE),
574 		       false, false);
575 
576   t = this->integer_type(true, BITS_PER_UNIT * 2)->get_tree();
577   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
578   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
579 		       NULL, build_function_type_list(t, p, t, NULL_TREE),
580 		       false, false);
581 
582   t = this->integer_type(true, BITS_PER_UNIT * 4)->get_tree();
583   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
584   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
585 		       NULL, build_function_type_list(t, p, t, NULL_TREE),
586 		       false, false);
587 
588   t = this->integer_type(true, BITS_PER_UNIT * 8)->get_tree();
589   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
590   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
591 		       NULL, build_function_type_list(t, p, t, NULL_TREE),
592 		       false, false);
593 
594   // We use __builtin_expect for magic import functions.
595   this->define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL,
596 		       build_function_type_list(long_integer_type_node,
597 						long_integer_type_node,
598 						long_integer_type_node,
599 						NULL_TREE),
600 		       true, false);
601 
602   // We use __builtin_memcmp for struct comparisons.
603   this->define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
604 		       build_function_type_list(integer_type_node,
605 						const_ptr_type_node,
606 						const_ptr_type_node,
607 						size_type_node,
608 						NULL_TREE),
609 		       false, false);
610 
611   // Used by runtime/internal/sys.
612   this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz",
613 		       build_function_type_list(integer_type_node,
614 						unsigned_type_node,
615 						NULL_TREE),
616 		       true, false);
617   this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
618 		       build_function_type_list(integer_type_node,
619 						long_long_unsigned_type_node,
620 						NULL_TREE),
621 		       true, false);
622   this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
623 		       build_function_type_list(uint32_type_node,
624 						uint32_type_node,
625 						NULL_TREE),
626 		       true, false);
627   this->define_builtin(BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
628 		       build_function_type_list(uint64_type_node,
629 						uint64_type_node,
630 						NULL_TREE),
631 		       true, false);
632 
633   // We provide some functions for the math library.
634   tree math_function_type = build_function_type_list(double_type_node,
635 						     double_type_node,
636 						     NULL_TREE);
637   tree math_function_type_long =
638     build_function_type_list(long_double_type_node, long_double_type_node,
639 			     NULL_TREE);
640   tree math_function_type_two = build_function_type_list(double_type_node,
641 							 double_type_node,
642 							 double_type_node,
643 							 NULL_TREE);
644   tree math_function_type_long_two =
645     build_function_type_list(long_double_type_node, long_double_type_node,
646 			     long_double_type_node, NULL_TREE);
647   this->define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
648 		       math_function_type, true, false);
649   this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
650 		       math_function_type_long, true, false);
651   this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
652 		       math_function_type, true, false);
653   this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
654 		       math_function_type_long, true, false);
655   this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
656 		       math_function_type, true, false);
657   this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
658 		       math_function_type_long, true, false);
659   this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
660 		       math_function_type_two, true, false);
661   this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
662 		       math_function_type_long_two, true, false);
663   this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
664 		       math_function_type, true, false);
665   this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
666 		       math_function_type_long, true, false);
667   this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
668 		       math_function_type, true, false);
669   this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
670 		       math_function_type_long, true, false);
671   this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
672 		       math_function_type, true, false);
673   this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
674 		       math_function_type_long, true, false);
675   this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
676 		       math_function_type, true, false);
677   this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
678 		       math_function_type_long, true, false);
679   this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
680 		       math_function_type, true, false);
681   this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
682 		       math_function_type_long, true, false);
683   this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
684 		       math_function_type, true, false);
685   this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
686 		       math_function_type_long, true, false);
687   this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
688 		       math_function_type_two, true, false);
689   this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
690 		       math_function_type_long_two, true, false);
691   this->define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
692 		       build_function_type_list(double_type_node,
693 						double_type_node,
694 						integer_type_node,
695 						NULL_TREE),
696 		       true, false);
697   this->define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
698 		       build_function_type_list(long_double_type_node,
699 						long_double_type_node,
700 						integer_type_node,
701 						NULL_TREE),
702 		       true, false);
703   this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
704 		       math_function_type, true, false);
705   this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
706 		       math_function_type_long, true, false);
707   this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
708 		       math_function_type, true, false);
709   this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
710 		       math_function_type_long, true, false);
711   this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
712 		       math_function_type, true, false);
713   this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
714 		       math_function_type_long, true, false);
715   this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
716 		       math_function_type, true, false);
717   this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
718 		       math_function_type_long, true, false);
719   this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
720 		       math_function_type, true, false);
721   this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
722 		       math_function_type_long, true, false);
723   this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
724 		       math_function_type, true, false);
725   this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
726 		       math_function_type_long, true, false);
727   this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
728 		       math_function_type, true, false);
729   this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
730 		       math_function_type_long, true, false);
731   this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
732 		       math_function_type, true, false);
733   this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
734 		       math_function_type_long, true, false);
735 
736   // We use __builtin_return_address in the thunk we build for
737   // functions which call recover, and for runtime.getcallerpc.
738   t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE);
739   this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
740 		       NULL, t, false, false);
741 
742   // The runtime calls __builtin_frame_address for runtime.getcallersp.
743   this->define_builtin(BUILT_IN_FRAME_ADDRESS, "__builtin_frame_address",
744 		       NULL, t, false, false);
745 
746   // The runtime calls __builtin_extract_return_addr when recording
747   // the address to which a function returns.
748   this->define_builtin(BUILT_IN_EXTRACT_RETURN_ADDR,
749 		       "__builtin_extract_return_addr", NULL,
750 		       build_function_type_list(ptr_type_node,
751 						ptr_type_node,
752 						NULL_TREE),
753 		       false, false);
754 
755   // The compiler uses __builtin_trap for some exception handling
756   // cases.
757   this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL,
758 		       build_function_type(void_type_node, void_list_node),
759 		       false, true);
760 
761   // The runtime uses __builtin_prefetch.
762   this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
763 		       build_varargs_function_type_list(void_type_node,
764 							const_ptr_type_node,
765 							NULL_TREE),
766 		       false, false);
767 
768   // The compiler uses __builtin_unreachable for cases that can not
769   // occur.
770   this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
771 		       build_function_type(void_type_node, void_list_node),
772 		       true, true);
773 }
774 
775 // Get an unnamed integer type.
776 
777 Btype*
integer_type(bool is_unsigned,int bits)778 Gcc_backend::integer_type(bool is_unsigned, int bits)
779 {
780   tree type;
781   if (is_unsigned)
782     {
783       if (bits == INT_TYPE_SIZE)
784         type = unsigned_type_node;
785       else if (bits == CHAR_TYPE_SIZE)
786         type = unsigned_char_type_node;
787       else if (bits == SHORT_TYPE_SIZE)
788         type = short_unsigned_type_node;
789       else if (bits == LONG_TYPE_SIZE)
790         type = long_unsigned_type_node;
791       else if (bits == LONG_LONG_TYPE_SIZE)
792         type = long_long_unsigned_type_node;
793       else
794         type = make_unsigned_type(bits);
795     }
796   else
797     {
798       if (bits == INT_TYPE_SIZE)
799         type = integer_type_node;
800       else if (bits == CHAR_TYPE_SIZE)
801         type = signed_char_type_node;
802       else if (bits == SHORT_TYPE_SIZE)
803         type = short_integer_type_node;
804       else if (bits == LONG_TYPE_SIZE)
805         type = long_integer_type_node;
806       else if (bits == LONG_LONG_TYPE_SIZE)
807         type = long_long_integer_type_node;
808       else
809         type = make_signed_type(bits);
810     }
811   return this->make_type(type);
812 }
813 
814 // Get an unnamed float type.
815 
816 Btype*
float_type(int bits)817 Gcc_backend::float_type(int bits)
818 {
819   tree type;
820   if (bits == FLOAT_TYPE_SIZE)
821     type = float_type_node;
822   else if (bits == DOUBLE_TYPE_SIZE)
823     type = double_type_node;
824   else if (bits == LONG_DOUBLE_TYPE_SIZE)
825     type = long_double_type_node;
826   else
827     {
828       type = make_node(REAL_TYPE);
829       TYPE_PRECISION(type) = bits;
830       layout_type(type);
831     }
832   return this->make_type(type);
833 }
834 
835 // Get an unnamed complex type.
836 
837 Btype*
complex_type(int bits)838 Gcc_backend::complex_type(int bits)
839 {
840   tree type;
841   if (bits == FLOAT_TYPE_SIZE * 2)
842     type = complex_float_type_node;
843   else if (bits == DOUBLE_TYPE_SIZE * 2)
844     type = complex_double_type_node;
845   else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
846     type = complex_long_double_type_node;
847   else
848     {
849       type = make_node(REAL_TYPE);
850       TYPE_PRECISION(type) = bits / 2;
851       layout_type(type);
852       type = build_complex_type(type);
853     }
854   return this->make_type(type);
855 }
856 
857 // Get a pointer type.
858 
859 Btype*
pointer_type(Btype * to_type)860 Gcc_backend::pointer_type(Btype* to_type)
861 {
862   tree to_type_tree = to_type->get_tree();
863   if (to_type_tree == error_mark_node)
864     return this->error_type();
865   tree type = build_pointer_type(to_type_tree);
866   return this->make_type(type);
867 }
868 
869 // Make a function type.
870 
871 Btype*
function_type(const Btyped_identifier & receiver,const std::vector<Btyped_identifier> & parameters,const std::vector<Btyped_identifier> & results,Btype * result_struct,Location)872 Gcc_backend::function_type(const Btyped_identifier& receiver,
873 			   const std::vector<Btyped_identifier>& parameters,
874 			   const std::vector<Btyped_identifier>& results,
875 			   Btype* result_struct,
876 			   Location)
877 {
878   tree args = NULL_TREE;
879   tree* pp = &args;
880   if (receiver.btype != NULL)
881     {
882       tree t = receiver.btype->get_tree();
883       if (t == error_mark_node)
884 	return this->error_type();
885       *pp = tree_cons(NULL_TREE, t, NULL_TREE);
886       pp = &TREE_CHAIN(*pp);
887     }
888 
889   for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
890        p != parameters.end();
891        ++p)
892     {
893       tree t = p->btype->get_tree();
894       if (t == error_mark_node)
895 	return this->error_type();
896       *pp = tree_cons(NULL_TREE, t, NULL_TREE);
897       pp = &TREE_CHAIN(*pp);
898     }
899 
900   // Varargs is handled entirely at the Go level.  When converted to
901   // GENERIC functions are not varargs.
902   *pp = void_list_node;
903 
904   tree result;
905   if (results.empty())
906     result = void_type_node;
907   else if (results.size() == 1)
908     result = results.front().btype->get_tree();
909   else
910     {
911       gcc_assert(result_struct != NULL);
912       result = result_struct->get_tree();
913     }
914   if (result == error_mark_node)
915     return this->error_type();
916 
917   // The libffi library can not represent a zero-sized object.  To
918   // avoid causing confusion on 32-bit SPARC, we treat a function that
919   // returns a zero-sized value as returning void.  That should do no
920   // harm since there is no actual value to be returned.  See
921   // https://gcc.gnu.org/PR72814 for details.
922   if (result != void_type_node && int_size_in_bytes(result) == 0)
923     result = void_type_node;
924 
925   tree fntype = build_function_type(result, args);
926   if (fntype == error_mark_node)
927     return this->error_type();
928 
929   return this->make_type(build_pointer_type(fntype));
930 }
931 
932 // Make a struct type.
933 
934 Btype*
struct_type(const std::vector<Btyped_identifier> & fields)935 Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
936 {
937   return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE)), fields);
938 }
939 
940 // Fill in the fields of a struct type.
941 
942 Btype*
fill_in_struct(Btype * fill,const std::vector<Btyped_identifier> & fields)943 Gcc_backend::fill_in_struct(Btype* fill,
944 			    const std::vector<Btyped_identifier>& fields)
945 {
946   tree fill_tree = fill->get_tree();
947   tree field_trees = NULL_TREE;
948   tree* pp = &field_trees;
949   for (std::vector<Btyped_identifier>::const_iterator p = fields.begin();
950        p != fields.end();
951        ++p)
952     {
953       tree name_tree = get_identifier_from_string(p->name);
954       tree type_tree = p->btype->get_tree();
955       if (type_tree == error_mark_node)
956 	return this->error_type();
957       tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
958                               type_tree);
959       DECL_CONTEXT(field) = fill_tree;
960       *pp = field;
961       pp = &DECL_CHAIN(field);
962     }
963   TYPE_FIELDS(fill_tree) = field_trees;
964   layout_type(fill_tree);
965 
966   // Because Go permits converting between named struct types and
967   // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
968   // because we don't try to maintain TYPE_CANONICAL for struct types,
969   // we need to tell the middle-end to use structural equality.
970   SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
971 
972   return fill;
973 }
974 
975 // Make an array type.
976 
977 Btype*
array_type(Btype * element_btype,Bexpression * length)978 Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
979 {
980   return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
981 			     element_btype, length);
982 }
983 
984 // Fill in an array type.
985 
986 Btype*
fill_in_array(Btype * fill,Btype * element_type,Bexpression * length)987 Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
988 			   Bexpression* length)
989 {
990   tree element_type_tree = element_type->get_tree();
991   tree length_tree = length->get_tree();
992   if (element_type_tree == error_mark_node || length_tree == error_mark_node)
993     return this->error_type();
994 
995   gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
996 
997   length_tree = fold_convert(sizetype, length_tree);
998 
999   // build_index_type takes the maximum index, which is one less than
1000   // the length.
1001   tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
1002 						      length_tree,
1003 						      size_one_node));
1004 
1005   tree fill_tree = fill->get_tree();
1006   TREE_TYPE(fill_tree) = element_type_tree;
1007   TYPE_DOMAIN(fill_tree) = index_type_tree;
1008   TYPE_ADDR_SPACE(fill_tree) = TYPE_ADDR_SPACE(element_type_tree);
1009   layout_type(fill_tree);
1010 
1011   if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree))
1012     SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
1013   else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
1014 	   || TYPE_CANONICAL(index_type_tree) != index_type_tree)
1015     TYPE_CANONICAL(fill_tree) =
1016       build_array_type(TYPE_CANONICAL(element_type_tree),
1017 		       TYPE_CANONICAL(index_type_tree));
1018 
1019   return fill;
1020 }
1021 
1022 // Create a placeholder for a pointer type.
1023 
1024 Btype*
placeholder_pointer_type(const std::string & name,Location location,bool)1025 Gcc_backend::placeholder_pointer_type(const std::string& name,
1026 				      Location location, bool)
1027 {
1028   tree ret = build_distinct_type_copy(ptr_type_node);
1029   if (!name.empty())
1030     {
1031       tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1032 			     get_identifier_from_string(name),
1033 			     ret);
1034       TYPE_NAME(ret) = decl;
1035     }
1036   return this->make_type(ret);
1037 }
1038 
1039 // Set the real target type for a placeholder pointer type.
1040 
1041 bool
set_placeholder_pointer_type(Btype * placeholder,Btype * to_type)1042 Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
1043 					  Btype* to_type)
1044 {
1045   tree pt = placeholder->get_tree();
1046   if (pt == error_mark_node)
1047     return false;
1048   gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
1049   tree tt = to_type->get_tree();
1050   if (tt == error_mark_node)
1051     {
1052       placeholder->set_tree(error_mark_node);
1053       return false;
1054     }
1055   gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
1056   TREE_TYPE(pt) = TREE_TYPE(tt);
1057   if (TYPE_NAME(pt) != NULL_TREE)
1058     {
1059       // Build the data structure gcc wants to see for a typedef.
1060       tree copy = build_variant_type_copy(pt);
1061       TYPE_NAME(copy) = NULL_TREE;
1062       DECL_ORIGINAL_TYPE(TYPE_NAME(pt)) = copy;
1063     }
1064   return true;
1065 }
1066 
1067 // Set the real values for a placeholder function type.
1068 
1069 bool
set_placeholder_function_type(Btype * placeholder,Btype * ft)1070 Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
1071 {
1072   return this->set_placeholder_pointer_type(placeholder, ft);
1073 }
1074 
1075 // Create a placeholder for a struct type.
1076 
1077 Btype*
placeholder_struct_type(const std::string & name,Location location)1078 Gcc_backend::placeholder_struct_type(const std::string& name,
1079 				     Location location)
1080 {
1081   tree ret = make_node(RECORD_TYPE);
1082   if (!name.empty())
1083     {
1084       tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1085 			     get_identifier_from_string(name),
1086 			     ret);
1087       TYPE_NAME(ret) = decl;
1088     }
1089   return this->make_type(ret);
1090 }
1091 
1092 // Fill in the fields of a placeholder struct type.
1093 
1094 bool
set_placeholder_struct_type(Btype * placeholder,const std::vector<Btyped_identifier> & fields)1095 Gcc_backend::set_placeholder_struct_type(
1096     Btype* placeholder,
1097     const std::vector<Btyped_identifier>& fields)
1098 {
1099   tree t = placeholder->get_tree();
1100   gcc_assert(TREE_CODE(t) == RECORD_TYPE && TYPE_FIELDS(t) == NULL_TREE);
1101   Btype* r = this->fill_in_struct(placeholder, fields);
1102 
1103   if (TYPE_NAME(t) != NULL_TREE)
1104     {
1105       // Build the data structure gcc wants to see for a typedef.
1106       tree copy = build_distinct_type_copy(t);
1107       TYPE_NAME(copy) = NULL_TREE;
1108       DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
1109     }
1110 
1111   return r->get_tree() != error_mark_node;
1112 }
1113 
1114 // Create a placeholder for an array type.
1115 
1116 Btype*
placeholder_array_type(const std::string & name,Location location)1117 Gcc_backend::placeholder_array_type(const std::string& name,
1118 				    Location location)
1119 {
1120   tree ret = make_node(ARRAY_TYPE);
1121   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1122 			 get_identifier_from_string(name),
1123 			 ret);
1124   TYPE_NAME(ret) = decl;
1125   return this->make_type(ret);
1126 }
1127 
1128 // Fill in the fields of a placeholder array type.
1129 
1130 bool
set_placeholder_array_type(Btype * placeholder,Btype * element_btype,Bexpression * length)1131 Gcc_backend::set_placeholder_array_type(Btype* placeholder,
1132 					Btype* element_btype,
1133 					Bexpression* length)
1134 {
1135   tree t = placeholder->get_tree();
1136   gcc_assert(TREE_CODE(t) == ARRAY_TYPE && TREE_TYPE(t) == NULL_TREE);
1137   Btype* r = this->fill_in_array(placeholder, element_btype, length);
1138 
1139   // Build the data structure gcc wants to see for a typedef.
1140   tree copy = build_distinct_type_copy(t);
1141   TYPE_NAME(copy) = NULL_TREE;
1142   DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
1143 
1144   return r->get_tree() != error_mark_node;
1145 }
1146 
1147 // Return a named version of a type.
1148 
1149 Btype*
named_type(const std::string & name,Btype * btype,Location location)1150 Gcc_backend::named_type(const std::string& name, Btype* btype,
1151 			Location location)
1152 {
1153   tree type = btype->get_tree();
1154   if (type == error_mark_node)
1155     return this->error_type();
1156 
1157   // The middle-end expects a basic type to have a name.  In Go every
1158   // basic type will have a name.  The first time we see a basic type,
1159   // give it whatever Go name we have at this point.
1160   if (TYPE_NAME(type) == NULL_TREE
1161       && location.gcc_location() == BUILTINS_LOCATION
1162       && (TREE_CODE(type) == INTEGER_TYPE
1163 	  || TREE_CODE(type) == REAL_TYPE
1164 	  || TREE_CODE(type) == COMPLEX_TYPE
1165 	  || TREE_CODE(type) == BOOLEAN_TYPE))
1166     {
1167       tree decl = build_decl(BUILTINS_LOCATION, TYPE_DECL,
1168 			     get_identifier_from_string(name),
1169 			     type);
1170       TYPE_NAME(type) = decl;
1171       return this->make_type(type);
1172     }
1173 
1174   tree copy = build_variant_type_copy(type);
1175   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1176 			 get_identifier_from_string(name),
1177 			 copy);
1178   DECL_ORIGINAL_TYPE(decl) = type;
1179   TYPE_NAME(copy) = decl;
1180   return this->make_type(copy);
1181 }
1182 
1183 // Return a pointer type used as a marker for a circular type.
1184 
1185 Btype*
circular_pointer_type(Btype *,bool)1186 Gcc_backend::circular_pointer_type(Btype*, bool)
1187 {
1188   return this->make_type(ptr_type_node);
1189 }
1190 
1191 // Return whether we might be looking at a circular type.
1192 
1193 bool
is_circular_pointer_type(Btype * btype)1194 Gcc_backend::is_circular_pointer_type(Btype* btype)
1195 {
1196   return btype->get_tree() == ptr_type_node;
1197 }
1198 
1199 // Return the size of a type.
1200 
1201 int64_t
type_size(Btype * btype)1202 Gcc_backend::type_size(Btype* btype)
1203 {
1204   tree t = btype->get_tree();
1205   if (t == error_mark_node)
1206     return 1;
1207   if (t == void_type_node)
1208     return 0;
1209   t = TYPE_SIZE_UNIT(t);
1210   gcc_assert(tree_fits_uhwi_p (t));
1211   unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
1212   int64_t ret = static_cast<int64_t>(val_wide);
1213   if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
1214     return -1;
1215   return ret;
1216 }
1217 
1218 // Return the alignment of a type.
1219 
1220 int64_t
type_alignment(Btype * btype)1221 Gcc_backend::type_alignment(Btype* btype)
1222 {
1223   tree t = btype->get_tree();
1224   if (t == error_mark_node)
1225     return 1;
1226   return TYPE_ALIGN_UNIT(t);
1227 }
1228 
1229 // Return the alignment of a struct field of type BTYPE.
1230 
1231 int64_t
type_field_alignment(Btype * btype)1232 Gcc_backend::type_field_alignment(Btype* btype)
1233 {
1234   tree t = btype->get_tree();
1235   if (t == error_mark_node)
1236     return 1;
1237   return go_field_alignment(t);
1238 }
1239 
1240 // Return the offset of a field in a struct.
1241 
1242 int64_t
type_field_offset(Btype * btype,size_t index)1243 Gcc_backend::type_field_offset(Btype* btype, size_t index)
1244 {
1245   tree struct_tree = btype->get_tree();
1246   if (struct_tree == error_mark_node)
1247     return 0;
1248   gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
1249   tree field = TYPE_FIELDS(struct_tree);
1250   for (; index > 0; --index)
1251     {
1252       field = DECL_CHAIN(field);
1253       gcc_assert(field != NULL_TREE);
1254     }
1255   HOST_WIDE_INT offset_wide = int_byte_position(field);
1256   int64_t ret = static_cast<int64_t>(offset_wide);
1257   gcc_assert(ret == offset_wide);
1258   return ret;
1259 }
1260 
1261 // Return the zero value for a type.
1262 
1263 Bexpression*
zero_expression(Btype * btype)1264 Gcc_backend::zero_expression(Btype* btype)
1265 {
1266   tree t = btype->get_tree();
1267   tree ret;
1268   if (t == error_mark_node)
1269     ret = error_mark_node;
1270   else
1271     ret = build_zero_cst(t);
1272   return this->make_expression(ret);
1273 }
1274 
1275 // An expression that references a variable.
1276 
1277 Bexpression*
var_expression(Bvariable * var,Location location)1278 Gcc_backend::var_expression(Bvariable* var, Location location)
1279 {
1280   tree ret = var->get_tree(location);
1281   if (ret == error_mark_node)
1282     return this->error_expression();
1283   return this->make_expression(ret);
1284 }
1285 
1286 // An expression that indirectly references an expression.
1287 
1288 Bexpression*
indirect_expression(Btype * btype,Bexpression * expr,bool known_valid,Location location)1289 Gcc_backend::indirect_expression(Btype* btype, Bexpression* expr,
1290 				 bool known_valid, Location location)
1291 {
1292   tree expr_tree = expr->get_tree();
1293   tree type_tree = btype->get_tree();
1294   if (expr_tree == error_mark_node || type_tree == error_mark_node)
1295     return this->error_expression();
1296 
1297   // If the type of EXPR is a recursive pointer type, then we
1298   // need to insert a cast before indirecting.
1299   tree target_type_tree = TREE_TYPE(TREE_TYPE(expr_tree));
1300   if (VOID_TYPE_P(target_type_tree))
1301     expr_tree = fold_convert_loc(location.gcc_location(),
1302 				 build_pointer_type(type_tree), expr_tree);
1303 
1304   tree ret = build_fold_indirect_ref_loc(location.gcc_location(),
1305                                          expr_tree);
1306   if (known_valid)
1307     TREE_THIS_NOTRAP(ret) = 1;
1308   return this->make_expression(ret);
1309 }
1310 
1311 // Return an expression that declares a constant named NAME with the
1312 // constant value VAL in BTYPE.
1313 
1314 Bexpression*
named_constant_expression(Btype * btype,const std::string & name,Bexpression * val,Location location)1315 Gcc_backend::named_constant_expression(Btype* btype, const std::string& name,
1316 				       Bexpression* val, Location location)
1317 {
1318   tree type_tree = btype->get_tree();
1319   tree const_val = val->get_tree();
1320   if (type_tree == error_mark_node || const_val == error_mark_node)
1321     return this->error_expression();
1322 
1323   tree name_tree = get_identifier_from_string(name);
1324   tree decl = build_decl(location.gcc_location(), CONST_DECL, name_tree,
1325 			 type_tree);
1326   DECL_INITIAL(decl) = const_val;
1327   TREE_CONSTANT(decl) = 1;
1328   TREE_READONLY(decl) = 1;
1329 
1330   go_preserve_from_gc(decl);
1331   return this->make_expression(decl);
1332 }
1333 
1334 // Return a typed value as a constant integer.
1335 
1336 Bexpression*
integer_constant_expression(Btype * btype,mpz_t val)1337 Gcc_backend::integer_constant_expression(Btype* btype, mpz_t val)
1338 {
1339   tree t = btype->get_tree();
1340   if (t == error_mark_node)
1341     return this->error_expression();
1342 
1343   tree ret = double_int_to_tree(t, mpz_get_double_int(t, val, true));
1344   return this->make_expression(ret);
1345 }
1346 
1347 // Return a typed value as a constant floating-point number.
1348 
1349 Bexpression*
float_constant_expression(Btype * btype,mpfr_t val)1350 Gcc_backend::float_constant_expression(Btype* btype, mpfr_t val)
1351 {
1352   tree t = btype->get_tree();
1353   tree ret;
1354   if (t == error_mark_node)
1355     return this->error_expression();
1356 
1357   REAL_VALUE_TYPE r1;
1358   real_from_mpfr(&r1, val, t, GMP_RNDN);
1359   REAL_VALUE_TYPE r2;
1360   real_convert(&r2, TYPE_MODE(t), &r1);
1361   ret = build_real(t, r2);
1362   return this->make_expression(ret);
1363 }
1364 
1365 // Return a typed real and imaginary value as a constant complex number.
1366 
1367 Bexpression*
complex_constant_expression(Btype * btype,mpc_t val)1368 Gcc_backend::complex_constant_expression(Btype* btype, mpc_t val)
1369 {
1370   tree t = btype->get_tree();
1371   tree ret;
1372   if (t == error_mark_node)
1373     return this->error_expression();
1374 
1375   REAL_VALUE_TYPE r1;
1376   real_from_mpfr(&r1, mpc_realref(val), TREE_TYPE(t), GMP_RNDN);
1377   REAL_VALUE_TYPE r2;
1378   real_convert(&r2, TYPE_MODE(TREE_TYPE(t)), &r1);
1379 
1380   REAL_VALUE_TYPE r3;
1381   real_from_mpfr(&r3, mpc_imagref(val), TREE_TYPE(t), GMP_RNDN);
1382   REAL_VALUE_TYPE r4;
1383   real_convert(&r4, TYPE_MODE(TREE_TYPE(t)), &r3);
1384 
1385   ret = build_complex(t, build_real(TREE_TYPE(t), r2),
1386                       build_real(TREE_TYPE(t), r4));
1387   return this->make_expression(ret);
1388 }
1389 
1390 // Make a constant string expression.
1391 
1392 Bexpression*
string_constant_expression(const std::string & val)1393 Gcc_backend::string_constant_expression(const std::string& val)
1394 {
1395   tree index_type = build_index_type(size_int(val.length()));
1396   tree const_char_type = build_qualified_type(unsigned_char_type_node,
1397 					      TYPE_QUAL_CONST);
1398   tree string_type = build_array_type(const_char_type, index_type);
1399   TYPE_STRING_FLAG(string_type) = 1;
1400   tree string_val = build_string(val.length(), val.data());
1401   TREE_TYPE(string_val) = string_type;
1402 
1403   return this->make_expression(string_val);
1404 }
1405 
1406 // Make a constant boolean expression.
1407 
1408 Bexpression*
boolean_constant_expression(bool val)1409 Gcc_backend::boolean_constant_expression(bool val)
1410 {
1411   tree bool_cst = val ? boolean_true_node : boolean_false_node;
1412   return this->make_expression(bool_cst);
1413 }
1414 
1415 // Return the real part of a complex expression.
1416 
1417 Bexpression*
real_part_expression(Bexpression * bcomplex,Location location)1418 Gcc_backend::real_part_expression(Bexpression* bcomplex, Location location)
1419 {
1420   tree complex_tree = bcomplex->get_tree();
1421   if (complex_tree == error_mark_node)
1422     return this->error_expression();
1423   gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
1424   tree ret = fold_build1_loc(location.gcc_location(), REALPART_EXPR,
1425                              TREE_TYPE(TREE_TYPE(complex_tree)),
1426                              complex_tree);
1427   return this->make_expression(ret);
1428 }
1429 
1430 // Return the imaginary part of a complex expression.
1431 
1432 Bexpression*
imag_part_expression(Bexpression * bcomplex,Location location)1433 Gcc_backend::imag_part_expression(Bexpression* bcomplex, Location location)
1434 {
1435   tree complex_tree = bcomplex->get_tree();
1436   if (complex_tree == error_mark_node)
1437     return this->error_expression();
1438   gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
1439   tree ret = fold_build1_loc(location.gcc_location(), IMAGPART_EXPR,
1440                              TREE_TYPE(TREE_TYPE(complex_tree)),
1441                              complex_tree);
1442   return this->make_expression(ret);
1443 }
1444 
1445 // Make a complex expression given its real and imaginary parts.
1446 
1447 Bexpression*
complex_expression(Bexpression * breal,Bexpression * bimag,Location location)1448 Gcc_backend::complex_expression(Bexpression* breal, Bexpression* bimag,
1449                                 Location location)
1450 {
1451   tree real_tree = breal->get_tree();
1452   tree imag_tree = bimag->get_tree();
1453   if (real_tree == error_mark_node || imag_tree == error_mark_node)
1454     return this->error_expression();
1455   gcc_assert(TYPE_MAIN_VARIANT(TREE_TYPE(real_tree))
1456             == TYPE_MAIN_VARIANT(TREE_TYPE(imag_tree)));
1457   gcc_assert(SCALAR_FLOAT_TYPE_P(TREE_TYPE(real_tree)));
1458   tree ret = fold_build2_loc(location.gcc_location(), COMPLEX_EXPR,
1459                              build_complex_type(TREE_TYPE(real_tree)),
1460                              real_tree, imag_tree);
1461   return this->make_expression(ret);
1462 }
1463 
1464 // An expression that converts an expression to a different type.
1465 
1466 Bexpression*
convert_expression(Btype * type,Bexpression * expr,Location location)1467 Gcc_backend::convert_expression(Btype* type, Bexpression* expr,
1468 				Location location)
1469 {
1470   tree type_tree = type->get_tree();
1471   tree expr_tree = expr->get_tree();
1472   if (type_tree == error_mark_node
1473       || expr_tree == error_mark_node
1474       || TREE_TYPE(expr_tree) == error_mark_node)
1475     return this->error_expression();
1476 
1477   tree ret;
1478   if (this->type_size(type) == 0
1479       || TREE_TYPE(expr_tree) == void_type_node)
1480     {
1481       // Do not convert zero-sized types.
1482       ret = expr_tree;
1483     }
1484   else if (TREE_CODE(type_tree) == INTEGER_TYPE)
1485     ret = fold(convert_to_integer(type_tree, expr_tree));
1486   else if (TREE_CODE(type_tree) == REAL_TYPE)
1487     ret = fold(convert_to_real(type_tree, expr_tree));
1488   else if (TREE_CODE(type_tree) == COMPLEX_TYPE)
1489     ret = fold(convert_to_complex(type_tree, expr_tree));
1490   else if (TREE_CODE(type_tree) == POINTER_TYPE
1491            && TREE_CODE(TREE_TYPE(expr_tree)) == INTEGER_TYPE)
1492     ret = fold(convert_to_pointer(type_tree, expr_tree));
1493   else if (TREE_CODE(type_tree) == RECORD_TYPE
1494            || TREE_CODE(type_tree) == ARRAY_TYPE)
1495     ret = fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
1496                           type_tree, expr_tree);
1497   else
1498     ret = fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
1499 
1500   return this->make_expression(ret);
1501 }
1502 
1503 // Get the address of a function.
1504 
1505 Bexpression*
function_code_expression(Bfunction * bfunc,Location location)1506 Gcc_backend::function_code_expression(Bfunction* bfunc, Location location)
1507 {
1508   tree func = bfunc->get_tree();
1509   if (func == error_mark_node)
1510     return this->error_expression();
1511 
1512   tree ret = build_fold_addr_expr_loc(location.gcc_location(), func);
1513   return this->make_expression(ret);
1514 }
1515 
1516 // Get the address of an expression.
1517 
1518 Bexpression*
address_expression(Bexpression * bexpr,Location location)1519 Gcc_backend::address_expression(Bexpression* bexpr, Location location)
1520 {
1521   tree expr = bexpr->get_tree();
1522   if (expr == error_mark_node)
1523     return this->error_expression();
1524 
1525   tree ret = build_fold_addr_expr_loc(location.gcc_location(), expr);
1526   return this->make_expression(ret);
1527 }
1528 
1529 // Return an expression for the field at INDEX in BSTRUCT.
1530 
1531 Bexpression*
struct_field_expression(Bexpression * bstruct,size_t index,Location location)1532 Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index,
1533                                      Location location)
1534 {
1535   tree struct_tree = bstruct->get_tree();
1536   if (struct_tree == error_mark_node
1537       || TREE_TYPE(struct_tree) == error_mark_node)
1538     return this->error_expression();
1539   gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
1540   tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
1541   if (field == NULL_TREE)
1542   {
1543     // This can happen for a type which refers to itself indirectly
1544     // and then turns out to be erroneous.
1545     return this->error_expression();
1546   }
1547   for (unsigned int i = index; i > 0; --i)
1548   {
1549     field = DECL_CHAIN(field);
1550     gcc_assert(field != NULL_TREE);
1551   }
1552   if (TREE_TYPE(field) == error_mark_node)
1553     return this->error_expression();
1554   tree ret = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
1555                              TREE_TYPE(field), struct_tree, field,
1556                              NULL_TREE);
1557   if (TREE_CONSTANT(struct_tree))
1558     TREE_CONSTANT(ret) = 1;
1559   return this->make_expression(ret);
1560 }
1561 
1562 // Return an expression that executes BSTAT before BEXPR.
1563 
1564 Bexpression*
compound_expression(Bstatement * bstat,Bexpression * bexpr,Location location)1565 Gcc_backend::compound_expression(Bstatement* bstat, Bexpression* bexpr,
1566                                  Location location)
1567 {
1568   tree stat = bstat->get_tree();
1569   tree expr = bexpr->get_tree();
1570   if (stat == error_mark_node || expr == error_mark_node)
1571     return this->error_expression();
1572   tree ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1573                              TREE_TYPE(expr), stat, expr);
1574   return this->make_expression(ret);
1575 }
1576 
1577 // Return an expression that executes THEN_EXPR if CONDITION is true, or
1578 // ELSE_EXPR otherwise.
1579 
1580 Bexpression*
conditional_expression(Bfunction *,Btype * btype,Bexpression * condition,Bexpression * then_expr,Bexpression * else_expr,Location location)1581 Gcc_backend::conditional_expression(Bfunction*, Btype* btype,
1582                                     Bexpression* condition,
1583                                     Bexpression* then_expr,
1584                                     Bexpression* else_expr, Location location)
1585 {
1586   tree type_tree = btype == NULL ? void_type_node : btype->get_tree();
1587   tree cond_tree = condition->get_tree();
1588   tree then_tree = then_expr->get_tree();
1589   tree else_tree = else_expr == NULL ? NULL_TREE : else_expr->get_tree();
1590   if (type_tree == error_mark_node
1591       || cond_tree == error_mark_node
1592       || then_tree == error_mark_node
1593       || else_tree == error_mark_node)
1594     return this->error_expression();
1595   tree ret = build3_loc(location.gcc_location(), COND_EXPR, type_tree,
1596                         cond_tree, then_tree, else_tree);
1597   return this->make_expression(ret);
1598 }
1599 
1600 // Return an expression for the unary operation OP EXPR.
1601 
1602 Bexpression*
unary_expression(Operator op,Bexpression * expr,Location location)1603 Gcc_backend::unary_expression(Operator op, Bexpression* expr, Location location)
1604 {
1605   tree expr_tree = expr->get_tree();
1606   if (expr_tree == error_mark_node
1607       || TREE_TYPE(expr_tree) == error_mark_node)
1608     return this->error_expression();
1609 
1610   tree type_tree = TREE_TYPE(expr_tree);
1611   enum tree_code code;
1612   switch (op)
1613     {
1614     case OPERATOR_MINUS:
1615       {
1616         tree computed_type = excess_precision_type(type_tree);
1617         if (computed_type != NULL_TREE)
1618           {
1619             expr_tree = convert(computed_type, expr_tree);
1620             type_tree = computed_type;
1621           }
1622         code = NEGATE_EXPR;
1623         break;
1624       }
1625     case OPERATOR_NOT:
1626       code = TRUTH_NOT_EXPR;
1627       break;
1628     case OPERATOR_XOR:
1629       code = BIT_NOT_EXPR;
1630       break;
1631     default:
1632       gcc_unreachable();
1633       break;
1634     }
1635 
1636   tree ret = fold_build1_loc(location.gcc_location(), code, type_tree,
1637                              expr_tree);
1638   return this->make_expression(ret);
1639 }
1640 
1641 // Convert a gofrontend operator to an equivalent tree_code.
1642 
1643 static enum tree_code
operator_to_tree_code(Operator op,tree type)1644 operator_to_tree_code(Operator op, tree type)
1645 {
1646   enum tree_code code;
1647   switch (op)
1648     {
1649     case OPERATOR_EQEQ:
1650       code = EQ_EXPR;
1651       break;
1652     case OPERATOR_NOTEQ:
1653       code = NE_EXPR;
1654       break;
1655     case OPERATOR_LT:
1656       code = LT_EXPR;
1657       break;
1658     case OPERATOR_LE:
1659       code = LE_EXPR;
1660       break;
1661     case OPERATOR_GT:
1662       code = GT_EXPR;
1663       break;
1664     case OPERATOR_GE:
1665       code = GE_EXPR;
1666       break;
1667     case OPERATOR_OROR:
1668       code = TRUTH_ORIF_EXPR;
1669       break;
1670     case OPERATOR_ANDAND:
1671       code = TRUTH_ANDIF_EXPR;
1672       break;
1673     case OPERATOR_PLUS:
1674       code = PLUS_EXPR;
1675       break;
1676     case OPERATOR_MINUS:
1677       code = MINUS_EXPR;
1678       break;
1679     case OPERATOR_OR:
1680       code = BIT_IOR_EXPR;
1681       break;
1682     case OPERATOR_XOR:
1683       code = BIT_XOR_EXPR;
1684       break;
1685     case OPERATOR_MULT:
1686       code = MULT_EXPR;
1687       break;
1688     case OPERATOR_DIV:
1689       if (TREE_CODE(type) == REAL_TYPE || TREE_CODE(type) == COMPLEX_TYPE)
1690 	code = RDIV_EXPR;
1691       else
1692 	code = TRUNC_DIV_EXPR;
1693       break;
1694     case OPERATOR_MOD:
1695       code = TRUNC_MOD_EXPR;
1696       break;
1697     case OPERATOR_LSHIFT:
1698       code = LSHIFT_EXPR;
1699       break;
1700     case OPERATOR_RSHIFT:
1701       code = RSHIFT_EXPR;
1702       break;
1703     case OPERATOR_AND:
1704       code = BIT_AND_EXPR;
1705       break;
1706     case OPERATOR_BITCLEAR:
1707       code = BIT_AND_EXPR;
1708       break;
1709     default:
1710       gcc_unreachable();
1711     }
1712 
1713   return code;
1714 }
1715 
1716 // Return an expression for the binary operation LEFT OP RIGHT.
1717 
1718 Bexpression*
binary_expression(Operator op,Bexpression * left,Bexpression * right,Location location)1719 Gcc_backend::binary_expression(Operator op, Bexpression* left,
1720                                Bexpression* right, Location location)
1721 {
1722   tree left_tree = left->get_tree();
1723   tree right_tree = right->get_tree();
1724   if (left_tree == error_mark_node
1725       || right_tree == error_mark_node)
1726     return this->error_expression();
1727   enum tree_code code = operator_to_tree_code(op, TREE_TYPE(left_tree));
1728 
1729   bool use_left_type = op != OPERATOR_OROR && op != OPERATOR_ANDAND;
1730   tree type_tree = use_left_type ? TREE_TYPE(left_tree) : TREE_TYPE(right_tree);
1731   tree computed_type = excess_precision_type(type_tree);
1732   if (computed_type != NULL_TREE)
1733     {
1734       left_tree = convert(computed_type, left_tree);
1735       right_tree = convert(computed_type, right_tree);
1736       type_tree = computed_type;
1737     }
1738 
1739   // For comparison operators, the resulting type should be boolean.
1740   switch (op)
1741     {
1742     case OPERATOR_EQEQ:
1743     case OPERATOR_NOTEQ:
1744     case OPERATOR_LT:
1745     case OPERATOR_LE:
1746     case OPERATOR_GT:
1747     case OPERATOR_GE:
1748       type_tree = boolean_type_node;
1749       break;
1750     default:
1751       break;
1752     }
1753 
1754   tree ret = fold_build2_loc(location.gcc_location(), code, type_tree,
1755                              left_tree, right_tree);
1756   return this->make_expression(ret);
1757 }
1758 
1759 // Return an expression that constructs BTYPE with VALS.
1760 
1761 Bexpression*
constructor_expression(Btype * btype,const std::vector<Bexpression * > & vals,Location location)1762 Gcc_backend::constructor_expression(Btype* btype,
1763                                     const std::vector<Bexpression*>& vals,
1764                                     Location location)
1765 {
1766   tree type_tree = btype->get_tree();
1767   if (type_tree == error_mark_node)
1768     return this->error_expression();
1769 
1770   vec<constructor_elt, va_gc> *init;
1771   vec_alloc(init, vals.size());
1772 
1773   tree sink = NULL_TREE;
1774   bool is_constant = true;
1775   tree field = TYPE_FIELDS(type_tree);
1776   for (std::vector<Bexpression*>::const_iterator p = vals.begin();
1777        p != vals.end();
1778        ++p, field = DECL_CHAIN(field))
1779     {
1780       gcc_assert(field != NULL_TREE);
1781       tree val = (*p)->get_tree();
1782       if (TREE_TYPE(field) == error_mark_node
1783           || val == error_mark_node
1784           || TREE_TYPE(val) == error_mark_node)
1785         return this->error_expression();
1786 
1787       if (int_size_in_bytes(TREE_TYPE(field)) == 0)
1788 	{
1789 	  // GIMPLE cannot represent indices of zero-sized types so
1790 	  // trying to construct a map with zero-sized keys might lead
1791 	  // to errors.  Instead, we evaluate each expression that
1792 	  // would have been added as a map element for its
1793 	  // side-effects and construct an empty map.
1794 	  append_to_statement_list(val, &sink);
1795 	  continue;
1796 	}
1797 
1798       constructor_elt empty = {NULL, NULL};
1799       constructor_elt* elt = init->quick_push(empty);
1800       elt->index = field;
1801       elt->value = this->convert_tree(TREE_TYPE(field), val, location);
1802       if (!TREE_CONSTANT(elt->value))
1803 	is_constant = false;
1804     }
1805   gcc_assert(field == NULL_TREE);
1806   tree ret = build_constructor(type_tree, init);
1807   if (is_constant)
1808     TREE_CONSTANT(ret) = 1;
1809   if (sink != NULL_TREE)
1810     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1811 			  type_tree, sink, ret);
1812   return this->make_expression(ret);
1813 }
1814 
1815 Bexpression*
array_constructor_expression(Btype * array_btype,const std::vector<unsigned long> & indexes,const std::vector<Bexpression * > & vals,Location location)1816 Gcc_backend::array_constructor_expression(
1817     Btype* array_btype, const std::vector<unsigned long>& indexes,
1818     const std::vector<Bexpression*>& vals, Location location)
1819 {
1820   tree type_tree = array_btype->get_tree();
1821   if (type_tree == error_mark_node)
1822     return this->error_expression();
1823 
1824   gcc_assert(indexes.size() == vals.size());
1825 
1826   tree element_type = TREE_TYPE(type_tree);
1827   HOST_WIDE_INT element_size = int_size_in_bytes(element_type);
1828   vec<constructor_elt, va_gc> *init;
1829   vec_alloc(init, element_size == 0 ? 0 : vals.size());
1830 
1831   tree sink = NULL_TREE;
1832   bool is_constant = true;
1833   for (size_t i = 0; i < vals.size(); ++i)
1834     {
1835       tree index = size_int(indexes[i]);
1836       tree val = (vals[i])->get_tree();
1837 
1838       if (index == error_mark_node
1839           || val == error_mark_node)
1840         return this->error_expression();
1841 
1842       if (element_size == 0)
1843        {
1844          // GIMPLE cannot represent arrays of zero-sized types so trying
1845          // to construct an array of zero-sized values might lead to errors.
1846          // Instead, we evaluate each expression that would have been added as
1847          // an array value for its side-effects and construct an empty array.
1848 	 append_to_statement_list(val, &sink);
1849          continue;
1850        }
1851 
1852       if (!TREE_CONSTANT(val))
1853         is_constant = false;
1854 
1855       constructor_elt empty = {NULL, NULL};
1856       constructor_elt* elt = init->quick_push(empty);
1857       elt->index = index;
1858       elt->value = val;
1859     }
1860 
1861   tree ret = build_constructor(type_tree, init);
1862   if (is_constant)
1863     TREE_CONSTANT(ret) = 1;
1864   if (sink != NULL_TREE)
1865     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1866                          type_tree, sink, ret);
1867   return this->make_expression(ret);
1868 }
1869 
1870 // Return an expression for the address of BASE[INDEX].
1871 
1872 Bexpression*
pointer_offset_expression(Bexpression * base,Bexpression * index,Location location)1873 Gcc_backend::pointer_offset_expression(Bexpression* base, Bexpression* index,
1874                                        Location location)
1875 {
1876   tree base_tree = base->get_tree();
1877   tree index_tree = index->get_tree();
1878   tree element_type_tree = TREE_TYPE(TREE_TYPE(base_tree));
1879   if (base_tree == error_mark_node
1880       || TREE_TYPE(base_tree) == error_mark_node
1881       || index_tree == error_mark_node
1882       || element_type_tree == error_mark_node)
1883     return this->error_expression();
1884 
1885   tree element_size = TYPE_SIZE_UNIT(element_type_tree);
1886   index_tree = fold_convert_loc(location.gcc_location(), sizetype, index_tree);
1887   tree offset = fold_build2_loc(location.gcc_location(), MULT_EXPR, sizetype,
1888                                 index_tree, element_size);
1889   tree ptr = fold_build2_loc(location.gcc_location(), POINTER_PLUS_EXPR,
1890                              TREE_TYPE(base_tree), base_tree, offset);
1891   return this->make_expression(ptr);
1892 }
1893 
1894 // Return an expression representing ARRAY[INDEX]
1895 
1896 Bexpression*
array_index_expression(Bexpression * array,Bexpression * index,Location location)1897 Gcc_backend::array_index_expression(Bexpression* array, Bexpression* index,
1898                                     Location location)
1899 {
1900   tree array_tree = array->get_tree();
1901   tree index_tree = index->get_tree();
1902   if (array_tree == error_mark_node
1903       || TREE_TYPE(array_tree) == error_mark_node
1904       || index_tree == error_mark_node)
1905     return this->error_expression();
1906 
1907   // A function call that returns a zero sized object will have been
1908   // changed to return void.  If we see void here, assume we are
1909   // dealing with a zero sized type and just evaluate the operands.
1910   tree ret;
1911   if (TREE_TYPE(array_tree) != void_type_node)
1912     ret = build4_loc(location.gcc_location(), ARRAY_REF,
1913 		     TREE_TYPE(TREE_TYPE(array_tree)), array_tree,
1914 		     index_tree, NULL_TREE, NULL_TREE);
1915   else
1916     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1917 			  void_type_node, array_tree, index_tree);
1918 
1919   return this->make_expression(ret);
1920 }
1921 
1922 // Create an expression for a call to FN_EXPR with FN_ARGS.
1923 Bexpression*
call_expression(Bfunction *,Bexpression * fn_expr,const std::vector<Bexpression * > & fn_args,Bexpression * chain_expr,Location location)1924 Gcc_backend::call_expression(Bfunction*, // containing fcn for call
1925                              Bexpression* fn_expr,
1926                              const std::vector<Bexpression*>& fn_args,
1927                              Bexpression* chain_expr,
1928                              Location location)
1929 {
1930   tree fn = fn_expr->get_tree();
1931   if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node)
1932     return this->error_expression();
1933 
1934   gcc_assert(FUNCTION_POINTER_TYPE_P(TREE_TYPE(fn)));
1935   tree rettype = TREE_TYPE(TREE_TYPE(TREE_TYPE(fn)));
1936 
1937   size_t nargs = fn_args.size();
1938   tree* args = nargs == 0 ? NULL : new tree[nargs];
1939   for (size_t i = 0; i < nargs; ++i)
1940     {
1941       args[i] = fn_args.at(i)->get_tree();
1942       if (args[i] == error_mark_node)
1943         return this->error_expression();
1944     }
1945 
1946   tree fndecl = fn;
1947   if (TREE_CODE(fndecl) == ADDR_EXPR)
1948     fndecl = TREE_OPERAND(fndecl, 0);
1949 
1950   // This is to support builtin math functions when using 80387 math.
1951   tree excess_type = NULL_TREE;
1952   if (optimize
1953       && TREE_CODE(fndecl) == FUNCTION_DECL
1954       && DECL_IS_BUILTIN(fndecl)
1955       && DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL
1956       && nargs > 0
1957       && ((SCALAR_FLOAT_TYPE_P(rettype)
1958 	   && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0])))
1959 	  || (COMPLEX_FLOAT_TYPE_P(rettype)
1960 	      && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0])))))
1961     {
1962       excess_type = excess_precision_type(TREE_TYPE(args[0]));
1963       if (excess_type != NULL_TREE)
1964 	{
1965 	  tree excess_fndecl = mathfn_built_in(excess_type,
1966 					       DECL_FUNCTION_CODE(fndecl));
1967 	  if (excess_fndecl == NULL_TREE)
1968 	    excess_type = NULL_TREE;
1969 	  else
1970 	    {
1971 	      fn = build_fold_addr_expr_loc(location.gcc_location(),
1972                                             excess_fndecl);
1973 	      for (size_t i = 0; i < nargs; ++i)
1974 		{
1975 		  if (SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[i]))
1976 		      || COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[i])))
1977 		    args[i] = ::convert(excess_type, args[i]);
1978 		}
1979 	    }
1980 	}
1981     }
1982 
1983   tree ret =
1984       build_call_array_loc(location.gcc_location(),
1985                            excess_type != NULL_TREE ? excess_type : rettype,
1986                            fn, nargs, args);
1987 
1988   if (chain_expr)
1989     CALL_EXPR_STATIC_CHAIN (ret) = chain_expr->get_tree();
1990 
1991   if (excess_type != NULL_TREE)
1992     {
1993       // Calling convert here can undo our excess precision change.
1994       // That may or may not be a bug in convert_to_real.
1995       ret = build1_loc(location.gcc_location(), NOP_EXPR, rettype, ret);
1996     }
1997 
1998   delete[] args;
1999   return this->make_expression(ret);
2000 }
2001 
2002 // Return an expression that allocates SIZE bytes on the stack.
2003 
2004 Bexpression*
stack_allocation_expression(int64_t size,Location location)2005 Gcc_backend::stack_allocation_expression(int64_t size, Location location)
2006 {
2007   tree alloca = builtin_decl_explicit(BUILT_IN_ALLOCA);
2008   tree size_tree = build_int_cst(integer_type_node, size);
2009   tree ret = build_call_expr_loc(location.gcc_location(), alloca, 1, size_tree);
2010   tree memset = builtin_decl_explicit(BUILT_IN_MEMSET);
2011   ret = build_call_expr_loc(location.gcc_location(), memset, 3,
2012                             ret, integer_zero_node, size_tree);
2013   return this->make_expression(ret);
2014 }
2015 
2016 // An expression as a statement.
2017 
2018 Bstatement*
expression_statement(Bfunction *,Bexpression * expr)2019 Gcc_backend::expression_statement(Bfunction*, Bexpression* expr)
2020 {
2021   return this->make_statement(expr->get_tree());
2022 }
2023 
2024 // Variable initialization.
2025 
2026 Bstatement*
init_statement(Bfunction *,Bvariable * var,Bexpression * init)2027 Gcc_backend::init_statement(Bfunction*, Bvariable* var, Bexpression* init)
2028 {
2029   tree var_tree = var->get_decl();
2030   tree init_tree = init->get_tree();
2031   if (var_tree == error_mark_node || init_tree == error_mark_node)
2032     return this->error_statement();
2033   gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
2034 
2035   // To avoid problems with GNU ld, we don't make zero-sized
2036   // externally visible variables.  That might lead us to doing an
2037   // initialization of a zero-sized expression to a non-zero sized
2038   // variable, or vice-versa.  Avoid crashes by omitting the
2039   // initializer.  Such initializations don't mean anything anyhow.
2040   if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0
2041       && init_tree != NULL_TREE
2042       && TREE_TYPE(init_tree) != void_type_node
2043       && int_size_in_bytes(TREE_TYPE(init_tree)) != 0)
2044     {
2045       DECL_INITIAL(var_tree) = init_tree;
2046       init_tree = NULL_TREE;
2047     }
2048 
2049   tree ret = build1_loc(DECL_SOURCE_LOCATION(var_tree), DECL_EXPR,
2050 			void_type_node, var_tree);
2051   if (init_tree != NULL_TREE)
2052     ret = build2_loc(DECL_SOURCE_LOCATION(var_tree), COMPOUND_EXPR,
2053 		     void_type_node, init_tree, ret);
2054 
2055   return this->make_statement(ret);
2056 }
2057 
2058 // Assignment.
2059 
2060 Bstatement*
assignment_statement(Bfunction * bfn,Bexpression * lhs,Bexpression * rhs,Location location)2061 Gcc_backend::assignment_statement(Bfunction* bfn, Bexpression* lhs,
2062 				  Bexpression* rhs, Location location)
2063 {
2064   tree lhs_tree = lhs->get_tree();
2065   tree rhs_tree = rhs->get_tree();
2066   if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
2067     return this->error_statement();
2068 
2069   // To avoid problems with GNU ld, we don't make zero-sized
2070   // externally visible variables.  That might lead us to doing an
2071   // assignment of a zero-sized expression to a non-zero sized
2072   // expression; avoid crashes here by avoiding assignments of
2073   // zero-sized expressions.  Such assignments don't really mean
2074   // anything anyhow.
2075   if (TREE_TYPE(lhs_tree) == void_type_node
2076       || int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
2077       || TREE_TYPE(rhs_tree) == void_type_node
2078       || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
2079     return this->compound_statement(this->expression_statement(bfn, lhs),
2080 				    this->expression_statement(bfn, rhs));
2081 
2082   rhs_tree = this->convert_tree(TREE_TYPE(lhs_tree), rhs_tree, location);
2083 
2084   return this->make_statement(fold_build2_loc(location.gcc_location(),
2085                                               MODIFY_EXPR,
2086 					      void_type_node,
2087 					      lhs_tree, rhs_tree));
2088 }
2089 
2090 // Return.
2091 
2092 Bstatement*
return_statement(Bfunction * bfunction,const std::vector<Bexpression * > & vals,Location location)2093 Gcc_backend::return_statement(Bfunction* bfunction,
2094 			      const std::vector<Bexpression*>& vals,
2095 			      Location location)
2096 {
2097   tree fntree = bfunction->get_tree();
2098   if (fntree == error_mark_node)
2099     return this->error_statement();
2100   tree result = DECL_RESULT(fntree);
2101   if (result == error_mark_node)
2102     return this->error_statement();
2103 
2104   // If the result size is zero bytes, we have set the function type
2105   // to have a result type of void, so don't return anything.
2106   // See the function_type method.
2107   tree res_type = TREE_TYPE(result);
2108   if (res_type == void_type_node || int_size_in_bytes(res_type) == 0)
2109     {
2110       tree stmt_list = NULL_TREE;
2111       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
2112 	   p != vals.end();
2113 	   p++)
2114 	{
2115 	  tree val = (*p)->get_tree();
2116 	  if (val == error_mark_node)
2117 	    return this->error_statement();
2118 	  append_to_statement_list(val, &stmt_list);
2119 	}
2120       tree ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
2121 				 void_type_node, NULL_TREE);
2122       append_to_statement_list(ret, &stmt_list);
2123       return this->make_statement(stmt_list);
2124     }
2125 
2126   tree ret;
2127   if (vals.empty())
2128     ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
2129                           NULL_TREE);
2130   else if (vals.size() == 1)
2131     {
2132       tree val = vals.front()->get_tree();
2133       if (val == error_mark_node)
2134 	return this->error_statement();
2135       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2136                                  void_type_node, result,
2137                                  vals.front()->get_tree());
2138       ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
2139                             void_type_node, set);
2140     }
2141   else
2142     {
2143       // To return multiple values, copy the values into a temporary
2144       // variable of the right structure type, and then assign the
2145       // temporary variable to the DECL_RESULT in the return
2146       // statement.
2147       tree stmt_list = NULL_TREE;
2148       tree rettype = TREE_TYPE(result);
2149 
2150       if (DECL_STRUCT_FUNCTION(fntree) == NULL)
2151 	push_struct_function(fntree);
2152       else
2153 	push_cfun(DECL_STRUCT_FUNCTION(fntree));
2154       tree rettmp = create_tmp_var(rettype, "RESULT");
2155       pop_cfun();
2156 
2157       tree field = TYPE_FIELDS(rettype);
2158       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
2159 	   p != vals.end();
2160 	   p++, field = DECL_CHAIN(field))
2161 	{
2162 	  gcc_assert(field != NULL_TREE);
2163 	  tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
2164                                      TREE_TYPE(field), rettmp, field,
2165                                      NULL_TREE);
2166 	  tree val = (*p)->get_tree();
2167 	  if (val == error_mark_node)
2168 	    return this->error_statement();
2169 	  tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2170                                      void_type_node,
2171 				     ref, (*p)->get_tree());
2172 	  append_to_statement_list(set, &stmt_list);
2173 	}
2174       gcc_assert(field == NULL_TREE);
2175       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2176                                  void_type_node,
2177 				 result, rettmp);
2178       tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
2179                                       void_type_node, set);
2180       append_to_statement_list(ret_expr, &stmt_list);
2181       ret = stmt_list;
2182     }
2183   return this->make_statement(ret);
2184 }
2185 
2186 // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an
2187 // error occurs.  EXCEPT_STMT may be NULL.  FINALLY_STMT may be NULL and if not
2188 // NULL, it will always be executed.  This is used for handling defers in Go
2189 // functions.  In C++, the resulting code is of this form:
2190 //   try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
2191 
2192 Bstatement*
exception_handler_statement(Bstatement * bstat,Bstatement * except_stmt,Bstatement * finally_stmt,Location location)2193 Gcc_backend::exception_handler_statement(Bstatement* bstat,
2194                                          Bstatement* except_stmt,
2195                                          Bstatement* finally_stmt,
2196                                          Location location)
2197 {
2198   tree stat_tree = bstat->get_tree();
2199   tree except_tree = except_stmt == NULL ? NULL_TREE : except_stmt->get_tree();
2200   tree finally_tree = finally_stmt == NULL
2201       ? NULL_TREE
2202       : finally_stmt->get_tree();
2203 
2204   if (stat_tree == error_mark_node
2205       || except_tree == error_mark_node
2206       || finally_tree == error_mark_node)
2207     return this->error_statement();
2208 
2209   if (except_tree != NULL_TREE)
2210     stat_tree = build2_loc(location.gcc_location(), TRY_CATCH_EXPR,
2211                            void_type_node, stat_tree,
2212                            build2_loc(location.gcc_location(), CATCH_EXPR,
2213                                       void_type_node, NULL, except_tree));
2214   if (finally_tree != NULL_TREE)
2215     stat_tree = build2_loc(location.gcc_location(), TRY_FINALLY_EXPR,
2216                            void_type_node, stat_tree, finally_tree);
2217   return this->make_statement(stat_tree);
2218 }
2219 
2220 // If.
2221 
2222 Bstatement*
if_statement(Bfunction *,Bexpression * condition,Bblock * then_block,Bblock * else_block,Location location)2223 Gcc_backend::if_statement(Bfunction*, Bexpression* condition,
2224 			  Bblock* then_block, Bblock* else_block,
2225 			  Location location)
2226 {
2227   tree cond_tree = condition->get_tree();
2228   tree then_tree = then_block->get_tree();
2229   tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
2230   if (cond_tree == error_mark_node
2231       || then_tree == error_mark_node
2232       || else_tree == error_mark_node)
2233     return this->error_statement();
2234   tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
2235                         cond_tree, then_tree, else_tree);
2236   return this->make_statement(ret);
2237 }
2238 
2239 // Switch.
2240 
2241 Bstatement*
switch_statement(Bfunction * function,Bexpression * value,const std::vector<std::vector<Bexpression * >> & cases,const std::vector<Bstatement * > & statements,Location switch_location)2242 Gcc_backend::switch_statement(
2243     Bfunction* function,
2244     Bexpression* value,
2245     const std::vector<std::vector<Bexpression*> >& cases,
2246     const std::vector<Bstatement*>& statements,
2247     Location switch_location)
2248 {
2249   gcc_assert(cases.size() == statements.size());
2250 
2251   tree decl = function->get_tree();
2252   if (DECL_STRUCT_FUNCTION(decl) == NULL)
2253     push_struct_function(decl);
2254   else
2255     push_cfun(DECL_STRUCT_FUNCTION(decl));
2256 
2257   tree stmt_list = NULL_TREE;
2258   std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
2259   for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
2260        ps != statements.end();
2261        ++ps, ++pc)
2262     {
2263       if (pc->empty())
2264 	{
2265 	  source_location loc = (*ps != NULL
2266                                  ? EXPR_LOCATION((*ps)->get_tree())
2267                                  : UNKNOWN_LOCATION);
2268 	  tree label = create_artificial_label(loc);
2269 	  tree c = build_case_label(NULL_TREE, NULL_TREE, label);
2270 	  append_to_statement_list(c, &stmt_list);
2271 	}
2272       else
2273 	{
2274 	  for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
2275 	       pcv != pc->end();
2276 	       ++pcv)
2277 	    {
2278 	      tree t = (*pcv)->get_tree();
2279 	      if (t == error_mark_node)
2280 		return this->error_statement();
2281 	      source_location loc = EXPR_LOCATION(t);
2282 	      tree label = create_artificial_label(loc);
2283 	      tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
2284 	      append_to_statement_list(c, &stmt_list);
2285 	    }
2286 	}
2287 
2288       if (*ps != NULL)
2289 	{
2290 	  tree t = (*ps)->get_tree();
2291 	  if (t == error_mark_node)
2292 	    return this->error_statement();
2293 	  append_to_statement_list(t, &stmt_list);
2294 	}
2295     }
2296   pop_cfun();
2297 
2298   tree tv = value->get_tree();
2299   if (tv == error_mark_node)
2300     return this->error_statement();
2301   tree t = build2_loc(switch_location.gcc_location(), SWITCH_EXPR,
2302                       NULL_TREE, tv, stmt_list);
2303   return this->make_statement(t);
2304 }
2305 
2306 // Pair of statements.
2307 
2308 Bstatement*
compound_statement(Bstatement * s1,Bstatement * s2)2309 Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
2310 {
2311   tree stmt_list = NULL_TREE;
2312   tree t = s1->get_tree();
2313   if (t == error_mark_node)
2314     return this->error_statement();
2315   append_to_statement_list(t, &stmt_list);
2316   t = s2->get_tree();
2317   if (t == error_mark_node)
2318     return this->error_statement();
2319   append_to_statement_list(t, &stmt_list);
2320 
2321   // If neither statement has any side effects, stmt_list can be NULL
2322   // at this point.
2323   if (stmt_list == NULL_TREE)
2324     stmt_list = integer_zero_node;
2325 
2326   return this->make_statement(stmt_list);
2327 }
2328 
2329 // List of statements.
2330 
2331 Bstatement*
statement_list(const std::vector<Bstatement * > & statements)2332 Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
2333 {
2334   tree stmt_list = NULL_TREE;
2335   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
2336        p != statements.end();
2337        ++p)
2338     {
2339       tree t = (*p)->get_tree();
2340       if (t == error_mark_node)
2341 	return this->error_statement();
2342       append_to_statement_list(t, &stmt_list);
2343     }
2344   return this->make_statement(stmt_list);
2345 }
2346 
2347 // Make a block.  For some reason gcc uses a dual structure for
2348 // blocks: BLOCK tree nodes and BIND_EXPR tree nodes.  Since the
2349 // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
2350 // the Bblock.
2351 
2352 Bblock*
block(Bfunction * function,Bblock * enclosing,const std::vector<Bvariable * > & vars,Location start_location,Location)2353 Gcc_backend::block(Bfunction* function, Bblock* enclosing,
2354 		   const std::vector<Bvariable*>& vars,
2355 		   Location start_location,
2356 		   Location)
2357 {
2358   tree block_tree = make_node(BLOCK);
2359   if (enclosing == NULL)
2360     {
2361       tree fndecl = function->get_tree();
2362       gcc_assert(fndecl != NULL_TREE);
2363 
2364       // We may have already created a block for local variables when
2365       // we take the address of a parameter.
2366       if (DECL_INITIAL(fndecl) == NULL_TREE)
2367 	{
2368 	  BLOCK_SUPERCONTEXT(block_tree) = fndecl;
2369 	  DECL_INITIAL(fndecl) = block_tree;
2370 	}
2371       else
2372 	{
2373 	  tree superblock_tree = DECL_INITIAL(fndecl);
2374 	  BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
2375 	  tree* pp;
2376 	  for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
2377 	       *pp != NULL_TREE;
2378 	       pp = &BLOCK_CHAIN(*pp))
2379 	    ;
2380 	  *pp = block_tree;
2381 	}
2382     }
2383   else
2384     {
2385       tree superbind_tree = enclosing->get_tree();
2386       tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
2387       gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
2388 
2389       BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
2390       tree* pp;
2391       for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
2392 	   *pp != NULL_TREE;
2393 	   pp = &BLOCK_CHAIN(*pp))
2394 	;
2395       *pp = block_tree;
2396     }
2397 
2398   tree* pp = &BLOCK_VARS(block_tree);
2399   for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
2400        pv != vars.end();
2401        ++pv)
2402     {
2403       *pp = (*pv)->get_decl();
2404       if (*pp != error_mark_node)
2405 	pp = &DECL_CHAIN(*pp);
2406     }
2407   *pp = NULL_TREE;
2408 
2409   TREE_USED(block_tree) = 1;
2410 
2411   tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
2412                               void_type_node, BLOCK_VARS(block_tree),
2413                               NULL_TREE, block_tree);
2414   TREE_SIDE_EFFECTS(bind_tree) = 1;
2415   return new Bblock(bind_tree);
2416 }
2417 
2418 // Add statements to a block.
2419 
2420 void
block_add_statements(Bblock * bblock,const std::vector<Bstatement * > & statements)2421 Gcc_backend::block_add_statements(Bblock* bblock,
2422 				  const std::vector<Bstatement*>& statements)
2423 {
2424   tree stmt_list = NULL_TREE;
2425   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
2426        p != statements.end();
2427        ++p)
2428     {
2429       tree s = (*p)->get_tree();
2430       if (s != error_mark_node)
2431 	append_to_statement_list(s, &stmt_list);
2432     }
2433 
2434   tree bind_tree = bblock->get_tree();
2435   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
2436   BIND_EXPR_BODY(bind_tree) = stmt_list;
2437 }
2438 
2439 // Return a block as a statement.
2440 
2441 Bstatement*
block_statement(Bblock * bblock)2442 Gcc_backend::block_statement(Bblock* bblock)
2443 {
2444   tree bind_tree = bblock->get_tree();
2445   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
2446   return this->make_statement(bind_tree);
2447 }
2448 
2449 // This is not static because we declare it with GTY(()) in go-c.h.
2450 tree go_non_zero_struct;
2451 
2452 // Return a type corresponding to TYPE with non-zero size.
2453 
2454 tree
non_zero_size_type(tree type)2455 Gcc_backend::non_zero_size_type(tree type)
2456 {
2457   if (int_size_in_bytes(type) != 0)
2458     return type;
2459 
2460   switch (TREE_CODE(type))
2461     {
2462     case RECORD_TYPE:
2463       if (TYPE_FIELDS(type) != NULL_TREE)
2464 	{
2465 	  tree ns = make_node(RECORD_TYPE);
2466 	  tree field_trees = NULL_TREE;
2467 	  tree *pp = &field_trees;
2468 	  for (tree field = TYPE_FIELDS(type);
2469 	       field != NULL_TREE;
2470 	       field = DECL_CHAIN(field))
2471 	    {
2472 	      tree ft = TREE_TYPE(field);
2473 	      if (field == TYPE_FIELDS(type))
2474 		ft = non_zero_size_type(ft);
2475 	      tree f = build_decl(DECL_SOURCE_LOCATION(field), FIELD_DECL,
2476 				  DECL_NAME(field), ft);
2477 	      DECL_CONTEXT(f) = ns;
2478 	      *pp = f;
2479 	      pp = &DECL_CHAIN(f);
2480 	    }
2481 	  TYPE_FIELDS(ns) = field_trees;
2482 	  layout_type(ns);
2483 	  return ns;
2484 	}
2485 
2486       if (go_non_zero_struct == NULL_TREE)
2487 	{
2488 	  type = make_node(RECORD_TYPE);
2489 	  tree field = build_decl(UNKNOWN_LOCATION, FIELD_DECL,
2490 				  get_identifier("dummy"),
2491 				  boolean_type_node);
2492 	  DECL_CONTEXT(field) = type;
2493 	  TYPE_FIELDS(type) = field;
2494 	  layout_type(type);
2495 	  go_non_zero_struct = type;
2496 	}
2497       return go_non_zero_struct;
2498 
2499     case ARRAY_TYPE:
2500       {
2501 	tree element_type = non_zero_size_type(TREE_TYPE(type));
2502 	return build_array_type_nelts(element_type, 1);
2503       }
2504 
2505     default:
2506       gcc_unreachable();
2507     }
2508 
2509   gcc_unreachable();
2510 }
2511 
2512 // Convert EXPR_TREE to TYPE_TREE.  Sometimes the same unnamed Go type
2513 // can be created multiple times and thus have multiple tree
2514 // representations.  Make sure this does not confuse the middle-end.
2515 
2516 tree
convert_tree(tree type_tree,tree expr_tree,Location location)2517 Gcc_backend::convert_tree(tree type_tree, tree expr_tree, Location location)
2518 {
2519   if (type_tree == TREE_TYPE(expr_tree))
2520     return expr_tree;
2521 
2522   if (type_tree == error_mark_node
2523       || expr_tree == error_mark_node
2524       || TREE_TYPE(expr_tree) == error_mark_node)
2525     return error_mark_node;
2526 
2527   gcc_assert(TREE_CODE(type_tree) == TREE_CODE(TREE_TYPE(expr_tree)));
2528   if (POINTER_TYPE_P(type_tree)
2529       || INTEGRAL_TYPE_P(type_tree)
2530       || SCALAR_FLOAT_TYPE_P(type_tree)
2531       || COMPLEX_FLOAT_TYPE_P(type_tree))
2532     return fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
2533   else if (TREE_CODE(type_tree) == RECORD_TYPE
2534 	   || TREE_CODE(type_tree) == ARRAY_TYPE)
2535     {
2536       gcc_assert(int_size_in_bytes(type_tree)
2537 		 == int_size_in_bytes(TREE_TYPE(expr_tree)));
2538       if (TYPE_MAIN_VARIANT(type_tree)
2539 	  == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree)))
2540 	return fold_build1_loc(location.gcc_location(), NOP_EXPR,
2541 			       type_tree, expr_tree);
2542       return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
2543 			     type_tree, expr_tree);
2544     }
2545 
2546   gcc_unreachable();
2547 }
2548 
2549 // Make a global variable.
2550 
2551 Bvariable*
global_variable(const std::string & var_name,const std::string & asm_name,Btype * btype,bool is_external,bool is_hidden,bool in_unique_section,Location location)2552 Gcc_backend::global_variable(const std::string& var_name,
2553 			     const std::string& asm_name,
2554 			     Btype* btype,
2555 			     bool is_external,
2556 			     bool is_hidden,
2557 			     bool in_unique_section,
2558 			     Location location)
2559 {
2560   tree type_tree = btype->get_tree();
2561   if (type_tree == error_mark_node)
2562     return this->error_variable();
2563 
2564   // The GNU linker does not like dynamic variables with zero size.
2565   tree orig_type_tree = type_tree;
2566   if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
2567     type_tree = this->non_zero_size_type(type_tree);
2568 
2569   tree decl = build_decl(location.gcc_location(), VAR_DECL,
2570 			 get_identifier_from_string(var_name),
2571 			 type_tree);
2572   if (is_external)
2573     DECL_EXTERNAL(decl) = 1;
2574   else
2575     TREE_STATIC(decl) = 1;
2576   if (!is_hidden)
2577     {
2578       TREE_PUBLIC(decl) = 1;
2579       SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2580     }
2581   else
2582     {
2583       SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2584     }
2585 
2586   TREE_USED(decl) = 1;
2587 
2588   if (in_unique_section)
2589     resolve_unique_section (decl, 0, 1);
2590 
2591   go_preserve_from_gc(decl);
2592 
2593   return new Bvariable(decl, orig_type_tree);
2594 }
2595 
2596 // Set the initial value of a global variable.
2597 
2598 void
global_variable_set_init(Bvariable * var,Bexpression * expr)2599 Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
2600 {
2601   tree expr_tree = expr->get_tree();
2602   if (expr_tree == error_mark_node)
2603     return;
2604   gcc_assert(TREE_CONSTANT(expr_tree));
2605   tree var_decl = var->get_decl();
2606   if (var_decl == error_mark_node)
2607     return;
2608   DECL_INITIAL(var_decl) = expr_tree;
2609 
2610   // If this variable goes in a unique section, it may need to go into
2611   // a different one now that DECL_INITIAL is set.
2612   if (symtab_node::get(var_decl)
2613       && symtab_node::get(var_decl)->implicit_section)
2614     {
2615       set_decl_section_name (var_decl, NULL);
2616       resolve_unique_section (var_decl,
2617 			      compute_reloc_for_constant (expr_tree),
2618 			      1);
2619     }
2620 }
2621 
2622 // Make a local variable.
2623 
2624 Bvariable*
local_variable(Bfunction * function,const std::string & name,Btype * btype,Bvariable * decl_var,bool is_address_taken,Location location)2625 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
2626 			    Btype* btype, Bvariable* decl_var,
2627 			    bool is_address_taken, Location location)
2628 {
2629   tree type_tree = btype->get_tree();
2630   if (type_tree == error_mark_node)
2631     return this->error_variable();
2632   tree decl = build_decl(location.gcc_location(), VAR_DECL,
2633 			 get_identifier_from_string(name),
2634 			 type_tree);
2635   DECL_CONTEXT(decl) = function->get_tree();
2636   TREE_USED(decl) = 1;
2637   if (is_address_taken)
2638     TREE_ADDRESSABLE(decl) = 1;
2639   if (decl_var != NULL)
2640     {
2641       DECL_HAS_VALUE_EXPR_P(decl) = 1;
2642       SET_DECL_VALUE_EXPR(decl, decl_var->get_decl());
2643     }
2644   go_preserve_from_gc(decl);
2645   return new Bvariable(decl);
2646 }
2647 
2648 // Make a function parameter variable.
2649 
2650 Bvariable*
parameter_variable(Bfunction * function,const std::string & name,Btype * btype,bool is_address_taken,Location location)2651 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
2652 				Btype* btype, bool is_address_taken,
2653 				Location location)
2654 {
2655   tree type_tree = btype->get_tree();
2656   if (type_tree == error_mark_node)
2657     return this->error_variable();
2658   tree decl = build_decl(location.gcc_location(), PARM_DECL,
2659 			 get_identifier_from_string(name),
2660 			 type_tree);
2661   DECL_CONTEXT(decl) = function->get_tree();
2662   DECL_ARG_TYPE(decl) = type_tree;
2663   TREE_USED(decl) = 1;
2664   if (is_address_taken)
2665     TREE_ADDRESSABLE(decl) = 1;
2666   go_preserve_from_gc(decl);
2667   return new Bvariable(decl);
2668 }
2669 
2670 // Make a static chain variable.
2671 
2672 Bvariable*
static_chain_variable(Bfunction * function,const std::string & name,Btype * btype,Location location)2673 Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
2674 				   Btype* btype, Location location)
2675 {
2676   tree type_tree = btype->get_tree();
2677   if (type_tree == error_mark_node)
2678     return this->error_variable();
2679   tree decl = build_decl(location.gcc_location(), PARM_DECL,
2680 			 get_identifier_from_string(name), type_tree);
2681   tree fndecl = function->get_tree();
2682   DECL_CONTEXT(decl) = fndecl;
2683   DECL_ARG_TYPE(decl) = type_tree;
2684   TREE_USED(decl) = 1;
2685   DECL_ARTIFICIAL(decl) = 1;
2686   DECL_IGNORED_P(decl) = 1;
2687   TREE_READONLY(decl) = 1;
2688 
2689   struct function *f = DECL_STRUCT_FUNCTION(fndecl);
2690   if (f == NULL)
2691     {
2692       push_struct_function(fndecl);
2693       pop_cfun();
2694       f = DECL_STRUCT_FUNCTION(fndecl);
2695     }
2696   gcc_assert(f->static_chain_decl == NULL);
2697   f->static_chain_decl = decl;
2698   DECL_STATIC_CHAIN(fndecl) = 1;
2699 
2700   go_preserve_from_gc(decl);
2701   return new Bvariable(decl);
2702 }
2703 
2704 // Make a temporary variable.
2705 
2706 Bvariable*
temporary_variable(Bfunction * function,Bblock * bblock,Btype * btype,Bexpression * binit,bool is_address_taken,Location location,Bstatement ** pstatement)2707 Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
2708 				Btype* btype, Bexpression* binit,
2709 				bool is_address_taken,
2710 				Location location,
2711 				Bstatement** pstatement)
2712 {
2713   gcc_assert(function != NULL);
2714   tree decl = function->get_tree();
2715   tree type_tree = btype->get_tree();
2716   tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
2717   if (type_tree == error_mark_node
2718       || init_tree == error_mark_node
2719       || decl == error_mark_node)
2720     {
2721       *pstatement = this->error_statement();
2722       return this->error_variable();
2723     }
2724 
2725   tree var;
2726   // We can only use create_tmp_var if the type is not addressable.
2727   if (!TREE_ADDRESSABLE(type_tree))
2728     {
2729       if (DECL_STRUCT_FUNCTION(decl) == NULL)
2730       	push_struct_function(decl);
2731       else
2732       	push_cfun(DECL_STRUCT_FUNCTION(decl));
2733 
2734       var = create_tmp_var(type_tree, "GOTMP");
2735       pop_cfun();
2736     }
2737   else
2738     {
2739       gcc_assert(bblock != NULL);
2740       var = build_decl(location.gcc_location(), VAR_DECL,
2741 		       create_tmp_var_name("GOTMP"),
2742 		       type_tree);
2743       DECL_ARTIFICIAL(var) = 1;
2744       DECL_IGNORED_P(var) = 1;
2745       TREE_USED(var) = 1;
2746       DECL_CONTEXT(var) = decl;
2747 
2748       // We have to add this variable to the BLOCK and the BIND_EXPR.
2749       tree bind_tree = bblock->get_tree();
2750       gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
2751       tree block_tree = BIND_EXPR_BLOCK(bind_tree);
2752       gcc_assert(TREE_CODE(block_tree) == BLOCK);
2753       DECL_CHAIN(var) = BLOCK_VARS(block_tree);
2754       BLOCK_VARS(block_tree) = var;
2755       BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
2756     }
2757 
2758   if (this->type_size(btype) != 0
2759       && init_tree != NULL_TREE
2760       && TREE_TYPE(init_tree) != void_type_node)
2761     DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location);
2762 
2763   if (is_address_taken)
2764     TREE_ADDRESSABLE(var) = 1;
2765 
2766   *pstatement = this->make_statement(build1_loc(location.gcc_location(),
2767                                                 DECL_EXPR,
2768 						void_type_node, var));
2769 
2770   // For a zero sized type, don't initialize VAR with BINIT, but still
2771   // evaluate BINIT for its side effects.
2772   if (init_tree != NULL_TREE
2773       && (this->type_size(btype) == 0
2774 	  || TREE_TYPE(init_tree) == void_type_node))
2775     *pstatement =
2776       this->compound_statement(this->expression_statement(function, binit),
2777 			       *pstatement);
2778 
2779   return new Bvariable(var);
2780 }
2781 
2782 // Create an implicit variable that is compiler-defined.  This is used when
2783 // generating GC root variables and storing the values of a slice initializer.
2784 
2785 Bvariable*
implicit_variable(const std::string & name,const std::string & asm_name,Btype * type,bool is_hidden,bool is_constant,bool is_common,int64_t alignment)2786 Gcc_backend::implicit_variable(const std::string& name,
2787                                const std::string& asm_name,
2788                                Btype* type, bool is_hidden, bool is_constant,
2789 			       bool is_common, int64_t alignment)
2790 {
2791   tree type_tree = type->get_tree();
2792   if (type_tree == error_mark_node)
2793     return this->error_variable();
2794 
2795   tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
2796                          get_identifier_from_string(name), type_tree);
2797   DECL_EXTERNAL(decl) = 0;
2798   TREE_PUBLIC(decl) = !is_hidden;
2799   TREE_STATIC(decl) = 1;
2800   TREE_USED(decl) = 1;
2801   DECL_ARTIFICIAL(decl) = 1;
2802   if (is_common)
2803     {
2804       DECL_COMMON(decl) = 1;
2805 
2806       // When the initializer for one implicit_variable refers to another,
2807       // it needs to know the visibility of the referenced struct so that
2808       // compute_reloc_for_constant will return the right value.  On many
2809       // systems calling make_decl_one_only will mark the decl as weak,
2810       // which will change the return value of compute_reloc_for_constant.
2811       // We can't reliably call make_decl_one_only yet, because we don't
2812       // yet know the initializer.  This issue doesn't arise in C because
2813       // Go initializers, unlike C initializers, can be indirectly
2814       // recursive.  To ensure that compute_reloc_for_constant computes
2815       // the right value if some other initializer refers to this one, we
2816       // mark this symbol as weak here.  We undo that below in
2817       // immutable_struct_set_init before calling mark_decl_one_only.
2818       DECL_WEAK(decl) = 1;
2819     }
2820   if (is_constant)
2821     {
2822       TREE_READONLY(decl) = 1;
2823       TREE_CONSTANT(decl) = 1;
2824     }
2825   if (alignment != 0)
2826     {
2827       SET_DECL_ALIGN(decl, alignment * BITS_PER_UNIT);
2828       DECL_USER_ALIGN(decl) = 1;
2829     }
2830   if (! asm_name.empty())
2831     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2832 
2833   go_preserve_from_gc(decl);
2834   return new Bvariable(decl);
2835 }
2836 
2837 // Set the initalizer for a variable created by implicit_variable.
2838 // This is where we finish compiling the variable.
2839 
2840 void
implicit_variable_set_init(Bvariable * var,const std::string &,Btype *,bool,bool,bool is_common,Bexpression * init)2841 Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
2842 					Btype*, bool, bool, bool is_common,
2843 					Bexpression* init)
2844 {
2845   tree decl = var->get_decl();
2846   tree init_tree;
2847   if (init == NULL)
2848     init_tree = NULL_TREE;
2849   else
2850     init_tree = init->get_tree();
2851   if (decl == error_mark_node || init_tree == error_mark_node)
2852     return;
2853 
2854   DECL_INITIAL(decl) = init_tree;
2855 
2856   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
2857   // See the comment where DECL_WEAK is set in implicit_variable.
2858   if (is_common)
2859     {
2860       DECL_WEAK(decl) = 0;
2861       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
2862     }
2863 
2864   resolve_unique_section(decl, 2, 1);
2865 
2866   rest_of_decl_compilation(decl, 1, 0);
2867 }
2868 
2869 // Return a reference to an implicit variable defined in another package.
2870 
2871 Bvariable*
implicit_variable_reference(const std::string & name,const std::string & asm_name,Btype * btype)2872 Gcc_backend::implicit_variable_reference(const std::string& name,
2873                                          const std::string& asm_name,
2874                                          Btype* btype)
2875 {
2876   tree type_tree = btype->get_tree();
2877   if (type_tree == error_mark_node)
2878     return this->error_variable();
2879 
2880   tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
2881                          get_identifier_from_string(name), type_tree);
2882   DECL_EXTERNAL(decl) = 1;
2883   TREE_PUBLIC(decl) = 1;
2884   TREE_STATIC(decl) = 0;
2885   DECL_ARTIFICIAL(decl) = 1;
2886   if (! asm_name.empty())
2887     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2888   go_preserve_from_gc(decl);
2889   return new Bvariable(decl);
2890 }
2891 
2892 // Create a named immutable initialized data structure.
2893 
2894 Bvariable*
immutable_struct(const std::string & name,const std::string & asm_name,bool is_hidden,bool is_common,Btype * btype,Location location)2895 Gcc_backend::immutable_struct(const std::string& name,
2896                               const std::string& asm_name,
2897                               bool is_hidden,
2898 			      bool is_common, Btype* btype, Location location)
2899 {
2900   tree type_tree = btype->get_tree();
2901   if (type_tree == error_mark_node)
2902     return this->error_variable();
2903   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
2904   tree decl = build_decl(location.gcc_location(), VAR_DECL,
2905 			 get_identifier_from_string(name),
2906 			 build_qualified_type(type_tree, TYPE_QUAL_CONST));
2907   TREE_STATIC(decl) = 1;
2908   TREE_USED(decl) = 1;
2909   TREE_READONLY(decl) = 1;
2910   TREE_CONSTANT(decl) = 1;
2911   DECL_ARTIFICIAL(decl) = 1;
2912   if (!is_hidden)
2913     TREE_PUBLIC(decl) = 1;
2914   if (! asm_name.empty())
2915     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2916 
2917   // When the initializer for one immutable_struct refers to another,
2918   // it needs to know the visibility of the referenced struct so that
2919   // compute_reloc_for_constant will return the right value.  On many
2920   // systems calling make_decl_one_only will mark the decl as weak,
2921   // which will change the return value of compute_reloc_for_constant.
2922   // We can't reliably call make_decl_one_only yet, because we don't
2923   // yet know the initializer.  This issue doesn't arise in C because
2924   // Go initializers, unlike C initializers, can be indirectly
2925   // recursive.  To ensure that compute_reloc_for_constant computes
2926   // the right value if some other initializer refers to this one, we
2927   // mark this symbol as weak here.  We undo that below in
2928   // immutable_struct_set_init before calling mark_decl_one_only.
2929   if (is_common)
2930     DECL_WEAK(decl) = 1;
2931 
2932   // We don't call rest_of_decl_compilation until we have the
2933   // initializer.
2934 
2935   go_preserve_from_gc(decl);
2936   return new Bvariable(decl);
2937 }
2938 
2939 // Set the initializer for a variable created by immutable_struct.
2940 // This is where we finish compiling the variable.
2941 
2942 void
immutable_struct_set_init(Bvariable * var,const std::string &,bool,bool is_common,Btype *,Location,Bexpression * initializer)2943 Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
2944 				       bool, bool is_common, Btype*, Location,
2945 				       Bexpression* initializer)
2946 {
2947   tree decl = var->get_decl();
2948   tree init_tree = initializer->get_tree();
2949   if (decl == error_mark_node || init_tree == error_mark_node)
2950     return;
2951 
2952   DECL_INITIAL(decl) = init_tree;
2953 
2954   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
2955   // See the comment where DECL_WEAK is set in immutable_struct.
2956   if (is_common)
2957     {
2958       DECL_WEAK(decl) = 0;
2959       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
2960     }
2961 
2962   // These variables are often unneeded in the final program, so put
2963   // them in their own section so that linker GC can discard them.
2964   resolve_unique_section(decl,
2965 			 compute_reloc_for_constant (init_tree),
2966 			 1);
2967 
2968   rest_of_decl_compilation(decl, 1, 0);
2969 }
2970 
2971 // Return a reference to an immutable initialized data structure
2972 // defined in another package.
2973 
2974 Bvariable*
immutable_struct_reference(const std::string & name,const std::string & asm_name,Btype * btype,Location location)2975 Gcc_backend::immutable_struct_reference(const std::string& name,
2976                                         const std::string& asm_name,
2977                                         Btype* btype,
2978 					Location location)
2979 {
2980   tree type_tree = btype->get_tree();
2981   if (type_tree == error_mark_node)
2982     return this->error_variable();
2983   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
2984   tree decl = build_decl(location.gcc_location(), VAR_DECL,
2985 			 get_identifier_from_string(name),
2986 			 build_qualified_type(type_tree, TYPE_QUAL_CONST));
2987   TREE_READONLY(decl) = 1;
2988   TREE_CONSTANT(decl) = 1;
2989   DECL_ARTIFICIAL(decl) = 1;
2990   TREE_PUBLIC(decl) = 1;
2991   DECL_EXTERNAL(decl) = 1;
2992   if (! asm_name.empty())
2993     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2994   go_preserve_from_gc(decl);
2995   return new Bvariable(decl);
2996 }
2997 
2998 // Make a label.
2999 
3000 Blabel*
label(Bfunction * function,const std::string & name,Location location)3001 Gcc_backend::label(Bfunction* function, const std::string& name,
3002 		   Location location)
3003 {
3004   tree decl;
3005   if (name.empty())
3006     {
3007       tree func_tree = function->get_tree();
3008       if (DECL_STRUCT_FUNCTION(func_tree) == NULL)
3009 	push_struct_function(func_tree);
3010       else
3011 	push_cfun(DECL_STRUCT_FUNCTION(func_tree));
3012 
3013       decl = create_artificial_label(location.gcc_location());
3014 
3015       pop_cfun();
3016     }
3017   else
3018     {
3019       tree id = get_identifier_from_string(name);
3020       decl = build_decl(location.gcc_location(), LABEL_DECL, id,
3021                         void_type_node);
3022       DECL_CONTEXT(decl) = function->get_tree();
3023     }
3024   return new Blabel(decl);
3025 }
3026 
3027 // Make a statement which defines a label.
3028 
3029 Bstatement*
label_definition_statement(Blabel * label)3030 Gcc_backend::label_definition_statement(Blabel* label)
3031 {
3032   tree lab = label->get_tree();
3033   tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
3034 			     void_type_node, lab);
3035   return this->make_statement(ret);
3036 }
3037 
3038 // Make a goto statement.
3039 
3040 Bstatement*
goto_statement(Blabel * label,Location location)3041 Gcc_backend::goto_statement(Blabel* label, Location location)
3042 {
3043   tree lab = label->get_tree();
3044   tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
3045                              lab);
3046   return this->make_statement(ret);
3047 }
3048 
3049 // Get the address of a label.
3050 
3051 Bexpression*
label_address(Blabel * label,Location location)3052 Gcc_backend::label_address(Blabel* label, Location location)
3053 {
3054   tree lab = label->get_tree();
3055   TREE_USED(lab) = 1;
3056   TREE_ADDRESSABLE(lab) = 1;
3057   tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
3058 			      build_fold_addr_expr_loc(location.gcc_location(),
3059                                                        lab));
3060   return this->make_expression(ret);
3061 }
3062 
3063 // Declare or define a new function.
3064 
3065 Bfunction*
function(Btype * fntype,const std::string & name,const std::string & asm_name,bool is_visible,bool is_declaration,bool is_inlinable,bool disable_split_stack,bool does_not_return,bool in_unique_section,Location location)3066 Gcc_backend::function(Btype* fntype, const std::string& name,
3067                       const std::string& asm_name, bool is_visible,
3068                       bool is_declaration, bool is_inlinable,
3069                       bool disable_split_stack, bool does_not_return,
3070 		      bool in_unique_section, Location location)
3071 {
3072   tree functype = fntype->get_tree();
3073   if (functype != error_mark_node)
3074     {
3075       gcc_assert(FUNCTION_POINTER_TYPE_P(functype));
3076       functype = TREE_TYPE(functype);
3077     }
3078   tree id = get_identifier_from_string(name);
3079   if (functype == error_mark_node || id == error_mark_node)
3080     return this->error_function();
3081 
3082   tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype);
3083   if (! asm_name.empty())
3084     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
3085   if (is_visible)
3086     TREE_PUBLIC(decl) = 1;
3087   if (is_declaration)
3088     DECL_EXTERNAL(decl) = 1;
3089   else
3090     {
3091       tree restype = TREE_TYPE(functype);
3092       tree resdecl =
3093           build_decl(location.gcc_location(), RESULT_DECL, NULL_TREE, restype);
3094       DECL_ARTIFICIAL(resdecl) = 1;
3095       DECL_IGNORED_P(resdecl) = 1;
3096       DECL_CONTEXT(resdecl) = decl;
3097       DECL_RESULT(decl) = resdecl;
3098     }
3099   if (!is_inlinable)
3100     DECL_UNINLINABLE(decl) = 1;
3101   if (disable_split_stack)
3102     {
3103       tree attr = get_identifier ("no_split_stack");
3104       DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
3105     }
3106   if (does_not_return)
3107     TREE_THIS_VOLATILE(decl) = 1;
3108   if (in_unique_section)
3109     resolve_unique_section(decl, 0, 1);
3110 
3111   go_preserve_from_gc(decl);
3112   return new Bfunction(decl);
3113 }
3114 
3115 // Create a statement that runs all deferred calls for FUNCTION.  This should
3116 // be a statement that looks like this in C++:
3117 //   finish:
3118 //     try { UNDEFER; } catch { CHECK_DEFER; goto finish; }
3119 
3120 Bstatement*
function_defer_statement(Bfunction * function,Bexpression * undefer,Bexpression * defer,Location location)3121 Gcc_backend::function_defer_statement(Bfunction* function, Bexpression* undefer,
3122                                       Bexpression* defer, Location location)
3123 {
3124   tree undefer_tree = undefer->get_tree();
3125   tree defer_tree = defer->get_tree();
3126   tree fntree = function->get_tree();
3127 
3128   if (undefer_tree == error_mark_node
3129       || defer_tree == error_mark_node
3130       || fntree == error_mark_node)
3131     return this->error_statement();
3132 
3133   if (DECL_STRUCT_FUNCTION(fntree) == NULL)
3134     push_struct_function(fntree);
3135   else
3136     push_cfun(DECL_STRUCT_FUNCTION(fntree));
3137 
3138   tree stmt_list = NULL;
3139   Blabel* blabel = this->label(function, "", location);
3140   Bstatement* label_def = this->label_definition_statement(blabel);
3141   append_to_statement_list(label_def->get_tree(), &stmt_list);
3142 
3143   Bstatement* jump_stmt = this->goto_statement(blabel, location);
3144   tree jump = jump_stmt->get_tree();
3145   tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer_tree, jump);
3146   catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body);
3147   tree try_catch =
3148       build2(TRY_CATCH_EXPR, void_type_node, undefer_tree, catch_body);
3149   append_to_statement_list(try_catch, &stmt_list);
3150   pop_cfun();
3151 
3152   return this->make_statement(stmt_list);
3153 }
3154 
3155 // Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
3156 // This will only be called for a function definition.
3157 
3158 bool
function_set_parameters(Bfunction * function,const std::vector<Bvariable * > & param_vars)3159 Gcc_backend::function_set_parameters(Bfunction* function,
3160                                      const std::vector<Bvariable*>& param_vars)
3161 {
3162   tree func_tree = function->get_tree();
3163   if (func_tree == error_mark_node)
3164     return false;
3165 
3166   tree params = NULL_TREE;
3167   tree *pp = &params;
3168   for (std::vector<Bvariable*>::const_iterator pv = param_vars.begin();
3169        pv != param_vars.end();
3170        ++pv)
3171     {
3172       *pp = (*pv)->get_decl();
3173       gcc_assert(*pp != error_mark_node);
3174       pp = &DECL_CHAIN(*pp);
3175     }
3176   *pp = NULL_TREE;
3177   DECL_ARGUMENTS(func_tree) = params;
3178   return true;
3179 }
3180 
3181 // Set the function body for FUNCTION using the code in CODE_BLOCK.
3182 
3183 bool
function_set_body(Bfunction * function,Bstatement * code_stmt)3184 Gcc_backend::function_set_body(Bfunction* function, Bstatement* code_stmt)
3185 {
3186   tree func_tree = function->get_tree();
3187   tree code = code_stmt->get_tree();
3188 
3189   if (func_tree == error_mark_node || code == error_mark_node)
3190     return false;
3191   DECL_SAVED_TREE(func_tree) = code;
3192   return true;
3193 }
3194 
3195 // Look up a named built-in function in the current backend implementation.
3196 // Returns NULL if no built-in function by that name exists.
3197 
3198 Bfunction*
lookup_builtin(const std::string & name)3199 Gcc_backend::lookup_builtin(const std::string& name)
3200 {
3201   if (this->builtin_functions_.count(name) != 0)
3202     return this->builtin_functions_[name];
3203   return NULL;
3204 }
3205 
3206 // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
3207 // FUNCTION_DECLS, and VARIABLE_DECLS declared globally, as well as
3208 // emit early debugging information.
3209 
3210 void
write_global_definitions(const std::vector<Btype * > & type_decls,const std::vector<Bexpression * > & constant_decls,const std::vector<Bfunction * > & function_decls,const std::vector<Bvariable * > & variable_decls)3211 Gcc_backend::write_global_definitions(
3212     const std::vector<Btype*>& type_decls,
3213     const std::vector<Bexpression*>& constant_decls,
3214     const std::vector<Bfunction*>& function_decls,
3215     const std::vector<Bvariable*>& variable_decls)
3216 {
3217   size_t count_definitions = type_decls.size() + constant_decls.size()
3218       + function_decls.size() + variable_decls.size();
3219 
3220   tree* defs = new tree[count_definitions];
3221 
3222   // Convert all non-erroneous declarations into Gimple form.
3223   size_t i = 0;
3224   for (std::vector<Bvariable*>::const_iterator p = variable_decls.begin();
3225        p != variable_decls.end();
3226        ++p)
3227     {
3228       tree v = (*p)->get_decl();
3229       if (v != error_mark_node)
3230         {
3231           defs[i] = v;
3232           go_preserve_from_gc(defs[i]);
3233           ++i;
3234         }
3235     }
3236 
3237   for (std::vector<Btype*>::const_iterator p = type_decls.begin();
3238        p != type_decls.end();
3239        ++p)
3240     {
3241       tree type_tree = (*p)->get_tree();
3242       if (type_tree != error_mark_node
3243           && IS_TYPE_OR_DECL_P(type_tree))
3244         {
3245           defs[i] = TYPE_NAME(type_tree);
3246           gcc_assert(defs[i] != NULL);
3247           go_preserve_from_gc(defs[i]);
3248           ++i;
3249         }
3250     }
3251   for (std::vector<Bexpression*>::const_iterator p = constant_decls.begin();
3252        p != constant_decls.end();
3253        ++p)
3254     {
3255       if ((*p)->get_tree() != error_mark_node)
3256         {
3257           defs[i] = (*p)->get_tree();
3258           go_preserve_from_gc(defs[i]);
3259           ++i;
3260         }
3261     }
3262   for (std::vector<Bfunction*>::const_iterator p = function_decls.begin();
3263        p != function_decls.end();
3264        ++p)
3265     {
3266       tree decl = (*p)->get_tree();
3267       if (decl != error_mark_node)
3268         {
3269           go_preserve_from_gc(decl);
3270           gimplify_function_tree(decl);
3271           cgraph_node::finalize_function(decl, true);
3272 
3273           defs[i] = decl;
3274           ++i;
3275         }
3276     }
3277 
3278   // Pass everything back to the middle-end.
3279 
3280   wrapup_global_declarations(defs, i);
3281 
3282   delete[] defs;
3283 }
3284 
3285 void
write_export_data(const char * bytes,unsigned int size)3286 Gcc_backend::write_export_data(const char* bytes, unsigned int size)
3287 {
3288   go_write_export_data(bytes, size);
3289 }
3290 
3291 
3292 // Define a builtin function.  BCODE is the builtin function code
3293 // defined by builtins.def.  NAME is the name of the builtin function.
3294 // LIBNAME is the name of the corresponding library function, and is
3295 // NULL if there isn't one.  FNTYPE is the type of the function.
3296 // CONST_P is true if the function has the const attribute.
3297 // NORETURN_P is true if the function has the noreturn attribute.
3298 
3299 void
define_builtin(built_in_function bcode,const char * name,const char * libname,tree fntype,bool const_p,bool noreturn_p)3300 Gcc_backend::define_builtin(built_in_function bcode, const char* name,
3301 			    const char* libname, tree fntype, bool const_p,
3302 			    bool noreturn_p)
3303 {
3304   tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL,
3305 				   libname, NULL_TREE);
3306   if (const_p)
3307     TREE_READONLY(decl) = 1;
3308   if (noreturn_p)
3309     TREE_THIS_VOLATILE(decl) = 1;
3310   set_builtin_decl(bcode, decl, true);
3311   this->builtin_functions_[name] = this->make_function(decl);
3312   if (libname != NULL)
3313     {
3314       decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL,
3315 				  NULL, NULL_TREE);
3316       if (const_p)
3317 	TREE_READONLY(decl) = 1;
3318       if (noreturn_p)
3319 	TREE_THIS_VOLATILE(decl) = 1;
3320       this->builtin_functions_[libname] = this->make_function(decl);
3321     }
3322 }
3323 
3324 // Return the backend generator.
3325 
3326 Backend*
go_get_backend()3327 go_get_backend()
3328 {
3329   return new Gcc_backend();
3330 }
3331