]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/go/go-gcc.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / go / go-gcc.cc
CommitLineData
87430073 1// go-gcc.cc -- Go frontend to gcc IR.
f1717362 2// Copyright (C) 2011-2016 Free Software Foundation, Inc.
87430073 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
9ef16211 27#include "tree.h"
b20a8bb4 28#include "fold-const.h"
9ed99284 29#include "stringpool.h"
30#include "stor-layout.h"
31#include "varasm.h"
be2fc38d 32#include "tree-iterator.h"
94ea8568 33#include "tm.h"
94ea8568 34#include "function.h"
1140c305 35#include "cgraph.h"
36#include "convert.h"
bc61cadb 37#include "gimple-expr.h"
76f85fd6 38#include "gimplify.h"
518151f2 39#include "langhooks.h"
a1d23b41 40#include "toplev.h"
149eabc5 41#include "output.h"
48c2a53a 42#include "realmpfr.h"
f7715905 43#include "builtins.h"
87430073 44
fe2f84cf 45#include "go-c.h"
46
be2fc38d 47#include "gogo.h"
87430073 48#include "backend.h"
49
50// A class wrapping a tree.
51
52class Gcc_tree
53{
54 public:
55 Gcc_tree(tree t)
56 : t_(t)
57 { }
58
59 tree
6254cf1d 60 get_tree() const
87430073 61 { return this->t_; }
62
6d3ed74c 63 void
64 set_tree(tree t)
65 { this->t_ = t; }
66
87430073 67 private:
68 tree t_;
69};
70
71// In gcc, types, expressions, and statements are all trees.
72class Btype : public Gcc_tree
73{
74 public:
75 Btype(tree t)
76 : Gcc_tree(t)
77 { }
78};
79
80class Bexpression : public Gcc_tree
81{
82 public:
83 Bexpression(tree t)
84 : Gcc_tree(t)
85 { }
86};
87
88class Bstatement : public Gcc_tree
89{
90 public:
91 Bstatement(tree t)
92 : Gcc_tree(t)
93 { }
94};
95
be2fc38d 96class Bfunction : public Gcc_tree
97{
98 public:
99 Bfunction(tree t)
100 : Gcc_tree(t)
101 { }
102};
103
7e84be55 104class Bblock : public Gcc_tree
105{
106 public:
107 Bblock(tree t)
108 : Gcc_tree(t)
109 { }
110};
111
ff048646 112class Blabel : public Gcc_tree
fe2f84cf 113{
114 public:
ff048646 115 Blabel(tree t)
fe2f84cf 116 : Gcc_tree(t)
117 { }
118};
119
ff048646 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
129class Bvariable
6e193e6f 130{
131 public:
ff048646 132 Bvariable(tree t)
133 : t_(t), orig_type_(NULL)
134 { }
135
136 Bvariable(tree t, tree orig_type)
137 : t_(t), orig_type_(orig_type)
6e193e6f 138 { }
ff048646 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
146 get_decl() const
147 { return this->t_; }
148
149 private:
150 tree t_;
151 tree orig_type_;
6e193e6f 152};
153
ff048646 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.
157tree
158Bvariable::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
87430073 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
177class Gcc_backend : public Backend
178{
179 public:
518151f2 180 Gcc_backend();
181
87430073 182 // Types.
183
184 Btype*
185 error_type()
a59bc27b 186 { return this->make_type(error_mark_node); }
87430073 187
188 Btype*
189 void_type()
6254cf1d 190 { return this->make_type(void_type_node); }
87430073 191
192 Btype*
193 bool_type()
6254cf1d 194 { return this->make_type(boolean_type_node); }
87430073 195
196 Btype*
6254cf1d 197 integer_type(bool, int);
87430073 198
199 Btype*
6254cf1d 200 float_type(int);
201
202 Btype*
203 complex_type(int);
87430073 204
205 Btype*
a59bc27b 206 pointer_type(Btype*);
87430073 207
6254cf1d 208 Btype*
a59bc27b 209 function_type(const Btyped_identifier&,
210 const std::vector<Btyped_identifier>&,
211 const std::vector<Btyped_identifier>&,
e4329d20 212 Btype*,
b13c66cd 213 const Location);
87430073 214
215 Btype*
4c5ca377 216 struct_type(const std::vector<Btyped_identifier>&);
87430073 217
218 Btype*
000a44cf 219 array_type(Btype*, Bexpression*);
220
221 Btype*
b13c66cd 222 placeholder_pointer_type(const std::string&, Location, bool);
000a44cf 223
224 bool
225 set_placeholder_pointer_type(Btype*, Btype*);
226
227 bool
228 set_placeholder_function_type(Btype*, Btype*);
229
230 Btype*
b13c66cd 231 placeholder_struct_type(const std::string&, Location);
000a44cf 232
233 bool
234 set_placeholder_struct_type(Btype* placeholder,
235 const std::vector<Btyped_identifier>&);
236
237 Btype*
b13c66cd 238 placeholder_array_type(const std::string&, Location);
000a44cf 239
240 bool
241 set_placeholder_array_type(Btype*, Btype*, Bexpression*);
242
243 Btype*
b13c66cd 244 named_type(const std::string&, Btype*, Location);
000a44cf 245
246 Btype*
247 circular_pointer_type(Btype*, bool);
248
249 bool
250 is_circular_pointer_type(Btype*);
87430073 251
3f378015 252 int64_t
927a01eb 253 type_size(Btype*);
254
3f378015 255 int64_t
927a01eb 256 type_alignment(Btype*);
257
3f378015 258 int64_t
927a01eb 259 type_field_alignment(Btype*);
260
3f378015 261 int64_t
927a01eb 262 type_field_offset(Btype*, size_t index);
263
63697958 264 // Expressions.
265
266 Bexpression*
267 zero_expression(Btype*);
268
c6777780 269 Bexpression*
270 error_expression()
271 { return this->make_expression(error_mark_node); }
272
ea664253 273 Bexpression*
274 nil_pointer_expression()
275 { return this->make_expression(null_pointer_node); }
276
c6777780 277 Bexpression*
278 var_expression(Bvariable* var, Location);
279
280 Bexpression*
9b27b43c 281 indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location);
c6777780 282
f2de4532 283 Bexpression*
284 named_constant_expression(Btype* btype, const std::string& name,
285 Bexpression* val, Location);
286
48c2a53a 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*
fcbea5e4 294 complex_constant_expression(Btype* btype, mpc_t val);
48c2a53a 295
2c809f8f 296 Bexpression*
297 string_constant_expression(const std::string& val);
298
ea664253 299 Bexpression*
300 boolean_constant_expression(bool val);
301
2c809f8f 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
cd440cff 311 Bexpression*
312 convert_expression(Btype* type, Bexpression* expr, Location);
313
97267c39 314 Bexpression*
315 function_code_expression(Bfunction*, Location);
316
175a4612 317 Bexpression*
318 address_expression(Bexpression*, Location);
319
fbb851c5 320 Bexpression*
321 struct_field_expression(Bexpression*, size_t, Location);
322
2387f644 323 Bexpression*
324 compound_expression(Bstatement*, Bexpression*, Location);
325
326 Bexpression*
a32698ee 327 conditional_expression(Btype*, Bexpression*, Bexpression*, Bexpression*,
328 Location);
329
f9ca30f9 330 Bexpression*
331 unary_expression(Operator, Bexpression*, Location);
332
a32698ee 333 Bexpression*
334 binary_expression(Operator, Bexpression*, Bexpression*, Location);
2387f644 335
2c809f8f 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,
1ecc6157 351 Bexpression* static_chain, Location);
2c809f8f 352
d5d1c295 353 Bexpression*
354 stack_allocation_expression(int64_t size, Location);
355
87430073 356 // Statements.
357
de0e0814 358 Bstatement*
359 error_statement()
360 { return this->make_statement(error_mark_node); }
361
0c9760fe 362 Bstatement*
363 expression_statement(Bexpression*);
364
fe2f84cf 365 Bstatement*
366 init_statement(Bvariable* var, Bexpression* init);
367
87430073 368 Bstatement*
b13c66cd 369 assignment_statement(Bexpression* lhs, Bexpression* rhs, Location);
be2fc38d 370
be2fc38d 371 Bstatement*
372 return_statement(Bfunction*, const std::vector<Bexpression*>&,
b13c66cd 373 Location);
87430073 374
e8816003 375 Bstatement*
7e84be55 376 if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
b13c66cd 377 Location);
e8816003 378
8259743a 379 Bstatement*
76f85fd6 380 switch_statement(Bfunction* function, Bexpression* value,
8259743a 381 const std::vector<std::vector<Bexpression*> >& cases,
382 const std::vector<Bstatement*>& statements,
b13c66cd 383 Location);
8259743a 384
f28bd647 385 Bstatement*
386 compound_statement(Bstatement*, Bstatement*);
387
8259743a 388 Bstatement*
389 statement_list(const std::vector<Bstatement*>&);
390
2c809f8f 391 Bstatement*
392 exception_handler_statement(Bstatement* bstat, Bstatement* except_stmt,
393 Bstatement* finally_stmt, Location);
394
7e84be55 395 // Blocks.
396
397 Bblock*
398 block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
b13c66cd 399 Location, Location);
7e84be55 400
401 void
402 block_add_statements(Bblock*, const std::vector<Bstatement*>&);
403
404 Bstatement*
405 block_statement(Bblock*);
406
fe2f84cf 407 // Variables.
408
409 Bvariable*
410 error_variable()
411 { return new Bvariable(error_mark_node); }
412
413 Bvariable*
414 global_variable(const std::string& package_name,
2a2647e2 415 const std::string& pkgpath,
fe2f84cf 416 const std::string& name,
417 Btype* btype,
418 bool is_external,
419 bool is_hidden,
149eabc5 420 bool in_unique_section,
b13c66cd 421 Location location);
fe2f84cf 422
423 void
424 global_variable_set_init(Bvariable*, Bexpression*);
425
426 Bvariable*
f325319b 427 local_variable(Bfunction*, const std::string&, Btype*, bool,
b13c66cd 428 Location);
fe2f84cf 429
430 Bvariable*
f325319b 431 parameter_variable(Bfunction*, const std::string&, Btype*, bool,
b13c66cd 432 Location);
fe2f84cf 433
1ecc6157 434 Bvariable*
435 static_chain_variable(Bfunction*, const std::string&, Btype*, Location);
436
eefc1ed3 437 Bvariable*
438 temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
b13c66cd 439 Location, Bstatement**);
eefc1ed3 440
76f85fd6 441 Bvariable*
aa5ae575 442 implicit_variable(const std::string&, Btype*, bool, bool, bool,
3f378015 443 int64_t);
76f85fd6 444
aa5ae575 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
a1d23b41 452 Bvariable*
8381eda7 453 immutable_struct(const std::string&, bool, bool, Btype*, Location);
a1d23b41 454
455 void
8381eda7 456 immutable_struct_set_init(Bvariable*, const std::string&, bool, bool, Btype*,
b13c66cd 457 Location, Bexpression*);
a1d23b41 458
459 Bvariable*
b13c66cd 460 immutable_struct_reference(const std::string&, Btype*, Location);
a1d23b41 461
6e193e6f 462 // Labels.
463
464 Blabel*
b13c66cd 465 label(Bfunction*, const std::string& name, Location);
6e193e6f 466
467 Bstatement*
468 label_definition_statement(Blabel*);
469
470 Bstatement*
b13c66cd 471 goto_statement(Blabel*, Location);
6e193e6f 472
473 Bexpression*
b13c66cd 474 label_address(Blabel*, Location);
6e193e6f 475
cf3cae55 476 // Functions.
477
478 Bfunction*
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
2c809f8f 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
518151f2 497 Bfunction*
498 lookup_builtin(const std::string&);
499
76f85fd6 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
87430073 506 private:
6e193e6f 507 // Make a Bexpression from a tree.
508 Bexpression*
509 make_expression(tree t)
510 { return new Bexpression(t); }
511
87430073 512 // Make a Bstatement from a tree.
513 Bstatement*
514 make_statement(tree t)
515 { return new Bstatement(t); }
6254cf1d 516
517 // Make a Btype from a tree.
518 Btype*
519 make_type(tree t)
520 { return new Btype(t); }
000a44cf 521
cf3cae55 522 Bfunction*
523 make_function(tree t)
524 { return new Bfunction(t); }
525
000a44cf 526 Btype*
527 fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
528
529 Btype*
530 fill_in_array(Btype*, Btype*, Bexpression*);
6e27a000 531
532 tree
533 non_zero_size_type(tree);
518151f2 534
535private:
536 void
537 define_builtin(built_in_function bcode, const char* name, const char* libname,
c157e584 538 tree fntype, bool const_p, bool noreturn_p);
518151f2 539
540 // A mapping of the GCC built-ins exposed to GCCGo.
541 std::map<std::string, Bfunction*> builtin_functions_;
87430073 542};
543
6e193e6f 544// A helper function.
545
546static inline tree
547get_identifier_from_string(const std::string& str)
548{
549 return get_identifier_with_length(str.data(), str.length());
550}
0c9760fe 551
518151f2 552// Define the built-in functions that are exposed to GCCGo.
553
554Gcc_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),
c157e584 562 false, false);
518151f2 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),
c157e584 568 false, false);
518151f2 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),
c157e584 574 false, false);
518151f2 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),
c157e584 580 false, false);
518151f2 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),
c157e584 588 true, false);
518151f2 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),
c157e584 597 false, false);
518151f2 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",
c157e584 614 math_function_type, true, false);
518151f2 615 this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
c157e584 616 math_function_type_long, true, false);
518151f2 617 this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
c157e584 618 math_function_type, true, false);
518151f2 619 this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
c157e584 620 math_function_type_long, true, false);
518151f2 621 this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
c157e584 622 math_function_type, true, false);
518151f2 623 this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
c157e584 624 math_function_type_long, true, false);
518151f2 625 this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
c157e584 626 math_function_type_two, true, false);
518151f2 627 this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
c157e584 628 math_function_type_long_two, true, false);
518151f2 629 this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
c157e584 630 math_function_type, true, false);
518151f2 631 this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
c157e584 632 math_function_type_long, true, false);
518151f2 633 this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
c157e584 634 math_function_type, true, false);
518151f2 635 this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
c157e584 636 math_function_type_long, true, false);
518151f2 637 this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
c157e584 638 math_function_type, true, false);
518151f2 639 this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
c157e584 640 math_function_type_long, true, false);
518151f2 641 this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
c157e584 642 math_function_type, true, false);
518151f2 643 this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
c157e584 644 math_function_type_long, true, false);
518151f2 645 this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
c157e584 646 math_function_type, true, false);
518151f2 647 this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
c157e584 648 math_function_type_long, true, false);
518151f2 649 this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
c157e584 650 math_function_type, true, false);
518151f2 651 this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
c157e584 652 math_function_type_long, true, false);
518151f2 653 this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
c157e584 654 math_function_type_two, true, false);
518151f2 655 this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
c157e584 656 math_function_type_long_two, true, false);
518151f2 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),
c157e584 662 true, false);
518151f2 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),
c157e584 668 true, false);
518151f2 669 this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
c157e584 670 math_function_type, true, false);
518151f2 671 this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
c157e584 672 math_function_type_long, true, false);
518151f2 673 this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
c157e584 674 math_function_type, true, false);
518151f2 675 this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
c157e584 676 math_function_type_long, true, false);
518151f2 677 this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
c157e584 678 math_function_type, true, false);
518151f2 679 this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
c157e584 680 math_function_type_long, true, false);
518151f2 681 this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
c157e584 682 math_function_type, true, false);
518151f2 683 this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
c157e584 684 math_function_type_long, true, false);
518151f2 685 this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
c157e584 686 math_function_type, true, false);
518151f2 687 this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
c157e584 688 math_function_type_long, true, false);
518151f2 689 this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
c157e584 690 math_function_type, true, false);
518151f2 691 this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
c157e584 692 math_function_type_long, true, false);
518151f2 693 this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
c157e584 694 math_function_type, true, false);
518151f2 695 this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
c157e584 696 math_function_type_long, true, false);
518151f2 697 this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
c157e584 698 math_function_type, true, false);
518151f2 699 this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
c157e584 700 math_function_type_long, true, false);
518151f2 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),
c157e584 709 false, false);
518151f2 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),
c157e584 715 false, true);
518151f2 716}
717
6254cf1d 718// Get an unnamed integer type.
719
720Btype*
721Gcc_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
759Btype*
760Gcc_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
780Btype*
781Gcc_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
802Btype*
a59bc27b 803Gcc_backend::pointer_type(Btype* to_type)
6254cf1d 804{
a59bc27b 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);
6254cf1d 809 return this->make_type(type);
810}
811
a59bc27b 812// Make a function type.
813
814Btype*
815Gcc_backend::function_type(const Btyped_identifier& receiver,
816 const std::vector<Btyped_identifier>& parameters,
817 const std::vector<Btyped_identifier>& results,
e4329d20 818 Btype* result_struct,
819 Location)
a59bc27b 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 {
e4329d20 854 gcc_assert(result_struct != NULL);
855 result = result_struct->get_tree();
a59bc27b 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
4c5ca377 867// Make a struct type.
868
869Btype*
870Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
871{
000a44cf 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
877Btype*
878Gcc_backend::fill_in_struct(Btype* fill,
879 const std::vector<Btyped_identifier>& fields)
880{
881 tree fill_tree = fill->get_tree();
4c5ca377 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();
b13c66cd 892 tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
893 type_tree);
000a44cf 894 DECL_CONTEXT(field) = fill_tree;
4c5ca377 895 *pp = field;
896 pp = &DECL_CHAIN(field);
897 }
000a44cf 898 TYPE_FIELDS(fill_tree) = field_trees;
899 layout_type(fill_tree);
900 return fill;
901}
902
903// Make an array type.
904
905Btype*
906Gcc_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
914Btype*
915Gcc_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
952Btype*
953Gcc_backend::placeholder_pointer_type(const std::string& name,
b13c66cd 954 Location location, bool)
000a44cf 955{
23842667 956 tree ret = build_distinct_type_copy(ptr_type_node);
f16348a4 957 if (!name.empty())
958 {
b13c66cd 959 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
f16348a4 960 get_identifier_from_string(name),
961 ret);
962 TYPE_NAME(ret) = decl;
963 }
000a44cf 964 return this->make_type(ret);
965}
966
967// Set the real target type for a placeholder pointer type.
968
969bool
970Gcc_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 {
6d3ed74c 980 placeholder->set_tree(error_mark_node);
000a44cf 981 return false;
982 }
983 gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
984 TREE_TYPE(pt) = TREE_TYPE(tt);
94d11348 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 }
000a44cf 992 return true;
993}
994
995// Set the real values for a placeholder function type.
996
997bool
998Gcc_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
1005Btype*
1006Gcc_backend::placeholder_struct_type(const std::string& name,
b13c66cd 1007 Location location)
000a44cf 1008{
1009 tree ret = make_node(RECORD_TYPE);
823c7e3d 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 }
4c5ca377 1017 return this->make_type(ret);
1018}
1019
000a44cf 1020// Fill in the fields of a placeholder struct type.
1021
1022bool
1023Gcc_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);
94d11348 1030
823c7e3d 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 }
94d11348 1038
000a44cf 1039 return r->get_tree() != error_mark_node;
1040}
1041
1042// Create a placeholder for an array type.
1043
1044Btype*
1045Gcc_backend::placeholder_array_type(const std::string& name,
b13c66cd 1046 Location location)
000a44cf 1047{
1048 tree ret = make_node(ARRAY_TYPE);
b13c66cd 1049 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
000a44cf 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
1058bool
1059Gcc_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);
94d11348 1066
1067 // Build the data structure gcc wants to see for a typedef.
23fe47e9 1068 tree copy = build_distinct_type_copy(t);
94d11348 1069 TYPE_NAME(copy) = NULL_TREE;
1070 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
1071
000a44cf 1072 return r->get_tree() != error_mark_node;
1073}
1074
1075// Return a named version of a type.
1076
1077Btype*
1078Gcc_backend::named_type(const std::string& name, Btype* btype,
b13c66cd 1079 Location location)
000a44cf 1080{
1081 tree type = btype->get_tree();
1082 if (type == error_mark_node)
1083 return this->error_type();
23fe47e9 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
94d11348 1102 tree copy = build_variant_type_copy(type);
b13c66cd 1103 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
000a44cf 1104 get_identifier_from_string(name),
94d11348 1105 copy);
1106 DECL_ORIGINAL_TYPE(decl) = type;
1107 TYPE_NAME(copy) = decl;
1108 return this->make_type(copy);
000a44cf 1109}
1110
1111// Return a pointer type used as a marker for a circular type.
1112
1113Btype*
1114Gcc_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
1121bool
1122Gcc_backend::is_circular_pointer_type(Btype* btype)
1123{
1124 return btype->get_tree() == ptr_type_node;
1125}
1126
927a01eb 1127// Return the size of a type.
1128
3f378015 1129int64_t
927a01eb 1130Gcc_backend::type_size(Btype* btype)
1131{
175bd153 1132 tree t = btype->get_tree();
1133 if (t == error_mark_node)
1134 return 1;
1135 t = TYPE_SIZE_UNIT(t);
e1d65c9f 1136 gcc_assert(tree_fits_uhwi_p (t));
5be33d50 1137 unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
3f378015 1138 int64_t ret = static_cast<int64_t>(val_wide);
2a305b85 1139 if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
1140 return -1;
927a01eb 1141 return ret;
1142}
1143
1144// Return the alignment of a type.
1145
3f378015 1146int64_t
927a01eb 1147Gcc_backend::type_alignment(Btype* btype)
1148{
175bd153 1149 tree t = btype->get_tree();
1150 if (t == error_mark_node)
1151 return 1;
1152 return TYPE_ALIGN_UNIT(t);
927a01eb 1153}
1154
1155// Return the alignment of a struct field of type BTYPE.
1156
3f378015 1157int64_t
927a01eb 1158Gcc_backend::type_field_alignment(Btype* btype)
1159{
175bd153 1160 tree t = btype->get_tree();
1161 if (t == error_mark_node)
1162 return 1;
1163 return go_field_alignment(t);
927a01eb 1164}
1165
1166// Return the offset of a field in a struct.
1167
3f378015 1168int64_t
927a01eb 1169Gcc_backend::type_field_offset(Btype* btype, size_t index)
1170{
1171 tree struct_tree = btype->get_tree();
175bd153 1172 if (struct_tree == error_mark_node)
1173 return 0;
927a01eb 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);
3f378015 1182 int64_t ret = static_cast<int64_t>(offset_wide);
1183 gcc_assert(ret == offset_wide);
927a01eb 1184 return ret;
1185}
1186
63697958 1187// Return the zero value for a type.
1188
1189Bexpression*
1190Gcc_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);
ea664253 1198 return this->make_expression(ret);
63697958 1199}
1200
c6777780 1201// An expression that references a variable.
1202
1203Bexpression*
ff048646 1204Gcc_backend::var_expression(Bvariable* var, Location location)
c6777780 1205{
ff048646 1206 tree ret = var->get_tree(location);
c6777780 1207 if (ret == error_mark_node)
1208 return this->error_expression();
ea664253 1209 return this->make_expression(ret);
c6777780 1210}
1211
1212// An expression that indirectly references an expression.
1213
1214Bexpression*
9b27b43c 1215Gcc_backend::indirect_expression(Btype* btype, Bexpression* expr,
1216 bool known_valid, Location location)
c6777780 1217{
9b27b43c 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
c6777780 1230 tree ret = build_fold_indirect_ref_loc(location.gcc_location(),
9b27b43c 1231 expr_tree);
c6777780 1232 if (known_valid)
1233 TREE_THIS_NOTRAP(ret) = 1;
9b27b43c 1234 return this->make_expression(ret);
48c2a53a 1235}
1236
f2de4532 1237// Return an expression that declares a constant named NAME with the
1238// constant value VAL in BTYPE.
1239
1240Bexpression*
1241Gcc_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
48c2a53a 1260// Return a typed value as a constant integer.
1261
1262Bexpression*
1263Gcc_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));
ea664253 1270 return this->make_expression(ret);
48c2a53a 1271}
1272
1273// Return a typed value as a constant floating-point number.
1274
1275Bexpression*
1276Gcc_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);
ea664253 1288 return this->make_expression(ret);
48c2a53a 1289}
1290
1291// Return a typed real and imaginary value as a constant complex number.
1292
1293Bexpression*
fcbea5e4 1294Gcc_backend::complex_constant_expression(Btype* btype, mpc_t val)
48c2a53a 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;
fcbea5e4 1302 real_from_mpfr(&r1, mpc_realref(val), TREE_TYPE(t), GMP_RNDN);
48c2a53a 1303 REAL_VALUE_TYPE r2;
1304 real_convert(&r2, TYPE_MODE(TREE_TYPE(t)), &r1);
1305
1306 REAL_VALUE_TYPE r3;
fcbea5e4 1307 real_from_mpfr(&r3, mpc_imagref(val), TREE_TYPE(t), GMP_RNDN);
48c2a53a 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));
ea664253 1313 return this->make_expression(ret);
cd440cff 1314}
1315
2c809f8f 1316// Make a constant string expression.
1317
1318Bexpression*
1319Gcc_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);
2c809f8f 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
ea664253 1332// Make a constant boolean expression.
1333
1334Bexpression*
1335Gcc_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
2c809f8f 1341// Return the real part of a complex expression.
1342
1343Bexpression*
1344Gcc_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
1358Bexpression*
1359Gcc_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
1373Bexpression*
1374Gcc_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
cd440cff 1390// An expression that converts an expression to a different type.
1391
1392Bexpression*
2c809f8f 1393Gcc_backend::convert_expression(Btype* type, Bexpression* expr,
1394 Location location)
cd440cff 1395{
1396 tree type_tree = type->get_tree();
1397 tree expr_tree = expr->get_tree();
2c809f8f 1398 if (type_tree == error_mark_node
1399 || expr_tree == error_mark_node
1400 || TREE_TYPE(expr_tree) == error_mark_node)
cd440cff 1401 return this->error_expression();
1402
2c809f8f 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);
63697958 1426}
1427
97267c39 1428// Get the address of a function.
1429
1430Bexpression*
1431Gcc_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
175a4612 1441// Get the address of an expression.
1442
1443Bexpression*
1444Gcc_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
fbb851c5 1454// Return an expression for the field at INDEX in BSTRUCT.
1455
1456Bexpression*
1457Gcc_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;
ea664253 1484 return this->make_expression(ret);
fbb851c5 1485}
1486
2387f644 1487// Return an expression that executes BSTAT before BEXPR.
1488
1489Bexpression*
1490Gcc_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
1505Bexpression*
a32698ee 1506Gcc_backend::conditional_expression(Btype* btype, Bexpression* condition,
2387f644 1507 Bexpression* then_expr,
1508 Bexpression* else_expr, Location location)
1509{
a32698ee 1510 tree type_tree = btype == NULL ? void_type_node : btype->get_tree();
2387f644 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();
a32698ee 1514 if (type_tree == error_mark_node
1515 || cond_tree == error_mark_node
2387f644 1516 || then_tree == error_mark_node
1517 || else_tree == error_mark_node)
1518 return this->error_expression();
a32698ee 1519 tree ret = build3_loc(location.gcc_location(), COND_EXPR, type_tree,
2387f644 1520 cond_tree, then_tree, else_tree);
1521 return this->make_expression(ret);
1522}
1523
f9ca30f9 1524// Return an expression for the unary operation OP EXPR.
1525
1526Bexpression*
1527Gcc_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
a32698ee 1565// Convert a gofrontend operator to an equivalent tree_code.
1566
1567static enum tree_code
1568operator_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
1642Bexpression*
1643Gcc_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
2c809f8f 1683// Return an expression that constructs BTYPE with VALS.
1684
1685Bexpression*
1686Gcc_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
cc408b86 1697 tree sink = NULL_TREE;
2c809f8f 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
cc408b86 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
2c809f8f 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;
cc408b86 1734 if (sink != NULL_TREE)
1735 ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1736 type_tree, sink, ret);
2c809f8f 1737 return this->make_expression(ret);
1738}
1739
1740Bexpression*
1741Gcc_backend::array_constructor_expression(
1742 Btype* array_btype, const std::vector<unsigned long>& indexes,
f932433f 1743 const std::vector<Bexpression*>& vals, Location location)
2c809f8f 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());
f932433f 1750
1751 tree element_type = TREE_TYPE(type_tree);
1752 HOST_WIDE_INT element_size = int_size_in_bytes(element_type);
2c809f8f 1753 vec<constructor_elt, va_gc> *init;
f932433f 1754 vec_alloc(init, element_size == 0 ? 0 : vals.size());
2c809f8f 1755
f932433f 1756 tree sink = NULL_TREE;
2c809f8f 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
f932433f 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
2c809f8f 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;
f932433f 1789 if (sink != NULL_TREE)
1790 ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1791 type_tree, sink, ret);
2c809f8f 1792 return this->make_expression(ret);
1793}
1794
1795// Return an expression for the address of BASE[INDEX].
1796
1797Bexpression*
1798Gcc_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
1821Bexpression*
1822Gcc_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.
1839Bexpression*
1840Gcc_backend::call_expression(Bexpression* fn_expr,
1841 const std::vector<Bexpression*>& fn_args,
1ecc6157 1842 Bexpression* chain_expr, Location location)
2c809f8f 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
1ecc6157 1902 if (chain_expr)
1903 CALL_EXPR_STATIC_CHAIN (ret) = chain_expr->get_tree();
1904
2c809f8f 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
d5d1c295 1916// Return an expression that allocates SIZE bytes on the stack.
1917
1918Bexpression*
1919Gcc_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
0c9760fe 1927// An expression as a statement.
1928
1929Bstatement*
1930Gcc_backend::expression_statement(Bexpression* expr)
1931{
1932 return this->make_statement(expr->get_tree());
1933}
1934
fe2f84cf 1935// Variable initialization.
1936
1937Bstatement*
1938Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
1939{
ff048646 1940 tree var_tree = var->get_decl();
fe2f84cf 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);
6e27a000 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);
fe2f84cf 1966}
1967
87430073 1968// Assignment.
1969
1970Bstatement*
be2fc38d 1971Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
b13c66cd 1972 Location location)
87430073 1973{
be2fc38d 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)
f28bd647 1977 return this->error_statement();
6e27a000 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
bb92f513 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
b13c66cd 2014 return this->make_statement(fold_build2_loc(location.gcc_location(),
2015 MODIFY_EXPR,
87430073 2016 void_type_node,
be2fc38d 2017 lhs_tree, rhs_tree));
2018}
2019
2020// Return.
2021
2022Bstatement*
2023Gcc_backend::return_statement(Bfunction* bfunction,
2024 const std::vector<Bexpression*>& vals,
b13c66cd 2025 Location location)
be2fc38d 2026{
2027 tree fntree = bfunction->get_tree();
2028 if (fntree == error_mark_node)
f28bd647 2029 return this->error_statement();
be2fc38d 2030 tree result = DECL_RESULT(fntree);
2031 if (result == error_mark_node)
f28bd647 2032 return this->error_statement();
76f85fd6 2033
be2fc38d 2034 tree ret;
2035 if (vals.empty())
b13c66cd 2036 ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
2037 NULL_TREE);
be2fc38d 2038 else if (vals.size() == 1)
2039 {
2040 tree val = vals.front()->get_tree();
2041 if (val == error_mark_node)
f28bd647 2042 return this->error_statement();
b13c66cd 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);
be2fc38d 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);
76f85fd6 2057
2058 if (DECL_STRUCT_FUNCTION(fntree) == NULL)
2059 push_struct_function(fntree);
2060 else
2061 push_cfun(DECL_STRUCT_FUNCTION(fntree));
be2fc38d 2062 tree rettmp = create_tmp_var(rettype, "RESULT");
76f85fd6 2063 pop_cfun();
2064
be2fc38d 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);
b13c66cd 2071 tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
2072 TREE_TYPE(field), rettmp, field,
2073 NULL_TREE);
be2fc38d 2074 tree val = (*p)->get_tree();
2075 if (val == error_mark_node)
f28bd647 2076 return this->error_statement();
b13c66cd 2077 tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2078 void_type_node,
be2fc38d 2079 ref, (*p)->get_tree());
2080 append_to_statement_list(set, &stmt_list);
2081 }
2082 gcc_assert(field == NULL_TREE);
b13c66cd 2083 tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2084 void_type_node,
be2fc38d 2085 result, rettmp);
b13c66cd 2086 tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
2087 void_type_node, set);
be2fc38d 2088 append_to_statement_list(ret_expr, &stmt_list);
2089 ret = stmt_list;
2090 }
2091 return this->make_statement(ret);
87430073 2092}
2093
2c809f8f 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
2100Bstatement*
2101Gcc_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
e8816003 2128// If.
2129
2130Bstatement*
7e84be55 2131Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
b13c66cd 2132 Bblock* else_block, Location location)
e8816003 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)
f28bd647 2140 return this->error_statement();
b13c66cd 2141 tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
2142 cond_tree, then_tree, else_tree);
e8816003 2143 return this->make_statement(ret);
2144}
2145
8259743a 2146// Switch.
2147
2148Bstatement*
2149Gcc_backend::switch_statement(
76f85fd6 2150 Bfunction* function,
8259743a 2151 Bexpression* value,
2152 const std::vector<std::vector<Bexpression*> >& cases,
2153 const std::vector<Bstatement*>& statements,
b13c66cd 2154 Location switch_location)
8259743a 2155{
2156 gcc_assert(cases.size() == statements.size());
2157
76f85fd6 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
8259743a 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
b13c66cd 2173 ? EXPR_LOCATION((*ps)->get_tree())
2174 : UNKNOWN_LOCATION);
8259743a 2175 tree label = create_artificial_label(loc);
b6e3dd65 2176 tree c = build_case_label(NULL_TREE, NULL_TREE, label);
8259743a 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)
f28bd647 2187 return this->error_statement();
8259743a 2188 source_location loc = EXPR_LOCATION(t);
2189 tree label = create_artificial_label(loc);
b6e3dd65 2190 tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
8259743a 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)
f28bd647 2199 return this->error_statement();
8259743a 2200 append_to_statement_list(t, &stmt_list);
2201 }
2202 }
76f85fd6 2203 pop_cfun();
8259743a 2204
2205 tree tv = value->get_tree();
2206 if (tv == error_mark_node)
f28bd647 2207 return this->error_statement();
b13c66cd 2208 tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR,
bfb10994 2209 NULL_TREE, tv, stmt_list, NULL_TREE);
8259743a 2210 return this->make_statement(t);
2211}
2212
f28bd647 2213// Pair of statements.
2214
2215Bstatement*
2216Gcc_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);
a2990dc1 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
f28bd647 2233 return this->make_statement(stmt_list);
2234}
2235
8259743a 2236// List of statements.
2237
2238Bstatement*
2239Gcc_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)
f28bd647 2248 return this->error_statement();
8259743a 2249 append_to_statement_list(t, &stmt_list);
2250 }
2251 return this->make_statement(stmt_list);
2252}
2253
7e84be55 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
2259Bblock*
2260Gcc_backend::block(Bfunction* function, Bblock* enclosing,
2261 const std::vector<Bvariable*>& vars,
b13c66cd 2262 Location start_location,
2263 Location)
7e84be55 2264{
2265 tree block_tree = make_node(BLOCK);
2266 if (enclosing == NULL)
2267 {
76f85fd6 2268 tree fndecl = function->get_tree();
7e84be55 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 {
ff048646 2310 *pp = (*pv)->get_decl();
7e84be55 2311 if (*pp != error_mark_node)
2312 pp = &DECL_CHAIN(*pp);
2313 }
2314 *pp = NULL_TREE;
2315
2316 TREE_USED(block_tree) = 1;
2317
b13c66cd 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);
7e84be55 2321 TREE_SIDE_EFFECTS(bind_tree) = 1;
7e84be55 2322 return new Bblock(bind_tree);
2323}
2324
2325// Add statements to a block.
2326
2327void
2328Gcc_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
2348Bstatement*
2349Gcc_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
6e27a000 2356// This is not static because we declare it with GTY(()) in go-c.h.
2357tree go_non_zero_struct;
2358
2359// Return a type corresponding to TYPE with non-zero size.
2360
2361tree
2362Gcc_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:
5194c57d 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;
6e27a000 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
fe2f84cf 2419// Make a global variable.
2420
2421Bvariable*
2422Gcc_backend::global_variable(const std::string& package_name,
2a2647e2 2423 const std::string& pkgpath,
fe2f84cf 2424 const std::string& name,
2425 Btype* btype,
2426 bool is_external,
2427 bool is_hidden,
149eabc5 2428 bool in_unique_section,
b13c66cd 2429 Location location)
fe2f84cf 2430{
2431 tree type_tree = btype->get_tree();
2432 if (type_tree == error_mark_node)
2433 return this->error_variable();
2434
6e27a000 2435 // The GNU linker does not like dynamic variables with zero size.
e62b5837 2436 tree orig_type_tree = type_tree;
6e27a000 2437 if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
2438 type_tree = this->non_zero_size_type(type_tree);
2439
fe2f84cf 2440 std::string var_name(package_name);
2441 var_name.push_back('.');
2442 var_name.append(name);
b13c66cd 2443 tree decl = build_decl(location.gcc_location(), VAR_DECL,
fe2f84cf 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
2a2647e2 2454 std::string asm_name(pkgpath);
fe2f84cf 2455 asm_name.push_back('.');
2a2647e2 2456 asm_name.append(name);
fe2f84cf 2457 SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2458 }
2459 TREE_USED(decl) = 1;
2460
149eabc5 2461 if (in_unique_section)
2462 resolve_unique_section (decl, 0, 1);
2463
fe2f84cf 2464 go_preserve_from_gc(decl);
2465
ff048646 2466 return new Bvariable(decl, orig_type_tree);
fe2f84cf 2467}
2468
2469// Set the initial value of a global variable.
2470
2471void
2472Gcc_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));
ff048646 2478 tree var_decl = var->get_decl();
fe2f84cf 2479 if (var_decl == error_mark_node)
2480 return;
2481 DECL_INITIAL(var_decl) = expr_tree;
149eabc5 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.
e07edb17 2485 if (symtab_node::get(var_decl)
2486 && symtab_node::get(var_decl)->implicit_section)
149eabc5 2487 {
71e19e54 2488 set_decl_section_name (var_decl, NULL);
149eabc5 2489 resolve_unique_section (var_decl,
2490 compute_reloc_for_constant (expr_tree),
2491 1);
2492 }
fe2f84cf 2493}
2494
2495// Make a local variable.
2496
2497Bvariable*
2498Gcc_backend::local_variable(Bfunction* function, const std::string& name,
f325319b 2499 Btype* btype, bool is_address_taken,
b13c66cd 2500 Location location)
fe2f84cf 2501{
2502 tree type_tree = btype->get_tree();
2503 if (type_tree == error_mark_node)
2504 return this->error_variable();
b13c66cd 2505 tree decl = build_decl(location.gcc_location(), VAR_DECL,
fe2f84cf 2506 get_identifier_from_string(name),
2507 type_tree);
2508 DECL_CONTEXT(decl) = function->get_tree();
2509 TREE_USED(decl) = 1;
f325319b 2510 if (is_address_taken)
2511 TREE_ADDRESSABLE(decl) = 1;
fe2f84cf 2512 go_preserve_from_gc(decl);
2513 return new Bvariable(decl);
2514}
2515
2516// Make a function parameter variable.
2517
2518Bvariable*
2519Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
f325319b 2520 Btype* btype, bool is_address_taken,
b13c66cd 2521 Location location)
fe2f84cf 2522{
2523 tree type_tree = btype->get_tree();
2524 if (type_tree == error_mark_node)
2525 return this->error_variable();
b13c66cd 2526 tree decl = build_decl(location.gcc_location(), PARM_DECL,
fe2f84cf 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;
f325319b 2532 if (is_address_taken)
2533 TREE_ADDRESSABLE(decl) = 1;
fe2f84cf 2534 go_preserve_from_gc(decl);
2535 return new Bvariable(decl);
2536}
2537
1ecc6157 2538// Make a static chain variable.
2539
2540Bvariable*
2541Gcc_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
eefc1ed3 2572// Make a temporary variable.
2573
2574Bvariable*
2575Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
2576 Btype* btype, Bexpression* binit,
2577 bool is_address_taken,
b13c66cd 2578 Location location,
eefc1ed3 2579 Bstatement** pstatement)
2580{
9b27b43c 2581 gcc_assert(function != NULL);
2582 tree decl = function->get_tree();
eefc1ed3 2583 tree type_tree = btype->get_tree();
2584 tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
9b27b43c 2585 if (type_tree == error_mark_node
2586 || init_tree == error_mark_node
2587 || decl == error_mark_node)
eefc1ed3 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))
64648b04 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 }
eefc1ed3 2605 else
2606 {
2607 gcc_assert(bblock != NULL);
b13c66cd 2608 var = build_decl(location.gcc_location(), VAR_DECL,
eefc1ed3 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;
64648b04 2614 DECL_CONTEXT(var) = decl;
eefc1ed3 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
6b059318 2626 if (this->type_size(btype) != 0 && init_tree != NULL_TREE)
b13c66cd 2627 DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree,
2628 init_tree);
eefc1ed3 2629
2630 if (is_address_taken)
2631 TREE_ADDRESSABLE(var) = 1;
2632
b13c66cd 2633 *pstatement = this->make_statement(build1_loc(location.gcc_location(),
2634 DECL_EXPR,
eefc1ed3 2635 void_type_node, var));
6b059318 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
eefc1ed3 2643 return new Bvariable(var);
2644}
2645
f23d7786 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.
76f85fd6 2648
2649Bvariable*
f23d7786 2650Gcc_backend::implicit_variable(const std::string& name, Btype* type,
aa5ae575 2651 bool is_hidden, bool is_constant,
3f378015 2652 bool is_common, int64_t alignment)
76f85fd6 2653{
2654 tree type_tree = type->get_tree();
aa5ae575 2655 if (type_tree == error_mark_node)
76f85fd6 2656 return this->error_variable();
2657
2658 tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
f23d7786 2659 get_identifier_from_string(name), type_tree);
76f85fd6 2660 DECL_EXTERNAL(decl) = 0;
aa5ae575 2661 TREE_PUBLIC(decl) = !is_hidden;
76f85fd6 2662 TREE_STATIC(decl) = 1;
aa5ae575 2663 TREE_USED(decl) = 1;
76f85fd6 2664 DECL_ARTIFICIAL(decl) = 1;
5892f89f 2665 if (is_common)
2666 {
2667 DECL_COMMON(decl) = 1;
aa5ae575 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;
5892f89f 2682 }
aa5ae575 2683 if (is_constant)
f23d7786 2684 {
2685 TREE_READONLY(decl) = 1;
2686 TREE_CONSTANT(decl) = 1;
2687 }
5892f89f 2688 if (alignment != 0)
2689 {
2690 DECL_ALIGN(decl) = alignment * BITS_PER_UNIT;
2691 DECL_USER_ALIGN(decl) = 1;
2692 }
2693
aa5ae575 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
2701void
2702Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
2703 Btype*, bool, bool, bool is_common,
2704 Bexpression* init)
2705{
ff048646 2706 tree decl = var->get_decl();
aa5ae575 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
76f85fd6 2727 rest_of_decl_compilation(decl, 1, 0);
aa5ae575 2728}
2729
2730// Return a reference to an implicit variable defined in another package.
76f85fd6 2731
aa5ae575 2732Bvariable*
2733Gcc_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) = 0;
2742 TREE_PUBLIC(decl) = 1;
2743 TREE_STATIC(decl) = 1;
2744 DECL_ARTIFICIAL(decl) = 1;
2745 go_preserve_from_gc(decl);
76f85fd6 2746 return new Bvariable(decl);
2747}
2748
a1d23b41 2749// Create a named immutable initialized data structure.
2750
2751Bvariable*
6fce1fe8 2752Gcc_backend::immutable_struct(const std::string& name, bool is_hidden,
5a16667a 2753 bool is_common, Btype* btype, Location location)
a1d23b41 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);
b13c66cd 2759 tree decl = build_decl(location.gcc_location(), VAR_DECL,
a1d23b41 2760 get_identifier_from_string(name),
2761 build_qualified_type(type_tree, TYPE_QUAL_CONST));
2762 TREE_STATIC(decl) = 1;
76f85fd6 2763 TREE_USED(decl) = 1;
a1d23b41 2764 TREE_READONLY(decl) = 1;
2765 TREE_CONSTANT(decl) = 1;
a1d23b41 2766 DECL_ARTIFICIAL(decl) = 1;
6fce1fe8 2767 if (!is_hidden)
2768 TREE_PUBLIC(decl) = 1;
a1d23b41 2769
5a16667a 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
a1d23b41 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
2795void
2796Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
6fce1fe8 2797 bool, bool is_common, Btype*, Location,
a1d23b41 2798 Bexpression* initializer)
2799{
ff048646 2800 tree decl = var->get_decl();
a1d23b41 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
5a16667a 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.
6fce1fe8 2809 if (is_common)
5a16667a 2810 {
2811 DECL_WEAK(decl) = 0;
2812 make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
2813 }
1eeab44f 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.
66b3edb8 2817 resolve_unique_section(decl,
2818 compute_reloc_for_constant (init_tree),
2819 1);
a1d23b41 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
2827Bvariable*
2828Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
b13c66cd 2829 Location location)
a1d23b41 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);
b13c66cd 2835 tree decl = build_decl(location.gcc_location(), VAR_DECL,
a1d23b41 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
6e193e6f 2847// Make a label.
2848
2849Blabel*
2850Gcc_backend::label(Bfunction* function, const std::string& name,
b13c66cd 2851 Location location)
6e193e6f 2852{
2853 tree decl;
2854 if (name.empty())
76f85fd6 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 }
6e193e6f 2866 else
2867 {
2868 tree id = get_identifier_from_string(name);
b13c66cd 2869 decl = build_decl(location.gcc_location(), LABEL_DECL, id,
2870 void_type_node);
6e193e6f 2871 DECL_CONTEXT(decl) = function->get_tree();
2872 }
2873 return new Blabel(decl);
2874}
2875
2876// Make a statement which defines a label.
2877
2878Bstatement*
2879Gcc_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
2889Bstatement*
b13c66cd 2890Gcc_backend::goto_statement(Blabel* label, Location location)
6e193e6f 2891{
2892 tree lab = label->get_tree();
b13c66cd 2893 tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
2894 lab);
6e193e6f 2895 return this->make_statement(ret);
2896}
2897
2898// Get the address of a label.
2899
2900Bexpression*
b13c66cd 2901Gcc_backend::label_address(Blabel* label, Location location)
6e193e6f 2902{
2903 tree lab = label->get_tree();
2904 TREE_USED(lab) = 1;
2905 TREE_ADDRESSABLE(lab) = 1;
b13c66cd 2906 tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
2907 build_fold_addr_expr_loc(location.gcc_location(),
2908 lab));
6e193e6f 2909 return this->make_expression(ret);
2910}
2911
cf3cae55 2912// Declare or define a new function.
2913
2914Bfunction*
2915Gcc_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
2c809f8f 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
2967Bstatement*
2968Gcc_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();
76f85fd6 2973 tree fntree = function->get_tree();
2c809f8f 2974
2975 if (undefer_tree == error_mark_node
76f85fd6 2976 || defer_tree == error_mark_node
2977 || fntree == error_mark_node)
2c809f8f 2978 return this->error_statement();
2979
76f85fd6 2980 if (DECL_STRUCT_FUNCTION(fntree) == NULL)
2981 push_struct_function(fntree);
2982 else
2983 push_cfun(DECL_STRUCT_FUNCTION(fntree));
2984
2c809f8f 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);
76f85fd6 2997 pop_cfun();
2c809f8f 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
3005bool
3006Gcc_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 {
ff048646 3019 *pp = (*pv)->get_decl();
2c809f8f 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
3030bool
3031Gcc_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
518151f2 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
3045Bfunction*
3046Gcc_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
76f85fd6 3053// Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
3a1c9df2 3054// FUNCTION_DECLS, and VARIABLE_DECLS declared globally, as well as
3055// emit early debugging information.
76f85fd6 3056
3057void
3058Gcc_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 {
ff048646 3075 tree v = (*p)->get_decl();
3076 if (v != error_mark_node)
76f85fd6 3077 {
ff048646 3078 defs[i] = v;
76f85fd6 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);
35ee1c66 3118 cgraph_node::finalize_function(decl, true);
76f85fd6 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
76f85fd6 3129 delete[] defs;
3130}
3131
518151f2 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.
c157e584 3137// NORETURN_P is true if the function has the noreturn attribute.
87430073 3138
518151f2 3139void
3140Gcc_backend::define_builtin(built_in_function bcode, const char* name,
c157e584 3141 const char* libname, tree fntype, bool const_p,
3142 bool noreturn_p)
518151f2 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;
c157e584 3148 if (noreturn_p)
3149 TREE_THIS_VOLATILE(decl) = 1;
518151f2 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;
c157e584 3158 if (noreturn_p)
3159 TREE_THIS_VOLATILE(decl) = 1;
518151f2 3160 this->builtin_functions_[libname] = this->make_function(decl);
3161 }
3162}
87430073 3163
3164// Return the backend generator.
3165
3166Backend*
3167go_get_backend()
3168{
518151f2 3169 return new Gcc_backend();
87430073 3170}