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