OSDN Git Service

dbdf95f2e7bdabdfb4a9324c4ded2aaf772e9efc
[pf3gnuchains/gcc-fork.git] / gcc / go / go-gcc.cc
1 // go-gcc.cc -- Go frontend to gcc IR.
2 // Copyright (C) 2011 Free Software Foundation, Inc.
3 // Contributed by Ian Lance Taylor, Google.
4
5 // This file is part of GCC.
6
7 // GCC is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3, or (at your option) any later
10 // version.
11
12 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 // for more details.
16
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/>.
20
21 #include "go-system.h"
22
23 // This has to be included outside of extern "C", so we have to
24 // include it here before tree.h includes it later.
25 #include <gmp.h>
26
27 #ifndef ENABLE_BUILD_WITH_CXX
28 extern "C"
29 {
30 #endif
31
32 #include "tree.h"
33 #include "tree-iterator.h"
34 #include "gimple.h"
35 #include "toplev.h"
36
37 #ifndef ENABLE_BUILD_WITH_CXX
38 }
39 #endif
40
41 #include "go-c.h"
42
43 #include "gogo.h"
44 #include "backend.h"
45
46 // A class wrapping a tree.
47
48 class Gcc_tree
49 {
50  public:
51   Gcc_tree(tree t)
52     : t_(t)
53   { }
54
55   tree
56   get_tree() const
57   { return this->t_; }
58
59  private:
60   tree t_;
61 };
62
63 // In gcc, types, expressions, and statements are all trees.
64 class Btype : public Gcc_tree
65 {
66  public:
67   Btype(tree t)
68     : Gcc_tree(t)
69   { }
70 };
71
72 class Bexpression : public Gcc_tree
73 {
74  public:
75   Bexpression(tree t)
76     : Gcc_tree(t)
77   { }
78 };
79
80 class Bstatement : public Gcc_tree
81 {
82  public:
83   Bstatement(tree t)
84     : Gcc_tree(t)
85   { }
86 };
87
88 class Bfunction : public Gcc_tree
89 {
90  public:
91   Bfunction(tree t)
92     : Gcc_tree(t)
93   { }
94 };
95
96 class Bblock : public Gcc_tree
97 {
98  public:
99   Bblock(tree t)
100     : Gcc_tree(t)
101   { }
102 };
103
104 class Bvariable : public Gcc_tree
105 {
106  public:
107   Bvariable(tree t)
108     : Gcc_tree(t)
109   { }
110 };
111
112 class Blabel : public Gcc_tree
113 {
114  public:
115   Blabel(tree t)
116     : Gcc_tree(t)
117   { }
118 };
119
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.
125
126 class Gcc_backend : public Backend
127 {
128  public:
129   // Types.
130
131   Btype*
132   error_type()
133   { return this->make_type(error_mark_node); }
134
135   Btype*
136   void_type()
137   { return this->make_type(void_type_node); }
138
139   Btype*
140   bool_type()
141   { return this->make_type(boolean_type_node); }
142
143   Btype*
144   integer_type(bool, int);
145
146   Btype*
147   float_type(int);
148
149   Btype*
150   complex_type(int);
151
152   Btype*
153   pointer_type(Btype*);
154
155   Btype*
156   function_type(const Btyped_identifier&,
157                 const std::vector<Btyped_identifier>&,
158                 const std::vector<Btyped_identifier>&,
159                 source_location);
160
161   Btype*
162   struct_type(const std::vector<Btyped_identifier>&);
163
164   Btype*
165   array_type(Btype*, Bexpression*);
166
167   Btype*
168   placeholder_pointer_type(const std::string&, source_location, bool);
169
170   bool
171   set_placeholder_pointer_type(Btype*, Btype*);
172
173   bool
174   set_placeholder_function_type(Btype*, Btype*);
175
176   Btype*
177   placeholder_struct_type(const std::string&, source_location);
178
179   bool
180   set_placeholder_struct_type(Btype* placeholder,
181                               const std::vector<Btyped_identifier>&);
182
183   Btype*
184   placeholder_array_type(const std::string&, source_location);
185
186   bool
187   set_placeholder_array_type(Btype*, Btype*, Bexpression*);
188
189   Btype*
190   named_type(const std::string&, Btype*, source_location);
191
192   Btype*
193   circular_pointer_type(Btype*, bool);
194
195   bool
196   is_circular_pointer_type(Btype*);
197
198   // Expressions.
199
200   Bexpression*
201   zero_expression(Btype*);
202
203   // Statements.
204
205   Bstatement*
206   error_statement()
207   { return this->make_statement(error_mark_node); }
208
209   Bstatement*
210   expression_statement(Bexpression*);
211
212   Bstatement*
213   init_statement(Bvariable* var, Bexpression* init);
214
215   Bstatement*
216   assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location);
217
218   Bstatement*
219   return_statement(Bfunction*, const std::vector<Bexpression*>&,
220                    source_location);
221
222   Bstatement*
223   if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
224                source_location);
225
226   Bstatement*
227   switch_statement(Bexpression* value,
228                    const std::vector<std::vector<Bexpression*> >& cases,
229                    const std::vector<Bstatement*>& statements,
230                    source_location);
231
232   Bstatement*
233   compound_statement(Bstatement*, Bstatement*);
234
235   Bstatement*
236   statement_list(const std::vector<Bstatement*>&);
237
238   // Blocks.
239
240   Bblock*
241   block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
242         source_location, source_location);
243
244   void
245   block_add_statements(Bblock*, const std::vector<Bstatement*>&);
246
247   Bstatement*
248   block_statement(Bblock*);
249
250   // Variables.
251
252   Bvariable*
253   error_variable()
254   { return new Bvariable(error_mark_node); }
255
256   Bvariable*
257   global_variable(const std::string& package_name,
258                   const std::string& unique_prefix,
259                   const std::string& name,
260                   Btype* btype,
261                   bool is_external,
262                   bool is_hidden,
263                   source_location location);
264
265   void
266   global_variable_set_init(Bvariable*, Bexpression*);
267
268   Bvariable*
269   local_variable(Bfunction*, const std::string&, Btype*, bool,
270                  source_location);
271
272   Bvariable*
273   parameter_variable(Bfunction*, const std::string&, Btype*, bool,
274                      source_location);
275
276   Bvariable*
277   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
278                      source_location, Bstatement**);
279
280   Bvariable*
281   immutable_struct(const std::string&, bool, Btype*, source_location);
282
283   void
284   immutable_struct_set_init(Bvariable*, const std::string&, bool, Btype*,
285                             source_location, Bexpression*);
286
287   Bvariable*
288   immutable_struct_reference(const std::string&, Btype*, source_location);
289
290   // Labels.
291
292   Blabel*
293   label(Bfunction*, const std::string& name, source_location);
294
295   Bstatement*
296   label_definition_statement(Blabel*);
297
298   Bstatement*
299   goto_statement(Blabel*, source_location);
300
301   Bexpression*
302   label_address(Blabel*, source_location);
303
304  private:
305   // Make a Bexpression from a tree.
306   Bexpression*
307   make_expression(tree t)
308   { return new Bexpression(t); }
309
310   // Make a Bstatement from a tree.
311   Bstatement*
312   make_statement(tree t)
313   { return new Bstatement(t); }
314
315   // Make a Btype from a tree.
316   Btype*
317   make_type(tree t)
318   { return new Btype(t); }
319
320   Btype*
321   fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
322
323   Btype*
324   fill_in_array(Btype*, Btype*, Bexpression*);
325 };
326
327 // A helper function.
328
329 static inline tree
330 get_identifier_from_string(const std::string& str)
331 {
332   return get_identifier_with_length(str.data(), str.length());
333 }
334
335 // Get an unnamed integer type.
336
337 Btype*
338 Gcc_backend::integer_type(bool is_unsigned, int bits)
339 {
340   tree type;
341   if (is_unsigned)
342     {
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;
353       else
354         type = make_unsigned_type(bits);
355     }
356   else
357     {
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;
368       else
369         type = make_signed_type(bits);
370     }
371   return this->make_type(type);
372 }
373
374 // Get an unnamed float type.
375
376 Btype*
377 Gcc_backend::float_type(int bits)
378 {
379   tree type;
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;
386   else
387     {
388       type = make_node(REAL_TYPE);
389       TYPE_PRECISION(type) = bits;
390       layout_type(type);
391     }
392   return this->make_type(type);
393 }
394
395 // Get an unnamed complex type.
396
397 Btype*
398 Gcc_backend::complex_type(int bits)
399 {
400   tree type;
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;
407   else
408     {
409       type = make_node(REAL_TYPE);
410       TYPE_PRECISION(type) = bits / 2;
411       layout_type(type);
412       type = build_complex_type(type);
413     }
414   return this->make_type(type);
415 }
416
417 // Get a pointer type.
418
419 Btype*
420 Gcc_backend::pointer_type(Btype* to_type)
421 {
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);
427 }
428
429 // Make a function type.
430
431 Btype*
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)
436 {
437   tree args = NULL_TREE;
438   tree* pp = &args;
439   if (receiver.btype != NULL)
440     {
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);
446     }
447
448   for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
449        p != parameters.end();
450        ++p)
451     {
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);
457     }
458
459   // Varargs is handled entirely at the Go level.  When converted to
460   // GENERIC functions are not varargs.
461   *pp = void_list_node;
462
463   tree result;
464   if (results.empty())
465     result = void_type_node;
466   else if (results.size() == 1)
467     result = results.front().btype->get_tree();
468   else
469     {
470       result = make_node(RECORD_TYPE);
471       tree field_trees = NULL_TREE;
472       pp = &field_trees;
473       for (std::vector<Btyped_identifier>::const_iterator p = results.begin();
474            p != results.end();
475            ++p)
476         {
477           const std::string name = (p->name.empty()
478                                     ? "UNNAMED"
479                                     : p->name);
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,
486                                   field_type_tree);
487           DECL_CONTEXT(field) = result;
488           *pp = field;
489           pp = &DECL_CHAIN(field);
490         }
491       TYPE_FIELDS(result) = field_trees;
492       layout_type(result);
493     }
494   if (result == error_mark_node)
495     return this->error_type();
496
497   tree fntype = build_function_type(result, args);
498   if (fntype == error_mark_node)
499     return this->error_type();
500
501   return this->make_type(build_pointer_type(fntype));
502 }
503
504 // Make a struct type.
505
506 Btype*
507 Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
508 {
509   return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE)), fields);
510 }
511
512 // Fill in the fields of a struct type.
513
514 Btype*
515 Gcc_backend::fill_in_struct(Btype* fill,
516                             const std::vector<Btyped_identifier>& fields)
517 {
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();
522        p != fields.end();
523        ++p)
524     {
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;
531       *pp = field;
532       pp = &DECL_CHAIN(field);
533     }
534   TYPE_FIELDS(fill_tree) = field_trees;
535   layout_type(fill_tree);
536   return fill;
537 }
538
539 // Make an array type.
540
541 Btype*
542 Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
543 {
544   return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
545                              element_btype, length);
546 }
547
548 // Fill in an array type.
549
550 Btype*
551 Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
552                            Bexpression* length)
553 {
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();
558
559   gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
560
561   length_tree = fold_convert(sizetype, length_tree);
562
563   // build_index_type takes the maximum index, which is one less than
564   // the length.
565   tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
566                                                       length_tree,
567                                                       size_one_node));
568
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);
574
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));
582
583   return fill;
584 }
585
586 // Create a placeholder for a pointer type.
587
588 Btype*
589 Gcc_backend::placeholder_pointer_type(const std::string& name,
590                                       source_location location, bool)
591 {
592   tree ret = build_variant_type_copy(ptr_type_node);
593   if (!name.empty())
594     {
595       tree decl = build_decl(location, TYPE_DECL,
596                              get_identifier_from_string(name),
597                              ret);
598       TYPE_NAME(ret) = decl;
599     }
600   return this->make_type(ret);
601 }
602
603 // Set the real target type for a placeholder pointer type.
604
605 bool
606 Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
607                                           Btype* to_type)
608 {
609   tree pt = placeholder->get_tree();
610   if (pt == error_mark_node)
611     return false;
612   gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
613   tree tt = to_type->get_tree();
614   if (tt == error_mark_node)
615     {
616       TREE_TYPE(pt) = tt;
617       return false;
618     }
619   gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
620   TREE_TYPE(pt) = TREE_TYPE(tt);
621   return true;
622 }
623
624 // Set the real values for a placeholder function type.
625
626 bool
627 Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
628 {
629   return this->set_placeholder_pointer_type(placeholder, ft);
630 }
631
632 // Create a placeholder for a struct type.
633
634 Btype*
635 Gcc_backend::placeholder_struct_type(const std::string& name,
636                                      source_location location)
637 {
638   tree ret = make_node(RECORD_TYPE);
639   tree decl = build_decl(location, TYPE_DECL,
640                          get_identifier_from_string(name),
641                          ret);
642   TYPE_NAME(ret) = decl;
643   return this->make_type(ret);
644 }
645
646 // Fill in the fields of a placeholder struct type.
647
648 bool
649 Gcc_backend::set_placeholder_struct_type(
650     Btype* placeholder,
651     const std::vector<Btyped_identifier>& fields)
652 {
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;
657 }
658
659 // Create a placeholder for an array type.
660
661 Btype*
662 Gcc_backend::placeholder_array_type(const std::string& name,
663                                     source_location location)
664 {
665   tree ret = make_node(ARRAY_TYPE);
666   tree decl = build_decl(location, TYPE_DECL,
667                          get_identifier_from_string(name),
668                          ret);
669   TYPE_NAME(ret) = decl;
670   return this->make_type(ret);
671 }
672
673 // Fill in the fields of a placeholder array type.
674
675 bool
676 Gcc_backend::set_placeholder_array_type(Btype* placeholder,
677                                         Btype* element_btype,
678                                         Bexpression* length)
679 {
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;
684 }
685
686 // Return a named version of a type.
687
688 Btype*
689 Gcc_backend::named_type(const std::string& name, Btype* btype,
690                         source_location location)
691 {
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),
698                          type);
699   TYPE_NAME(type) = decl;
700   return this->make_type(type);
701 }
702
703 // Return a pointer type used as a marker for a circular type.
704
705 Btype*
706 Gcc_backend::circular_pointer_type(Btype*, bool)
707 {
708   return this->make_type(ptr_type_node);
709 }
710
711 // Return whether we might be looking at a circular type.
712
713 bool
714 Gcc_backend::is_circular_pointer_type(Btype* btype)
715 {
716   return btype->get_tree() == ptr_type_node;
717 }
718
719 // Return the zero value for a type.
720
721 Bexpression*
722 Gcc_backend::zero_expression(Btype* btype)
723 {
724   tree t = btype->get_tree();
725   tree ret;
726   if (t == error_mark_node)
727     ret = error_mark_node;
728   else
729     ret = build_zero_cst(t);
730   return tree_to_expr(ret);
731 }
732
733 // An expression as a statement.
734
735 Bstatement*
736 Gcc_backend::expression_statement(Bexpression* expr)
737 {
738   return this->make_statement(expr->get_tree());
739 }
740
741 // Variable initialization.
742
743 Bstatement*
744 Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
745 {
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));
754 }
755
756 // Assignment.
757
758 Bstatement*
759 Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
760                                   source_location location)
761 {
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,
767                                               void_type_node,
768                                               lhs_tree, rhs_tree));
769 }
770
771 // Return.
772
773 Bstatement*
774 Gcc_backend::return_statement(Bfunction* bfunction,
775                               const std::vector<Bexpression*>& vals,
776                               source_location location)
777 {
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();
784   tree ret;
785   if (vals.empty())
786     ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, NULL_TREE);
787   else if (vals.size() == 1)
788     {
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);
795     }
796   else
797     {
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
801       // statement.
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();
807            p != vals.end();
808            p++, field = DECL_CHAIN(field))
809         {
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);
819         }
820       gcc_assert(field == NULL_TREE);
821       tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
822                                  result, rettmp);
823       tree ret_expr = fold_build1_loc(location, RETURN_EXPR, void_type_node,
824                                       set);
825       append_to_statement_list(ret_expr, &stmt_list);
826       ret = stmt_list;
827     }
828   return this->make_statement(ret);
829 }
830
831 // If.
832
833 Bstatement*
834 Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
835                           Bblock* else_block, source_location location)
836 {
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);
847 }
848
849 // Switch.
850
851 Bstatement*
852 Gcc_backend::switch_statement(
853     Bexpression* value,
854     const std::vector<std::vector<Bexpression*> >& cases,
855     const std::vector<Bstatement*>& statements,
856     source_location switch_location)
857 {
858   gcc_assert(cases.size() == statements.size());
859
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();
864        ++ps, ++pc)
865     {
866       if (pc->empty())
867         {
868           source_location loc = (*ps != NULL
869                                  ? EXPR_LOCATION((*ps)->get_tree())
870                                  : UNKNOWN_LOCATION);
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);
874         }
875       else
876         {
877           for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
878                pcv != pc->end();
879                ++pcv)
880             {
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);
888             }
889         }
890
891       if (*ps != NULL)
892         {
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);
897         }
898     }
899
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);
906 }
907
908 // Pair of statements.
909
910 Bstatement*
911 Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
912 {
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);
918   t = s2->get_tree();
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);
923 }
924
925 // List of statements.
926
927 Bstatement*
928 Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
929 {
930   tree stmt_list = NULL_TREE;
931   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
932        p != statements.end();
933        ++p)
934     {
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);
939     }
940   return this->make_statement(stmt_list);
941 }
942
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
946 // the Bblock.
947
948 Bblock*
949 Gcc_backend::block(Bfunction* function, Bblock* enclosing,
950                    const std::vector<Bvariable*>& vars,
951                    source_location start_location,
952                    source_location)
953 {
954   tree block_tree = make_node(BLOCK);
955   if (enclosing == NULL)
956     {
957       // FIXME: Permitting FUNCTION to be NULL is a temporary measure
958       // until we have a proper representation of the init function.
959       tree fndecl;
960       if (function == NULL)
961         fndecl = current_function_decl;
962       else
963         fndecl = function->get_tree();
964       gcc_assert(fndecl != NULL_TREE);
965
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)
969         {
970           BLOCK_SUPERCONTEXT(block_tree) = fndecl;
971           DECL_INITIAL(fndecl) = block_tree;
972         }
973       else
974         {
975           tree superblock_tree = DECL_INITIAL(fndecl);
976           BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
977           tree* pp;
978           for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
979                *pp != NULL_TREE;
980                pp = &BLOCK_CHAIN(*pp))
981             ;
982           *pp = block_tree;
983         }
984     }
985   else
986     {
987       tree superbind_tree = enclosing->get_tree();
988       tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
989       gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
990
991       BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
992       tree* pp;
993       for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
994            *pp != NULL_TREE;
995            pp = &BLOCK_CHAIN(*pp))
996         ;
997       *pp = block_tree;
998     }
999
1000   tree* pp = &BLOCK_VARS(block_tree);
1001   for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
1002        pv != vars.end();
1003        ++pv)
1004     {
1005       *pp = (*pv)->get_tree();
1006       if (*pp != error_mark_node)
1007         pp = &DECL_CHAIN(*pp);
1008     }
1009   *pp = NULL_TREE;
1010
1011   TREE_USED(block_tree) = 1;
1012
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;
1016
1017   return new Bblock(bind_tree);
1018 }
1019
1020 // Add statements to a block.
1021
1022 void
1023 Gcc_backend::block_add_statements(Bblock* bblock,
1024                                   const std::vector<Bstatement*>& statements)
1025 {
1026   tree stmt_list = NULL_TREE;
1027   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
1028        p != statements.end();
1029        ++p)
1030     {
1031       tree s = (*p)->get_tree();
1032       if (s != error_mark_node)
1033         append_to_statement_list(s, &stmt_list);
1034     }
1035
1036   tree bind_tree = bblock->get_tree();
1037   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1038   BIND_EXPR_BODY(bind_tree) = stmt_list;
1039 }
1040
1041 // Return a block as a statement.
1042
1043 Bstatement*
1044 Gcc_backend::block_statement(Bblock* bblock)
1045 {
1046   tree bind_tree = bblock->get_tree();
1047   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1048   return this->make_statement(bind_tree);
1049 }
1050
1051 // Make a global variable.
1052
1053 Bvariable*
1054 Gcc_backend::global_variable(const std::string& package_name,
1055                              const std::string& unique_prefix,
1056                              const std::string& name,
1057                              Btype* btype,
1058                              bool is_external,
1059                              bool is_hidden,
1060                              source_location location)
1061 {
1062   tree type_tree = btype->get_tree();
1063   if (type_tree == error_mark_node)
1064     return this->error_variable();
1065
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),
1071                          type_tree);
1072   if (is_external)
1073     DECL_EXTERNAL(decl) = 1;
1074   else
1075     TREE_STATIC(decl) = 1;
1076   if (!is_hidden)
1077     {
1078       TREE_PUBLIC(decl) = 1;
1079
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));
1084     }
1085   TREE_USED(decl) = 1;
1086
1087   go_preserve_from_gc(decl);
1088
1089   return new Bvariable(decl);
1090 }
1091
1092 // Set the initial value of a global variable.
1093
1094 void
1095 Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
1096 {
1097   tree expr_tree = expr->get_tree();
1098   if (expr_tree == error_mark_node)
1099     return;
1100   gcc_assert(TREE_CONSTANT(expr_tree));
1101   tree var_decl = var->get_tree();
1102   if (var_decl == error_mark_node)
1103     return;
1104   DECL_INITIAL(var_decl) = expr_tree;
1105 }
1106
1107 // Make a local variable.
1108
1109 Bvariable*
1110 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
1111                             Btype* btype, bool is_address_taken,
1112                             source_location location)
1113 {
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),
1119                          type_tree);
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);
1126 }
1127
1128 // Make a function parameter variable.
1129
1130 Bvariable*
1131 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
1132                                 Btype* btype, bool is_address_taken,
1133                                 source_location location)
1134 {
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),
1140                          type_tree);
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);
1148 }
1149
1150 // Make a temporary variable.
1151
1152 Bvariable*
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)
1158 {
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)
1162     {
1163       *pstatement = this->error_statement();
1164       return this->error_variable();
1165     }
1166
1167   tree var;
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");
1171   else
1172     {
1173       gcc_assert(bblock != NULL);
1174       var = build_decl(location, VAR_DECL,
1175                        create_tmp_var_name("GOTMP"),
1176                        type_tree);
1177       DECL_ARTIFICIAL(var) = 1;
1178       DECL_IGNORED_P(var) = 1;
1179       TREE_USED(var) = 1;
1180       // FIXME: Permitting function to be NULL here is a temporary
1181       // measure until we have a proper representation of the init
1182       // function.
1183       if (function != NULL)
1184         DECL_CONTEXT(var) = function->get_tree();
1185       else
1186         {
1187           gcc_assert(current_function_decl != NULL_TREE);
1188           DECL_CONTEXT(var) = current_function_decl;
1189         }
1190
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);
1199     }
1200
1201   if (init_tree != NULL_TREE)
1202     DECL_INITIAL(var) = fold_convert_loc(location, type_tree, init_tree);
1203
1204   if (is_address_taken)
1205     TREE_ADDRESSABLE(var) = 1;
1206
1207   *pstatement = this->make_statement(build1_loc(location, DECL_EXPR,
1208                                                 void_type_node, var));
1209   return new Bvariable(var);
1210 }
1211
1212 // Create a named immutable initialized data structure.
1213
1214 Bvariable*
1215 Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype,
1216                               source_location location)
1217 {
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;
1230
1231   // We don't call rest_of_decl_compilation until we have the
1232   // initializer.
1233
1234   go_preserve_from_gc(decl);
1235   return new Bvariable(decl);
1236 }
1237
1238 // Set the initializer for a variable created by immutable_struct.
1239 // This is where we finish compiling the variable.
1240
1241 void
1242 Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
1243                                        bool is_common, Btype*,
1244                                        source_location,
1245                                        Bexpression* initializer)
1246 {
1247   tree decl = var->get_tree();
1248   tree init_tree = initializer->get_tree();
1249   if (decl == error_mark_node || init_tree == error_mark_node)
1250     return;
1251
1252   DECL_INITIAL(decl) = init_tree;
1253
1254   // We can't call make_decl_one_only until we set DECL_INITIAL.
1255   if (!is_common)
1256     TREE_PUBLIC(decl) = 1;
1257   else
1258     {
1259       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
1260       resolve_unique_section(decl, 1, 0);
1261     }
1262
1263   rest_of_decl_compilation(decl, 1, 0);
1264 }
1265
1266 // Return a reference to an immutable initialized data structure
1267 // defined in another package.
1268
1269 Bvariable*
1270 Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
1271                                         source_location location)
1272 {
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);
1287 }
1288
1289 // Make a label.
1290
1291 Blabel*
1292 Gcc_backend::label(Bfunction* function, const std::string& name,
1293                    source_location location)
1294 {
1295   tree decl;
1296   if (name.empty())
1297     decl = create_artificial_label(location);
1298   else
1299     {
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();
1303     }
1304   return new Blabel(decl);
1305 }
1306
1307 // Make a statement which defines a label.
1308
1309 Bstatement*
1310 Gcc_backend::label_definition_statement(Blabel* label)
1311 {
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);
1316 }
1317
1318 // Make a goto statement.
1319
1320 Bstatement*
1321 Gcc_backend::goto_statement(Blabel* label, source_location location)
1322 {
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);
1326 }
1327
1328 // Get the address of a label.
1329
1330 Bexpression*
1331 Gcc_backend::label_address(Blabel* label, source_location location)
1332 {
1333   tree lab = label->get_tree();
1334   TREE_USED(lab) = 1;
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);
1339 }
1340
1341 // The single backend.
1342
1343 static Gcc_backend gcc_backend;
1344
1345 // Return the backend generator.
1346
1347 Backend*
1348 go_get_backend()
1349 {
1350   return &gcc_backend;
1351 }
1352
1353 // FIXME: Temporary functions while converting to the new backend
1354 // interface.
1355
1356 Btype*
1357 tree_to_type(tree t)
1358 {
1359   return new Btype(t);
1360 }
1361
1362 Bexpression*
1363 tree_to_expr(tree t)
1364 {
1365   return new Bexpression(t);
1366 }
1367
1368 Bstatement*
1369 tree_to_stat(tree t)
1370 {
1371   return new Bstatement(t);
1372 }
1373
1374 Bfunction*
1375 tree_to_function(tree t)
1376 {
1377   return new Bfunction(t);
1378 }
1379
1380 Bblock*
1381 tree_to_block(tree t)
1382 {
1383   gcc_assert(TREE_CODE(t) == BIND_EXPR);
1384   return new Bblock(t);
1385 }
1386
1387 tree
1388 type_to_tree(Btype* bt)
1389 {
1390   return bt->get_tree();
1391 }
1392
1393 tree
1394 expr_to_tree(Bexpression* be)
1395 {
1396   return be->get_tree();
1397 }
1398
1399 tree
1400 stat_to_tree(Bstatement* bs)
1401 {
1402   return bs->get_tree();
1403 }
1404
1405 tree
1406 block_to_tree(Bblock* bb)
1407 {
1408   return bb->get_tree();
1409 }
1410
1411 tree
1412 var_to_tree(Bvariable* bv)
1413 {
1414   return bv->get_tree();
1415 }