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