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
>&);
164 array_type(Btype
*, Bexpression
*);
167 placeholder_pointer_type(const std::string
&, source_location
, bool);
170 set_placeholder_pointer_type(Btype
*, Btype
*);
173 set_placeholder_function_type(Btype
*, Btype
*);
176 placeholder_struct_type(const std::string
&, source_location
);
179 set_placeholder_struct_type(Btype
* placeholder
,
180 const std::vector
<Btyped_identifier
>&);
183 placeholder_array_type(const std::string
&, source_location
);
186 set_placeholder_array_type(Btype
*, Btype
*, Bexpression
*);
189 named_type(const std::string
&, Btype
*, source_location
);
192 circular_pointer_type(Btype
*, bool);
195 is_circular_pointer_type(Btype
*);
201 { return this->make_statement(error_mark_node
); }
204 expression_statement(Bexpression
*);
207 init_statement(Bvariable
* var
, Bexpression
* init
);
210 assignment_statement(Bexpression
* lhs
, Bexpression
* rhs
, source_location
);
213 return_statement(Bfunction
*, const std::vector
<Bexpression
*>&,
217 if_statement(Bexpression
* condition
, Bblock
* then_block
, Bblock
* else_block
,
221 switch_statement(Bexpression
* value
,
222 const std::vector
<std::vector
<Bexpression
*> >& cases
,
223 const std::vector
<Bstatement
*>& statements
,
227 compound_statement(Bstatement
*, Bstatement
*);
230 statement_list(const std::vector
<Bstatement
*>&);
235 block(Bfunction
*, Bblock
*, const std::vector
<Bvariable
*>&,
236 source_location
, source_location
);
239 block_add_statements(Bblock
*, const std::vector
<Bstatement
*>&);
242 block_statement(Bblock
*);
248 { return new Bvariable(error_mark_node
); }
251 global_variable(const std::string
& package_name
,
252 const std::string
& unique_prefix
,
253 const std::string
& name
,
257 source_location location
);
260 global_variable_set_init(Bvariable
*, Bexpression
*);
263 local_variable(Bfunction
*, const std::string
& name
, Btype
* type
,
267 parameter_variable(Bfunction
*, const std::string
& name
, Btype
* type
,
271 temporary_variable(Bfunction
*, Bblock
*, Btype
*, Bexpression
*, bool,
272 source_location
, Bstatement
**);
277 label(Bfunction
*, const std::string
& name
, source_location
);
280 label_definition_statement(Blabel
*);
283 goto_statement(Blabel
*, source_location
);
286 label_address(Blabel
*, source_location
);
289 // Make a Bexpression from a tree.
291 make_expression(tree t
)
292 { return new Bexpression(t
); }
294 // Make a Bstatement from a tree.
296 make_statement(tree t
)
297 { return new Bstatement(t
); }
299 // Make a Btype from a tree.
302 { return new Btype(t
); }
305 fill_in_struct(Btype
*, const std::vector
<Btyped_identifier
>&);
308 fill_in_array(Btype
*, Btype
*, Bexpression
*);
311 // A helper function.
314 get_identifier_from_string(const std::string
& str
)
316 return get_identifier_with_length(str
.data(), str
.length());
319 // Get an unnamed integer type.
322 Gcc_backend::integer_type(bool is_unsigned
, int bits
)
327 if (bits
== INT_TYPE_SIZE
)
328 type
= unsigned_type_node
;
329 else if (bits
== CHAR_TYPE_SIZE
)
330 type
= unsigned_char_type_node
;
331 else if (bits
== SHORT_TYPE_SIZE
)
332 type
= short_unsigned_type_node
;
333 else if (bits
== LONG_TYPE_SIZE
)
334 type
= long_unsigned_type_node
;
335 else if (bits
== LONG_LONG_TYPE_SIZE
)
336 type
= long_long_unsigned_type_node
;
338 type
= make_unsigned_type(bits
);
342 if (bits
== INT_TYPE_SIZE
)
343 type
= integer_type_node
;
344 else if (bits
== CHAR_TYPE_SIZE
)
345 type
= signed_char_type_node
;
346 else if (bits
== SHORT_TYPE_SIZE
)
347 type
= short_integer_type_node
;
348 else if (bits
== LONG_TYPE_SIZE
)
349 type
= long_integer_type_node
;
350 else if (bits
== LONG_LONG_TYPE_SIZE
)
351 type
= long_long_integer_type_node
;
353 type
= make_signed_type(bits
);
355 return this->make_type(type
);
358 // Get an unnamed float type.
361 Gcc_backend::float_type(int bits
)
364 if (bits
== FLOAT_TYPE_SIZE
)
365 type
= float_type_node
;
366 else if (bits
== DOUBLE_TYPE_SIZE
)
367 type
= double_type_node
;
368 else if (bits
== LONG_DOUBLE_TYPE_SIZE
)
369 type
= long_double_type_node
;
372 type
= make_node(REAL_TYPE
);
373 TYPE_PRECISION(type
) = bits
;
376 return this->make_type(type
);
379 // Get an unnamed complex type.
382 Gcc_backend::complex_type(int bits
)
385 if (bits
== FLOAT_TYPE_SIZE
* 2)
386 type
= complex_float_type_node
;
387 else if (bits
== DOUBLE_TYPE_SIZE
* 2)
388 type
= complex_double_type_node
;
389 else if (bits
== LONG_DOUBLE_TYPE_SIZE
* 2)
390 type
= complex_long_double_type_node
;
393 type
= make_node(REAL_TYPE
);
394 TYPE_PRECISION(type
) = bits
/ 2;
396 type
= build_complex_type(type
);
398 return this->make_type(type
);
401 // Get a pointer type.
404 Gcc_backend::pointer_type(Btype
* to_type
)
406 tree to_type_tree
= to_type
->get_tree();
407 if (to_type_tree
== error_mark_node
)
408 return this->error_type();
409 tree type
= build_pointer_type(to_type_tree
);
410 return this->make_type(type
);
413 // Make a function type.
416 Gcc_backend::function_type(const Btyped_identifier
& receiver
,
417 const std::vector
<Btyped_identifier
>& parameters
,
418 const std::vector
<Btyped_identifier
>& results
,
419 source_location location
)
421 tree args
= NULL_TREE
;
423 if (receiver
.btype
!= NULL
)
425 tree t
= receiver
.btype
->get_tree();
426 if (t
== error_mark_node
)
427 return this->error_type();
428 *pp
= tree_cons(NULL_TREE
, t
, NULL_TREE
);
429 pp
= &TREE_CHAIN(*pp
);
432 for (std::vector
<Btyped_identifier
>::const_iterator p
= parameters
.begin();
433 p
!= parameters
.end();
436 tree t
= p
->btype
->get_tree();
437 if (t
== error_mark_node
)
438 return this->error_type();
439 *pp
= tree_cons(NULL_TREE
, t
, NULL_TREE
);
440 pp
= &TREE_CHAIN(*pp
);
443 // Varargs is handled entirely at the Go level. When converted to
444 // GENERIC functions are not varargs.
445 *pp
= void_list_node
;
449 result
= void_type_node
;
450 else if (results
.size() == 1)
451 result
= results
.front().btype
->get_tree();
454 result
= make_node(RECORD_TYPE
);
455 tree field_trees
= NULL_TREE
;
457 for (std::vector
<Btyped_identifier
>::const_iterator p
= results
.begin();
461 const std::string name
= (p
->name
.empty()
464 tree name_tree
= get_identifier_from_string(name
);
465 tree field_type_tree
= p
->btype
->get_tree();
466 if (field_type_tree
== error_mark_node
)
467 return this->error_type();
468 tree field
= build_decl(location
, FIELD_DECL
, name_tree
,
470 DECL_CONTEXT(field
) = result
;
472 pp
= &DECL_CHAIN(field
);
474 TYPE_FIELDS(result
) = field_trees
;
477 if (result
== error_mark_node
)
478 return this->error_type();
480 tree fntype
= build_function_type(result
, args
);
481 if (fntype
== error_mark_node
)
482 return this->error_type();
484 return this->make_type(build_pointer_type(fntype
));
487 // Make a struct type.
490 Gcc_backend::struct_type(const std::vector
<Btyped_identifier
>& fields
)
492 return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE
)), fields
);
495 // Fill in the fields of a struct type.
498 Gcc_backend::fill_in_struct(Btype
* fill
,
499 const std::vector
<Btyped_identifier
>& fields
)
501 tree fill_tree
= fill
->get_tree();
502 tree field_trees
= NULL_TREE
;
503 tree
* pp
= &field_trees
;
504 for (std::vector
<Btyped_identifier
>::const_iterator p
= fields
.begin();
508 tree name_tree
= get_identifier_from_string(p
->name
);
509 tree type_tree
= p
->btype
->get_tree();
510 if (type_tree
== error_mark_node
)
511 return this->error_type();
512 tree field
= build_decl(p
->location
, FIELD_DECL
, name_tree
, type_tree
);
513 DECL_CONTEXT(field
) = fill_tree
;
515 pp
= &DECL_CHAIN(field
);
517 TYPE_FIELDS(fill_tree
) = field_trees
;
518 layout_type(fill_tree
);
522 // Make an array type.
525 Gcc_backend::array_type(Btype
* element_btype
, Bexpression
* length
)
527 return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE
)),
528 element_btype
, length
);
531 // Fill in an array type.
534 Gcc_backend::fill_in_array(Btype
* fill
, Btype
* element_type
,
537 tree element_type_tree
= element_type
->get_tree();
538 tree length_tree
= length
->get_tree();
539 if (element_type_tree
== error_mark_node
|| length_tree
== error_mark_node
)
540 return this->error_type();
542 gcc_assert(TYPE_SIZE(element_type_tree
) != NULL_TREE
);
544 length_tree
= fold_convert(sizetype
, length_tree
);
546 // build_index_type takes the maximum index, which is one less than
548 tree index_type_tree
= build_index_type(fold_build2(MINUS_EXPR
, sizetype
,
552 tree fill_tree
= fill
->get_tree();
553 TREE_TYPE(fill_tree
) = element_type_tree
;
554 TYPE_DOMAIN(fill_tree
) = index_type_tree
;
555 TYPE_ADDR_SPACE(fill_tree
) = TYPE_ADDR_SPACE(element_type_tree
);
556 layout_type(fill_tree
);
558 if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree
))
559 SET_TYPE_STRUCTURAL_EQUALITY(fill_tree
);
560 else if (TYPE_CANONICAL(element_type_tree
) != element_type_tree
561 || TYPE_CANONICAL(index_type_tree
) != index_type_tree
)
562 TYPE_CANONICAL(fill_tree
) =
563 build_array_type(TYPE_CANONICAL(element_type_tree
),
564 TYPE_CANONICAL(index_type_tree
));
569 // Create a placeholder for a pointer type.
572 Gcc_backend::placeholder_pointer_type(const std::string
& name
,
573 source_location location
, bool)
575 tree ret
= build_variant_type_copy(ptr_type_node
);
576 tree decl
= build_decl(location
, TYPE_DECL
,
577 get_identifier_from_string(name
),
579 TYPE_NAME(ret
) = decl
;
580 return this->make_type(ret
);
583 // Set the real target type for a placeholder pointer type.
586 Gcc_backend::set_placeholder_pointer_type(Btype
* placeholder
,
589 tree pt
= placeholder
->get_tree();
590 if (pt
== error_mark_node
)
592 gcc_assert(TREE_CODE(pt
) == POINTER_TYPE
);
593 tree tt
= to_type
->get_tree();
594 if (tt
== error_mark_node
)
599 gcc_assert(TREE_CODE(tt
) == POINTER_TYPE
);
600 TREE_TYPE(pt
) = TREE_TYPE(tt
);
604 // Set the real values for a placeholder function type.
607 Gcc_backend::set_placeholder_function_type(Btype
* placeholder
, Btype
* ft
)
609 return this->set_placeholder_pointer_type(placeholder
, ft
);
612 // Create a placeholder for a struct type.
615 Gcc_backend::placeholder_struct_type(const std::string
& name
,
616 source_location location
)
618 tree ret
= make_node(RECORD_TYPE
);
619 tree decl
= build_decl(location
, TYPE_DECL
,
620 get_identifier_from_string(name
),
622 TYPE_NAME(ret
) = decl
;
623 return this->make_type(ret
);
626 // Fill in the fields of a placeholder struct type.
629 Gcc_backend::set_placeholder_struct_type(
631 const std::vector
<Btyped_identifier
>& fields
)
633 tree t
= placeholder
->get_tree();
634 gcc_assert(TREE_CODE(t
) == RECORD_TYPE
&& TYPE_FIELDS(t
) == NULL_TREE
);
635 Btype
* r
= this->fill_in_struct(placeholder
, fields
);
636 return r
->get_tree() != error_mark_node
;
639 // Create a placeholder for an array type.
642 Gcc_backend::placeholder_array_type(const std::string
& name
,
643 source_location location
)
645 tree ret
= make_node(ARRAY_TYPE
);
646 tree decl
= build_decl(location
, TYPE_DECL
,
647 get_identifier_from_string(name
),
649 TYPE_NAME(ret
) = decl
;
650 return this->make_type(ret
);
653 // Fill in the fields of a placeholder array type.
656 Gcc_backend::set_placeholder_array_type(Btype
* placeholder
,
657 Btype
* element_btype
,
660 tree t
= placeholder
->get_tree();
661 gcc_assert(TREE_CODE(t
) == ARRAY_TYPE
&& TREE_TYPE(t
) == NULL_TREE
);
662 Btype
* r
= this->fill_in_array(placeholder
, element_btype
, length
);
663 return r
->get_tree() != error_mark_node
;
666 // Return a named version of a type.
669 Gcc_backend::named_type(const std::string
& name
, Btype
* btype
,
670 source_location location
)
672 tree type
= btype
->get_tree();
673 if (type
== error_mark_node
)
674 return this->error_type();
675 type
= build_variant_type_copy(type
);
676 tree decl
= build_decl(location
, TYPE_DECL
,
677 get_identifier_from_string(name
),
679 TYPE_NAME(type
) = decl
;
680 return this->make_type(type
);
683 // Return a pointer type used as a marker for a circular type.
686 Gcc_backend::circular_pointer_type(Btype
*, bool)
688 return this->make_type(ptr_type_node
);
691 // Return whether we might be looking at a circular type.
694 Gcc_backend::is_circular_pointer_type(Btype
* btype
)
696 return btype
->get_tree() == ptr_type_node
;
699 // An expression as a statement.
702 Gcc_backend::expression_statement(Bexpression
* expr
)
704 return this->make_statement(expr
->get_tree());
707 // Variable initialization.
710 Gcc_backend::init_statement(Bvariable
* var
, Bexpression
* init
)
712 tree var_tree
= var
->get_tree();
713 tree init_tree
= init
->get_tree();
714 if (var_tree
== error_mark_node
|| init_tree
== error_mark_node
)
715 return this->error_statement();
716 gcc_assert(TREE_CODE(var_tree
) == VAR_DECL
);
717 DECL_INITIAL(var_tree
) = init_tree
;
718 return this->make_statement(build1_loc(DECL_SOURCE_LOCATION(var_tree
),
719 DECL_EXPR
, void_type_node
, var_tree
));
725 Gcc_backend::assignment_statement(Bexpression
* lhs
, Bexpression
* rhs
,
726 source_location location
)
728 tree lhs_tree
= lhs
->get_tree();
729 tree rhs_tree
= rhs
->get_tree();
730 if (lhs_tree
== error_mark_node
|| rhs_tree
== error_mark_node
)
731 return this->error_statement();
732 return this->make_statement(fold_build2_loc(location
, MODIFY_EXPR
,
734 lhs_tree
, rhs_tree
));
740 Gcc_backend::return_statement(Bfunction
* bfunction
,
741 const std::vector
<Bexpression
*>& vals
,
742 source_location location
)
744 tree fntree
= bfunction
->get_tree();
745 if (fntree
== error_mark_node
)
746 return this->error_statement();
747 tree result
= DECL_RESULT(fntree
);
748 if (result
== error_mark_node
)
749 return this->error_statement();
752 ret
= fold_build1_loc(location
, RETURN_EXPR
, void_type_node
, NULL_TREE
);
753 else if (vals
.size() == 1)
755 tree val
= vals
.front()->get_tree();
756 if (val
== error_mark_node
)
757 return this->error_statement();
758 tree set
= fold_build2_loc(location
, MODIFY_EXPR
, void_type_node
,
759 result
, vals
.front()->get_tree());
760 ret
= fold_build1_loc(location
, RETURN_EXPR
, void_type_node
, set
);
764 // To return multiple values, copy the values into a temporary
765 // variable of the right structure type, and then assign the
766 // temporary variable to the DECL_RESULT in the return
768 tree stmt_list
= NULL_TREE
;
769 tree rettype
= TREE_TYPE(result
);
770 tree rettmp
= create_tmp_var(rettype
, "RESULT");
771 tree field
= TYPE_FIELDS(rettype
);
772 for (std::vector
<Bexpression
*>::const_iterator p
= vals
.begin();
774 p
++, field
= DECL_CHAIN(field
))
776 gcc_assert(field
!= NULL_TREE
);
777 tree ref
= fold_build3_loc(location
, COMPONENT_REF
, TREE_TYPE(field
),
778 rettmp
, field
, NULL_TREE
);
779 tree val
= (*p
)->get_tree();
780 if (val
== error_mark_node
)
781 return this->error_statement();
782 tree set
= fold_build2_loc(location
, MODIFY_EXPR
, void_type_node
,
783 ref
, (*p
)->get_tree());
784 append_to_statement_list(set
, &stmt_list
);
786 gcc_assert(field
== NULL_TREE
);
787 tree set
= fold_build2_loc(location
, MODIFY_EXPR
, void_type_node
,
789 tree ret_expr
= fold_build1_loc(location
, RETURN_EXPR
, void_type_node
,
791 append_to_statement_list(ret_expr
, &stmt_list
);
794 return this->make_statement(ret
);
800 Gcc_backend::if_statement(Bexpression
* condition
, Bblock
* then_block
,
801 Bblock
* else_block
, source_location location
)
803 tree cond_tree
= condition
->get_tree();
804 tree then_tree
= then_block
->get_tree();
805 tree else_tree
= else_block
== NULL
? NULL_TREE
: else_block
->get_tree();
806 if (cond_tree
== error_mark_node
807 || then_tree
== error_mark_node
808 || else_tree
== error_mark_node
)
809 return this->error_statement();
810 tree ret
= build3_loc(location
, COND_EXPR
, void_type_node
, cond_tree
,
811 then_tree
, else_tree
);
812 return this->make_statement(ret
);
818 Gcc_backend::switch_statement(
820 const std::vector
<std::vector
<Bexpression
*> >& cases
,
821 const std::vector
<Bstatement
*>& statements
,
822 source_location switch_location
)
824 gcc_assert(cases
.size() == statements
.size());
826 tree stmt_list
= NULL_TREE
;
827 std::vector
<std::vector
<Bexpression
*> >::const_iterator pc
= cases
.begin();
828 for (std::vector
<Bstatement
*>::const_iterator ps
= statements
.begin();
829 ps
!= statements
.end();
834 source_location loc
= (*ps
!= NULL
835 ? EXPR_LOCATION((*ps
)->get_tree())
837 tree label
= create_artificial_label(loc
);
838 tree c
= build_case_label(NULL_TREE
, NULL_TREE
, label
);
839 append_to_statement_list(c
, &stmt_list
);
843 for (std::vector
<Bexpression
*>::const_iterator pcv
= pc
->begin();
847 tree t
= (*pcv
)->get_tree();
848 if (t
== error_mark_node
)
849 return this->error_statement();
850 source_location loc
= EXPR_LOCATION(t
);
851 tree label
= create_artificial_label(loc
);
852 tree c
= build_case_label((*pcv
)->get_tree(), NULL_TREE
, label
);
853 append_to_statement_list(c
, &stmt_list
);
859 tree t
= (*ps
)->get_tree();
860 if (t
== error_mark_node
)
861 return this->error_statement();
862 append_to_statement_list(t
, &stmt_list
);
866 tree tv
= value
->get_tree();
867 if (tv
== error_mark_node
)
868 return this->error_statement();
869 tree t
= build3_loc(switch_location
, SWITCH_EXPR
, void_type_node
,
870 tv
, stmt_list
, NULL_TREE
);
871 return this->make_statement(t
);
874 // Pair of statements.
877 Gcc_backend::compound_statement(Bstatement
* s1
, Bstatement
* s2
)
879 tree stmt_list
= NULL_TREE
;
880 tree t
= s1
->get_tree();
881 if (t
== error_mark_node
)
882 return this->error_statement();
883 append_to_statement_list(t
, &stmt_list
);
885 if (t
== error_mark_node
)
886 return this->error_statement();
887 append_to_statement_list(t
, &stmt_list
);
888 return this->make_statement(stmt_list
);
891 // List of statements.
894 Gcc_backend::statement_list(const std::vector
<Bstatement
*>& statements
)
896 tree stmt_list
= NULL_TREE
;
897 for (std::vector
<Bstatement
*>::const_iterator p
= statements
.begin();
898 p
!= statements
.end();
901 tree t
= (*p
)->get_tree();
902 if (t
== error_mark_node
)
903 return this->error_statement();
904 append_to_statement_list(t
, &stmt_list
);
906 return this->make_statement(stmt_list
);
909 // Make a block. For some reason gcc uses a dual structure for
910 // blocks: BLOCK tree nodes and BIND_EXPR tree nodes. Since the
911 // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
915 Gcc_backend::block(Bfunction
* function
, Bblock
* enclosing
,
916 const std::vector
<Bvariable
*>& vars
,
917 source_location start_location
,
920 tree block_tree
= make_node(BLOCK
);
921 if (enclosing
== NULL
)
923 // FIXME: Permitting FUNCTION to be NULL is a temporary measure
924 // until we have a proper representation of the init function.
926 if (function
== NULL
)
927 fndecl
= current_function_decl
;
929 fndecl
= function
->get_tree();
930 gcc_assert(fndecl
!= NULL_TREE
);
932 // We may have already created a block for local variables when
933 // we take the address of a parameter.
934 if (DECL_INITIAL(fndecl
) == NULL_TREE
)
936 BLOCK_SUPERCONTEXT(block_tree
) = fndecl
;
937 DECL_INITIAL(fndecl
) = block_tree
;
941 tree superblock_tree
= DECL_INITIAL(fndecl
);
942 BLOCK_SUPERCONTEXT(block_tree
) = superblock_tree
;
944 for (pp
= &BLOCK_SUBBLOCKS(superblock_tree
);
946 pp
= &BLOCK_CHAIN(*pp
))
953 tree superbind_tree
= enclosing
->get_tree();
954 tree superblock_tree
= BIND_EXPR_BLOCK(superbind_tree
);
955 gcc_assert(TREE_CODE(superblock_tree
) == BLOCK
);
957 BLOCK_SUPERCONTEXT(block_tree
) = superblock_tree
;
959 for (pp
= &BLOCK_SUBBLOCKS(superblock_tree
);
961 pp
= &BLOCK_CHAIN(*pp
))
966 tree
* pp
= &BLOCK_VARS(block_tree
);
967 for (std::vector
<Bvariable
*>::const_iterator pv
= vars
.begin();
971 *pp
= (*pv
)->get_tree();
972 if (*pp
!= error_mark_node
)
973 pp
= &DECL_CHAIN(*pp
);
977 TREE_USED(block_tree
) = 1;
979 tree bind_tree
= build3_loc(start_location
, BIND_EXPR
, void_type_node
,
980 BLOCK_VARS(block_tree
), NULL_TREE
, block_tree
);
981 TREE_SIDE_EFFECTS(bind_tree
) = 1;
983 return new Bblock(bind_tree
);
986 // Add statements to a block.
989 Gcc_backend::block_add_statements(Bblock
* bblock
,
990 const std::vector
<Bstatement
*>& statements
)
992 tree stmt_list
= NULL_TREE
;
993 for (std::vector
<Bstatement
*>::const_iterator p
= statements
.begin();
994 p
!= statements
.end();
997 tree s
= (*p
)->get_tree();
998 if (s
!= error_mark_node
)
999 append_to_statement_list(s
, &stmt_list
);
1002 tree bind_tree
= bblock
->get_tree();
1003 gcc_assert(TREE_CODE(bind_tree
) == BIND_EXPR
);
1004 BIND_EXPR_BODY(bind_tree
) = stmt_list
;
1007 // Return a block as a statement.
1010 Gcc_backend::block_statement(Bblock
* bblock
)
1012 tree bind_tree
= bblock
->get_tree();
1013 gcc_assert(TREE_CODE(bind_tree
) == BIND_EXPR
);
1014 return this->make_statement(bind_tree
);
1017 // Make a global variable.
1020 Gcc_backend::global_variable(const std::string
& package_name
,
1021 const std::string
& unique_prefix
,
1022 const std::string
& name
,
1026 source_location location
)
1028 tree type_tree
= btype
->get_tree();
1029 if (type_tree
== error_mark_node
)
1030 return this->error_variable();
1032 std::string
var_name(package_name
);
1033 var_name
.push_back('.');
1034 var_name
.append(name
);
1035 tree decl
= build_decl(location
, VAR_DECL
,
1036 get_identifier_from_string(var_name
),
1039 DECL_EXTERNAL(decl
) = 1;
1041 TREE_STATIC(decl
) = 1;
1044 TREE_PUBLIC(decl
) = 1;
1046 std::string
asm_name(unique_prefix
);
1047 asm_name
.push_back('.');
1048 asm_name
.append(var_name
);
1049 SET_DECL_ASSEMBLER_NAME(decl
, get_identifier_from_string(asm_name
));
1051 TREE_USED(decl
) = 1;
1053 go_preserve_from_gc(decl
);
1055 return new Bvariable(decl
);
1058 // Set the initial value of a global variable.
1061 Gcc_backend::global_variable_set_init(Bvariable
* var
, Bexpression
* expr
)
1063 tree expr_tree
= expr
->get_tree();
1064 if (expr_tree
== error_mark_node
)
1066 gcc_assert(TREE_CONSTANT(expr_tree
));
1067 tree var_decl
= var
->get_tree();
1068 if (var_decl
== error_mark_node
)
1070 DECL_INITIAL(var_decl
) = expr_tree
;
1073 // Make a local variable.
1076 Gcc_backend::local_variable(Bfunction
* function
, const std::string
& name
,
1077 Btype
* btype
, source_location location
)
1079 tree type_tree
= btype
->get_tree();
1080 if (type_tree
== error_mark_node
)
1081 return this->error_variable();
1082 tree decl
= build_decl(location
, VAR_DECL
,
1083 get_identifier_from_string(name
),
1085 DECL_CONTEXT(decl
) = function
->get_tree();
1086 TREE_USED(decl
) = 1;
1087 go_preserve_from_gc(decl
);
1088 return new Bvariable(decl
);
1091 // Make a function parameter variable.
1094 Gcc_backend::parameter_variable(Bfunction
* function
, const std::string
& name
,
1095 Btype
* btype
, source_location location
)
1097 tree type_tree
= btype
->get_tree();
1098 if (type_tree
== error_mark_node
)
1099 return this->error_variable();
1100 tree decl
= build_decl(location
, PARM_DECL
,
1101 get_identifier_from_string(name
),
1103 DECL_CONTEXT(decl
) = function
->get_tree();
1104 DECL_ARG_TYPE(decl
) = type_tree
;
1105 TREE_USED(decl
) = 1;
1106 go_preserve_from_gc(decl
);
1107 return new Bvariable(decl
);
1110 // Make a temporary variable.
1113 Gcc_backend::temporary_variable(Bfunction
* function
, Bblock
* bblock
,
1114 Btype
* btype
, Bexpression
* binit
,
1115 bool is_address_taken
,
1116 source_location location
,
1117 Bstatement
** pstatement
)
1119 tree type_tree
= btype
->get_tree();
1120 tree init_tree
= binit
== NULL
? NULL_TREE
: binit
->get_tree();
1121 if (type_tree
== error_mark_node
|| init_tree
== error_mark_node
)
1123 *pstatement
= this->error_statement();
1124 return this->error_variable();
1128 // We can only use create_tmp_var if the type is not addressable.
1129 if (!TREE_ADDRESSABLE(type_tree
))
1130 var
= create_tmp_var(type_tree
, "GOTMP");
1133 gcc_assert(bblock
!= NULL
);
1134 var
= build_decl(location
, VAR_DECL
,
1135 create_tmp_var_name("GOTMP"),
1137 DECL_ARTIFICIAL(var
) = 1;
1138 DECL_IGNORED_P(var
) = 1;
1140 // FIXME: Permitting function to be NULL here is a temporary
1141 // measure until we have a proper representation of the init
1143 if (function
!= NULL
)
1144 DECL_CONTEXT(var
) = function
->get_tree();
1147 gcc_assert(current_function_decl
!= NULL_TREE
);
1148 DECL_CONTEXT(var
) = current_function_decl
;
1151 // We have to add this variable to the BLOCK and the BIND_EXPR.
1152 tree bind_tree
= bblock
->get_tree();
1153 gcc_assert(TREE_CODE(bind_tree
) == BIND_EXPR
);
1154 tree block_tree
= BIND_EXPR_BLOCK(bind_tree
);
1155 gcc_assert(TREE_CODE(block_tree
) == BLOCK
);
1156 DECL_CHAIN(var
) = BLOCK_VARS(block_tree
);
1157 BLOCK_VARS(block_tree
) = var
;
1158 BIND_EXPR_VARS(bind_tree
) = BLOCK_VARS(block_tree
);
1161 if (init_tree
!= NULL_TREE
)
1162 DECL_INITIAL(var
) = fold_convert_loc(location
, type_tree
, init_tree
);
1164 if (is_address_taken
)
1165 TREE_ADDRESSABLE(var
) = 1;
1167 *pstatement
= this->make_statement(build1_loc(location
, DECL_EXPR
,
1168 void_type_node
, var
));
1169 return new Bvariable(var
);
1175 Gcc_backend::label(Bfunction
* function
, const std::string
& name
,
1176 source_location location
)
1180 decl
= create_artificial_label(location
);
1183 tree id
= get_identifier_from_string(name
);
1184 decl
= build_decl(location
, LABEL_DECL
, id
, void_type_node
);
1185 DECL_CONTEXT(decl
) = function
->get_tree();
1187 return new Blabel(decl
);
1190 // Make a statement which defines a label.
1193 Gcc_backend::label_definition_statement(Blabel
* label
)
1195 tree lab
= label
->get_tree();
1196 tree ret
= fold_build1_loc(DECL_SOURCE_LOCATION(lab
), LABEL_EXPR
,
1197 void_type_node
, lab
);
1198 return this->make_statement(ret
);
1201 // Make a goto statement.
1204 Gcc_backend::goto_statement(Blabel
* label
, source_location location
)
1206 tree lab
= label
->get_tree();
1207 tree ret
= fold_build1_loc(location
, GOTO_EXPR
, void_type_node
, lab
);
1208 return this->make_statement(ret
);
1211 // Get the address of a label.
1214 Gcc_backend::label_address(Blabel
* label
, source_location location
)
1216 tree lab
= label
->get_tree();
1218 TREE_ADDRESSABLE(lab
) = 1;
1219 tree ret
= fold_convert_loc(location
, ptr_type_node
,
1220 build_fold_addr_expr_loc(location
, lab
));
1221 return this->make_expression(ret
);
1224 // The single backend.
1226 static Gcc_backend gcc_backend
;
1228 // Return the backend generator.
1233 return &gcc_backend
;
1236 // FIXME: Temporary functions while converting to the new backend
1240 tree_to_type(tree t
)
1242 return new Btype(t
);
1246 tree_to_expr(tree t
)
1248 return new Bexpression(t
);
1252 tree_to_stat(tree t
)
1254 return new Bstatement(t
);
1258 tree_to_function(tree t
)
1260 return new Bfunction(t
);
1264 tree_to_block(tree t
)
1266 gcc_assert(TREE_CODE(t
) == BIND_EXPR
);
1267 return new Bblock(t
);
1271 type_to_tree(Btype
* bt
)
1273 return bt
->get_tree();
1277 expr_to_tree(Bexpression
* be
)
1279 return be
->get_tree();
1283 stat_to_tree(Bstatement
* bs
)
1285 return bs
->get_tree();
1289 block_to_tree(Bblock
* bb
)
1291 return bb
->get_tree();
1295 var_to_tree(Bvariable
* bv
)
1297 return bv
->get_tree();