Use backend interface for function types.
[official-gcc.git] / gcc / go / go-gcc.cc
blobd250646ecda24e2772810c28bebc9b73bafd1597
1 // go-gcc.cc -- Go frontend to gcc IR.
2 // Copyright (C) 2011 Free Software Foundation, Inc.
3 // Contributed by Ian Lance Taylor, Google.
5 // This file is part of GCC.
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.
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.
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/>.
21 #include "go-system.h"
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>
27 #ifndef ENABLE_BUILD_WITH_CXX
28 extern "C"
30 #endif
32 #include "tree.h"
33 #include "tree-iterator.h"
34 #include "gimple.h"
36 #ifndef ENABLE_BUILD_WITH_CXX
38 #endif
40 #include "go-c.h"
42 #include "gogo.h"
43 #include "backend.h"
45 // A class wrapping a tree.
47 class Gcc_tree
49 public:
50 Gcc_tree(tree t)
51 : t_(t)
52 { }
54 tree
55 get_tree() const
56 { return this->t_; }
58 private:
59 tree t_;
62 // In gcc, types, expressions, and statements are all trees.
63 class Btype : public Gcc_tree
65 public:
66 Btype(tree t)
67 : Gcc_tree(t)
68 { }
71 class Bexpression : public Gcc_tree
73 public:
74 Bexpression(tree t)
75 : Gcc_tree(t)
76 { }
79 class Bstatement : public Gcc_tree
81 public:
82 Bstatement(tree t)
83 : Gcc_tree(t)
84 { }
87 class Bfunction : public Gcc_tree
89 public:
90 Bfunction(tree t)
91 : Gcc_tree(t)
92 { }
95 class Bblock : public Gcc_tree
97 public:
98 Bblock(tree t)
99 : Gcc_tree(t)
103 class Bvariable : public Gcc_tree
105 public:
106 Bvariable(tree t)
107 : Gcc_tree(t)
111 class Blabel : public Gcc_tree
113 public:
114 Blabel(tree t)
115 : Gcc_tree(t)
119 // This file implements the interface between the Go frontend proper
120 // and the gcc IR. This implements specific instantiations of
121 // abstract classes defined by the Go frontend proper. The Go
122 // frontend proper class methods of these classes to generate the
123 // backend representation.
125 class Gcc_backend : public Backend
127 public:
128 // Types.
130 Btype*
131 error_type()
132 { return this->make_type(error_mark_node); }
134 Btype*
135 void_type()
136 { return this->make_type(void_type_node); }
138 Btype*
139 bool_type()
140 { return this->make_type(boolean_type_node); }
142 Btype*
143 integer_type(bool, int);
145 Btype*
146 float_type(int);
148 Btype*
149 complex_type(int);
151 Btype*
152 pointer_type(Btype*);
154 Btype*
155 function_type(const Btyped_identifier&,
156 const std::vector<Btyped_identifier>&,
157 const std::vector<Btyped_identifier>&,
158 source_location);
160 Btype*
161 struct_type(const std::vector<Btyped_identifier>&)
162 { gcc_unreachable(); }
164 Btype*
165 array_type(const Btype* /* element_type */, const Bexpression* /* length */)
166 { gcc_unreachable(); }
168 // Statements.
170 Bstatement*
171 error_statement()
172 { return this->make_statement(error_mark_node); }
174 Bstatement*
175 expression_statement(Bexpression*);
177 Bstatement*
178 init_statement(Bvariable* var, Bexpression* init);
180 Bstatement*
181 assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location);
183 Bstatement*
184 return_statement(Bfunction*, const std::vector<Bexpression*>&,
185 source_location);
187 Bstatement*
188 if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
189 source_location);
191 Bstatement*
192 switch_statement(Bexpression* value,
193 const std::vector<std::vector<Bexpression*> >& cases,
194 const std::vector<Bstatement*>& statements,
195 source_location);
197 Bstatement*
198 compound_statement(Bstatement*, Bstatement*);
200 Bstatement*
201 statement_list(const std::vector<Bstatement*>&);
203 // Blocks.
205 Bblock*
206 block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
207 source_location, source_location);
209 void
210 block_add_statements(Bblock*, const std::vector<Bstatement*>&);
212 Bstatement*
213 block_statement(Bblock*);
215 // Variables.
217 Bvariable*
218 error_variable()
219 { return new Bvariable(error_mark_node); }
221 Bvariable*
222 global_variable(const std::string& package_name,
223 const std::string& unique_prefix,
224 const std::string& name,
225 Btype* btype,
226 bool is_external,
227 bool is_hidden,
228 source_location location);
230 void
231 global_variable_set_init(Bvariable*, Bexpression*);
233 Bvariable*
234 local_variable(Bfunction*, const std::string& name, Btype* type,
235 source_location);
237 Bvariable*
238 parameter_variable(Bfunction*, const std::string& name, Btype* type,
239 source_location);
241 Bvariable*
242 temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
243 source_location, Bstatement**);
245 // Labels.
247 Blabel*
248 label(Bfunction*, const std::string& name, source_location);
250 Bstatement*
251 label_definition_statement(Blabel*);
253 Bstatement*
254 goto_statement(Blabel*, source_location);
256 Bexpression*
257 label_address(Blabel*, source_location);
259 private:
260 // Make a Bexpression from a tree.
261 Bexpression*
262 make_expression(tree t)
263 { return new Bexpression(t); }
265 // Make a Bstatement from a tree.
266 Bstatement*
267 make_statement(tree t)
268 { return new Bstatement(t); }
270 // Make a Btype from a tree.
271 Btype*
272 make_type(tree t)
273 { return new Btype(t); }
276 // A helper function.
278 static inline tree
279 get_identifier_from_string(const std::string& str)
281 return get_identifier_with_length(str.data(), str.length());
284 // Get an unnamed integer type.
286 Btype*
287 Gcc_backend::integer_type(bool is_unsigned, int bits)
289 tree type;
290 if (is_unsigned)
292 if (bits == INT_TYPE_SIZE)
293 type = unsigned_type_node;
294 else if (bits == CHAR_TYPE_SIZE)
295 type = unsigned_char_type_node;
296 else if (bits == SHORT_TYPE_SIZE)
297 type = short_unsigned_type_node;
298 else if (bits == LONG_TYPE_SIZE)
299 type = long_unsigned_type_node;
300 else if (bits == LONG_LONG_TYPE_SIZE)
301 type = long_long_unsigned_type_node;
302 else
303 type = make_unsigned_type(bits);
305 else
307 if (bits == INT_TYPE_SIZE)
308 type = integer_type_node;
309 else if (bits == CHAR_TYPE_SIZE)
310 type = signed_char_type_node;
311 else if (bits == SHORT_TYPE_SIZE)
312 type = short_integer_type_node;
313 else if (bits == LONG_TYPE_SIZE)
314 type = long_integer_type_node;
315 else if (bits == LONG_LONG_TYPE_SIZE)
316 type = long_long_integer_type_node;
317 else
318 type = make_signed_type(bits);
320 return this->make_type(type);
323 // Get an unnamed float type.
325 Btype*
326 Gcc_backend::float_type(int bits)
328 tree type;
329 if (bits == FLOAT_TYPE_SIZE)
330 type = float_type_node;
331 else if (bits == DOUBLE_TYPE_SIZE)
332 type = double_type_node;
333 else if (bits == LONG_DOUBLE_TYPE_SIZE)
334 type = long_double_type_node;
335 else
337 type = make_node(REAL_TYPE);
338 TYPE_PRECISION(type) = bits;
339 layout_type(type);
341 return this->make_type(type);
344 // Get an unnamed complex type.
346 Btype*
347 Gcc_backend::complex_type(int bits)
349 tree type;
350 if (bits == FLOAT_TYPE_SIZE * 2)
351 type = complex_float_type_node;
352 else if (bits == DOUBLE_TYPE_SIZE * 2)
353 type = complex_double_type_node;
354 else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
355 type = complex_long_double_type_node;
356 else
358 type = make_node(REAL_TYPE);
359 TYPE_PRECISION(type) = bits / 2;
360 layout_type(type);
361 type = build_complex_type(type);
363 return this->make_type(type);
366 // Get a pointer type.
368 Btype*
369 Gcc_backend::pointer_type(Btype* to_type)
371 tree to_type_tree = to_type->get_tree();
372 if (to_type_tree == error_mark_node)
373 return this->error_type();
374 tree type = build_pointer_type(to_type_tree);
375 return this->make_type(type);
378 // Make a function type.
380 Btype*
381 Gcc_backend::function_type(const Btyped_identifier& receiver,
382 const std::vector<Btyped_identifier>& parameters,
383 const std::vector<Btyped_identifier>& results,
384 source_location location)
386 tree args = NULL_TREE;
387 tree* pp = &args;
388 if (receiver.btype != NULL)
390 tree t = receiver.btype->get_tree();
391 if (t == error_mark_node)
392 return this->error_type();
393 *pp = tree_cons(NULL_TREE, t, NULL_TREE);
394 pp = &TREE_CHAIN(*pp);
397 for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
398 p != parameters.end();
399 ++p)
401 tree t = p->btype->get_tree();
402 if (t == error_mark_node)
403 return this->error_type();
404 *pp = tree_cons(NULL_TREE, t, NULL_TREE);
405 pp = &TREE_CHAIN(*pp);
408 // Varargs is handled entirely at the Go level. When converted to
409 // GENERIC functions are not varargs.
410 *pp = void_list_node;
412 tree result;
413 if (results.empty())
414 result = void_type_node;
415 else if (results.size() == 1)
416 result = results.front().btype->get_tree();
417 else
419 result = make_node(RECORD_TYPE);
420 tree field_trees = NULL_TREE;
421 pp = &field_trees;
422 for (std::vector<Btyped_identifier>::const_iterator p = results.begin();
423 p != results.end();
424 ++p)
426 const std::string name = (p->name.empty()
427 ? "UNNAMED"
428 : p->name);
429 tree name_tree = get_identifier_from_string(name);
430 tree field_type_tree = p->btype->get_tree();
431 if (field_type_tree == error_mark_node)
432 return this->error_type();
433 tree field = build_decl(location, FIELD_DECL, name_tree,
434 field_type_tree);
435 DECL_CONTEXT(field) = result;
436 *pp = field;
437 pp = &DECL_CHAIN(field);
439 TYPE_FIELDS(result) = field_trees;
440 layout_type(result);
442 if (result == error_mark_node)
443 return this->error_type();
445 tree fntype = build_function_type(result, args);
446 if (fntype == error_mark_node)
447 return this->error_type();
449 return this->make_type(build_pointer_type(fntype));
452 // An expression as a statement.
454 Bstatement*
455 Gcc_backend::expression_statement(Bexpression* expr)
457 return this->make_statement(expr->get_tree());
460 // Variable initialization.
462 Bstatement*
463 Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
465 tree var_tree = var->get_tree();
466 tree init_tree = init->get_tree();
467 if (var_tree == error_mark_node || init_tree == error_mark_node)
468 return this->error_statement();
469 gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
470 DECL_INITIAL(var_tree) = init_tree;
471 return this->make_statement(build1_loc(DECL_SOURCE_LOCATION(var_tree),
472 DECL_EXPR, void_type_node, var_tree));
475 // Assignment.
477 Bstatement*
478 Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
479 source_location location)
481 tree lhs_tree = lhs->get_tree();
482 tree rhs_tree = rhs->get_tree();
483 if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
484 return this->error_statement();
485 return this->make_statement(fold_build2_loc(location, MODIFY_EXPR,
486 void_type_node,
487 lhs_tree, rhs_tree));
490 // Return.
492 Bstatement*
493 Gcc_backend::return_statement(Bfunction* bfunction,
494 const std::vector<Bexpression*>& vals,
495 source_location location)
497 tree fntree = bfunction->get_tree();
498 if (fntree == error_mark_node)
499 return this->error_statement();
500 tree result = DECL_RESULT(fntree);
501 if (result == error_mark_node)
502 return this->error_statement();
503 tree ret;
504 if (vals.empty())
505 ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, NULL_TREE);
506 else if (vals.size() == 1)
508 tree val = vals.front()->get_tree();
509 if (val == error_mark_node)
510 return this->error_statement();
511 tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
512 result, vals.front()->get_tree());
513 ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, set);
515 else
517 // To return multiple values, copy the values into a temporary
518 // variable of the right structure type, and then assign the
519 // temporary variable to the DECL_RESULT in the return
520 // statement.
521 tree stmt_list = NULL_TREE;
522 tree rettype = TREE_TYPE(result);
523 tree rettmp = create_tmp_var(rettype, "RESULT");
524 tree field = TYPE_FIELDS(rettype);
525 for (std::vector<Bexpression*>::const_iterator p = vals.begin();
526 p != vals.end();
527 p++, field = DECL_CHAIN(field))
529 gcc_assert(field != NULL_TREE);
530 tree ref = fold_build3_loc(location, COMPONENT_REF, TREE_TYPE(field),
531 rettmp, field, NULL_TREE);
532 tree val = (*p)->get_tree();
533 if (val == error_mark_node)
534 return this->error_statement();
535 tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
536 ref, (*p)->get_tree());
537 append_to_statement_list(set, &stmt_list);
539 gcc_assert(field == NULL_TREE);
540 tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
541 result, rettmp);
542 tree ret_expr = fold_build1_loc(location, RETURN_EXPR, void_type_node,
543 set);
544 append_to_statement_list(ret_expr, &stmt_list);
545 ret = stmt_list;
547 return this->make_statement(ret);
550 // If.
552 Bstatement*
553 Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
554 Bblock* else_block, source_location location)
556 tree cond_tree = condition->get_tree();
557 tree then_tree = then_block->get_tree();
558 tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
559 if (cond_tree == error_mark_node
560 || then_tree == error_mark_node
561 || else_tree == error_mark_node)
562 return this->error_statement();
563 tree ret = build3_loc(location, COND_EXPR, void_type_node, cond_tree,
564 then_tree, else_tree);
565 return this->make_statement(ret);
568 // Switch.
570 Bstatement*
571 Gcc_backend::switch_statement(
572 Bexpression* value,
573 const std::vector<std::vector<Bexpression*> >& cases,
574 const std::vector<Bstatement*>& statements,
575 source_location switch_location)
577 gcc_assert(cases.size() == statements.size());
579 tree stmt_list = NULL_TREE;
580 std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
581 for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
582 ps != statements.end();
583 ++ps, ++pc)
585 if (pc->empty())
587 source_location loc = (*ps != NULL
588 ? EXPR_LOCATION((*ps)->get_tree())
589 : UNKNOWN_LOCATION);
590 tree label = create_artificial_label(loc);
591 tree c = build3_loc(loc, CASE_LABEL_EXPR, void_type_node, NULL_TREE,
592 NULL_TREE, label);
593 append_to_statement_list(c, &stmt_list);
595 else
597 for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
598 pcv != pc->end();
599 ++pcv)
601 tree t = (*pcv)->get_tree();
602 if (t == error_mark_node)
603 return this->error_statement();
604 source_location loc = EXPR_LOCATION(t);
605 tree label = create_artificial_label(loc);
606 tree c = build3_loc(loc, CASE_LABEL_EXPR, void_type_node,
607 (*pcv)->get_tree(), NULL_TREE, label);
608 append_to_statement_list(c, &stmt_list);
612 if (*ps != NULL)
614 tree t = (*ps)->get_tree();
615 if (t == error_mark_node)
616 return this->error_statement();
617 append_to_statement_list(t, &stmt_list);
621 tree tv = value->get_tree();
622 if (tv == error_mark_node)
623 return this->error_statement();
624 tree t = build3_loc(switch_location, SWITCH_EXPR, void_type_node,
625 tv, stmt_list, NULL_TREE);
626 return this->make_statement(t);
629 // Pair of statements.
631 Bstatement*
632 Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
634 tree stmt_list = NULL_TREE;
635 tree t = s1->get_tree();
636 if (t == error_mark_node)
637 return this->error_statement();
638 append_to_statement_list(t, &stmt_list);
639 t = s2->get_tree();
640 if (t == error_mark_node)
641 return this->error_statement();
642 append_to_statement_list(t, &stmt_list);
643 return this->make_statement(stmt_list);
646 // List of statements.
648 Bstatement*
649 Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
651 tree stmt_list = NULL_TREE;
652 for (std::vector<Bstatement*>::const_iterator p = statements.begin();
653 p != statements.end();
654 ++p)
656 tree t = (*p)->get_tree();
657 if (t == error_mark_node)
658 return this->error_statement();
659 append_to_statement_list(t, &stmt_list);
661 return this->make_statement(stmt_list);
664 // Make a block. For some reason gcc uses a dual structure for
665 // blocks: BLOCK tree nodes and BIND_EXPR tree nodes. Since the
666 // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
667 // the Bblock.
669 Bblock*
670 Gcc_backend::block(Bfunction* function, Bblock* enclosing,
671 const std::vector<Bvariable*>& vars,
672 source_location start_location,
673 source_location)
675 tree block_tree = make_node(BLOCK);
676 if (enclosing == NULL)
678 // FIXME: Permitting FUNCTION to be NULL is a temporary measure
679 // until we have a proper representation of the init function.
680 tree fndecl;
681 if (function == NULL)
682 fndecl = current_function_decl;
683 else
684 fndecl = function->get_tree();
685 gcc_assert(fndecl != NULL_TREE);
687 // We may have already created a block for local variables when
688 // we take the address of a parameter.
689 if (DECL_INITIAL(fndecl) == NULL_TREE)
691 BLOCK_SUPERCONTEXT(block_tree) = fndecl;
692 DECL_INITIAL(fndecl) = block_tree;
694 else
696 tree superblock_tree = DECL_INITIAL(fndecl);
697 BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
698 tree* pp;
699 for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
700 *pp != NULL_TREE;
701 pp = &BLOCK_CHAIN(*pp))
703 *pp = block_tree;
706 else
708 tree superbind_tree = enclosing->get_tree();
709 tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
710 gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
712 BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
713 tree* pp;
714 for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
715 *pp != NULL_TREE;
716 pp = &BLOCK_CHAIN(*pp))
718 *pp = block_tree;
721 tree* pp = &BLOCK_VARS(block_tree);
722 for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
723 pv != vars.end();
724 ++pv)
726 *pp = (*pv)->get_tree();
727 if (*pp != error_mark_node)
728 pp = &DECL_CHAIN(*pp);
730 *pp = NULL_TREE;
732 TREE_USED(block_tree) = 1;
734 tree bind_tree = build3_loc(start_location, BIND_EXPR, void_type_node,
735 BLOCK_VARS(block_tree), NULL_TREE, block_tree);
736 TREE_SIDE_EFFECTS(bind_tree) = 1;
738 return new Bblock(bind_tree);
741 // Add statements to a block.
743 void
744 Gcc_backend::block_add_statements(Bblock* bblock,
745 const std::vector<Bstatement*>& statements)
747 tree stmt_list = NULL_TREE;
748 for (std::vector<Bstatement*>::const_iterator p = statements.begin();
749 p != statements.end();
750 ++p)
752 tree s = (*p)->get_tree();
753 if (s != error_mark_node)
754 append_to_statement_list(s, &stmt_list);
757 tree bind_tree = bblock->get_tree();
758 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
759 BIND_EXPR_BODY(bind_tree) = stmt_list;
762 // Return a block as a statement.
764 Bstatement*
765 Gcc_backend::block_statement(Bblock* bblock)
767 tree bind_tree = bblock->get_tree();
768 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
769 return this->make_statement(bind_tree);
772 // Make a global variable.
774 Bvariable*
775 Gcc_backend::global_variable(const std::string& package_name,
776 const std::string& unique_prefix,
777 const std::string& name,
778 Btype* btype,
779 bool is_external,
780 bool is_hidden,
781 source_location location)
783 tree type_tree = btype->get_tree();
784 if (type_tree == error_mark_node)
785 return this->error_variable();
787 std::string var_name(package_name);
788 var_name.push_back('.');
789 var_name.append(name);
790 tree decl = build_decl(location, VAR_DECL,
791 get_identifier_from_string(var_name),
792 type_tree);
793 if (is_external)
794 DECL_EXTERNAL(decl) = 1;
795 else
796 TREE_STATIC(decl) = 1;
797 if (!is_hidden)
799 TREE_PUBLIC(decl) = 1;
801 std::string asm_name(unique_prefix);
802 asm_name.push_back('.');
803 asm_name.append(var_name);
804 SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
806 TREE_USED(decl) = 1;
808 go_preserve_from_gc(decl);
810 return new Bvariable(decl);
813 // Set the initial value of a global variable.
815 void
816 Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
818 tree expr_tree = expr->get_tree();
819 if (expr_tree == error_mark_node)
820 return;
821 gcc_assert(TREE_CONSTANT(expr_tree));
822 tree var_decl = var->get_tree();
823 if (var_decl == error_mark_node)
824 return;
825 DECL_INITIAL(var_decl) = expr_tree;
828 // Make a local variable.
830 Bvariable*
831 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
832 Btype* btype, source_location location)
834 tree type_tree = btype->get_tree();
835 if (type_tree == error_mark_node)
836 return this->error_variable();
837 tree decl = build_decl(location, VAR_DECL,
838 get_identifier_from_string(name),
839 type_tree);
840 DECL_CONTEXT(decl) = function->get_tree();
841 TREE_USED(decl) = 1;
842 go_preserve_from_gc(decl);
843 return new Bvariable(decl);
846 // Make a function parameter variable.
848 Bvariable*
849 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
850 Btype* btype, source_location location)
852 tree type_tree = btype->get_tree();
853 if (type_tree == error_mark_node)
854 return this->error_variable();
855 tree decl = build_decl(location, PARM_DECL,
856 get_identifier_from_string(name),
857 type_tree);
858 DECL_CONTEXT(decl) = function->get_tree();
859 DECL_ARG_TYPE(decl) = type_tree;
860 TREE_USED(decl) = 1;
861 go_preserve_from_gc(decl);
862 return new Bvariable(decl);
865 // Make a temporary variable.
867 Bvariable*
868 Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
869 Btype* btype, Bexpression* binit,
870 bool is_address_taken,
871 source_location location,
872 Bstatement** pstatement)
874 tree type_tree = btype->get_tree();
875 tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
876 if (type_tree == error_mark_node || init_tree == error_mark_node)
878 *pstatement = this->error_statement();
879 return this->error_variable();
882 tree var;
883 // We can only use create_tmp_var if the type is not addressable.
884 if (!TREE_ADDRESSABLE(type_tree))
885 var = create_tmp_var(type_tree, "GOTMP");
886 else
888 gcc_assert(bblock != NULL);
889 var = build_decl(location, VAR_DECL,
890 create_tmp_var_name("GOTMP"),
891 type_tree);
892 DECL_ARTIFICIAL(var) = 1;
893 DECL_IGNORED_P(var) = 1;
894 TREE_USED(var) = 1;
895 // FIXME: Permitting function to be NULL here is a temporary
896 // measure until we have a proper representation of the init
897 // function.
898 if (function != NULL)
899 DECL_CONTEXT(var) = function->get_tree();
900 else
902 gcc_assert(current_function_decl != NULL_TREE);
903 DECL_CONTEXT(var) = current_function_decl;
906 // We have to add this variable to the BLOCK and the BIND_EXPR.
907 tree bind_tree = bblock->get_tree();
908 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
909 tree block_tree = BIND_EXPR_BLOCK(bind_tree);
910 gcc_assert(TREE_CODE(block_tree) == BLOCK);
911 DECL_CHAIN(var) = BLOCK_VARS(block_tree);
912 BLOCK_VARS(block_tree) = var;
913 BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
916 if (init_tree != NULL_TREE)
917 DECL_INITIAL(var) = fold_convert_loc(location, type_tree, init_tree);
919 if (is_address_taken)
920 TREE_ADDRESSABLE(var) = 1;
922 *pstatement = this->make_statement(build1_loc(location, DECL_EXPR,
923 void_type_node, var));
924 return new Bvariable(var);
927 // Make a label.
929 Blabel*
930 Gcc_backend::label(Bfunction* function, const std::string& name,
931 source_location location)
933 tree decl;
934 if (name.empty())
935 decl = create_artificial_label(location);
936 else
938 tree id = get_identifier_from_string(name);
939 decl = build_decl(location, LABEL_DECL, id, void_type_node);
940 DECL_CONTEXT(decl) = function->get_tree();
942 return new Blabel(decl);
945 // Make a statement which defines a label.
947 Bstatement*
948 Gcc_backend::label_definition_statement(Blabel* label)
950 tree lab = label->get_tree();
951 tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
952 void_type_node, lab);
953 return this->make_statement(ret);
956 // Make a goto statement.
958 Bstatement*
959 Gcc_backend::goto_statement(Blabel* label, source_location location)
961 tree lab = label->get_tree();
962 tree ret = fold_build1_loc(location, GOTO_EXPR, void_type_node, lab);
963 return this->make_statement(ret);
966 // Get the address of a label.
968 Bexpression*
969 Gcc_backend::label_address(Blabel* label, source_location location)
971 tree lab = label->get_tree();
972 TREE_USED(lab) = 1;
973 TREE_ADDRESSABLE(lab) = 1;
974 tree ret = fold_convert_loc(location, ptr_type_node,
975 build_fold_addr_expr_loc(location, lab));
976 return this->make_expression(ret);
979 // The single backend.
981 static Gcc_backend gcc_backend;
983 // Return the backend generator.
985 Backend*
986 go_get_backend()
988 return &gcc_backend;
991 // FIXME: Temporary functions while converting to the new backend
992 // interface.
994 Btype*
995 tree_to_type(tree t)
997 return new Btype(t);
1000 Bexpression*
1001 tree_to_expr(tree t)
1003 return new Bexpression(t);
1006 Bstatement*
1007 tree_to_stat(tree t)
1009 return new Bstatement(t);
1012 Bfunction*
1013 tree_to_function(tree t)
1015 return new Bfunction(t);
1018 Bblock*
1019 tree_to_block(tree t)
1021 gcc_assert(TREE_CODE(t) == BIND_EXPR);
1022 return new Bblock(t);
1025 tree
1026 type_to_tree(Btype* bt)
1028 return bt->get_tree();
1031 tree
1032 expr_to_tree(Bexpression* be)
1034 return be->get_tree();
1037 tree
1038 stat_to_tree(Bstatement* bs)
1040 return bs->get_tree();
1043 tree
1044 block_to_tree(Bblock* bb)
1046 return bb->get_tree();
1049 tree
1050 var_to_tree(Bvariable* bv)
1052 return bv->get_tree();