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