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 { return this->make_type(error_mark_node
); }
136 { return this->make_type(void_type_node
); }
140 { return this->make_type(boolean_type_node
); }
143 integer_type(bool, int);
152 pointer_type(Btype
*);
155 function_type(const Btyped_identifier
&,
156 const std::vector
<Btyped_identifier
>&,
157 const std::vector
<Btyped_identifier
>&,
161 struct_type(const std::vector
<Btyped_identifier
>&)
162 { gcc_unreachable(); }
165 array_type(const Btype
* /* element_type */, const Bexpression
* /* length */)
166 { gcc_unreachable(); }
172 { return this->make_statement(error_mark_node
); }
175 expression_statement(Bexpression
*);
178 init_statement(Bvariable
* var
, Bexpression
* init
);
181 assignment_statement(Bexpression
* lhs
, Bexpression
* rhs
, source_location
);
184 return_statement(Bfunction
*, const std::vector
<Bexpression
*>&,
188 if_statement(Bexpression
* condition
, Bblock
* then_block
, Bblock
* else_block
,
192 switch_statement(Bexpression
* value
,
193 const std::vector
<std::vector
<Bexpression
*> >& cases
,
194 const std::vector
<Bstatement
*>& statements
,
198 compound_statement(Bstatement
*, Bstatement
*);
201 statement_list(const std::vector
<Bstatement
*>&);
206 block(Bfunction
*, Bblock
*, const std::vector
<Bvariable
*>&,
207 source_location
, source_location
);
210 block_add_statements(Bblock
*, const std::vector
<Bstatement
*>&);
213 block_statement(Bblock
*);
219 { return new Bvariable(error_mark_node
); }
222 global_variable(const std::string
& package_name
,
223 const std::string
& unique_prefix
,
224 const std::string
& name
,
228 source_location location
);
231 global_variable_set_init(Bvariable
*, Bexpression
*);
234 local_variable(Bfunction
*, const std::string
& name
, Btype
* type
,
238 parameter_variable(Bfunction
*, const std::string
& name
, Btype
* type
,
242 temporary_variable(Bfunction
*, Bblock
*, Btype
*, Bexpression
*, bool,
243 source_location
, Bstatement
**);
248 label(Bfunction
*, const std::string
& name
, source_location
);
251 label_definition_statement(Blabel
*);
254 goto_statement(Blabel
*, source_location
);
257 label_address(Blabel
*, source_location
);
260 // Make a Bexpression from a tree.
262 make_expression(tree t
)
263 { return new Bexpression(t
); }
265 // Make a Bstatement from a tree.
267 make_statement(tree t
)
268 { return new Bstatement(t
); }
270 // Make a Btype from a tree.
273 { return new Btype(t
); }
276 // A helper function.
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.
287 Gcc_backend::integer_type(bool is_unsigned
, int bits
)
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
;
303 type
= make_unsigned_type(bits
);
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
;
318 type
= make_signed_type(bits
);
320 return this->make_type(type
);
323 // Get an unnamed float type.
326 Gcc_backend::float_type(int bits
)
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
;
337 type
= make_node(REAL_TYPE
);
338 TYPE_PRECISION(type
) = bits
;
341 return this->make_type(type
);
344 // Get an unnamed complex type.
347 Gcc_backend::complex_type(int bits
)
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
;
358 type
= make_node(REAL_TYPE
);
359 TYPE_PRECISION(type
) = bits
/ 2;
361 type
= build_complex_type(type
);
363 return this->make_type(type
);
366 // Get a pointer type.
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.
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
;
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();
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
;
414 result
= void_type_node
;
415 else if (results
.size() == 1)
416 result
= results
.front().btype
->get_tree();
419 result
= make_node(RECORD_TYPE
);
420 tree field_trees
= NULL_TREE
;
422 for (std::vector
<Btyped_identifier
>::const_iterator p
= results
.begin();
426 const std::string name
= (p
->name
.empty()
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
,
435 DECL_CONTEXT(field
) = result
;
437 pp
= &DECL_CHAIN(field
);
439 TYPE_FIELDS(result
) = field_trees
;
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.
455 Gcc_backend::expression_statement(Bexpression
* expr
)
457 return this->make_statement(expr
->get_tree());
460 // Variable initialization.
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
));
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
,
487 lhs_tree
, rhs_tree
));
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();
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
);
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
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();
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
,
542 tree ret_expr
= fold_build1_loc(location
, RETURN_EXPR
, void_type_node
,
544 append_to_statement_list(ret_expr
, &stmt_list
);
547 return this->make_statement(ret
);
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
);
571 Gcc_backend::switch_statement(
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();
587 source_location loc
= (*ps
!= NULL
588 ? EXPR_LOCATION((*ps
)->get_tree())
590 tree label
= create_artificial_label(loc
);
591 tree c
= build3_loc(loc
, CASE_LABEL_EXPR
, void_type_node
, NULL_TREE
,
593 append_to_statement_list(c
, &stmt_list
);
597 for (std::vector
<Bexpression
*>::const_iterator pcv
= pc
->begin();
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
);
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.
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
);
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.
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();
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
670 Gcc_backend::block(Bfunction
* function
, Bblock
* enclosing
,
671 const std::vector
<Bvariable
*>& vars
,
672 source_location start_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.
681 if (function
== NULL
)
682 fndecl
= current_function_decl
;
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
;
696 tree superblock_tree
= DECL_INITIAL(fndecl
);
697 BLOCK_SUPERCONTEXT(block_tree
) = superblock_tree
;
699 for (pp
= &BLOCK_SUBBLOCKS(superblock_tree
);
701 pp
= &BLOCK_CHAIN(*pp
))
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
;
714 for (pp
= &BLOCK_SUBBLOCKS(superblock_tree
);
716 pp
= &BLOCK_CHAIN(*pp
))
721 tree
* pp
= &BLOCK_VARS(block_tree
);
722 for (std::vector
<Bvariable
*>::const_iterator pv
= vars
.begin();
726 *pp
= (*pv
)->get_tree();
727 if (*pp
!= error_mark_node
)
728 pp
= &DECL_CHAIN(*pp
);
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.
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();
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.
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.
775 Gcc_backend::global_variable(const std::string
& package_name
,
776 const std::string
& unique_prefix
,
777 const std::string
& name
,
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
),
794 DECL_EXTERNAL(decl
) = 1;
796 TREE_STATIC(decl
) = 1;
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
));
808 go_preserve_from_gc(decl
);
810 return new Bvariable(decl
);
813 // Set the initial value of a global variable.
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
)
821 gcc_assert(TREE_CONSTANT(expr_tree
));
822 tree var_decl
= var
->get_tree();
823 if (var_decl
== error_mark_node
)
825 DECL_INITIAL(var_decl
) = expr_tree
;
828 // Make a local variable.
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
),
840 DECL_CONTEXT(decl
) = function
->get_tree();
842 go_preserve_from_gc(decl
);
843 return new Bvariable(decl
);
846 // Make a function parameter variable.
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
),
858 DECL_CONTEXT(decl
) = function
->get_tree();
859 DECL_ARG_TYPE(decl
) = type_tree
;
861 go_preserve_from_gc(decl
);
862 return new Bvariable(decl
);
865 // Make a temporary variable.
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();
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");
888 gcc_assert(bblock
!= NULL
);
889 var
= build_decl(location
, VAR_DECL
,
890 create_tmp_var_name("GOTMP"),
892 DECL_ARTIFICIAL(var
) = 1;
893 DECL_IGNORED_P(var
) = 1;
895 // FIXME: Permitting function to be NULL here is a temporary
896 // measure until we have a proper representation of the init
898 if (function
!= NULL
)
899 DECL_CONTEXT(var
) = function
->get_tree();
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
);
930 Gcc_backend::label(Bfunction
* function
, const std::string
& name
,
931 source_location location
)
935 decl
= create_artificial_label(location
);
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.
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.
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.
969 Gcc_backend::label_address(Blabel
* label
, source_location location
)
971 tree lab
= label
->get_tree();
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.
991 // FIXME: Temporary functions while converting to the new backend
1001 tree_to_expr(tree t
)
1003 return new Bexpression(t
);
1007 tree_to_stat(tree t
)
1009 return new Bstatement(t
);
1013 tree_to_function(tree t
)
1015 return new Bfunction(t
);
1019 tree_to_block(tree t
)
1021 gcc_assert(TREE_CODE(t
) == BIND_EXPR
);
1022 return new Bblock(t
);
1026 type_to_tree(Btype
* bt
)
1028 return bt
->get_tree();
1032 expr_to_tree(Bexpression
* be
)
1034 return be
->get_tree();
1038 stat_to_tree(Bstatement
* bs
)
1040 return bs
->get_tree();
1044 block_to_tree(Bblock
* bb
)
1046 return bb
->get_tree();
1050 var_to_tree(Bvariable
* bv
)
1052 return bv
->get_tree();