]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/go/go-gcc.cc
re PR fortran/57987 (Fortran finalizers considered extern-inline by middle-end)
[thirdparty/gcc.git] / gcc / go / go-gcc.cc
CommitLineData
a9ac13f7 1// go-gcc.cc -- Go frontend to gcc IR.
d1e082c2 2// Copyright (C) 2011-2013 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
a9ac13f7 27#include "tree.h"
94039447
ILT
28#include "tree-iterator.h"
29#include "gimple.h"
70f91024 30#include "toplev.h"
744c3195 31#include "output.h"
a9ac13f7 32
e09ce6c5
ILT
33#include "go-c.h"
34
94039447 35#include "gogo.h"
a9ac13f7
ILT
36#include "backend.h"
37
38// A class wrapping a tree.
39
40class Gcc_tree
41{
42 public:
43 Gcc_tree(tree t)
44 : t_(t)
45 { }
46
47 tree
0aa5e7f2 48 get_tree() const
a9ac13f7
ILT
49 { return this->t_; }
50
ce842ad6
ILT
51 void
52 set_tree(tree t)
53 { this->t_ = t; }
54
a9ac13f7
ILT
55 private:
56 tree t_;
57};
58
59// In gcc, types, expressions, and statements are all trees.
60class Btype : public Gcc_tree
61{
62 public:
63 Btype(tree t)
64 : Gcc_tree(t)
65 { }
66};
67
68class Bexpression : public Gcc_tree
69{
70 public:
71 Bexpression(tree t)
72 : Gcc_tree(t)
73 { }
74};
75
76class Bstatement : public Gcc_tree
77{
78 public:
79 Bstatement(tree t)
80 : Gcc_tree(t)
81 { }
82};
83
94039447
ILT
84class Bfunction : public Gcc_tree
85{
86 public:
87 Bfunction(tree t)
88 : Gcc_tree(t)
89 { }
90};
91
5ad7db5f
ILT
92class Bblock : public Gcc_tree
93{
94 public:
95 Bblock(tree t)
96 : Gcc_tree(t)
97 { }
98};
99
e09ce6c5
ILT
100class Bvariable : public Gcc_tree
101{
102 public:
103 Bvariable(tree t)
104 : Gcc_tree(t)
105 { }
106};
107
d56e6679
ILT
108class Blabel : public Gcc_tree
109{
110 public:
111 Blabel(tree t)
112 : Gcc_tree(t)
113 { }
114};
115
a9ac13f7
ILT
116// This file implements the interface between the Go frontend proper
117// and the gcc IR. This implements specific instantiations of
118// abstract classes defined by the Go frontend proper. The Go
119// frontend proper class methods of these classes to generate the
120// backend representation.
121
122class Gcc_backend : public Backend
123{
124 public:
125 // Types.
126
127 Btype*
128 error_type()
482829ac 129 { return this->make_type(error_mark_node); }
a9ac13f7
ILT
130
131 Btype*
132 void_type()
0aa5e7f2 133 { return this->make_type(void_type_node); }
a9ac13f7
ILT
134
135 Btype*
136 bool_type()
0aa5e7f2 137 { return this->make_type(boolean_type_node); }
a9ac13f7
ILT
138
139 Btype*
0aa5e7f2 140 integer_type(bool, int);
a9ac13f7
ILT
141
142 Btype*
0aa5e7f2
ES
143 float_type(int);
144
145 Btype*
146 complex_type(int);
a9ac13f7
ILT
147
148 Btype*
482829ac 149 pointer_type(Btype*);
a9ac13f7 150
0aa5e7f2 151 Btype*
482829ac
ILT
152 function_type(const Btyped_identifier&,
153 const std::vector<Btyped_identifier>&,
154 const std::vector<Btyped_identifier>&,
8afa2bfb 155 const Location);
a9ac13f7
ILT
156
157 Btype*
6d69c02e 158 struct_type(const std::vector<Btyped_identifier>&);
a9ac13f7
ILT
159
160 Btype*
7fc2f86b
ILT
161 array_type(Btype*, Bexpression*);
162
163 Btype*
8afa2bfb 164 placeholder_pointer_type(const std::string&, Location, bool);
7fc2f86b
ILT
165
166 bool
167 set_placeholder_pointer_type(Btype*, Btype*);
168
169 bool
170 set_placeholder_function_type(Btype*, Btype*);
171
172 Btype*
8afa2bfb 173 placeholder_struct_type(const std::string&, Location);
7fc2f86b
ILT
174
175 bool
176 set_placeholder_struct_type(Btype* placeholder,
177 const std::vector<Btyped_identifier>&);
178
179 Btype*
8afa2bfb 180 placeholder_array_type(const std::string&, Location);
7fc2f86b
ILT
181
182 bool
183 set_placeholder_array_type(Btype*, Btype*, Bexpression*);
184
185 Btype*
8afa2bfb 186 named_type(const std::string&, Btype*, Location);
7fc2f86b
ILT
187
188 Btype*
189 circular_pointer_type(Btype*, bool);
190
191 bool
192 is_circular_pointer_type(Btype*);
a9ac13f7 193
ef1ed13d
ILT
194 size_t
195 type_size(Btype*);
196
197 size_t
198 type_alignment(Btype*);
199
200 size_t
201 type_field_alignment(Btype*);
202
203 size_t
204 type_field_offset(Btype*, size_t index);
205
54466dde
ILT
206 // Expressions.
207
208 Bexpression*
209 zero_expression(Btype*);
210
a9ac13f7
ILT
211 // Statements.
212
f54d331e
ILT
213 Bstatement*
214 error_statement()
215 { return this->make_statement(error_mark_node); }
216
cfebcf30
ILT
217 Bstatement*
218 expression_statement(Bexpression*);
219
e09ce6c5
ILT
220 Bstatement*
221 init_statement(Bvariable* var, Bexpression* init);
222
a9ac13f7 223 Bstatement*
8afa2bfb 224 assignment_statement(Bexpression* lhs, Bexpression* rhs, Location);
94039447 225
94039447
ILT
226 Bstatement*
227 return_statement(Bfunction*, const std::vector<Bexpression*>&,
8afa2bfb 228 Location);
a9ac13f7 229
db0adf82 230 Bstatement*
5ad7db5f 231 if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
8afa2bfb 232 Location);
db0adf82 233
8d0b03a2
ILT
234 Bstatement*
235 switch_statement(Bexpression* value,
236 const std::vector<std::vector<Bexpression*> >& cases,
237 const std::vector<Bstatement*>& statements,
8afa2bfb 238 Location);
8d0b03a2 239
00b44a6e
ILT
240 Bstatement*
241 compound_statement(Bstatement*, Bstatement*);
242
8d0b03a2
ILT
243 Bstatement*
244 statement_list(const std::vector<Bstatement*>&);
245
5ad7db5f
ILT
246 // Blocks.
247
248 Bblock*
249 block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
8afa2bfb 250 Location, Location);
5ad7db5f
ILT
251
252 void
253 block_add_statements(Bblock*, const std::vector<Bstatement*>&);
254
255 Bstatement*
256 block_statement(Bblock*);
257
e09ce6c5
ILT
258 // Variables.
259
260 Bvariable*
261 error_variable()
262 { return new Bvariable(error_mark_node); }
263
264 Bvariable*
265 global_variable(const std::string& package_name,
097b12fb 266 const std::string& pkgpath,
e09ce6c5
ILT
267 const std::string& name,
268 Btype* btype,
269 bool is_external,
270 bool is_hidden,
744c3195 271 bool in_unique_section,
8afa2bfb 272 Location location);
e09ce6c5
ILT
273
274 void
275 global_variable_set_init(Bvariable*, Bexpression*);
276
277 Bvariable*
acf98146 278 local_variable(Bfunction*, const std::string&, Btype*, bool,
8afa2bfb 279 Location);
e09ce6c5
ILT
280
281 Bvariable*
acf98146 282 parameter_variable(Bfunction*, const std::string&, Btype*, bool,
8afa2bfb 283 Location);
e09ce6c5 284
9131ad67
ILT
285 Bvariable*
286 temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
8afa2bfb 287 Location, Bstatement**);
9131ad67 288
70f91024 289 Bvariable*
fdbc38a6 290 immutable_struct(const std::string&, bool, bool, Btype*, Location);
70f91024
ILT
291
292 void
fdbc38a6 293 immutable_struct_set_init(Bvariable*, const std::string&, bool, bool, Btype*,
8afa2bfb 294 Location, Bexpression*);
70f91024
ILT
295
296 Bvariable*
8afa2bfb 297 immutable_struct_reference(const std::string&, Btype*, Location);
70f91024 298
d56e6679
ILT
299 // Labels.
300
301 Blabel*
8afa2bfb 302 label(Bfunction*, const std::string& name, Location);
d56e6679
ILT
303
304 Bstatement*
305 label_definition_statement(Blabel*);
306
307 Bstatement*
8afa2bfb 308 goto_statement(Blabel*, Location);
d56e6679
ILT
309
310 Bexpression*
8afa2bfb 311 label_address(Blabel*, Location);
d56e6679 312
a9ac13f7 313 private:
d56e6679
ILT
314 // Make a Bexpression from a tree.
315 Bexpression*
316 make_expression(tree t)
317 { return new Bexpression(t); }
318
a9ac13f7
ILT
319 // Make a Bstatement from a tree.
320 Bstatement*
321 make_statement(tree t)
322 { return new Bstatement(t); }
0aa5e7f2
ES
323
324 // Make a Btype from a tree.
325 Btype*
326 make_type(tree t)
327 { return new Btype(t); }
7fc2f86b
ILT
328
329 Btype*
330 fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
331
332 Btype*
333 fill_in_array(Btype*, Btype*, Bexpression*);
7d6be4c8
ILT
334
335 tree
336 non_zero_size_type(tree);
a9ac13f7
ILT
337};
338
d56e6679
ILT
339// A helper function.
340
341static inline tree
342get_identifier_from_string(const std::string& str)
343{
344 return get_identifier_with_length(str.data(), str.length());
345}
cfebcf30 346
0aa5e7f2
ES
347// Get an unnamed integer type.
348
349Btype*
350Gcc_backend::integer_type(bool is_unsigned, int bits)
351{
352 tree type;
353 if (is_unsigned)
354 {
355 if (bits == INT_TYPE_SIZE)
356 type = unsigned_type_node;
357 else if (bits == CHAR_TYPE_SIZE)
358 type = unsigned_char_type_node;
359 else if (bits == SHORT_TYPE_SIZE)
360 type = short_unsigned_type_node;
361 else if (bits == LONG_TYPE_SIZE)
362 type = long_unsigned_type_node;
363 else if (bits == LONG_LONG_TYPE_SIZE)
364 type = long_long_unsigned_type_node;
365 else
366 type = make_unsigned_type(bits);
367 }
368 else
369 {
370 if (bits == INT_TYPE_SIZE)
371 type = integer_type_node;
372 else if (bits == CHAR_TYPE_SIZE)
373 type = signed_char_type_node;
374 else if (bits == SHORT_TYPE_SIZE)
375 type = short_integer_type_node;
376 else if (bits == LONG_TYPE_SIZE)
377 type = long_integer_type_node;
378 else if (bits == LONG_LONG_TYPE_SIZE)
379 type = long_long_integer_type_node;
380 else
381 type = make_signed_type(bits);
382 }
383 return this->make_type(type);
384}
385
386// Get an unnamed float type.
387
388Btype*
389Gcc_backend::float_type(int bits)
390{
391 tree type;
392 if (bits == FLOAT_TYPE_SIZE)
393 type = float_type_node;
394 else if (bits == DOUBLE_TYPE_SIZE)
395 type = double_type_node;
396 else if (bits == LONG_DOUBLE_TYPE_SIZE)
397 type = long_double_type_node;
398 else
399 {
400 type = make_node(REAL_TYPE);
401 TYPE_PRECISION(type) = bits;
402 layout_type(type);
403 }
404 return this->make_type(type);
405}
406
407// Get an unnamed complex type.
408
409Btype*
410Gcc_backend::complex_type(int bits)
411{
412 tree type;
413 if (bits == FLOAT_TYPE_SIZE * 2)
414 type = complex_float_type_node;
415 else if (bits == DOUBLE_TYPE_SIZE * 2)
416 type = complex_double_type_node;
417 else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
418 type = complex_long_double_type_node;
419 else
420 {
421 type = make_node(REAL_TYPE);
422 TYPE_PRECISION(type) = bits / 2;
423 layout_type(type);
424 type = build_complex_type(type);
425 }
426 return this->make_type(type);
427}
428
429// Get a pointer type.
430
431Btype*
482829ac 432Gcc_backend::pointer_type(Btype* to_type)
0aa5e7f2 433{
482829ac
ILT
434 tree to_type_tree = to_type->get_tree();
435 if (to_type_tree == error_mark_node)
436 return this->error_type();
437 tree type = build_pointer_type(to_type_tree);
0aa5e7f2
ES
438 return this->make_type(type);
439}
440
482829ac
ILT
441// Make a function type.
442
443Btype*
444Gcc_backend::function_type(const Btyped_identifier& receiver,
445 const std::vector<Btyped_identifier>& parameters,
446 const std::vector<Btyped_identifier>& results,
8afa2bfb 447 Location location)
482829ac
ILT
448{
449 tree args = NULL_TREE;
450 tree* pp = &args;
451 if (receiver.btype != NULL)
452 {
453 tree t = receiver.btype->get_tree();
454 if (t == error_mark_node)
455 return this->error_type();
456 *pp = tree_cons(NULL_TREE, t, NULL_TREE);
457 pp = &TREE_CHAIN(*pp);
458 }
459
460 for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
461 p != parameters.end();
462 ++p)
463 {
464 tree t = p->btype->get_tree();
465 if (t == error_mark_node)
466 return this->error_type();
467 *pp = tree_cons(NULL_TREE, t, NULL_TREE);
468 pp = &TREE_CHAIN(*pp);
469 }
470
471 // Varargs is handled entirely at the Go level. When converted to
472 // GENERIC functions are not varargs.
473 *pp = void_list_node;
474
475 tree result;
476 if (results.empty())
477 result = void_type_node;
478 else if (results.size() == 1)
479 result = results.front().btype->get_tree();
480 else
481 {
482 result = make_node(RECORD_TYPE);
483 tree field_trees = NULL_TREE;
484 pp = &field_trees;
485 for (std::vector<Btyped_identifier>::const_iterator p = results.begin();
486 p != results.end();
487 ++p)
488 {
489 const std::string name = (p->name.empty()
490 ? "UNNAMED"
491 : p->name);
492 tree name_tree = get_identifier_from_string(name);
493 tree field_type_tree = p->btype->get_tree();
494 if (field_type_tree == error_mark_node)
495 return this->error_type();
26793fb5 496 gcc_assert(TYPE_SIZE(field_type_tree) != NULL_TREE);
8afa2bfb
SD
497 tree field = build_decl(location.gcc_location(), FIELD_DECL,
498 name_tree, field_type_tree);
482829ac
ILT
499 DECL_CONTEXT(field) = result;
500 *pp = field;
501 pp = &DECL_CHAIN(field);
502 }
503 TYPE_FIELDS(result) = field_trees;
504 layout_type(result);
505 }
506 if (result == error_mark_node)
507 return this->error_type();
508
509 tree fntype = build_function_type(result, args);
510 if (fntype == error_mark_node)
511 return this->error_type();
512
513 return this->make_type(build_pointer_type(fntype));
514}
515
6d69c02e
ILT
516// Make a struct type.
517
518Btype*
519Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
520{
7fc2f86b
ILT
521 return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE)), fields);
522}
523
524// Fill in the fields of a struct type.
525
526Btype*
527Gcc_backend::fill_in_struct(Btype* fill,
528 const std::vector<Btyped_identifier>& fields)
529{
530 tree fill_tree = fill->get_tree();
6d69c02e
ILT
531 tree field_trees = NULL_TREE;
532 tree* pp = &field_trees;
533 for (std::vector<Btyped_identifier>::const_iterator p = fields.begin();
534 p != fields.end();
535 ++p)
536 {
537 tree name_tree = get_identifier_from_string(p->name);
538 tree type_tree = p->btype->get_tree();
539 if (type_tree == error_mark_node)
540 return this->error_type();
8afa2bfb
SD
541 tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
542 type_tree);
7fc2f86b 543 DECL_CONTEXT(field) = fill_tree;
6d69c02e
ILT
544 *pp = field;
545 pp = &DECL_CHAIN(field);
546 }
7fc2f86b
ILT
547 TYPE_FIELDS(fill_tree) = field_trees;
548 layout_type(fill_tree);
549 return fill;
550}
551
552// Make an array type.
553
554Btype*
555Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
556{
557 return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
558 element_btype, length);
559}
560
561// Fill in an array type.
562
563Btype*
564Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
565 Bexpression* length)
566{
567 tree element_type_tree = element_type->get_tree();
568 tree length_tree = length->get_tree();
569 if (element_type_tree == error_mark_node || length_tree == error_mark_node)
570 return this->error_type();
571
572 gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
573
574 length_tree = fold_convert(sizetype, length_tree);
575
576 // build_index_type takes the maximum index, which is one less than
577 // the length.
578 tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
579 length_tree,
580 size_one_node));
581
582 tree fill_tree = fill->get_tree();
583 TREE_TYPE(fill_tree) = element_type_tree;
584 TYPE_DOMAIN(fill_tree) = index_type_tree;
585 TYPE_ADDR_SPACE(fill_tree) = TYPE_ADDR_SPACE(element_type_tree);
586 layout_type(fill_tree);
587
588 if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree))
589 SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
590 else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
591 || TYPE_CANONICAL(index_type_tree) != index_type_tree)
592 TYPE_CANONICAL(fill_tree) =
593 build_array_type(TYPE_CANONICAL(element_type_tree),
594 TYPE_CANONICAL(index_type_tree));
595
596 return fill;
597}
598
599// Create a placeholder for a pointer type.
600
601Btype*
602Gcc_backend::placeholder_pointer_type(const std::string& name,
8afa2bfb 603 Location location, bool)
7fc2f86b 604{
3762c343 605 tree ret = build_distinct_type_copy(ptr_type_node);
26793fb5
ILT
606 if (!name.empty())
607 {
8afa2bfb 608 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
26793fb5
ILT
609 get_identifier_from_string(name),
610 ret);
611 TYPE_NAME(ret) = decl;
612 }
7fc2f86b
ILT
613 return this->make_type(ret);
614}
615
616// Set the real target type for a placeholder pointer type.
617
618bool
619Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
620 Btype* to_type)
621{
622 tree pt = placeholder->get_tree();
623 if (pt == error_mark_node)
624 return false;
625 gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
626 tree tt = to_type->get_tree();
627 if (tt == error_mark_node)
628 {
ce842ad6 629 placeholder->set_tree(error_mark_node);
7fc2f86b
ILT
630 return false;
631 }
632 gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
633 TREE_TYPE(pt) = TREE_TYPE(tt);
dcf30625
ILT
634 if (TYPE_NAME(pt) != NULL_TREE)
635 {
636 // Build the data structure gcc wants to see for a typedef.
637 tree copy = build_variant_type_copy(pt);
638 TYPE_NAME(copy) = NULL_TREE;
639 DECL_ORIGINAL_TYPE(TYPE_NAME(pt)) = copy;
640 }
7fc2f86b
ILT
641 return true;
642}
643
644// Set the real values for a placeholder function type.
645
646bool
647Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
648{
649 return this->set_placeholder_pointer_type(placeholder, ft);
650}
651
652// Create a placeholder for a struct type.
653
654Btype*
655Gcc_backend::placeholder_struct_type(const std::string& name,
8afa2bfb 656 Location location)
7fc2f86b
ILT
657{
658 tree ret = make_node(RECORD_TYPE);
7c0434e5
ILT
659 if (!name.empty())
660 {
661 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
662 get_identifier_from_string(name),
663 ret);
664 TYPE_NAME(ret) = decl;
665 }
6d69c02e
ILT
666 return this->make_type(ret);
667}
668
7fc2f86b
ILT
669// Fill in the fields of a placeholder struct type.
670
671bool
672Gcc_backend::set_placeholder_struct_type(
673 Btype* placeholder,
674 const std::vector<Btyped_identifier>& fields)
675{
676 tree t = placeholder->get_tree();
677 gcc_assert(TREE_CODE(t) == RECORD_TYPE && TYPE_FIELDS(t) == NULL_TREE);
678 Btype* r = this->fill_in_struct(placeholder, fields);
dcf30625 679
7c0434e5
ILT
680 if (TYPE_NAME(t) != NULL_TREE)
681 {
682 // Build the data structure gcc wants to see for a typedef.
683 tree copy = build_distinct_type_copy(t);
684 TYPE_NAME(copy) = NULL_TREE;
685 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
686 }
dcf30625 687
7fc2f86b
ILT
688 return r->get_tree() != error_mark_node;
689}
690
691// Create a placeholder for an array type.
692
693Btype*
694Gcc_backend::placeholder_array_type(const std::string& name,
8afa2bfb 695 Location location)
7fc2f86b
ILT
696{
697 tree ret = make_node(ARRAY_TYPE);
8afa2bfb 698 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
7fc2f86b
ILT
699 get_identifier_from_string(name),
700 ret);
701 TYPE_NAME(ret) = decl;
702 return this->make_type(ret);
703}
704
705// Fill in the fields of a placeholder array type.
706
707bool
708Gcc_backend::set_placeholder_array_type(Btype* placeholder,
709 Btype* element_btype,
710 Bexpression* length)
711{
712 tree t = placeholder->get_tree();
713 gcc_assert(TREE_CODE(t) == ARRAY_TYPE && TREE_TYPE(t) == NULL_TREE);
714 Btype* r = this->fill_in_array(placeholder, element_btype, length);
dcf30625
ILT
715
716 // Build the data structure gcc wants to see for a typedef.
11304b7b 717 tree copy = build_distinct_type_copy(t);
dcf30625
ILT
718 TYPE_NAME(copy) = NULL_TREE;
719 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
720
7fc2f86b
ILT
721 return r->get_tree() != error_mark_node;
722}
723
724// Return a named version of a type.
725
726Btype*
727Gcc_backend::named_type(const std::string& name, Btype* btype,
8afa2bfb 728 Location location)
7fc2f86b
ILT
729{
730 tree type = btype->get_tree();
731 if (type == error_mark_node)
732 return this->error_type();
11304b7b
ILT
733
734 // The middle-end expects a basic type to have a name. In Go every
735 // basic type will have a name. The first time we see a basic type,
736 // give it whatever Go name we have at this point.
737 if (TYPE_NAME(type) == NULL_TREE
738 && location.gcc_location() == BUILTINS_LOCATION
739 && (TREE_CODE(type) == INTEGER_TYPE
740 || TREE_CODE(type) == REAL_TYPE
741 || TREE_CODE(type) == COMPLEX_TYPE
742 || TREE_CODE(type) == BOOLEAN_TYPE))
743 {
744 tree decl = build_decl(BUILTINS_LOCATION, TYPE_DECL,
745 get_identifier_from_string(name),
746 type);
747 TYPE_NAME(type) = decl;
748 return this->make_type(type);
749 }
750
dcf30625 751 tree copy = build_variant_type_copy(type);
8afa2bfb 752 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
7fc2f86b 753 get_identifier_from_string(name),
dcf30625
ILT
754 copy);
755 DECL_ORIGINAL_TYPE(decl) = type;
756 TYPE_NAME(copy) = decl;
757 return this->make_type(copy);
7fc2f86b
ILT
758}
759
760// Return a pointer type used as a marker for a circular type.
761
762Btype*
763Gcc_backend::circular_pointer_type(Btype*, bool)
764{
765 return this->make_type(ptr_type_node);
766}
767
768// Return whether we might be looking at a circular type.
769
770bool
771Gcc_backend::is_circular_pointer_type(Btype* btype)
772{
773 return btype->get_tree() == ptr_type_node;
774}
775
ef1ed13d
ILT
776// Return the size of a type.
777
778size_t
779Gcc_backend::type_size(Btype* btype)
780{
08be22dc
ILT
781 tree t = btype->get_tree();
782 if (t == error_mark_node)
783 return 1;
784 t = TYPE_SIZE_UNIT(t);
ef1ed13d
ILT
785 gcc_assert(TREE_CODE(t) == INTEGER_CST);
786 gcc_assert(TREE_INT_CST_HIGH(t) == 0);
787 unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
788 size_t ret = static_cast<size_t>(val_wide);
789 gcc_assert(ret == val_wide);
790 return ret;
791}
792
793// Return the alignment of a type.
794
795size_t
796Gcc_backend::type_alignment(Btype* btype)
797{
08be22dc
ILT
798 tree t = btype->get_tree();
799 if (t == error_mark_node)
800 return 1;
801 return TYPE_ALIGN_UNIT(t);
ef1ed13d
ILT
802}
803
804// Return the alignment of a struct field of type BTYPE.
805
806size_t
807Gcc_backend::type_field_alignment(Btype* btype)
808{
08be22dc
ILT
809 tree t = btype->get_tree();
810 if (t == error_mark_node)
811 return 1;
812 return go_field_alignment(t);
ef1ed13d
ILT
813}
814
815// Return the offset of a field in a struct.
816
817size_t
818Gcc_backend::type_field_offset(Btype* btype, size_t index)
819{
820 tree struct_tree = btype->get_tree();
08be22dc
ILT
821 if (struct_tree == error_mark_node)
822 return 0;
ef1ed13d
ILT
823 gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
824 tree field = TYPE_FIELDS(struct_tree);
825 for (; index > 0; --index)
826 {
827 field = DECL_CHAIN(field);
828 gcc_assert(field != NULL_TREE);
829 }
830 HOST_WIDE_INT offset_wide = int_byte_position(field);
831 gcc_assert(offset_wide >= 0);
832 size_t ret = static_cast<size_t>(offset_wide);
833 gcc_assert(ret == static_cast<unsigned HOST_WIDE_INT>(offset_wide));
834 return ret;
835}
836
54466dde
ILT
837// Return the zero value for a type.
838
839Bexpression*
840Gcc_backend::zero_expression(Btype* btype)
841{
842 tree t = btype->get_tree();
843 tree ret;
844 if (t == error_mark_node)
845 ret = error_mark_node;
846 else
847 ret = build_zero_cst(t);
848 return tree_to_expr(ret);
849}
850
cfebcf30
ILT
851// An expression as a statement.
852
853Bstatement*
854Gcc_backend::expression_statement(Bexpression* expr)
855{
856 return this->make_statement(expr->get_tree());
857}
858
e09ce6c5
ILT
859// Variable initialization.
860
861Bstatement*
862Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
863{
864 tree var_tree = var->get_tree();
865 tree init_tree = init->get_tree();
866 if (var_tree == error_mark_node || init_tree == error_mark_node)
867 return this->error_statement();
868 gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
7d6be4c8
ILT
869
870 // To avoid problems with GNU ld, we don't make zero-sized
871 // externally visible variables. That might lead us to doing an
872 // initialization of a zero-sized expression to a non-zero sized
873 // variable, or vice-versa. Avoid crashes by omitting the
874 // initializer. Such initializations don't mean anything anyhow.
875 if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0
876 && init_tree != NULL_TREE
877 && int_size_in_bytes(TREE_TYPE(init_tree)) != 0)
878 {
879 DECL_INITIAL(var_tree) = init_tree;
880 init_tree = NULL_TREE;
881 }
882
883 tree ret = build1_loc(DECL_SOURCE_LOCATION(var_tree), DECL_EXPR,
884 void_type_node, var_tree);
885 if (init_tree != NULL_TREE)
886 ret = build2_loc(DECL_SOURCE_LOCATION(var_tree), COMPOUND_EXPR,
887 void_type_node, init_tree, ret);
888
889 return this->make_statement(ret);
e09ce6c5
ILT
890}
891
a9ac13f7
ILT
892// Assignment.
893
894Bstatement*
94039447 895Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
8afa2bfb 896 Location location)
a9ac13f7 897{
94039447
ILT
898 tree lhs_tree = lhs->get_tree();
899 tree rhs_tree = rhs->get_tree();
900 if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
00b44a6e 901 return this->error_statement();
7d6be4c8
ILT
902
903 // To avoid problems with GNU ld, we don't make zero-sized
904 // externally visible variables. That might lead us to doing an
905 // assignment of a zero-sized expression to a non-zero sized
906 // expression; avoid crashes here by avoiding assignments of
907 // zero-sized expressions. Such assignments don't really mean
908 // anything anyhow.
909 if (int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
910 || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
911 return this->compound_statement(this->expression_statement(lhs),
912 this->expression_statement(rhs));
913
68c5d97b
ILT
914 // Sometimes the same unnamed Go type can be created multiple times
915 // and thus have multiple tree representations. Make sure this does
916 // not confuse the middle-end.
917 if (TREE_TYPE(lhs_tree) != TREE_TYPE(rhs_tree))
918 {
919 tree lhs_type_tree = TREE_TYPE(lhs_tree);
920 gcc_assert(TREE_CODE(lhs_type_tree) == TREE_CODE(TREE_TYPE(rhs_tree)));
921 if (POINTER_TYPE_P(lhs_type_tree)
922 || INTEGRAL_TYPE_P(lhs_type_tree)
923 || SCALAR_FLOAT_TYPE_P(lhs_type_tree)
924 || COMPLEX_FLOAT_TYPE_P(lhs_type_tree))
925 rhs_tree = fold_convert_loc(location.gcc_location(), lhs_type_tree,
926 rhs_tree);
927 else if (TREE_CODE(lhs_type_tree) == RECORD_TYPE
928 || TREE_CODE(lhs_type_tree) == ARRAY_TYPE)
929 {
930 gcc_assert(int_size_in_bytes(lhs_type_tree)
931 == int_size_in_bytes(TREE_TYPE(rhs_tree)));
932 rhs_tree = fold_build1_loc(location.gcc_location(),
933 VIEW_CONVERT_EXPR,
934 lhs_type_tree, rhs_tree);
935 }
936 }
937
8afa2bfb
SD
938 return this->make_statement(fold_build2_loc(location.gcc_location(),
939 MODIFY_EXPR,
a9ac13f7 940 void_type_node,
94039447
ILT
941 lhs_tree, rhs_tree));
942}
943
944// Return.
945
946Bstatement*
947Gcc_backend::return_statement(Bfunction* bfunction,
948 const std::vector<Bexpression*>& vals,
8afa2bfb 949 Location location)
94039447
ILT
950{
951 tree fntree = bfunction->get_tree();
952 if (fntree == error_mark_node)
00b44a6e 953 return this->error_statement();
94039447
ILT
954 tree result = DECL_RESULT(fntree);
955 if (result == error_mark_node)
00b44a6e 956 return this->error_statement();
94039447
ILT
957 tree ret;
958 if (vals.empty())
8afa2bfb
SD
959 ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
960 NULL_TREE);
94039447
ILT
961 else if (vals.size() == 1)
962 {
963 tree val = vals.front()->get_tree();
964 if (val == error_mark_node)
00b44a6e 965 return this->error_statement();
8afa2bfb
SD
966 tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
967 void_type_node, result,
968 vals.front()->get_tree());
969 ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
970 void_type_node, set);
94039447
ILT
971 }
972 else
973 {
974 // To return multiple values, copy the values into a temporary
975 // variable of the right structure type, and then assign the
976 // temporary variable to the DECL_RESULT in the return
977 // statement.
978 tree stmt_list = NULL_TREE;
979 tree rettype = TREE_TYPE(result);
980 tree rettmp = create_tmp_var(rettype, "RESULT");
981 tree field = TYPE_FIELDS(rettype);
982 for (std::vector<Bexpression*>::const_iterator p = vals.begin();
983 p != vals.end();
984 p++, field = DECL_CHAIN(field))
985 {
986 gcc_assert(field != NULL_TREE);
8afa2bfb
SD
987 tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
988 TREE_TYPE(field), rettmp, field,
989 NULL_TREE);
94039447
ILT
990 tree val = (*p)->get_tree();
991 if (val == error_mark_node)
00b44a6e 992 return this->error_statement();
8afa2bfb
SD
993 tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
994 void_type_node,
94039447
ILT
995 ref, (*p)->get_tree());
996 append_to_statement_list(set, &stmt_list);
997 }
998 gcc_assert(field == NULL_TREE);
8afa2bfb
SD
999 tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
1000 void_type_node,
94039447 1001 result, rettmp);
8afa2bfb
SD
1002 tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
1003 void_type_node, set);
94039447
ILT
1004 append_to_statement_list(ret_expr, &stmt_list);
1005 ret = stmt_list;
1006 }
1007 return this->make_statement(ret);
a9ac13f7
ILT
1008}
1009
db0adf82
ILT
1010// If.
1011
1012Bstatement*
5ad7db5f 1013Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
8afa2bfb 1014 Bblock* else_block, Location location)
db0adf82
ILT
1015{
1016 tree cond_tree = condition->get_tree();
1017 tree then_tree = then_block->get_tree();
1018 tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
1019 if (cond_tree == error_mark_node
1020 || then_tree == error_mark_node
1021 || else_tree == error_mark_node)
00b44a6e 1022 return this->error_statement();
8afa2bfb
SD
1023 tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
1024 cond_tree, then_tree, else_tree);
db0adf82
ILT
1025 return this->make_statement(ret);
1026}
1027
8d0b03a2
ILT
1028// Switch.
1029
1030Bstatement*
1031Gcc_backend::switch_statement(
1032 Bexpression* value,
1033 const std::vector<std::vector<Bexpression*> >& cases,
1034 const std::vector<Bstatement*>& statements,
8afa2bfb 1035 Location switch_location)
8d0b03a2
ILT
1036{
1037 gcc_assert(cases.size() == statements.size());
1038
1039 tree stmt_list = NULL_TREE;
1040 std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
1041 for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
1042 ps != statements.end();
1043 ++ps, ++pc)
1044 {
1045 if (pc->empty())
1046 {
1047 source_location loc = (*ps != NULL
8afa2bfb
SD
1048 ? EXPR_LOCATION((*ps)->get_tree())
1049 : UNKNOWN_LOCATION);
8d0b03a2 1050 tree label = create_artificial_label(loc);
3d528853 1051 tree c = build_case_label(NULL_TREE, NULL_TREE, label);
8d0b03a2
ILT
1052 append_to_statement_list(c, &stmt_list);
1053 }
1054 else
1055 {
1056 for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
1057 pcv != pc->end();
1058 ++pcv)
1059 {
1060 tree t = (*pcv)->get_tree();
1061 if (t == error_mark_node)
00b44a6e 1062 return this->error_statement();
8d0b03a2
ILT
1063 source_location loc = EXPR_LOCATION(t);
1064 tree label = create_artificial_label(loc);
3d528853 1065 tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
8d0b03a2
ILT
1066 append_to_statement_list(c, &stmt_list);
1067 }
1068 }
1069
1070 if (*ps != NULL)
1071 {
1072 tree t = (*ps)->get_tree();
1073 if (t == error_mark_node)
00b44a6e 1074 return this->error_statement();
8d0b03a2
ILT
1075 append_to_statement_list(t, &stmt_list);
1076 }
1077 }
1078
1079 tree tv = value->get_tree();
1080 if (tv == error_mark_node)
00b44a6e 1081 return this->error_statement();
8afa2bfb 1082 tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR,
0cd2402d 1083 NULL_TREE, tv, stmt_list, NULL_TREE);
8d0b03a2
ILT
1084 return this->make_statement(t);
1085}
1086
00b44a6e
ILT
1087// Pair of statements.
1088
1089Bstatement*
1090Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
1091{
1092 tree stmt_list = NULL_TREE;
1093 tree t = s1->get_tree();
1094 if (t == error_mark_node)
1095 return this->error_statement();
1096 append_to_statement_list(t, &stmt_list);
1097 t = s2->get_tree();
1098 if (t == error_mark_node)
1099 return this->error_statement();
1100 append_to_statement_list(t, &stmt_list);
1101 return this->make_statement(stmt_list);
1102}
1103
8d0b03a2
ILT
1104// List of statements.
1105
1106Bstatement*
1107Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
1108{
1109 tree stmt_list = NULL_TREE;
1110 for (std::vector<Bstatement*>::const_iterator p = statements.begin();
1111 p != statements.end();
1112 ++p)
1113 {
1114 tree t = (*p)->get_tree();
1115 if (t == error_mark_node)
00b44a6e 1116 return this->error_statement();
8d0b03a2
ILT
1117 append_to_statement_list(t, &stmt_list);
1118 }
1119 return this->make_statement(stmt_list);
1120}
1121
5ad7db5f
ILT
1122// Make a block. For some reason gcc uses a dual structure for
1123// blocks: BLOCK tree nodes and BIND_EXPR tree nodes. Since the
1124// BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
1125// the Bblock.
1126
1127Bblock*
1128Gcc_backend::block(Bfunction* function, Bblock* enclosing,
1129 const std::vector<Bvariable*>& vars,
8afa2bfb
SD
1130 Location start_location,
1131 Location)
5ad7db5f
ILT
1132{
1133 tree block_tree = make_node(BLOCK);
1134 if (enclosing == NULL)
1135 {
1136 // FIXME: Permitting FUNCTION to be NULL is a temporary measure
1137 // until we have a proper representation of the init function.
1138 tree fndecl;
1139 if (function == NULL)
1140 fndecl = current_function_decl;
1141 else
1142 fndecl = function->get_tree();
1143 gcc_assert(fndecl != NULL_TREE);
1144
1145 // We may have already created a block for local variables when
1146 // we take the address of a parameter.
1147 if (DECL_INITIAL(fndecl) == NULL_TREE)
1148 {
1149 BLOCK_SUPERCONTEXT(block_tree) = fndecl;
1150 DECL_INITIAL(fndecl) = block_tree;
1151 }
1152 else
1153 {
1154 tree superblock_tree = DECL_INITIAL(fndecl);
1155 BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
1156 tree* pp;
1157 for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
1158 *pp != NULL_TREE;
1159 pp = &BLOCK_CHAIN(*pp))
1160 ;
1161 *pp = block_tree;
1162 }
1163 }
1164 else
1165 {
1166 tree superbind_tree = enclosing->get_tree();
1167 tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
1168 gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
1169
1170 BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
1171 tree* pp;
1172 for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
1173 *pp != NULL_TREE;
1174 pp = &BLOCK_CHAIN(*pp))
1175 ;
1176 *pp = block_tree;
1177 }
1178
1179 tree* pp = &BLOCK_VARS(block_tree);
1180 for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
1181 pv != vars.end();
1182 ++pv)
1183 {
1184 *pp = (*pv)->get_tree();
1185 if (*pp != error_mark_node)
1186 pp = &DECL_CHAIN(*pp);
1187 }
1188 *pp = NULL_TREE;
1189
1190 TREE_USED(block_tree) = 1;
1191
8afa2bfb
SD
1192 tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
1193 void_type_node, BLOCK_VARS(block_tree),
1194 NULL_TREE, block_tree);
5ad7db5f
ILT
1195 TREE_SIDE_EFFECTS(bind_tree) = 1;
1196
1197 return new Bblock(bind_tree);
1198}
1199
1200// Add statements to a block.
1201
1202void
1203Gcc_backend::block_add_statements(Bblock* bblock,
1204 const std::vector<Bstatement*>& statements)
1205{
1206 tree stmt_list = NULL_TREE;
1207 for (std::vector<Bstatement*>::const_iterator p = statements.begin();
1208 p != statements.end();
1209 ++p)
1210 {
1211 tree s = (*p)->get_tree();
1212 if (s != error_mark_node)
1213 append_to_statement_list(s, &stmt_list);
1214 }
1215
1216 tree bind_tree = bblock->get_tree();
1217 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1218 BIND_EXPR_BODY(bind_tree) = stmt_list;
1219}
1220
1221// Return a block as a statement.
1222
1223Bstatement*
1224Gcc_backend::block_statement(Bblock* bblock)
1225{
1226 tree bind_tree = bblock->get_tree();
1227 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1228 return this->make_statement(bind_tree);
1229}
1230
7d6be4c8
ILT
1231// This is not static because we declare it with GTY(()) in go-c.h.
1232tree go_non_zero_struct;
1233
1234// Return a type corresponding to TYPE with non-zero size.
1235
1236tree
1237Gcc_backend::non_zero_size_type(tree type)
1238{
1239 if (int_size_in_bytes(type) != 0)
1240 return type;
1241
1242 switch (TREE_CODE(type))
1243 {
1244 case RECORD_TYPE:
f1e18725
ILT
1245 if (TYPE_FIELDS(type) != NULL_TREE)
1246 {
1247 tree ns = make_node(RECORD_TYPE);
1248 tree field_trees = NULL_TREE;
1249 tree *pp = &field_trees;
1250 for (tree field = TYPE_FIELDS(type);
1251 field != NULL_TREE;
1252 field = DECL_CHAIN(field))
1253 {
1254 tree ft = TREE_TYPE(field);
1255 if (field == TYPE_FIELDS(type))
1256 ft = non_zero_size_type(ft);
1257 tree f = build_decl(DECL_SOURCE_LOCATION(field), FIELD_DECL,
1258 DECL_NAME(field), ft);
1259 DECL_CONTEXT(f) = ns;
1260 *pp = f;
1261 pp = &DECL_CHAIN(f);
1262 }
1263 TYPE_FIELDS(ns) = field_trees;
1264 layout_type(ns);
1265 return ns;
1266 }
1267
1268 if (go_non_zero_struct == NULL_TREE)
1269 {
1270 type = make_node(RECORD_TYPE);
1271 tree field = build_decl(UNKNOWN_LOCATION, FIELD_DECL,
1272 get_identifier("dummy"),
1273 boolean_type_node);
1274 DECL_CONTEXT(field) = type;
1275 TYPE_FIELDS(type) = field;
1276 layout_type(type);
1277 go_non_zero_struct = type;
1278 }
1279 return go_non_zero_struct;
7d6be4c8
ILT
1280
1281 case ARRAY_TYPE:
1282 {
1283 tree element_type = non_zero_size_type(TREE_TYPE(type));
1284 return build_array_type_nelts(element_type, 1);
1285 }
1286
1287 default:
1288 gcc_unreachable();
1289 }
1290
1291 gcc_unreachable();
1292}
1293
e09ce6c5
ILT
1294// Make a global variable.
1295
1296Bvariable*
1297Gcc_backend::global_variable(const std::string& package_name,
097b12fb 1298 const std::string& pkgpath,
e09ce6c5
ILT
1299 const std::string& name,
1300 Btype* btype,
1301 bool is_external,
1302 bool is_hidden,
744c3195 1303 bool in_unique_section,
8afa2bfb 1304 Location location)
e09ce6c5
ILT
1305{
1306 tree type_tree = btype->get_tree();
1307 if (type_tree == error_mark_node)
1308 return this->error_variable();
1309
7d6be4c8
ILT
1310 // The GNU linker does not like dynamic variables with zero size.
1311 if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
1312 type_tree = this->non_zero_size_type(type_tree);
1313
e09ce6c5
ILT
1314 std::string var_name(package_name);
1315 var_name.push_back('.');
1316 var_name.append(name);
8afa2bfb 1317 tree decl = build_decl(location.gcc_location(), VAR_DECL,
e09ce6c5
ILT
1318 get_identifier_from_string(var_name),
1319 type_tree);
1320 if (is_external)
1321 DECL_EXTERNAL(decl) = 1;
1322 else
1323 TREE_STATIC(decl) = 1;
1324 if (!is_hidden)
1325 {
1326 TREE_PUBLIC(decl) = 1;
1327
097b12fb 1328 std::string asm_name(pkgpath);
e09ce6c5 1329 asm_name.push_back('.');
097b12fb 1330 asm_name.append(name);
e09ce6c5
ILT
1331 SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
1332 }
1333 TREE_USED(decl) = 1;
1334
744c3195
ILT
1335 if (in_unique_section)
1336 resolve_unique_section (decl, 0, 1);
1337
e09ce6c5
ILT
1338 go_preserve_from_gc(decl);
1339
1340 return new Bvariable(decl);
1341}
1342
1343// Set the initial value of a global variable.
1344
1345void
1346Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
1347{
1348 tree expr_tree = expr->get_tree();
1349 if (expr_tree == error_mark_node)
1350 return;
1351 gcc_assert(TREE_CONSTANT(expr_tree));
1352 tree var_decl = var->get_tree();
1353 if (var_decl == error_mark_node)
1354 return;
1355 DECL_INITIAL(var_decl) = expr_tree;
744c3195
ILT
1356
1357 // If this variable goes in a unique section, it may need to go into
1358 // a different one now that DECL_INITIAL is set.
1359 if (DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl))
1360 {
1361 DECL_SECTION_NAME (var_decl) = NULL_TREE;
1362 resolve_unique_section (var_decl,
1363 compute_reloc_for_constant (expr_tree),
1364 1);
1365 }
e09ce6c5
ILT
1366}
1367
1368// Make a local variable.
1369
1370Bvariable*
1371Gcc_backend::local_variable(Bfunction* function, const std::string& name,
acf98146 1372 Btype* btype, bool is_address_taken,
8afa2bfb 1373 Location location)
e09ce6c5
ILT
1374{
1375 tree type_tree = btype->get_tree();
1376 if (type_tree == error_mark_node)
1377 return this->error_variable();
8afa2bfb 1378 tree decl = build_decl(location.gcc_location(), VAR_DECL,
e09ce6c5
ILT
1379 get_identifier_from_string(name),
1380 type_tree);
1381 DECL_CONTEXT(decl) = function->get_tree();
1382 TREE_USED(decl) = 1;
acf98146
ILT
1383 if (is_address_taken)
1384 TREE_ADDRESSABLE(decl) = 1;
e09ce6c5
ILT
1385 go_preserve_from_gc(decl);
1386 return new Bvariable(decl);
1387}
1388
1389// Make a function parameter variable.
1390
1391Bvariable*
1392Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
acf98146 1393 Btype* btype, bool is_address_taken,
8afa2bfb 1394 Location location)
e09ce6c5
ILT
1395{
1396 tree type_tree = btype->get_tree();
1397 if (type_tree == error_mark_node)
1398 return this->error_variable();
8afa2bfb 1399 tree decl = build_decl(location.gcc_location(), PARM_DECL,
e09ce6c5
ILT
1400 get_identifier_from_string(name),
1401 type_tree);
1402 DECL_CONTEXT(decl) = function->get_tree();
1403 DECL_ARG_TYPE(decl) = type_tree;
1404 TREE_USED(decl) = 1;
acf98146
ILT
1405 if (is_address_taken)
1406 TREE_ADDRESSABLE(decl) = 1;
e09ce6c5
ILT
1407 go_preserve_from_gc(decl);
1408 return new Bvariable(decl);
1409}
1410
9131ad67
ILT
1411// Make a temporary variable.
1412
1413Bvariable*
1414Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
1415 Btype* btype, Bexpression* binit,
1416 bool is_address_taken,
8afa2bfb 1417 Location location,
9131ad67
ILT
1418 Bstatement** pstatement)
1419{
1420 tree type_tree = btype->get_tree();
1421 tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
1422 if (type_tree == error_mark_node || init_tree == error_mark_node)
1423 {
1424 *pstatement = this->error_statement();
1425 return this->error_variable();
1426 }
1427
1428 tree var;
1429 // We can only use create_tmp_var if the type is not addressable.
1430 if (!TREE_ADDRESSABLE(type_tree))
1431 var = create_tmp_var(type_tree, "GOTMP");
1432 else
1433 {
1434 gcc_assert(bblock != NULL);
8afa2bfb 1435 var = build_decl(location.gcc_location(), VAR_DECL,
9131ad67
ILT
1436 create_tmp_var_name("GOTMP"),
1437 type_tree);
1438 DECL_ARTIFICIAL(var) = 1;
1439 DECL_IGNORED_P(var) = 1;
1440 TREE_USED(var) = 1;
1441 // FIXME: Permitting function to be NULL here is a temporary
1442 // measure until we have a proper representation of the init
1443 // function.
1444 if (function != NULL)
1445 DECL_CONTEXT(var) = function->get_tree();
1446 else
1447 {
1448 gcc_assert(current_function_decl != NULL_TREE);
1449 DECL_CONTEXT(var) = current_function_decl;
1450 }
1451
1452 // We have to add this variable to the BLOCK and the BIND_EXPR.
1453 tree bind_tree = bblock->get_tree();
1454 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1455 tree block_tree = BIND_EXPR_BLOCK(bind_tree);
1456 gcc_assert(TREE_CODE(block_tree) == BLOCK);
1457 DECL_CHAIN(var) = BLOCK_VARS(block_tree);
1458 BLOCK_VARS(block_tree) = var;
1459 BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
1460 }
1461
1462 if (init_tree != NULL_TREE)
8afa2bfb
SD
1463 DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree,
1464 init_tree);
9131ad67
ILT
1465
1466 if (is_address_taken)
1467 TREE_ADDRESSABLE(var) = 1;
1468
8afa2bfb
SD
1469 *pstatement = this->make_statement(build1_loc(location.gcc_location(),
1470 DECL_EXPR,
9131ad67
ILT
1471 void_type_node, var));
1472 return new Bvariable(var);
1473}
1474
70f91024
ILT
1475// Create a named immutable initialized data structure.
1476
1477Bvariable*
fdbc38a6
ILT
1478Gcc_backend::immutable_struct(const std::string& name, bool, bool,
1479 Btype* btype, Location location)
70f91024
ILT
1480{
1481 tree type_tree = btype->get_tree();
1482 if (type_tree == error_mark_node)
1483 return this->error_variable();
1484 gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
8afa2bfb 1485 tree decl = build_decl(location.gcc_location(), VAR_DECL,
70f91024
ILT
1486 get_identifier_from_string(name),
1487 build_qualified_type(type_tree, TYPE_QUAL_CONST));
1488 TREE_STATIC(decl) = 1;
1489 TREE_READONLY(decl) = 1;
1490 TREE_CONSTANT(decl) = 1;
1491 TREE_USED(decl) = 1;
1492 DECL_ARTIFICIAL(decl) = 1;
1493
1494 // We don't call rest_of_decl_compilation until we have the
1495 // initializer.
1496
1497 go_preserve_from_gc(decl);
1498 return new Bvariable(decl);
1499}
1500
1501// Set the initializer for a variable created by immutable_struct.
1502// This is where we finish compiling the variable.
1503
1504void
1505Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
fdbc38a6 1506 bool is_hidden, bool is_common, Btype*,
8afa2bfb 1507 Location,
70f91024
ILT
1508 Bexpression* initializer)
1509{
1510 tree decl = var->get_tree();
1511 tree init_tree = initializer->get_tree();
1512 if (decl == error_mark_node || init_tree == error_mark_node)
1513 return;
1514
1515 DECL_INITIAL(decl) = init_tree;
1516
1517 // We can't call make_decl_one_only until we set DECL_INITIAL.
1518 if (!is_common)
fdbc38a6
ILT
1519 {
1520 if (!is_hidden)
1521 TREE_PUBLIC(decl) = 1;
1522 }
70f91024 1523 else
a572c454
ILT
1524 make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
1525
1526 // These variables are often unneeded in the final program, so put
1527 // them in their own section so that linker GC can discard them.
1528 resolve_unique_section(decl, 1, 1);
70f91024
ILT
1529
1530 rest_of_decl_compilation(decl, 1, 0);
1531}
1532
1533// Return a reference to an immutable initialized data structure
1534// defined in another package.
1535
1536Bvariable*
1537Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
8afa2bfb 1538 Location location)
70f91024
ILT
1539{
1540 tree type_tree = btype->get_tree();
1541 if (type_tree == error_mark_node)
1542 return this->error_variable();
1543 gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
8afa2bfb 1544 tree decl = build_decl(location.gcc_location(), VAR_DECL,
70f91024
ILT
1545 get_identifier_from_string(name),
1546 build_qualified_type(type_tree, TYPE_QUAL_CONST));
1547 TREE_READONLY(decl) = 1;
1548 TREE_CONSTANT(decl) = 1;
1549 DECL_ARTIFICIAL(decl) = 1;
1550 TREE_PUBLIC(decl) = 1;
1551 DECL_EXTERNAL(decl) = 1;
1552 go_preserve_from_gc(decl);
1553 return new Bvariable(decl);
1554}
1555
d56e6679
ILT
1556// Make a label.
1557
1558Blabel*
1559Gcc_backend::label(Bfunction* function, const std::string& name,
8afa2bfb 1560 Location location)
d56e6679
ILT
1561{
1562 tree decl;
1563 if (name.empty())
8afa2bfb 1564 decl = create_artificial_label(location.gcc_location());
d56e6679
ILT
1565 else
1566 {
1567 tree id = get_identifier_from_string(name);
8afa2bfb
SD
1568 decl = build_decl(location.gcc_location(), LABEL_DECL, id,
1569 void_type_node);
d56e6679
ILT
1570 DECL_CONTEXT(decl) = function->get_tree();
1571 }
1572 return new Blabel(decl);
1573}
1574
1575// Make a statement which defines a label.
1576
1577Bstatement*
1578Gcc_backend::label_definition_statement(Blabel* label)
1579{
1580 tree lab = label->get_tree();
1581 tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
1582 void_type_node, lab);
1583 return this->make_statement(ret);
1584}
1585
1586// Make a goto statement.
1587
1588Bstatement*
8afa2bfb 1589Gcc_backend::goto_statement(Blabel* label, Location location)
d56e6679
ILT
1590{
1591 tree lab = label->get_tree();
8afa2bfb
SD
1592 tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
1593 lab);
d56e6679
ILT
1594 return this->make_statement(ret);
1595}
1596
1597// Get the address of a label.
1598
1599Bexpression*
8afa2bfb 1600Gcc_backend::label_address(Blabel* label, Location location)
d56e6679
ILT
1601{
1602 tree lab = label->get_tree();
1603 TREE_USED(lab) = 1;
1604 TREE_ADDRESSABLE(lab) = 1;
8afa2bfb
SD
1605 tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
1606 build_fold_addr_expr_loc(location.gcc_location(),
1607 lab));
d56e6679
ILT
1608 return this->make_expression(ret);
1609}
1610
a9ac13f7
ILT
1611// The single backend.
1612
1613static Gcc_backend gcc_backend;
1614
1615// Return the backend generator.
1616
1617Backend*
1618go_get_backend()
1619{
1620 return &gcc_backend;
1621}
1622
1623// FIXME: Temporary functions while converting to the new backend
1624// interface.
1625
e09ce6c5
ILT
1626Btype*
1627tree_to_type(tree t)
1628{
1629 return new Btype(t);
1630}
1631
a9ac13f7
ILT
1632Bexpression*
1633tree_to_expr(tree t)
1634{
1635 return new Bexpression(t);
1636}
1637
db0adf82
ILT
1638Bstatement*
1639tree_to_stat(tree t)
1640{
1641 return new Bstatement(t);
1642}
1643
94039447
ILT
1644Bfunction*
1645tree_to_function(tree t)
1646{
1647 return new Bfunction(t);
1648}
1649
5ad7db5f
ILT
1650Bblock*
1651tree_to_block(tree t)
1652{
1653 gcc_assert(TREE_CODE(t) == BIND_EXPR);
1654 return new Bblock(t);
1655}
1656
0aa5e7f2
ES
1657tree
1658type_to_tree(Btype* bt)
1659{
1660 return bt->get_tree();
1661}
1662
d56e6679 1663tree
db0adf82 1664expr_to_tree(Bexpression* be)
d56e6679
ILT
1665{
1666 return be->get_tree();
1667}
1668
a9ac13f7 1669tree
db0adf82 1670stat_to_tree(Bstatement* bs)
a9ac13f7
ILT
1671{
1672 return bs->get_tree();
1673}
e09ce6c5 1674
5ad7db5f
ILT
1675tree
1676block_to_tree(Bblock* bb)
1677{
1678 return bb->get_tree();
1679}
1680
e09ce6c5
ILT
1681tree
1682var_to_tree(Bvariable* bv)
1683{
1684 return bv->get_tree();
1685}