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