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"
37 #ifndef ENABLE_BUILD_WITH_CXX
46 // A class wrapping a tree.
63 // In gcc, types, expressions, and statements are all trees.
64 class Btype
: public Gcc_tree
72 class Bexpression
: public Gcc_tree
80 class Bstatement
: public Gcc_tree
88 class Bfunction
: public Gcc_tree
96 class Bblock
: public Gcc_tree
104 class Bvariable
: public Gcc_tree
112 class Blabel
: public Gcc_tree
120 // This file implements the interface between the Go frontend proper
121 // and the gcc IR. This implements specific instantiations of
122 // abstract classes defined by the Go frontend proper. The Go
123 // frontend proper class methods of these classes to generate the
124 // backend representation.
126 class Gcc_backend
: public Backend
133 { return this->make_type(error_mark_node
); }
137 { return this->make_type(void_type_node
); }
141 { return this->make_type(boolean_type_node
); }
144 integer_type(bool, int);
153 pointer_type(Btype
*);
156 function_type(const Btyped_identifier
&,
157 const std::vector
<Btyped_identifier
>&,
158 const std::vector
<Btyped_identifier
>&,
162 struct_type(const std::vector
<Btyped_identifier
>&);
165 array_type(Btype
*, Bexpression
*);
168 placeholder_pointer_type(const std::string
&, source_location
, bool);
171 set_placeholder_pointer_type(Btype
*, Btype
*);
174 set_placeholder_function_type(Btype
*, Btype
*);
177 placeholder_struct_type(const std::string
&, source_location
);
180 set_placeholder_struct_type(Btype
* placeholder
,
181 const std::vector
<Btyped_identifier
>&);
184 placeholder_array_type(const std::string
&, source_location
);
187 set_placeholder_array_type(Btype
*, Btype
*, Bexpression
*);
190 named_type(const std::string
&, Btype
*, source_location
);
193 circular_pointer_type(Btype
*, bool);
196 is_circular_pointer_type(Btype
*);
201 zero_expression(Btype
*);
207 { return this->make_statement(error_mark_node
); }
210 expression_statement(Bexpression
*);
213 init_statement(Bvariable
* var
, Bexpression
* init
);
216 assignment_statement(Bexpression
* lhs
, Bexpression
* rhs
, source_location
);
219 return_statement(Bfunction
*, const std::vector
<Bexpression
*>&,
223 if_statement(Bexpression
* condition
, Bblock
* then_block
, Bblock
* else_block
,
227 switch_statement(Bexpression
* value
,
228 const std::vector
<std::vector
<Bexpression
*> >& cases
,
229 const std::vector
<Bstatement
*>& statements
,
233 compound_statement(Bstatement
*, Bstatement
*);
236 statement_list(const std::vector
<Bstatement
*>&);
241 block(Bfunction
*, Bblock
*, const std::vector
<Bvariable
*>&,
242 source_location
, source_location
);
245 block_add_statements(Bblock
*, const std::vector
<Bstatement
*>&);
248 block_statement(Bblock
*);
254 { return new Bvariable(error_mark_node
); }
257 global_variable(const std::string
& package_name
,
258 const std::string
& unique_prefix
,
259 const std::string
& name
,
263 source_location location
);
266 global_variable_set_init(Bvariable
*, Bexpression
*);
269 local_variable(Bfunction
*, const std::string
&, Btype
*, bool,
273 parameter_variable(Bfunction
*, const std::string
&, Btype
*, bool,
277 temporary_variable(Bfunction
*, Bblock
*, Btype
*, Bexpression
*, bool,
278 source_location
, Bstatement
**);
281 immutable_struct(const std::string
&, bool, Btype
*, source_location
);
284 immutable_struct_set_init(Bvariable
*, const std::string
&, bool, Btype
*,
285 source_location
, Bexpression
*);
288 immutable_struct_reference(const std::string
&, Btype
*, source_location
);
293 label(Bfunction
*, const std::string
& name
, source_location
);
296 label_definition_statement(Blabel
*);
299 goto_statement(Blabel
*, source_location
);
302 label_address(Blabel
*, source_location
);
305 // Make a Bexpression from a tree.
307 make_expression(tree t
)
308 { return new Bexpression(t
); }
310 // Make a Bstatement from a tree.
312 make_statement(tree t
)
313 { return new Bstatement(t
); }
315 // Make a Btype from a tree.
318 { return new Btype(t
); }
321 fill_in_struct(Btype
*, const std::vector
<Btyped_identifier
>&);
324 fill_in_array(Btype
*, Btype
*, Bexpression
*);
327 // A helper function.
330 get_identifier_from_string(const std::string
& str
)
332 return get_identifier_with_length(str
.data(), str
.length());
335 // Get an unnamed integer type.
338 Gcc_backend::integer_type(bool is_unsigned
, int bits
)
343 if (bits
== INT_TYPE_SIZE
)
344 type
= unsigned_type_node
;
345 else if (bits
== CHAR_TYPE_SIZE
)
346 type
= unsigned_char_type_node
;
347 else if (bits
== SHORT_TYPE_SIZE
)
348 type
= short_unsigned_type_node
;
349 else if (bits
== LONG_TYPE_SIZE
)
350 type
= long_unsigned_type_node
;
351 else if (bits
== LONG_LONG_TYPE_SIZE
)
352 type
= long_long_unsigned_type_node
;
354 type
= make_unsigned_type(bits
);
358 if (bits
== INT_TYPE_SIZE
)
359 type
= integer_type_node
;
360 else if (bits
== CHAR_TYPE_SIZE
)
361 type
= signed_char_type_node
;
362 else if (bits
== SHORT_TYPE_SIZE
)
363 type
= short_integer_type_node
;
364 else if (bits
== LONG_TYPE_SIZE
)
365 type
= long_integer_type_node
;
366 else if (bits
== LONG_LONG_TYPE_SIZE
)
367 type
= long_long_integer_type_node
;
369 type
= make_signed_type(bits
);
371 return this->make_type(type
);
374 // Get an unnamed float type.
377 Gcc_backend::float_type(int bits
)
380 if (bits
== FLOAT_TYPE_SIZE
)
381 type
= float_type_node
;
382 else if (bits
== DOUBLE_TYPE_SIZE
)
383 type
= double_type_node
;
384 else if (bits
== LONG_DOUBLE_TYPE_SIZE
)
385 type
= long_double_type_node
;
388 type
= make_node(REAL_TYPE
);
389 TYPE_PRECISION(type
) = bits
;
392 return this->make_type(type
);
395 // Get an unnamed complex type.
398 Gcc_backend::complex_type(int bits
)
401 if (bits
== FLOAT_TYPE_SIZE
* 2)
402 type
= complex_float_type_node
;
403 else if (bits
== DOUBLE_TYPE_SIZE
* 2)
404 type
= complex_double_type_node
;
405 else if (bits
== LONG_DOUBLE_TYPE_SIZE
* 2)
406 type
= complex_long_double_type_node
;
409 type
= make_node(REAL_TYPE
);
410 TYPE_PRECISION(type
) = bits
/ 2;
412 type
= build_complex_type(type
);
414 return this->make_type(type
);
417 // Get a pointer type.
420 Gcc_backend::pointer_type(Btype
* to_type
)
422 tree to_type_tree
= to_type
->get_tree();
423 if (to_type_tree
== error_mark_node
)
424 return this->error_type();
425 tree type
= build_pointer_type(to_type_tree
);
426 return this->make_type(type
);
429 // Make a function type.
432 Gcc_backend::function_type(const Btyped_identifier
& receiver
,
433 const std::vector
<Btyped_identifier
>& parameters
,
434 const std::vector
<Btyped_identifier
>& results
,
435 source_location location
)
437 tree args
= NULL_TREE
;
439 if (receiver
.btype
!= NULL
)
441 tree t
= receiver
.btype
->get_tree();
442 if (t
== error_mark_node
)
443 return this->error_type();
444 *pp
= tree_cons(NULL_TREE
, t
, NULL_TREE
);
445 pp
= &TREE_CHAIN(*pp
);
448 for (std::vector
<Btyped_identifier
>::const_iterator p
= parameters
.begin();
449 p
!= parameters
.end();
452 tree t
= p
->btype
->get_tree();
453 if (t
== error_mark_node
)
454 return this->error_type();
455 *pp
= tree_cons(NULL_TREE
, t
, NULL_TREE
);
456 pp
= &TREE_CHAIN(*pp
);
459 // Varargs is handled entirely at the Go level. When converted to
460 // GENERIC functions are not varargs.
461 *pp
= void_list_node
;
465 result
= void_type_node
;
466 else if (results
.size() == 1)
467 result
= results
.front().btype
->get_tree();
470 result
= make_node(RECORD_TYPE
);
471 tree field_trees
= NULL_TREE
;
473 for (std::vector
<Btyped_identifier
>::const_iterator p
= results
.begin();
477 const std::string name
= (p
->name
.empty()
480 tree name_tree
= get_identifier_from_string(name
);
481 tree field_type_tree
= p
->btype
->get_tree();
482 if (field_type_tree
== error_mark_node
)
483 return this->error_type();
484 gcc_assert(TYPE_SIZE(field_type_tree
) != NULL_TREE
);
485 tree field
= build_decl(location
, FIELD_DECL
, name_tree
,
487 DECL_CONTEXT(field
) = result
;
489 pp
= &DECL_CHAIN(field
);
491 TYPE_FIELDS(result
) = field_trees
;
494 if (result
== error_mark_node
)
495 return this->error_type();
497 tree fntype
= build_function_type(result
, args
);
498 if (fntype
== error_mark_node
)
499 return this->error_type();
501 return this->make_type(build_pointer_type(fntype
));
504 // Make a struct type.
507 Gcc_backend::struct_type(const std::vector
<Btyped_identifier
>& fields
)
509 return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE
)), fields
);
512 // Fill in the fields of a struct type.
515 Gcc_backend::fill_in_struct(Btype
* fill
,
516 const std::vector
<Btyped_identifier
>& fields
)
518 tree fill_tree
= fill
->get_tree();
519 tree field_trees
= NULL_TREE
;
520 tree
* pp
= &field_trees
;
521 for (std::vector
<Btyped_identifier
>::const_iterator p
= fields
.begin();
525 tree name_tree
= get_identifier_from_string(p
->name
);
526 tree type_tree
= p
->btype
->get_tree();
527 if (type_tree
== error_mark_node
)
528 return this->error_type();
529 tree field
= build_decl(p
->location
, FIELD_DECL
, name_tree
, type_tree
);
530 DECL_CONTEXT(field
) = fill_tree
;
532 pp
= &DECL_CHAIN(field
);
534 TYPE_FIELDS(fill_tree
) = field_trees
;
535 layout_type(fill_tree
);
539 // Make an array type.
542 Gcc_backend::array_type(Btype
* element_btype
, Bexpression
* length
)
544 return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE
)),
545 element_btype
, length
);
548 // Fill in an array type.
551 Gcc_backend::fill_in_array(Btype
* fill
, Btype
* element_type
,
554 tree element_type_tree
= element_type
->get_tree();
555 tree length_tree
= length
->get_tree();
556 if (element_type_tree
== error_mark_node
|| length_tree
== error_mark_node
)
557 return this->error_type();
559 gcc_assert(TYPE_SIZE(element_type_tree
) != NULL_TREE
);
561 length_tree
= fold_convert(sizetype
, length_tree
);
563 // build_index_type takes the maximum index, which is one less than
565 tree index_type_tree
= build_index_type(fold_build2(MINUS_EXPR
, sizetype
,
569 tree fill_tree
= fill
->get_tree();
570 TREE_TYPE(fill_tree
) = element_type_tree
;
571 TYPE_DOMAIN(fill_tree
) = index_type_tree
;
572 TYPE_ADDR_SPACE(fill_tree
) = TYPE_ADDR_SPACE(element_type_tree
);
573 layout_type(fill_tree
);
575 if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree
))
576 SET_TYPE_STRUCTURAL_EQUALITY(fill_tree
);
577 else if (TYPE_CANONICAL(element_type_tree
) != element_type_tree
578 || TYPE_CANONICAL(index_type_tree
) != index_type_tree
)
579 TYPE_CANONICAL(fill_tree
) =
580 build_array_type(TYPE_CANONICAL(element_type_tree
),
581 TYPE_CANONICAL(index_type_tree
));
586 // Create a placeholder for a pointer type.
589 Gcc_backend::placeholder_pointer_type(const std::string
& name
,
590 source_location location
, bool)
592 tree ret
= build_variant_type_copy(ptr_type_node
);
595 tree decl
= build_decl(location
, TYPE_DECL
,
596 get_identifier_from_string(name
),
598 TYPE_NAME(ret
) = decl
;
600 return this->make_type(ret
);
603 // Set the real target type for a placeholder pointer type.
606 Gcc_backend::set_placeholder_pointer_type(Btype
* placeholder
,
609 tree pt
= placeholder
->get_tree();
610 if (pt
== error_mark_node
)
612 gcc_assert(TREE_CODE(pt
) == POINTER_TYPE
);
613 tree tt
= to_type
->get_tree();
614 if (tt
== error_mark_node
)
619 gcc_assert(TREE_CODE(tt
) == POINTER_TYPE
);
620 TREE_TYPE(pt
) = TREE_TYPE(tt
);
624 // Set the real values for a placeholder function type.
627 Gcc_backend::set_placeholder_function_type(Btype
* placeholder
, Btype
* ft
)
629 return this->set_placeholder_pointer_type(placeholder
, ft
);
632 // Create a placeholder for a struct type.
635 Gcc_backend::placeholder_struct_type(const std::string
& name
,
636 source_location location
)
638 tree ret
= make_node(RECORD_TYPE
);
639 tree decl
= build_decl(location
, TYPE_DECL
,
640 get_identifier_from_string(name
),
642 TYPE_NAME(ret
) = decl
;
643 return this->make_type(ret
);
646 // Fill in the fields of a placeholder struct type.
649 Gcc_backend::set_placeholder_struct_type(
651 const std::vector
<Btyped_identifier
>& fields
)
653 tree t
= placeholder
->get_tree();
654 gcc_assert(TREE_CODE(t
) == RECORD_TYPE
&& TYPE_FIELDS(t
) == NULL_TREE
);
655 Btype
* r
= this->fill_in_struct(placeholder
, fields
);
656 return r
->get_tree() != error_mark_node
;
659 // Create a placeholder for an array type.
662 Gcc_backend::placeholder_array_type(const std::string
& name
,
663 source_location location
)
665 tree ret
= make_node(ARRAY_TYPE
);
666 tree decl
= build_decl(location
, TYPE_DECL
,
667 get_identifier_from_string(name
),
669 TYPE_NAME(ret
) = decl
;
670 return this->make_type(ret
);
673 // Fill in the fields of a placeholder array type.
676 Gcc_backend::set_placeholder_array_type(Btype
* placeholder
,
677 Btype
* element_btype
,
680 tree t
= placeholder
->get_tree();
681 gcc_assert(TREE_CODE(t
) == ARRAY_TYPE
&& TREE_TYPE(t
) == NULL_TREE
);
682 Btype
* r
= this->fill_in_array(placeholder
, element_btype
, length
);
683 return r
->get_tree() != error_mark_node
;
686 // Return a named version of a type.
689 Gcc_backend::named_type(const std::string
& name
, Btype
* btype
,
690 source_location location
)
692 tree type
= btype
->get_tree();
693 if (type
== error_mark_node
)
694 return this->error_type();
695 type
= build_variant_type_copy(type
);
696 tree decl
= build_decl(location
, TYPE_DECL
,
697 get_identifier_from_string(name
),
699 TYPE_NAME(type
) = decl
;
700 return this->make_type(type
);
703 // Return a pointer type used as a marker for a circular type.
706 Gcc_backend::circular_pointer_type(Btype
*, bool)
708 return this->make_type(ptr_type_node
);
711 // Return whether we might be looking at a circular type.
714 Gcc_backend::is_circular_pointer_type(Btype
* btype
)
716 return btype
->get_tree() == ptr_type_node
;
719 // Return the zero value for a type.
722 Gcc_backend::zero_expression(Btype
* btype
)
724 tree t
= btype
->get_tree();
726 if (t
== error_mark_node
)
727 ret
= error_mark_node
;
729 ret
= build_zero_cst(t
);
730 return tree_to_expr(ret
);
733 // An expression as a statement.
736 Gcc_backend::expression_statement(Bexpression
* expr
)
738 return this->make_statement(expr
->get_tree());
741 // Variable initialization.
744 Gcc_backend::init_statement(Bvariable
* var
, Bexpression
* init
)
746 tree var_tree
= var
->get_tree();
747 tree init_tree
= init
->get_tree();
748 if (var_tree
== error_mark_node
|| init_tree
== error_mark_node
)
749 return this->error_statement();
750 gcc_assert(TREE_CODE(var_tree
) == VAR_DECL
);
751 DECL_INITIAL(var_tree
) = init_tree
;
752 return this->make_statement(build1_loc(DECL_SOURCE_LOCATION(var_tree
),
753 DECL_EXPR
, void_type_node
, var_tree
));
759 Gcc_backend::assignment_statement(Bexpression
* lhs
, Bexpression
* rhs
,
760 source_location location
)
762 tree lhs_tree
= lhs
->get_tree();
763 tree rhs_tree
= rhs
->get_tree();
764 if (lhs_tree
== error_mark_node
|| rhs_tree
== error_mark_node
)
765 return this->error_statement();
766 return this->make_statement(fold_build2_loc(location
, MODIFY_EXPR
,
768 lhs_tree
, rhs_tree
));
774 Gcc_backend::return_statement(Bfunction
* bfunction
,
775 const std::vector
<Bexpression
*>& vals
,
776 source_location location
)
778 tree fntree
= bfunction
->get_tree();
779 if (fntree
== error_mark_node
)
780 return this->error_statement();
781 tree result
= DECL_RESULT(fntree
);
782 if (result
== error_mark_node
)
783 return this->error_statement();
786 ret
= fold_build1_loc(location
, RETURN_EXPR
, void_type_node
, NULL_TREE
);
787 else if (vals
.size() == 1)
789 tree val
= vals
.front()->get_tree();
790 if (val
== error_mark_node
)
791 return this->error_statement();
792 tree set
= fold_build2_loc(location
, MODIFY_EXPR
, void_type_node
,
793 result
, vals
.front()->get_tree());
794 ret
= fold_build1_loc(location
, RETURN_EXPR
, void_type_node
, set
);
798 // To return multiple values, copy the values into a temporary
799 // variable of the right structure type, and then assign the
800 // temporary variable to the DECL_RESULT in the return
802 tree stmt_list
= NULL_TREE
;
803 tree rettype
= TREE_TYPE(result
);
804 tree rettmp
= create_tmp_var(rettype
, "RESULT");
805 tree field
= TYPE_FIELDS(rettype
);
806 for (std::vector
<Bexpression
*>::const_iterator p
= vals
.begin();
808 p
++, field
= DECL_CHAIN(field
))
810 gcc_assert(field
!= NULL_TREE
);
811 tree ref
= fold_build3_loc(location
, COMPONENT_REF
, TREE_TYPE(field
),
812 rettmp
, field
, NULL_TREE
);
813 tree val
= (*p
)->get_tree();
814 if (val
== error_mark_node
)
815 return this->error_statement();
816 tree set
= fold_build2_loc(location
, MODIFY_EXPR
, void_type_node
,
817 ref
, (*p
)->get_tree());
818 append_to_statement_list(set
, &stmt_list
);
820 gcc_assert(field
== NULL_TREE
);
821 tree set
= fold_build2_loc(location
, MODIFY_EXPR
, void_type_node
,
823 tree ret_expr
= fold_build1_loc(location
, RETURN_EXPR
, void_type_node
,
825 append_to_statement_list(ret_expr
, &stmt_list
);
828 return this->make_statement(ret
);
834 Gcc_backend::if_statement(Bexpression
* condition
, Bblock
* then_block
,
835 Bblock
* else_block
, source_location location
)
837 tree cond_tree
= condition
->get_tree();
838 tree then_tree
= then_block
->get_tree();
839 tree else_tree
= else_block
== NULL
? NULL_TREE
: else_block
->get_tree();
840 if (cond_tree
== error_mark_node
841 || then_tree
== error_mark_node
842 || else_tree
== error_mark_node
)
843 return this->error_statement();
844 tree ret
= build3_loc(location
, COND_EXPR
, void_type_node
, cond_tree
,
845 then_tree
, else_tree
);
846 return this->make_statement(ret
);
852 Gcc_backend::switch_statement(
854 const std::vector
<std::vector
<Bexpression
*> >& cases
,
855 const std::vector
<Bstatement
*>& statements
,
856 source_location switch_location
)
858 gcc_assert(cases
.size() == statements
.size());
860 tree stmt_list
= NULL_TREE
;
861 std::vector
<std::vector
<Bexpression
*> >::const_iterator pc
= cases
.begin();
862 for (std::vector
<Bstatement
*>::const_iterator ps
= statements
.begin();
863 ps
!= statements
.end();
868 source_location loc
= (*ps
!= NULL
869 ? EXPR_LOCATION((*ps
)->get_tree())
871 tree label
= create_artificial_label(loc
);
872 tree c
= build_case_label(NULL_TREE
, NULL_TREE
, label
);
873 append_to_statement_list(c
, &stmt_list
);
877 for (std::vector
<Bexpression
*>::const_iterator pcv
= pc
->begin();
881 tree t
= (*pcv
)->get_tree();
882 if (t
== error_mark_node
)
883 return this->error_statement();
884 source_location loc
= EXPR_LOCATION(t
);
885 tree label
= create_artificial_label(loc
);
886 tree c
= build_case_label((*pcv
)->get_tree(), NULL_TREE
, label
);
887 append_to_statement_list(c
, &stmt_list
);
893 tree t
= (*ps
)->get_tree();
894 if (t
== error_mark_node
)
895 return this->error_statement();
896 append_to_statement_list(t
, &stmt_list
);
900 tree tv
= value
->get_tree();
901 if (tv
== error_mark_node
)
902 return this->error_statement();
903 tree t
= build3_loc(switch_location
, SWITCH_EXPR
, void_type_node
,
904 tv
, stmt_list
, NULL_TREE
);
905 return this->make_statement(t
);
908 // Pair of statements.
911 Gcc_backend::compound_statement(Bstatement
* s1
, Bstatement
* s2
)
913 tree stmt_list
= NULL_TREE
;
914 tree t
= s1
->get_tree();
915 if (t
== error_mark_node
)
916 return this->error_statement();
917 append_to_statement_list(t
, &stmt_list
);
919 if (t
== error_mark_node
)
920 return this->error_statement();
921 append_to_statement_list(t
, &stmt_list
);
922 return this->make_statement(stmt_list
);
925 // List of statements.
928 Gcc_backend::statement_list(const std::vector
<Bstatement
*>& statements
)
930 tree stmt_list
= NULL_TREE
;
931 for (std::vector
<Bstatement
*>::const_iterator p
= statements
.begin();
932 p
!= statements
.end();
935 tree t
= (*p
)->get_tree();
936 if (t
== error_mark_node
)
937 return this->error_statement();
938 append_to_statement_list(t
, &stmt_list
);
940 return this->make_statement(stmt_list
);
943 // Make a block. For some reason gcc uses a dual structure for
944 // blocks: BLOCK tree nodes and BIND_EXPR tree nodes. Since the
945 // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
949 Gcc_backend::block(Bfunction
* function
, Bblock
* enclosing
,
950 const std::vector
<Bvariable
*>& vars
,
951 source_location start_location
,
954 tree block_tree
= make_node(BLOCK
);
955 if (enclosing
== NULL
)
957 // FIXME: Permitting FUNCTION to be NULL is a temporary measure
958 // until we have a proper representation of the init function.
960 if (function
== NULL
)
961 fndecl
= current_function_decl
;
963 fndecl
= function
->get_tree();
964 gcc_assert(fndecl
!= NULL_TREE
);
966 // We may have already created a block for local variables when
967 // we take the address of a parameter.
968 if (DECL_INITIAL(fndecl
) == NULL_TREE
)
970 BLOCK_SUPERCONTEXT(block_tree
) = fndecl
;
971 DECL_INITIAL(fndecl
) = block_tree
;
975 tree superblock_tree
= DECL_INITIAL(fndecl
);
976 BLOCK_SUPERCONTEXT(block_tree
) = superblock_tree
;
978 for (pp
= &BLOCK_SUBBLOCKS(superblock_tree
);
980 pp
= &BLOCK_CHAIN(*pp
))
987 tree superbind_tree
= enclosing
->get_tree();
988 tree superblock_tree
= BIND_EXPR_BLOCK(superbind_tree
);
989 gcc_assert(TREE_CODE(superblock_tree
) == BLOCK
);
991 BLOCK_SUPERCONTEXT(block_tree
) = superblock_tree
;
993 for (pp
= &BLOCK_SUBBLOCKS(superblock_tree
);
995 pp
= &BLOCK_CHAIN(*pp
))
1000 tree
* pp
= &BLOCK_VARS(block_tree
);
1001 for (std::vector
<Bvariable
*>::const_iterator pv
= vars
.begin();
1005 *pp
= (*pv
)->get_tree();
1006 if (*pp
!= error_mark_node
)
1007 pp
= &DECL_CHAIN(*pp
);
1011 TREE_USED(block_tree
) = 1;
1013 tree bind_tree
= build3_loc(start_location
, BIND_EXPR
, void_type_node
,
1014 BLOCK_VARS(block_tree
), NULL_TREE
, block_tree
);
1015 TREE_SIDE_EFFECTS(bind_tree
) = 1;
1017 return new Bblock(bind_tree
);
1020 // Add statements to a block.
1023 Gcc_backend::block_add_statements(Bblock
* bblock
,
1024 const std::vector
<Bstatement
*>& statements
)
1026 tree stmt_list
= NULL_TREE
;
1027 for (std::vector
<Bstatement
*>::const_iterator p
= statements
.begin();
1028 p
!= statements
.end();
1031 tree s
= (*p
)->get_tree();
1032 if (s
!= error_mark_node
)
1033 append_to_statement_list(s
, &stmt_list
);
1036 tree bind_tree
= bblock
->get_tree();
1037 gcc_assert(TREE_CODE(bind_tree
) == BIND_EXPR
);
1038 BIND_EXPR_BODY(bind_tree
) = stmt_list
;
1041 // Return a block as a statement.
1044 Gcc_backend::block_statement(Bblock
* bblock
)
1046 tree bind_tree
= bblock
->get_tree();
1047 gcc_assert(TREE_CODE(bind_tree
) == BIND_EXPR
);
1048 return this->make_statement(bind_tree
);
1051 // Make a global variable.
1054 Gcc_backend::global_variable(const std::string
& package_name
,
1055 const std::string
& unique_prefix
,
1056 const std::string
& name
,
1060 source_location location
)
1062 tree type_tree
= btype
->get_tree();
1063 if (type_tree
== error_mark_node
)
1064 return this->error_variable();
1066 std::string
var_name(package_name
);
1067 var_name
.push_back('.');
1068 var_name
.append(name
);
1069 tree decl
= build_decl(location
, VAR_DECL
,
1070 get_identifier_from_string(var_name
),
1073 DECL_EXTERNAL(decl
) = 1;
1075 TREE_STATIC(decl
) = 1;
1078 TREE_PUBLIC(decl
) = 1;
1080 std::string
asm_name(unique_prefix
);
1081 asm_name
.push_back('.');
1082 asm_name
.append(var_name
);
1083 SET_DECL_ASSEMBLER_NAME(decl
, get_identifier_from_string(asm_name
));
1085 TREE_USED(decl
) = 1;
1087 go_preserve_from_gc(decl
);
1089 return new Bvariable(decl
);
1092 // Set the initial value of a global variable.
1095 Gcc_backend::global_variable_set_init(Bvariable
* var
, Bexpression
* expr
)
1097 tree expr_tree
= expr
->get_tree();
1098 if (expr_tree
== error_mark_node
)
1100 gcc_assert(TREE_CONSTANT(expr_tree
));
1101 tree var_decl
= var
->get_tree();
1102 if (var_decl
== error_mark_node
)
1104 DECL_INITIAL(var_decl
) = expr_tree
;
1107 // Make a local variable.
1110 Gcc_backend::local_variable(Bfunction
* function
, const std::string
& name
,
1111 Btype
* btype
, bool is_address_taken
,
1112 source_location location
)
1114 tree type_tree
= btype
->get_tree();
1115 if (type_tree
== error_mark_node
)
1116 return this->error_variable();
1117 tree decl
= build_decl(location
, VAR_DECL
,
1118 get_identifier_from_string(name
),
1120 DECL_CONTEXT(decl
) = function
->get_tree();
1121 TREE_USED(decl
) = 1;
1122 if (is_address_taken
)
1123 TREE_ADDRESSABLE(decl
) = 1;
1124 go_preserve_from_gc(decl
);
1125 return new Bvariable(decl
);
1128 // Make a function parameter variable.
1131 Gcc_backend::parameter_variable(Bfunction
* function
, const std::string
& name
,
1132 Btype
* btype
, bool is_address_taken
,
1133 source_location location
)
1135 tree type_tree
= btype
->get_tree();
1136 if (type_tree
== error_mark_node
)
1137 return this->error_variable();
1138 tree decl
= build_decl(location
, PARM_DECL
,
1139 get_identifier_from_string(name
),
1141 DECL_CONTEXT(decl
) = function
->get_tree();
1142 DECL_ARG_TYPE(decl
) = type_tree
;
1143 TREE_USED(decl
) = 1;
1144 if (is_address_taken
)
1145 TREE_ADDRESSABLE(decl
) = 1;
1146 go_preserve_from_gc(decl
);
1147 return new Bvariable(decl
);
1150 // Make a temporary variable.
1153 Gcc_backend::temporary_variable(Bfunction
* function
, Bblock
* bblock
,
1154 Btype
* btype
, Bexpression
* binit
,
1155 bool is_address_taken
,
1156 source_location location
,
1157 Bstatement
** pstatement
)
1159 tree type_tree
= btype
->get_tree();
1160 tree init_tree
= binit
== NULL
? NULL_TREE
: binit
->get_tree();
1161 if (type_tree
== error_mark_node
|| init_tree
== error_mark_node
)
1163 *pstatement
= this->error_statement();
1164 return this->error_variable();
1168 // We can only use create_tmp_var if the type is not addressable.
1169 if (!TREE_ADDRESSABLE(type_tree
))
1170 var
= create_tmp_var(type_tree
, "GOTMP");
1173 gcc_assert(bblock
!= NULL
);
1174 var
= build_decl(location
, VAR_DECL
,
1175 create_tmp_var_name("GOTMP"),
1177 DECL_ARTIFICIAL(var
) = 1;
1178 DECL_IGNORED_P(var
) = 1;
1180 // FIXME: Permitting function to be NULL here is a temporary
1181 // measure until we have a proper representation of the init
1183 if (function
!= NULL
)
1184 DECL_CONTEXT(var
) = function
->get_tree();
1187 gcc_assert(current_function_decl
!= NULL_TREE
);
1188 DECL_CONTEXT(var
) = current_function_decl
;
1191 // We have to add this variable to the BLOCK and the BIND_EXPR.
1192 tree bind_tree
= bblock
->get_tree();
1193 gcc_assert(TREE_CODE(bind_tree
) == BIND_EXPR
);
1194 tree block_tree
= BIND_EXPR_BLOCK(bind_tree
);
1195 gcc_assert(TREE_CODE(block_tree
) == BLOCK
);
1196 DECL_CHAIN(var
) = BLOCK_VARS(block_tree
);
1197 BLOCK_VARS(block_tree
) = var
;
1198 BIND_EXPR_VARS(bind_tree
) = BLOCK_VARS(block_tree
);
1201 if (init_tree
!= NULL_TREE
)
1202 DECL_INITIAL(var
) = fold_convert_loc(location
, type_tree
, init_tree
);
1204 if (is_address_taken
)
1205 TREE_ADDRESSABLE(var
) = 1;
1207 *pstatement
= this->make_statement(build1_loc(location
, DECL_EXPR
,
1208 void_type_node
, var
));
1209 return new Bvariable(var
);
1212 // Create a named immutable initialized data structure.
1215 Gcc_backend::immutable_struct(const std::string
& name
, bool, Btype
* btype
,
1216 source_location location
)
1218 tree type_tree
= btype
->get_tree();
1219 if (type_tree
== error_mark_node
)
1220 return this->error_variable();
1221 gcc_assert(TREE_CODE(type_tree
) == RECORD_TYPE
);
1222 tree decl
= build_decl(location
, VAR_DECL
,
1223 get_identifier_from_string(name
),
1224 build_qualified_type(type_tree
, TYPE_QUAL_CONST
));
1225 TREE_STATIC(decl
) = 1;
1226 TREE_READONLY(decl
) = 1;
1227 TREE_CONSTANT(decl
) = 1;
1228 TREE_USED(decl
) = 1;
1229 DECL_ARTIFICIAL(decl
) = 1;
1231 // We don't call rest_of_decl_compilation until we have the
1234 go_preserve_from_gc(decl
);
1235 return new Bvariable(decl
);
1238 // Set the initializer for a variable created by immutable_struct.
1239 // This is where we finish compiling the variable.
1242 Gcc_backend::immutable_struct_set_init(Bvariable
* var
, const std::string
&,
1243 bool is_common
, Btype
*,
1245 Bexpression
* initializer
)
1247 tree decl
= var
->get_tree();
1248 tree init_tree
= initializer
->get_tree();
1249 if (decl
== error_mark_node
|| init_tree
== error_mark_node
)
1252 DECL_INITIAL(decl
) = init_tree
;
1254 // We can't call make_decl_one_only until we set DECL_INITIAL.
1256 TREE_PUBLIC(decl
) = 1;
1259 make_decl_one_only(decl
, DECL_ASSEMBLER_NAME(decl
));
1260 resolve_unique_section(decl
, 1, 0);
1263 rest_of_decl_compilation(decl
, 1, 0);
1266 // Return a reference to an immutable initialized data structure
1267 // defined in another package.
1270 Gcc_backend::immutable_struct_reference(const std::string
& name
, Btype
* btype
,
1271 source_location location
)
1273 tree type_tree
= btype
->get_tree();
1274 if (type_tree
== error_mark_node
)
1275 return this->error_variable();
1276 gcc_assert(TREE_CODE(type_tree
) == RECORD_TYPE
);
1277 tree decl
= build_decl(location
, VAR_DECL
,
1278 get_identifier_from_string(name
),
1279 build_qualified_type(type_tree
, TYPE_QUAL_CONST
));
1280 TREE_READONLY(decl
) = 1;
1281 TREE_CONSTANT(decl
) = 1;
1282 DECL_ARTIFICIAL(decl
) = 1;
1283 TREE_PUBLIC(decl
) = 1;
1284 DECL_EXTERNAL(decl
) = 1;
1285 go_preserve_from_gc(decl
);
1286 return new Bvariable(decl
);
1292 Gcc_backend::label(Bfunction
* function
, const std::string
& name
,
1293 source_location location
)
1297 decl
= create_artificial_label(location
);
1300 tree id
= get_identifier_from_string(name
);
1301 decl
= build_decl(location
, LABEL_DECL
, id
, void_type_node
);
1302 DECL_CONTEXT(decl
) = function
->get_tree();
1304 return new Blabel(decl
);
1307 // Make a statement which defines a label.
1310 Gcc_backend::label_definition_statement(Blabel
* label
)
1312 tree lab
= label
->get_tree();
1313 tree ret
= fold_build1_loc(DECL_SOURCE_LOCATION(lab
), LABEL_EXPR
,
1314 void_type_node
, lab
);
1315 return this->make_statement(ret
);
1318 // Make a goto statement.
1321 Gcc_backend::goto_statement(Blabel
* label
, source_location location
)
1323 tree lab
= label
->get_tree();
1324 tree ret
= fold_build1_loc(location
, GOTO_EXPR
, void_type_node
, lab
);
1325 return this->make_statement(ret
);
1328 // Get the address of a label.
1331 Gcc_backend::label_address(Blabel
* label
, source_location location
)
1333 tree lab
= label
->get_tree();
1335 TREE_ADDRESSABLE(lab
) = 1;
1336 tree ret
= fold_convert_loc(location
, ptr_type_node
,
1337 build_fold_addr_expr_loc(location
, lab
));
1338 return this->make_expression(ret
);
1341 // The single backend.
1343 static Gcc_backend gcc_backend
;
1345 // Return the backend generator.
1350 return &gcc_backend
;
1353 // FIXME: Temporary functions while converting to the new backend
1357 tree_to_type(tree t
)
1359 return new Btype(t
);
1363 tree_to_expr(tree t
)
1365 return new Bexpression(t
);
1369 tree_to_stat(tree t
)
1371 return new Bstatement(t
);
1375 tree_to_function(tree t
)
1377 return new Bfunction(t
);
1381 tree_to_block(tree t
)
1383 gcc_assert(TREE_CODE(t
) == BIND_EXPR
);
1384 return new Bblock(t
);
1388 type_to_tree(Btype
* bt
)
1390 return bt
->get_tree();
1394 expr_to_tree(Bexpression
* be
)
1396 return be
->get_tree();
1400 stat_to_tree(Bstatement
* bs
)
1402 return bs
->get_tree();
1406 block_to_tree(Bblock
* bb
)
1408 return bb
->get_tree();
1412 var_to_tree(Bvariable
* bv
)
1414 return bv
->get_tree();