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