OSDN Git Service

* common/config/i386/i386-common.c (ix86_option_optimization_table):
[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                 const 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&, 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&, 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&, Location);
185
186   bool
187   set_placeholder_array_type(Btype*, Btype*, Bexpression*);
188
189   Btype*
190   named_type(const std::string&, Btype*, 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, Location);
217
218   Bstatement*
219   return_statement(Bfunction*, const std::vector<Bexpression*>&,
220                    Location);
221
222   Bstatement*
223   if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
224                Location);
225
226   Bstatement*
227   switch_statement(Bexpression* value,
228                    const std::vector<std::vector<Bexpression*> >& cases,
229                    const std::vector<Bstatement*>& statements,
230                    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         Location, 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                   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                  Location);
271
272   Bvariable*
273   parameter_variable(Bfunction*, const std::string&, Btype*, bool,
274                      Location);
275
276   Bvariable*
277   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
278                      Location, Bstatement**);
279
280   Bvariable*
281   immutable_struct(const std::string&, bool, Btype*, Location);
282
283   void
284   immutable_struct_set_init(Bvariable*, const std::string&, bool, Btype*,
285                             Location, Bexpression*);
286
287   Bvariable*
288   immutable_struct_reference(const std::string&, Btype*, Location);
289
290   // Labels.
291
292   Blabel*
293   label(Bfunction*, const std::string& name, Location);
294
295   Bstatement*
296   label_definition_statement(Blabel*);
297
298   Bstatement*
299   goto_statement(Blabel*, Location);
300
301   Bexpression*
302   label_address(Blabel*, 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                            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.gcc_location(), FIELD_DECL,
486                                   name_tree, 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.gcc_location(), FIELD_DECL, name_tree,
530                               type_tree);
531       DECL_CONTEXT(field) = fill_tree;
532       *pp = field;
533       pp = &DECL_CHAIN(field);
534     }
535   TYPE_FIELDS(fill_tree) = field_trees;
536   layout_type(fill_tree);
537   return fill;
538 }
539
540 // Make an array type.
541
542 Btype*
543 Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
544 {
545   return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
546                              element_btype, length);
547 }
548
549 // Fill in an array type.
550
551 Btype*
552 Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
553                            Bexpression* length)
554 {
555   tree element_type_tree = element_type->get_tree();
556   tree length_tree = length->get_tree();
557   if (element_type_tree == error_mark_node || length_tree == error_mark_node)
558     return this->error_type();
559
560   gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
561
562   length_tree = fold_convert(sizetype, length_tree);
563
564   // build_index_type takes the maximum index, which is one less than
565   // the length.
566   tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
567                                                       length_tree,
568                                                       size_one_node));
569
570   tree fill_tree = fill->get_tree();
571   TREE_TYPE(fill_tree) = element_type_tree;
572   TYPE_DOMAIN(fill_tree) = index_type_tree;
573   TYPE_ADDR_SPACE(fill_tree) = TYPE_ADDR_SPACE(element_type_tree);
574   layout_type(fill_tree);
575
576   if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree))
577     SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
578   else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
579            || TYPE_CANONICAL(index_type_tree) != index_type_tree)
580     TYPE_CANONICAL(fill_tree) =
581       build_array_type(TYPE_CANONICAL(element_type_tree),
582                        TYPE_CANONICAL(index_type_tree));
583
584   return fill;
585 }
586
587 // Create a placeholder for a pointer type.
588
589 Btype*
590 Gcc_backend::placeholder_pointer_type(const std::string& name,
591                                       Location location, bool)
592 {
593   tree ret = build_variant_type_copy(ptr_type_node);
594   if (!name.empty())
595     {
596       tree decl = build_decl(location.gcc_location(), TYPE_DECL,
597                              get_identifier_from_string(name),
598                              ret);
599       TYPE_NAME(ret) = decl;
600     }
601   return this->make_type(ret);
602 }
603
604 // Set the real target type for a placeholder pointer type.
605
606 bool
607 Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
608                                           Btype* to_type)
609 {
610   tree pt = placeholder->get_tree();
611   if (pt == error_mark_node)
612     return false;
613   gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
614   tree tt = to_type->get_tree();
615   if (tt == error_mark_node)
616     {
617       TREE_TYPE(pt) = tt;
618       return false;
619     }
620   gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
621   TREE_TYPE(pt) = TREE_TYPE(tt);
622   return true;
623 }
624
625 // Set the real values for a placeholder function type.
626
627 bool
628 Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
629 {
630   return this->set_placeholder_pointer_type(placeholder, ft);
631 }
632
633 // Create a placeholder for a struct type.
634
635 Btype*
636 Gcc_backend::placeholder_struct_type(const std::string& name,
637                                      Location location)
638 {
639   tree ret = make_node(RECORD_TYPE);
640   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
641                          get_identifier_from_string(name),
642                          ret);
643   TYPE_NAME(ret) = decl;
644   return this->make_type(ret);
645 }
646
647 // Fill in the fields of a placeholder struct type.
648
649 bool
650 Gcc_backend::set_placeholder_struct_type(
651     Btype* placeholder,
652     const std::vector<Btyped_identifier>& fields)
653 {
654   tree t = placeholder->get_tree();
655   gcc_assert(TREE_CODE(t) == RECORD_TYPE && TYPE_FIELDS(t) == NULL_TREE);
656   Btype* r = this->fill_in_struct(placeholder, fields);
657   return r->get_tree() != error_mark_node;
658 }
659
660 // Create a placeholder for an array type.
661
662 Btype*
663 Gcc_backend::placeholder_array_type(const std::string& name,
664                                     Location location)
665 {
666   tree ret = make_node(ARRAY_TYPE);
667   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
668                          get_identifier_from_string(name),
669                          ret);
670   TYPE_NAME(ret) = decl;
671   return this->make_type(ret);
672 }
673
674 // Fill in the fields of a placeholder array type.
675
676 bool
677 Gcc_backend::set_placeholder_array_type(Btype* placeholder,
678                                         Btype* element_btype,
679                                         Bexpression* length)
680 {
681   tree t = placeholder->get_tree();
682   gcc_assert(TREE_CODE(t) == ARRAY_TYPE && TREE_TYPE(t) == NULL_TREE);
683   Btype* r = this->fill_in_array(placeholder, element_btype, length);
684   return r->get_tree() != error_mark_node;
685 }
686
687 // Return a named version of a type.
688
689 Btype*
690 Gcc_backend::named_type(const std::string& name, Btype* btype,
691                         Location location)
692 {
693   tree type = btype->get_tree();
694   if (type == error_mark_node)
695     return this->error_type();
696   type = build_variant_type_copy(type);
697   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
698                          get_identifier_from_string(name),
699                          type);
700   TYPE_NAME(type) = decl;
701   return this->make_type(type);
702 }
703
704 // Return a pointer type used as a marker for a circular type.
705
706 Btype*
707 Gcc_backend::circular_pointer_type(Btype*, bool)
708 {
709   return this->make_type(ptr_type_node);
710 }
711
712 // Return whether we might be looking at a circular type.
713
714 bool
715 Gcc_backend::is_circular_pointer_type(Btype* btype)
716 {
717   return btype->get_tree() == ptr_type_node;
718 }
719
720 // Return the zero value for a type.
721
722 Bexpression*
723 Gcc_backend::zero_expression(Btype* btype)
724 {
725   tree t = btype->get_tree();
726   tree ret;
727   if (t == error_mark_node)
728     ret = error_mark_node;
729   else
730     ret = build_zero_cst(t);
731   return tree_to_expr(ret);
732 }
733
734 // An expression as a statement.
735
736 Bstatement*
737 Gcc_backend::expression_statement(Bexpression* expr)
738 {
739   return this->make_statement(expr->get_tree());
740 }
741
742 // Variable initialization.
743
744 Bstatement*
745 Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
746 {
747   tree var_tree = var->get_tree();
748   tree init_tree = init->get_tree();
749   if (var_tree == error_mark_node || init_tree == error_mark_node)
750     return this->error_statement();
751   gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
752   DECL_INITIAL(var_tree) = init_tree;
753   return this->make_statement(build1_loc(DECL_SOURCE_LOCATION(var_tree),
754                                          DECL_EXPR, void_type_node, var_tree));
755 }
756
757 // Assignment.
758
759 Bstatement*
760 Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
761                                   Location location)
762 {
763   tree lhs_tree = lhs->get_tree();
764   tree rhs_tree = rhs->get_tree();
765   if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
766     return this->error_statement();
767   return this->make_statement(fold_build2_loc(location.gcc_location(),
768                                               MODIFY_EXPR,
769                                               void_type_node,
770                                               lhs_tree, rhs_tree));
771 }
772
773 // Return.
774
775 Bstatement*
776 Gcc_backend::return_statement(Bfunction* bfunction,
777                               const std::vector<Bexpression*>& vals,
778                               Location location)
779 {
780   tree fntree = bfunction->get_tree();
781   if (fntree == error_mark_node)
782     return this->error_statement();
783   tree result = DECL_RESULT(fntree);
784   if (result == error_mark_node)
785     return this->error_statement();
786   tree ret;
787   if (vals.empty())
788     ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
789                           NULL_TREE);
790   else if (vals.size() == 1)
791     {
792       tree val = vals.front()->get_tree();
793       if (val == error_mark_node)
794         return this->error_statement();
795       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
796                                  void_type_node, result,
797                                  vals.front()->get_tree());
798       ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
799                             void_type_node, set);
800     }
801   else
802     {
803       // To return multiple values, copy the values into a temporary
804       // variable of the right structure type, and then assign the
805       // temporary variable to the DECL_RESULT in the return
806       // statement.
807       tree stmt_list = NULL_TREE;
808       tree rettype = TREE_TYPE(result);
809       tree rettmp = create_tmp_var(rettype, "RESULT");
810       tree field = TYPE_FIELDS(rettype);
811       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
812            p != vals.end();
813            p++, field = DECL_CHAIN(field))
814         {
815           gcc_assert(field != NULL_TREE);
816           tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
817                                      TREE_TYPE(field), rettmp, field,
818                                      NULL_TREE);
819           tree val = (*p)->get_tree();
820           if (val == error_mark_node)
821             return this->error_statement();
822           tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
823                                      void_type_node,
824                                      ref, (*p)->get_tree());
825           append_to_statement_list(set, &stmt_list);
826         }
827       gcc_assert(field == NULL_TREE);
828       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
829                                  void_type_node,
830                                  result, rettmp);
831       tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
832                                       void_type_node, set);
833       append_to_statement_list(ret_expr, &stmt_list);
834       ret = stmt_list;
835     }
836   return this->make_statement(ret);
837 }
838
839 // If.
840
841 Bstatement*
842 Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
843                           Bblock* else_block, Location location)
844 {
845   tree cond_tree = condition->get_tree();
846   tree then_tree = then_block->get_tree();
847   tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
848   if (cond_tree == error_mark_node
849       || then_tree == error_mark_node
850       || else_tree == error_mark_node)
851     return this->error_statement();
852   tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
853                         cond_tree, then_tree, else_tree);
854   return this->make_statement(ret);
855 }
856
857 // Switch.
858
859 Bstatement*
860 Gcc_backend::switch_statement(
861     Bexpression* value,
862     const std::vector<std::vector<Bexpression*> >& cases,
863     const std::vector<Bstatement*>& statements,
864     Location switch_location)
865 {
866   gcc_assert(cases.size() == statements.size());
867
868   tree stmt_list = NULL_TREE;
869   std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
870   for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
871        ps != statements.end();
872        ++ps, ++pc)
873     {
874       if (pc->empty())
875         {
876           source_location loc = (*ps != NULL
877                                  ? EXPR_LOCATION((*ps)->get_tree())
878                                  : UNKNOWN_LOCATION);
879           tree label = create_artificial_label(loc);
880           tree c = build_case_label(NULL_TREE, NULL_TREE, label);
881           append_to_statement_list(c, &stmt_list);
882         }
883       else
884         {
885           for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
886                pcv != pc->end();
887                ++pcv)
888             {
889               tree t = (*pcv)->get_tree();
890               if (t == error_mark_node)
891                 return this->error_statement();
892               source_location loc = EXPR_LOCATION(t);
893               tree label = create_artificial_label(loc);
894               tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
895               append_to_statement_list(c, &stmt_list);
896             }
897         }
898
899       if (*ps != NULL)
900         {
901           tree t = (*ps)->get_tree();
902           if (t == error_mark_node)
903             return this->error_statement();
904           append_to_statement_list(t, &stmt_list);
905         }
906     }
907
908   tree tv = value->get_tree();
909   if (tv == error_mark_node)
910     return this->error_statement();
911   tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR,
912                       void_type_node, tv, stmt_list, NULL_TREE);
913   return this->make_statement(t);
914 }
915
916 // Pair of statements.
917
918 Bstatement*
919 Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
920 {
921   tree stmt_list = NULL_TREE;
922   tree t = s1->get_tree();
923   if (t == error_mark_node)
924     return this->error_statement();
925   append_to_statement_list(t, &stmt_list);
926   t = s2->get_tree();
927   if (t == error_mark_node)
928     return this->error_statement();
929   append_to_statement_list(t, &stmt_list);
930   return this->make_statement(stmt_list);
931 }
932
933 // List of statements.
934
935 Bstatement*
936 Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
937 {
938   tree stmt_list = NULL_TREE;
939   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
940        p != statements.end();
941        ++p)
942     {
943       tree t = (*p)->get_tree();
944       if (t == error_mark_node)
945         return this->error_statement();
946       append_to_statement_list(t, &stmt_list);
947     }
948   return this->make_statement(stmt_list);
949 }
950
951 // Make a block.  For some reason gcc uses a dual structure for
952 // blocks: BLOCK tree nodes and BIND_EXPR tree nodes.  Since the
953 // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
954 // the Bblock.
955
956 Bblock*
957 Gcc_backend::block(Bfunction* function, Bblock* enclosing,
958                    const std::vector<Bvariable*>& vars,
959                    Location start_location,
960                    Location)
961 {
962   tree block_tree = make_node(BLOCK);
963   if (enclosing == NULL)
964     {
965       // FIXME: Permitting FUNCTION to be NULL is a temporary measure
966       // until we have a proper representation of the init function.
967       tree fndecl;
968       if (function == NULL)
969         fndecl = current_function_decl;
970       else
971         fndecl = function->get_tree();
972       gcc_assert(fndecl != NULL_TREE);
973
974       // We may have already created a block for local variables when
975       // we take the address of a parameter.
976       if (DECL_INITIAL(fndecl) == NULL_TREE)
977         {
978           BLOCK_SUPERCONTEXT(block_tree) = fndecl;
979           DECL_INITIAL(fndecl) = block_tree;
980         }
981       else
982         {
983           tree superblock_tree = DECL_INITIAL(fndecl);
984           BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
985           tree* pp;
986           for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
987                *pp != NULL_TREE;
988                pp = &BLOCK_CHAIN(*pp))
989             ;
990           *pp = block_tree;
991         }
992     }
993   else
994     {
995       tree superbind_tree = enclosing->get_tree();
996       tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
997       gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
998
999       BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
1000       tree* pp;
1001       for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
1002            *pp != NULL_TREE;
1003            pp = &BLOCK_CHAIN(*pp))
1004         ;
1005       *pp = block_tree;
1006     }
1007
1008   tree* pp = &BLOCK_VARS(block_tree);
1009   for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
1010        pv != vars.end();
1011        ++pv)
1012     {
1013       *pp = (*pv)->get_tree();
1014       if (*pp != error_mark_node)
1015         pp = &DECL_CHAIN(*pp);
1016     }
1017   *pp = NULL_TREE;
1018
1019   TREE_USED(block_tree) = 1;
1020
1021   tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
1022                               void_type_node, BLOCK_VARS(block_tree),
1023                               NULL_TREE, block_tree);
1024   TREE_SIDE_EFFECTS(bind_tree) = 1;
1025
1026   return new Bblock(bind_tree);
1027 }
1028
1029 // Add statements to a block.
1030
1031 void
1032 Gcc_backend::block_add_statements(Bblock* bblock,
1033                                   const std::vector<Bstatement*>& statements)
1034 {
1035   tree stmt_list = NULL_TREE;
1036   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
1037        p != statements.end();
1038        ++p)
1039     {
1040       tree s = (*p)->get_tree();
1041       if (s != error_mark_node)
1042         append_to_statement_list(s, &stmt_list);
1043     }
1044
1045   tree bind_tree = bblock->get_tree();
1046   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1047   BIND_EXPR_BODY(bind_tree) = stmt_list;
1048 }
1049
1050 // Return a block as a statement.
1051
1052 Bstatement*
1053 Gcc_backend::block_statement(Bblock* bblock)
1054 {
1055   tree bind_tree = bblock->get_tree();
1056   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1057   return this->make_statement(bind_tree);
1058 }
1059
1060 // Make a global variable.
1061
1062 Bvariable*
1063 Gcc_backend::global_variable(const std::string& package_name,
1064                              const std::string& unique_prefix,
1065                              const std::string& name,
1066                              Btype* btype,
1067                              bool is_external,
1068                              bool is_hidden,
1069                              Location location)
1070 {
1071   tree type_tree = btype->get_tree();
1072   if (type_tree == error_mark_node)
1073     return this->error_variable();
1074
1075   std::string var_name(package_name);
1076   var_name.push_back('.');
1077   var_name.append(name);
1078   tree decl = build_decl(location.gcc_location(), VAR_DECL,
1079                          get_identifier_from_string(var_name),
1080                          type_tree);
1081   if (is_external)
1082     DECL_EXTERNAL(decl) = 1;
1083   else
1084     TREE_STATIC(decl) = 1;
1085   if (!is_hidden)
1086     {
1087       TREE_PUBLIC(decl) = 1;
1088
1089       std::string asm_name(unique_prefix);
1090       asm_name.push_back('.');
1091       asm_name.append(var_name);
1092       SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
1093     }
1094   TREE_USED(decl) = 1;
1095
1096   go_preserve_from_gc(decl);
1097
1098   return new Bvariable(decl);
1099 }
1100
1101 // Set the initial value of a global variable.
1102
1103 void
1104 Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
1105 {
1106   tree expr_tree = expr->get_tree();
1107   if (expr_tree == error_mark_node)
1108     return;
1109   gcc_assert(TREE_CONSTANT(expr_tree));
1110   tree var_decl = var->get_tree();
1111   if (var_decl == error_mark_node)
1112     return;
1113   DECL_INITIAL(var_decl) = expr_tree;
1114 }
1115
1116 // Make a local variable.
1117
1118 Bvariable*
1119 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
1120                             Btype* btype, bool is_address_taken,
1121                             Location location)
1122 {
1123   tree type_tree = btype->get_tree();
1124   if (type_tree == error_mark_node)
1125     return this->error_variable();
1126   tree decl = build_decl(location.gcc_location(), VAR_DECL,
1127                          get_identifier_from_string(name),
1128                          type_tree);
1129   DECL_CONTEXT(decl) = function->get_tree();
1130   TREE_USED(decl) = 1;
1131   if (is_address_taken)
1132     TREE_ADDRESSABLE(decl) = 1;
1133   go_preserve_from_gc(decl);
1134   return new Bvariable(decl);
1135 }
1136
1137 // Make a function parameter variable.
1138
1139 Bvariable*
1140 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
1141                                 Btype* btype, bool is_address_taken,
1142                                 Location location)
1143 {
1144   tree type_tree = btype->get_tree();
1145   if (type_tree == error_mark_node)
1146     return this->error_variable();
1147   tree decl = build_decl(location.gcc_location(), PARM_DECL,
1148                          get_identifier_from_string(name),
1149                          type_tree);
1150   DECL_CONTEXT(decl) = function->get_tree();
1151   DECL_ARG_TYPE(decl) = type_tree;
1152   TREE_USED(decl) = 1;
1153   if (is_address_taken)
1154     TREE_ADDRESSABLE(decl) = 1;
1155   go_preserve_from_gc(decl);
1156   return new Bvariable(decl);
1157 }
1158
1159 // Make a temporary variable.
1160
1161 Bvariable*
1162 Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
1163                                 Btype* btype, Bexpression* binit,
1164                                 bool is_address_taken,
1165                                 Location location,
1166                                 Bstatement** pstatement)
1167 {
1168   tree type_tree = btype->get_tree();
1169   tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
1170   if (type_tree == error_mark_node || init_tree == error_mark_node)
1171     {
1172       *pstatement = this->error_statement();
1173       return this->error_variable();
1174     }
1175
1176   tree var;
1177   // We can only use create_tmp_var if the type is not addressable.
1178   if (!TREE_ADDRESSABLE(type_tree))
1179     var = create_tmp_var(type_tree, "GOTMP");
1180   else
1181     {
1182       gcc_assert(bblock != NULL);
1183       var = build_decl(location.gcc_location(), VAR_DECL,
1184                        create_tmp_var_name("GOTMP"),
1185                        type_tree);
1186       DECL_ARTIFICIAL(var) = 1;
1187       DECL_IGNORED_P(var) = 1;
1188       TREE_USED(var) = 1;
1189       // FIXME: Permitting function to be NULL here is a temporary
1190       // measure until we have a proper representation of the init
1191       // function.
1192       if (function != NULL)
1193         DECL_CONTEXT(var) = function->get_tree();
1194       else
1195         {
1196           gcc_assert(current_function_decl != NULL_TREE);
1197           DECL_CONTEXT(var) = current_function_decl;
1198         }
1199
1200       // We have to add this variable to the BLOCK and the BIND_EXPR.
1201       tree bind_tree = bblock->get_tree();
1202       gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1203       tree block_tree = BIND_EXPR_BLOCK(bind_tree);
1204       gcc_assert(TREE_CODE(block_tree) == BLOCK);
1205       DECL_CHAIN(var) = BLOCK_VARS(block_tree);
1206       BLOCK_VARS(block_tree) = var;
1207       BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
1208     }
1209
1210   if (init_tree != NULL_TREE)
1211     DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree,
1212                                          init_tree);
1213
1214   if (is_address_taken)
1215     TREE_ADDRESSABLE(var) = 1;
1216
1217   *pstatement = this->make_statement(build1_loc(location.gcc_location(),
1218                                                 DECL_EXPR,
1219                                                 void_type_node, var));
1220   return new Bvariable(var);
1221 }
1222
1223 // Create a named immutable initialized data structure.
1224
1225 Bvariable*
1226 Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype,
1227                               Location location)
1228 {
1229   tree type_tree = btype->get_tree();
1230   if (type_tree == error_mark_node)
1231     return this->error_variable();
1232   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
1233   tree decl = build_decl(location.gcc_location(), VAR_DECL,
1234                          get_identifier_from_string(name),
1235                          build_qualified_type(type_tree, TYPE_QUAL_CONST));
1236   TREE_STATIC(decl) = 1;
1237   TREE_READONLY(decl) = 1;
1238   TREE_CONSTANT(decl) = 1;
1239   TREE_USED(decl) = 1;
1240   DECL_ARTIFICIAL(decl) = 1;
1241
1242   // We don't call rest_of_decl_compilation until we have the
1243   // initializer.
1244
1245   go_preserve_from_gc(decl);
1246   return new Bvariable(decl);
1247 }
1248
1249 // Set the initializer for a variable created by immutable_struct.
1250 // This is where we finish compiling the variable.
1251
1252 void
1253 Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
1254                                        bool is_common, Btype*,
1255                                        Location,
1256                                        Bexpression* initializer)
1257 {
1258   tree decl = var->get_tree();
1259   tree init_tree = initializer->get_tree();
1260   if (decl == error_mark_node || init_tree == error_mark_node)
1261     return;
1262
1263   DECL_INITIAL(decl) = init_tree;
1264
1265   // We can't call make_decl_one_only until we set DECL_INITIAL.
1266   if (!is_common)
1267     TREE_PUBLIC(decl) = 1;
1268   else
1269     {
1270       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
1271       resolve_unique_section(decl, 1, 0);
1272     }
1273
1274   rest_of_decl_compilation(decl, 1, 0);
1275 }
1276
1277 // Return a reference to an immutable initialized data structure
1278 // defined in another package.
1279
1280 Bvariable*
1281 Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
1282                                         Location location)
1283 {
1284   tree type_tree = btype->get_tree();
1285   if (type_tree == error_mark_node)
1286     return this->error_variable();
1287   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
1288   tree decl = build_decl(location.gcc_location(), VAR_DECL,
1289                          get_identifier_from_string(name),
1290                          build_qualified_type(type_tree, TYPE_QUAL_CONST));
1291   TREE_READONLY(decl) = 1;
1292   TREE_CONSTANT(decl) = 1;
1293   DECL_ARTIFICIAL(decl) = 1;
1294   TREE_PUBLIC(decl) = 1;
1295   DECL_EXTERNAL(decl) = 1;
1296   go_preserve_from_gc(decl);
1297   return new Bvariable(decl);
1298 }
1299
1300 // Make a label.
1301
1302 Blabel*
1303 Gcc_backend::label(Bfunction* function, const std::string& name,
1304                    Location location)
1305 {
1306   tree decl;
1307   if (name.empty())
1308     decl = create_artificial_label(location.gcc_location());
1309   else
1310     {
1311       tree id = get_identifier_from_string(name);
1312       decl = build_decl(location.gcc_location(), LABEL_DECL, id,
1313                         void_type_node);
1314       DECL_CONTEXT(decl) = function->get_tree();
1315     }
1316   return new Blabel(decl);
1317 }
1318
1319 // Make a statement which defines a label.
1320
1321 Bstatement*
1322 Gcc_backend::label_definition_statement(Blabel* label)
1323 {
1324   tree lab = label->get_tree();
1325   tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
1326                              void_type_node, lab);
1327   return this->make_statement(ret);
1328 }
1329
1330 // Make a goto statement.
1331
1332 Bstatement*
1333 Gcc_backend::goto_statement(Blabel* label, Location location)
1334 {
1335   tree lab = label->get_tree();
1336   tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
1337                              lab);
1338   return this->make_statement(ret);
1339 }
1340
1341 // Get the address of a label.
1342
1343 Bexpression*
1344 Gcc_backend::label_address(Blabel* label, Location location)
1345 {
1346   tree lab = label->get_tree();
1347   TREE_USED(lab) = 1;
1348   TREE_ADDRESSABLE(lab) = 1;
1349   tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
1350                               build_fold_addr_expr_loc(location.gcc_location(),
1351                                                        lab));
1352   return this->make_expression(ret);
1353 }
1354
1355 // The single backend.
1356
1357 static Gcc_backend gcc_backend;
1358
1359 // Return the backend generator.
1360
1361 Backend*
1362 go_get_backend()
1363 {
1364   return &gcc_backend;
1365 }
1366
1367 // FIXME: Temporary functions while converting to the new backend
1368 // interface.
1369
1370 Btype*
1371 tree_to_type(tree t)
1372 {
1373   return new Btype(t);
1374 }
1375
1376 Bexpression*
1377 tree_to_expr(tree t)
1378 {
1379   return new Bexpression(t);
1380 }
1381
1382 Bstatement*
1383 tree_to_stat(tree t)
1384 {
1385   return new Bstatement(t);
1386 }
1387
1388 Bfunction*
1389 tree_to_function(tree t)
1390 {
1391   return new Bfunction(t);
1392 }
1393
1394 Bblock*
1395 tree_to_block(tree t)
1396 {
1397   gcc_assert(TREE_CODE(t) == BIND_EXPR);
1398   return new Bblock(t);
1399 }
1400
1401 tree
1402 type_to_tree(Btype* bt)
1403 {
1404   return bt->get_tree();
1405 }
1406
1407 tree
1408 expr_to_tree(Bexpression* be)
1409 {
1410   return be->get_tree();
1411 }
1412
1413 tree
1414 stat_to_tree(Bstatement* bs)
1415 {
1416   return bs->get_tree();
1417 }
1418
1419 tree
1420 block_to_tree(Bblock* bb)
1421 {
1422   return bb->get_tree();
1423 }
1424
1425 tree
1426 var_to_tree(Bvariable* bv)
1427 {
1428   return bv->get_tree();
1429 }