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
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
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.
27 #ifndef ENABLE_BUILD_WITH_CXX
33 #include "tree-iterator.h"
36 #ifndef ENABLE_BUILD_WITH_CXX
45 // A class wrapping a tree.
62 // In gcc, types, expressions, and statements are all trees.
63 class Btype : public Gcc_tree
71 class Bexpression : public Gcc_tree
79 class Bstatement : public Gcc_tree
87 class Bfunction : public Gcc_tree
95 class Bblock : public Gcc_tree
103 class Bvariable : public Gcc_tree
111 class Blabel : public Gcc_tree
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
132 { gcc_unreachable(); }
136 { return this->make_type(void_type_node); }
140 { return this->make_type(boolean_type_node); }
143 integer_type(bool, int);
153 { gcc_unreachable(); }
156 pointer_type(const Btype*);
159 function_type(const Function_type*, Btype* /* receiver */,
160 const Btypes* /* parameters */,
161 const Btypes* /* results */)
162 { gcc_unreachable(); }
165 struct_type(const Struct_type*, const Btypes* /* field_types */)
166 { gcc_unreachable(); }
169 array_type(const Btype* /* element_type */, const Bexpression* /* length */)
170 { gcc_unreachable(); }
173 slice_type(const Btype* /* element_type */)
174 { gcc_unreachable(); }
177 map_type(const Btype* /* key_type */, const Btype* /* value_type */,
179 { gcc_unreachable(); }
182 channel_type(const Btype* /* element_type */)
183 { gcc_unreachable(); }
186 interface_type(const Interface_type*, const Btypes* /* method_types */)
187 { gcc_unreachable(); }
193 { return this->make_statement(error_mark_node); }
196 expression_statement(Bexpression*);
199 init_statement(Bvariable* var, Bexpression* init);
202 assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location);
205 return_statement(Bfunction*, const std::vector<Bexpression*>&,
209 if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
213 switch_statement(Bexpression* value,
214 const std::vector<std::vector<Bexpression*> >& cases,
215 const std::vector<Bstatement*>& statements,
219 compound_statement(Bstatement*, Bstatement*);
222 statement_list(const std::vector<Bstatement*>&);
227 block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
228 source_location, source_location);
231 block_add_statements(Bblock*, const std::vector<Bstatement*>&);
234 block_statement(Bblock*);
240 { return new Bvariable(error_mark_node); }
243 global_variable(const std::string& package_name,
244 const std::string& unique_prefix,
245 const std::string& name,
249 source_location location);
252 global_variable_set_init(Bvariable*, Bexpression*);
255 local_variable(Bfunction*, const std::string& name, Btype* type,
259 parameter_variable(Bfunction*, const std::string& name, Btype* type,
263 temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
264 source_location, Bstatement**);
269 label(Bfunction*, const std::string& name, source_location);
272 label_definition_statement(Blabel*);
275 goto_statement(Blabel*, source_location);
278 label_address(Blabel*, source_location);
281 // Make a Bexpression from a tree.
283 make_expression(tree t)
284 { return new Bexpression(t); }
286 // Make a Bstatement from a tree.
288 make_statement(tree t)
289 { return new Bstatement(t); }
291 // Make a Btype from a tree.
294 { return new Btype(t); }
297 // A helper function.
300 get_identifier_from_string(const std::string& str)
302 return get_identifier_with_length(str.data(), str.length());
305 // Get an unnamed integer type.
308 Gcc_backend::integer_type(bool is_unsigned, int bits)
313 if (bits == INT_TYPE_SIZE)
314 type = unsigned_type_node;
315 else if (bits == CHAR_TYPE_SIZE)
316 type = unsigned_char_type_node;
317 else if (bits == SHORT_TYPE_SIZE)
318 type = short_unsigned_type_node;
319 else if (bits == LONG_TYPE_SIZE)
320 type = long_unsigned_type_node;
321 else if (bits == LONG_LONG_TYPE_SIZE)
322 type = long_long_unsigned_type_node;
324 type = make_unsigned_type(bits);
328 if (bits == INT_TYPE_SIZE)
329 type = integer_type_node;
330 else if (bits == CHAR_TYPE_SIZE)
331 type = signed_char_type_node;
332 else if (bits == SHORT_TYPE_SIZE)
333 type = short_integer_type_node;
334 else if (bits == LONG_TYPE_SIZE)
335 type = long_integer_type_node;
336 else if (bits == LONG_LONG_TYPE_SIZE)
337 type = long_long_integer_type_node;
339 type = make_signed_type(bits);
341 return this->make_type(type);
344 // Get an unnamed float type.
347 Gcc_backend::float_type(int bits)
350 if (bits == FLOAT_TYPE_SIZE)
351 type = float_type_node;
352 else if (bits == DOUBLE_TYPE_SIZE)
353 type = double_type_node;
354 else if (bits == LONG_DOUBLE_TYPE_SIZE)
355 type = long_double_type_node;
358 type = make_node(REAL_TYPE);
359 TYPE_PRECISION(type) = bits;
362 return this->make_type(type);
365 // Get an unnamed complex type.
368 Gcc_backend::complex_type(int bits)
371 if (bits == FLOAT_TYPE_SIZE * 2)
372 type = complex_float_type_node;
373 else if (bits == DOUBLE_TYPE_SIZE * 2)
374 type = complex_double_type_node;
375 else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
376 type = complex_long_double_type_node;
379 type = make_node(REAL_TYPE);
380 TYPE_PRECISION(type) = bits / 2;
382 type = build_complex_type(type);
384 return this->make_type(type);
387 // Get a pointer type.
390 Gcc_backend::pointer_type(const Btype* to_type)
392 tree type = build_pointer_type(to_type->get_tree());
393 return this->make_type(type);
396 // An expression as a statement.
399 Gcc_backend::expression_statement(Bexpression* expr)
401 return this->make_statement(expr->get_tree());
404 // Variable initialization.
407 Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
409 tree var_tree = var->get_tree();
410 tree init_tree = init->get_tree();
411 if (var_tree == error_mark_node || init_tree == error_mark_node)
412 return this->error_statement();
413 gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
414 DECL_INITIAL(var_tree) = init_tree;
415 return this->make_statement(build1_loc(DECL_SOURCE_LOCATION(var_tree),
416 DECL_EXPR, void_type_node, var_tree));
422 Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
423 source_location location)
425 tree lhs_tree = lhs->get_tree();
426 tree rhs_tree = rhs->get_tree();
427 if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
428 return this->error_statement();
429 return this->make_statement(fold_build2_loc(location, MODIFY_EXPR,
431 lhs_tree, rhs_tree));
437 Gcc_backend::return_statement(Bfunction* bfunction,
438 const std::vector<Bexpression*>& vals,
439 source_location location)
441 tree fntree = bfunction->get_tree();
442 if (fntree == error_mark_node)
443 return this->error_statement();
444 tree result = DECL_RESULT(fntree);
445 if (result == error_mark_node)
446 return this->error_statement();
449 ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, NULL_TREE);
450 else if (vals.size() == 1)
452 tree val = vals.front()->get_tree();
453 if (val == error_mark_node)
454 return this->error_statement();
455 tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
456 result, vals.front()->get_tree());
457 ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, set);
461 // To return multiple values, copy the values into a temporary
462 // variable of the right structure type, and then assign the
463 // temporary variable to the DECL_RESULT in the return
465 tree stmt_list = NULL_TREE;
466 tree rettype = TREE_TYPE(result);
467 tree rettmp = create_tmp_var(rettype, "RESULT");
468 tree field = TYPE_FIELDS(rettype);
469 for (std::vector<Bexpression*>::const_iterator p = vals.begin();
471 p++, field = DECL_CHAIN(field))
473 gcc_assert(field != NULL_TREE);
474 tree ref = fold_build3_loc(location, COMPONENT_REF, TREE_TYPE(field),
475 rettmp, field, NULL_TREE);
476 tree val = (*p)->get_tree();
477 if (val == error_mark_node)
478 return this->error_statement();
479 tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
480 ref, (*p)->get_tree());
481 append_to_statement_list(set, &stmt_list);
483 gcc_assert(field == NULL_TREE);
484 tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
486 tree ret_expr = fold_build1_loc(location, RETURN_EXPR, void_type_node,
488 append_to_statement_list(ret_expr, &stmt_list);
491 return this->make_statement(ret);
497 Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
498 Bblock* else_block, source_location location)
500 tree cond_tree = condition->get_tree();
501 tree then_tree = then_block->get_tree();
502 tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
503 if (cond_tree == error_mark_node
504 || then_tree == error_mark_node
505 || else_tree == error_mark_node)
506 return this->error_statement();
507 tree ret = build3_loc(location, COND_EXPR, void_type_node, cond_tree,
508 then_tree, else_tree);
509 return this->make_statement(ret);
515 Gcc_backend::switch_statement(
517 const std::vector<std::vector<Bexpression*> >& cases,
518 const std::vector<Bstatement*>& statements,
519 source_location switch_location)
521 gcc_assert(cases.size() == statements.size());
523 tree stmt_list = NULL_TREE;
524 std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
525 for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
526 ps != statements.end();
531 source_location loc = (*ps != NULL
532 ? EXPR_LOCATION((*ps)->get_tree())
534 tree label = create_artificial_label(loc);
535 tree c = build3_loc(loc, CASE_LABEL_EXPR, void_type_node, NULL_TREE,
537 append_to_statement_list(c, &stmt_list);
541 for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
545 tree t = (*pcv)->get_tree();
546 if (t == error_mark_node)
547 return this->error_statement();
548 source_location loc = EXPR_LOCATION(t);
549 tree label = create_artificial_label(loc);
550 tree c = build3_loc(loc, CASE_LABEL_EXPR, void_type_node,
551 (*pcv)->get_tree(), NULL_TREE, label);
552 append_to_statement_list(c, &stmt_list);
558 tree t = (*ps)->get_tree();
559 if (t == error_mark_node)
560 return this->error_statement();
561 append_to_statement_list(t, &stmt_list);
565 tree tv = value->get_tree();
566 if (tv == error_mark_node)
567 return this->error_statement();
568 tree t = build3_loc(switch_location, SWITCH_EXPR, void_type_node,
569 tv, stmt_list, NULL_TREE);
570 return this->make_statement(t);
573 // Pair of statements.
576 Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
578 tree stmt_list = NULL_TREE;
579 tree t = s1->get_tree();
580 if (t == error_mark_node)
581 return this->error_statement();
582 append_to_statement_list(t, &stmt_list);
584 if (t == error_mark_node)
585 return this->error_statement();
586 append_to_statement_list(t, &stmt_list);
587 return this->make_statement(stmt_list);
590 // List of statements.
593 Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
595 tree stmt_list = NULL_TREE;
596 for (std::vector<Bstatement*>::const_iterator p = statements.begin();
597 p != statements.end();
600 tree t = (*p)->get_tree();
601 if (t == error_mark_node)
602 return this->error_statement();
603 append_to_statement_list(t, &stmt_list);
605 return this->make_statement(stmt_list);
608 // Make a block. For some reason gcc uses a dual structure for
609 // blocks: BLOCK tree nodes and BIND_EXPR tree nodes. Since the
610 // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
614 Gcc_backend::block(Bfunction* function, Bblock* enclosing,
615 const std::vector<Bvariable*>& vars,
616 source_location start_location,
619 tree block_tree = make_node(BLOCK);
620 if (enclosing == NULL)
622 // FIXME: Permitting FUNCTION to be NULL is a temporary measure
623 // until we have a proper representation of the init function.
625 if (function == NULL)
626 fndecl = current_function_decl;
628 fndecl = function->get_tree();
629 gcc_assert(fndecl != NULL_TREE);
631 // We may have already created a block for local variables when
632 // we take the address of a parameter.
633 if (DECL_INITIAL(fndecl) == NULL_TREE)
635 BLOCK_SUPERCONTEXT(block_tree) = fndecl;
636 DECL_INITIAL(fndecl) = block_tree;
640 tree superblock_tree = DECL_INITIAL(fndecl);
641 BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
643 for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
645 pp = &BLOCK_CHAIN(*pp))
652 tree superbind_tree = enclosing->get_tree();
653 tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
654 gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
656 BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
658 for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
660 pp = &BLOCK_CHAIN(*pp))
665 tree* pp = &BLOCK_VARS(block_tree);
666 for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
670 *pp = (*pv)->get_tree();
671 if (*pp != error_mark_node)
672 pp = &DECL_CHAIN(*pp);
676 TREE_USED(block_tree) = 1;
678 tree bind_tree = build3_loc(start_location, BIND_EXPR, void_type_node,
679 BLOCK_VARS(block_tree), NULL_TREE, block_tree);
680 TREE_SIDE_EFFECTS(bind_tree) = 1;
682 return new Bblock(bind_tree);
685 // Add statements to a block.
688 Gcc_backend::block_add_statements(Bblock* bblock,
689 const std::vector<Bstatement*>& statements)
691 tree stmt_list = NULL_TREE;
692 for (std::vector<Bstatement*>::const_iterator p = statements.begin();
693 p != statements.end();
696 tree s = (*p)->get_tree();
697 if (s != error_mark_node)
698 append_to_statement_list(s, &stmt_list);
701 tree bind_tree = bblock->get_tree();
702 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
703 BIND_EXPR_BODY(bind_tree) = stmt_list;
706 // Return a block as a statement.
709 Gcc_backend::block_statement(Bblock* bblock)
711 tree bind_tree = bblock->get_tree();
712 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
713 return this->make_statement(bind_tree);
716 // Make a global variable.
719 Gcc_backend::global_variable(const std::string& package_name,
720 const std::string& unique_prefix,
721 const std::string& name,
725 source_location location)
727 tree type_tree = btype->get_tree();
728 if (type_tree == error_mark_node)
729 return this->error_variable();
731 std::string var_name(package_name);
732 var_name.push_back('.');
733 var_name.append(name);
734 tree decl = build_decl(location, VAR_DECL,
735 get_identifier_from_string(var_name),
738 DECL_EXTERNAL(decl) = 1;
740 TREE_STATIC(decl) = 1;
743 TREE_PUBLIC(decl) = 1;
745 std::string asm_name(unique_prefix);
746 asm_name.push_back('.');
747 asm_name.append(var_name);
748 SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
752 go_preserve_from_gc(decl);
754 return new Bvariable(decl);
757 // Set the initial value of a global variable.
760 Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
762 tree expr_tree = expr->get_tree();
763 if (expr_tree == error_mark_node)
765 gcc_assert(TREE_CONSTANT(expr_tree));
766 tree var_decl = var->get_tree();
767 if (var_decl == error_mark_node)
769 DECL_INITIAL(var_decl) = expr_tree;
772 // Make a local variable.
775 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
776 Btype* btype, source_location location)
778 tree type_tree = btype->get_tree();
779 if (type_tree == error_mark_node)
780 return this->error_variable();
781 tree decl = build_decl(location, VAR_DECL,
782 get_identifier_from_string(name),
784 DECL_CONTEXT(decl) = function->get_tree();
786 go_preserve_from_gc(decl);
787 return new Bvariable(decl);
790 // Make a function parameter variable.
793 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
794 Btype* btype, source_location location)
796 tree type_tree = btype->get_tree();
797 if (type_tree == error_mark_node)
798 return this->error_variable();
799 tree decl = build_decl(location, PARM_DECL,
800 get_identifier_from_string(name),
802 DECL_CONTEXT(decl) = function->get_tree();
803 DECL_ARG_TYPE(decl) = type_tree;
805 go_preserve_from_gc(decl);
806 return new Bvariable(decl);
809 // Make a temporary variable.
812 Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
813 Btype* btype, Bexpression* binit,
814 bool is_address_taken,
815 source_location location,
816 Bstatement** pstatement)
818 tree type_tree = btype->get_tree();
819 tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
820 if (type_tree == error_mark_node || init_tree == error_mark_node)
822 *pstatement = this->error_statement();
823 return this->error_variable();
827 // We can only use create_tmp_var if the type is not addressable.
828 if (!TREE_ADDRESSABLE(type_tree))
829 var = create_tmp_var(type_tree, "GOTMP");
832 gcc_assert(bblock != NULL);
833 var = build_decl(location, VAR_DECL,
834 create_tmp_var_name("GOTMP"),
836 DECL_ARTIFICIAL(var) = 1;
837 DECL_IGNORED_P(var) = 1;
839 // FIXME: Permitting function to be NULL here is a temporary
840 // measure until we have a proper representation of the init
842 if (function != NULL)
843 DECL_CONTEXT(var) = function->get_tree();
846 gcc_assert(current_function_decl != NULL_TREE);
847 DECL_CONTEXT(var) = current_function_decl;
850 // We have to add this variable to the BLOCK and the BIND_EXPR.
851 tree bind_tree = bblock->get_tree();
852 gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
853 tree block_tree = BIND_EXPR_BLOCK(bind_tree);
854 gcc_assert(TREE_CODE(block_tree) == BLOCK);
855 DECL_CHAIN(var) = BLOCK_VARS(block_tree);
856 BLOCK_VARS(block_tree) = var;
857 BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
860 if (init_tree != NULL_TREE)
861 DECL_INITIAL(var) = fold_convert_loc(location, type_tree, init_tree);
863 if (is_address_taken)
864 TREE_ADDRESSABLE(var) = 1;
866 *pstatement = this->make_statement(build1_loc(location, DECL_EXPR,
867 void_type_node, var));
868 return new Bvariable(var);
874 Gcc_backend::label(Bfunction* function, const std::string& name,
875 source_location location)
879 decl = create_artificial_label(location);
882 tree id = get_identifier_from_string(name);
883 decl = build_decl(location, LABEL_DECL, id, void_type_node);
884 DECL_CONTEXT(decl) = function->get_tree();
886 return new Blabel(decl);
889 // Make a statement which defines a label.
892 Gcc_backend::label_definition_statement(Blabel* label)
894 tree lab = label->get_tree();
895 tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
896 void_type_node, lab);
897 return this->make_statement(ret);
900 // Make a goto statement.
903 Gcc_backend::goto_statement(Blabel* label, source_location location)
905 tree lab = label->get_tree();
906 tree ret = fold_build1_loc(location, GOTO_EXPR, void_type_node, lab);
907 return this->make_statement(ret);
910 // Get the address of a label.
913 Gcc_backend::label_address(Blabel* label, source_location location)
915 tree lab = label->get_tree();
917 TREE_ADDRESSABLE(lab) = 1;
918 tree ret = fold_convert_loc(location, ptr_type_node,
919 build_fold_addr_expr_loc(location, lab));
920 return this->make_expression(ret);
923 // The single backend.
925 static Gcc_backend gcc_backend;
927 // Return the backend generator.
935 // FIXME: Temporary functions while converting to the new backend
947 return new Bexpression(t);
953 return new Bstatement(t);
957 tree_to_function(tree t)
959 return new Bfunction(t);
963 tree_to_block(tree t)
965 gcc_assert(TREE_CODE(t) == BIND_EXPR);
966 return new Bblock(t);
970 type_to_tree(Btype* bt)
972 return bt->get_tree();
976 expr_to_tree(Bexpression* be)
978 return be->get_tree();
982 stat_to_tree(Bstatement* bs)
984 return bs->get_tree();
988 block_to_tree(Bblock* bb)
990 return bb->get_tree();
994 var_to_tree(Bvariable* bv)
996 return bv->get_tree();