OSDN Git Service

Use backend interface for basic types
[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
36 #ifndef ENABLE_BUILD_WITH_CXX
37 }
38 #endif
39
40 #include "go-c.h"
41
42 #include "gogo.h"
43 #include "backend.h"
44
45 // A class wrapping a tree.
46
47 class Gcc_tree
48 {
49  public:
50   Gcc_tree(tree t)
51     : t_(t)
52   { }
53
54   tree
55   get_tree() const
56   { return this->t_; }
57
58  private:
59   tree t_;
60 };
61
62 // In gcc, types, expressions, and statements are all trees.
63 class Btype : public Gcc_tree
64 {
65  public:
66   Btype(tree t)
67     : Gcc_tree(t)
68   { }
69 };
70
71 class Bexpression : public Gcc_tree
72 {
73  public:
74   Bexpression(tree t)
75     : Gcc_tree(t)
76   { }
77 };
78
79 class Bstatement : public Gcc_tree
80 {
81  public:
82   Bstatement(tree t)
83     : Gcc_tree(t)
84   { }
85 };
86
87 class Bfunction : public Gcc_tree
88 {
89  public:
90   Bfunction(tree t)
91     : Gcc_tree(t)
92   { }
93 };
94
95 class Bblock : public Gcc_tree
96 {
97  public:
98   Bblock(tree t)
99     : Gcc_tree(t)
100   { }
101 };
102
103 class Bvariable : public Gcc_tree
104 {
105  public:
106   Bvariable(tree t)
107     : Gcc_tree(t)
108   { }
109 };
110
111 class Blabel : public Gcc_tree
112 {
113  public:
114   Blabel(tree t)
115     : Gcc_tree(t)
116   { }
117 };
118
119 // This file implements the interface between the Go frontend proper
120 // and the gcc IR.  This implements specific instantiations of
121 // abstract classes defined by the Go frontend proper.  The Go
122 // frontend proper class methods of these classes to generate the
123 // backend representation.
124
125 class Gcc_backend : public Backend
126 {
127  public:
128   // Types.
129
130   Btype*
131   error_type()
132   { gcc_unreachable(); }
133
134   Btype*
135   void_type()
136   { return this->make_type(void_type_node); }
137
138   Btype*
139   bool_type()
140   { return this->make_type(boolean_type_node); }
141
142   Btype*
143   integer_type(bool, int);
144
145   Btype*
146   float_type(int);
147
148   Btype*
149   complex_type(int);
150
151   Btype*
152   string_type()
153   { gcc_unreachable(); }
154
155   Btype*
156   pointer_type(const Btype*);
157
158   Btype*
159   function_type(const Function_type*, Btype* /* receiver */,
160                 const Btypes* /* parameters */,
161                 const Btypes* /* results */)
162   { gcc_unreachable(); }
163
164   Btype*
165   struct_type(const Struct_type*, const Btypes* /* field_types */)
166   { gcc_unreachable(); }
167
168   Btype*
169   array_type(const Btype* /* element_type */, const Bexpression* /* length */)
170   { gcc_unreachable(); }
171
172   Btype*
173   slice_type(const Btype* /* element_type */)
174   { gcc_unreachable(); }
175
176   Btype*
177   map_type(const Btype* /* key_type */, const Btype* /* value_type */,
178            source_location)
179   { gcc_unreachable(); }
180
181   Btype*
182   channel_type(const Btype* /* element_type */)
183   { gcc_unreachable(); }
184
185   Btype*
186   interface_type(const Interface_type*, const Btypes* /* method_types */)
187   { gcc_unreachable(); }
188
189   // Statements.
190
191   Bstatement*
192   error_statement()
193   { return this->make_statement(error_mark_node); }
194
195   Bstatement*
196   expression_statement(Bexpression*);
197
198   Bstatement*
199   init_statement(Bvariable* var, Bexpression* init);
200
201   Bstatement*
202   assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location);
203
204   Bstatement*
205   return_statement(Bfunction*, const std::vector<Bexpression*>&,
206                    source_location);
207
208   Bstatement*
209   if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
210                source_location);
211
212   Bstatement*
213   switch_statement(Bexpression* value,
214                    const std::vector<std::vector<Bexpression*> >& cases,
215                    const std::vector<Bstatement*>& statements,
216                    source_location);
217
218   Bstatement*
219   compound_statement(Bstatement*, Bstatement*);
220
221   Bstatement*
222   statement_list(const std::vector<Bstatement*>&);
223
224   // Blocks.
225
226   Bblock*
227   block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
228         source_location, source_location);
229
230   void
231   block_add_statements(Bblock*, const std::vector<Bstatement*>&);
232
233   Bstatement*
234   block_statement(Bblock*);
235
236   // Variables.
237
238   Bvariable*
239   error_variable()
240   { return new Bvariable(error_mark_node); }
241
242   Bvariable*
243   global_variable(const std::string& package_name,
244                   const std::string& unique_prefix,
245                   const std::string& name,
246                   Btype* btype,
247                   bool is_external,
248                   bool is_hidden,
249                   source_location location);
250
251   void
252   global_variable_set_init(Bvariable*, Bexpression*);
253
254   Bvariable*
255   local_variable(Bfunction*, const std::string& name, Btype* type,
256                  source_location);
257
258   Bvariable*
259   parameter_variable(Bfunction*, const std::string& name, Btype* type,
260                      source_location);
261
262   Bvariable*
263   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
264                      source_location, Bstatement**);
265
266   // Labels.
267
268   Blabel*
269   label(Bfunction*, const std::string& name, source_location);
270
271   Bstatement*
272   label_definition_statement(Blabel*);
273
274   Bstatement*
275   goto_statement(Blabel*, source_location);
276
277   Bexpression*
278   label_address(Blabel*, source_location);
279
280  private:
281   // Make a Bexpression from a tree.
282   Bexpression*
283   make_expression(tree t)
284   { return new Bexpression(t); }
285
286   // Make a Bstatement from a tree.
287   Bstatement*
288   make_statement(tree t)
289   { return new Bstatement(t); }
290
291   // Make a Btype from a tree.
292   Btype*
293   make_type(tree t)
294   { return new Btype(t); }
295 };
296
297 // A helper function.
298
299 static inline tree
300 get_identifier_from_string(const std::string& str)
301 {
302   return get_identifier_with_length(str.data(), str.length());
303 }
304
305 // Get an unnamed integer type.
306
307 Btype*
308 Gcc_backend::integer_type(bool is_unsigned, int bits)
309 {
310   tree type;
311   if (is_unsigned)
312     {
313       if (bits == INT_TYPE_SIZE)
314         type = unsigned_type_node;
315       else if (bits == CHAR_TYPE_SIZE)
316         type = unsigned_char_type_node;
317       else if (bits == SHORT_TYPE_SIZE)
318         type = short_unsigned_type_node;
319       else if (bits == LONG_TYPE_SIZE)
320         type = long_unsigned_type_node;
321       else if (bits == LONG_LONG_TYPE_SIZE)
322         type = long_long_unsigned_type_node;
323       else
324         type = make_unsigned_type(bits);
325     }
326   else
327     {
328       if (bits == INT_TYPE_SIZE)
329         type = integer_type_node;
330       else if (bits == CHAR_TYPE_SIZE)
331         type = signed_char_type_node;
332       else if (bits == SHORT_TYPE_SIZE)
333         type = short_integer_type_node;
334       else if (bits == LONG_TYPE_SIZE)
335         type = long_integer_type_node;
336       else if (bits == LONG_LONG_TYPE_SIZE)
337         type = long_long_integer_type_node;
338       else
339         type = make_signed_type(bits);
340     }
341   return this->make_type(type);
342 }
343
344 // Get an unnamed float type.
345
346 Btype*
347 Gcc_backend::float_type(int bits)
348 {
349   tree type;
350   if (bits == FLOAT_TYPE_SIZE)
351     type = float_type_node;
352   else if (bits == DOUBLE_TYPE_SIZE)
353     type = double_type_node;
354   else if (bits == LONG_DOUBLE_TYPE_SIZE)
355     type = long_double_type_node;
356   else
357     {
358       type = make_node(REAL_TYPE);
359       TYPE_PRECISION(type) = bits;
360       layout_type(type);
361     }
362   return this->make_type(type);
363 }
364
365 // Get an unnamed complex type.
366
367 Btype*
368 Gcc_backend::complex_type(int bits)
369 {
370   tree type;
371   if (bits == FLOAT_TYPE_SIZE * 2)
372     type = complex_float_type_node;
373   else if (bits == DOUBLE_TYPE_SIZE * 2)
374     type = complex_double_type_node;
375   else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
376     type = complex_long_double_type_node;
377   else
378     {
379       type = make_node(REAL_TYPE);
380       TYPE_PRECISION(type) = bits / 2;
381       layout_type(type);
382       type = build_complex_type(type);
383     }
384   return this->make_type(type);
385 }
386
387 // Get a pointer type.
388
389 Btype*
390 Gcc_backend::pointer_type(const Btype* to_type)
391 {
392   tree type = build_pointer_type(to_type->get_tree());
393   return this->make_type(type);
394 }
395
396 // An expression as a statement.
397
398 Bstatement*
399 Gcc_backend::expression_statement(Bexpression* expr)
400 {
401   return this->make_statement(expr->get_tree());
402 }
403
404 // Variable initialization.
405
406 Bstatement*
407 Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
408 {
409   tree var_tree = var->get_tree();
410   tree init_tree = init->get_tree();
411   if (var_tree == error_mark_node || init_tree == error_mark_node)
412     return this->error_statement();
413   gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
414   DECL_INITIAL(var_tree) = init_tree;
415   return this->make_statement(build1_loc(DECL_SOURCE_LOCATION(var_tree),
416                                          DECL_EXPR, void_type_node, var_tree));
417 }
418
419 // Assignment.
420
421 Bstatement*
422 Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
423                                   source_location location)
424 {
425   tree lhs_tree = lhs->get_tree();
426   tree rhs_tree = rhs->get_tree();
427   if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
428     return this->error_statement();
429   return this->make_statement(fold_build2_loc(location, MODIFY_EXPR,
430                                               void_type_node,
431                                               lhs_tree, rhs_tree));
432 }
433
434 // Return.
435
436 Bstatement*
437 Gcc_backend::return_statement(Bfunction* bfunction,
438                               const std::vector<Bexpression*>& vals,
439                               source_location location)
440 {
441   tree fntree = bfunction->get_tree();
442   if (fntree == error_mark_node)
443     return this->error_statement();
444   tree result = DECL_RESULT(fntree);
445   if (result == error_mark_node)
446     return this->error_statement();
447   tree ret;
448   if (vals.empty())
449     ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, NULL_TREE);
450   else if (vals.size() == 1)
451     {
452       tree val = vals.front()->get_tree();
453       if (val == error_mark_node)
454         return this->error_statement();
455       tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
456                                  result, vals.front()->get_tree());
457       ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, set);
458     }
459   else
460     {
461       // To return multiple values, copy the values into a temporary
462       // variable of the right structure type, and then assign the
463       // temporary variable to the DECL_RESULT in the return
464       // statement.
465       tree stmt_list = NULL_TREE;
466       tree rettype = TREE_TYPE(result);
467       tree rettmp = create_tmp_var(rettype, "RESULT");
468       tree field = TYPE_FIELDS(rettype);
469       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
470            p != vals.end();
471            p++, field = DECL_CHAIN(field))
472         {
473           gcc_assert(field != NULL_TREE);
474           tree ref = fold_build3_loc(location, COMPONENT_REF, TREE_TYPE(field),
475                                      rettmp, field, NULL_TREE);
476           tree val = (*p)->get_tree();
477           if (val == error_mark_node)
478             return this->error_statement();
479           tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
480                                      ref, (*p)->get_tree());
481           append_to_statement_list(set, &stmt_list);
482         }
483       gcc_assert(field == NULL_TREE);
484       tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
485                                  result, rettmp);
486       tree ret_expr = fold_build1_loc(location, RETURN_EXPR, void_type_node,
487                                       set);
488       append_to_statement_list(ret_expr, &stmt_list);
489       ret = stmt_list;
490     }
491   return this->make_statement(ret);
492 }
493
494 // If.
495
496 Bstatement*
497 Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
498                           Bblock* else_block, source_location location)
499 {
500   tree cond_tree = condition->get_tree();
501   tree then_tree = then_block->get_tree();
502   tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
503   if (cond_tree == error_mark_node
504       || then_tree == error_mark_node
505       || else_tree == error_mark_node)
506     return this->error_statement();
507   tree ret = build3_loc(location, COND_EXPR, void_type_node, cond_tree,
508                         then_tree, else_tree);
509   return this->make_statement(ret);
510 }
511
512 // Switch.
513
514 Bstatement*
515 Gcc_backend::switch_statement(
516     Bexpression* value,
517     const std::vector<std::vector<Bexpression*> >& cases,
518     const std::vector<Bstatement*>& statements,
519     source_location switch_location)
520 {
521   gcc_assert(cases.size() == statements.size());
522
523   tree stmt_list = NULL_TREE;
524   std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
525   for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
526        ps != statements.end();
527        ++ps, ++pc)
528     {
529       if (pc->empty())
530         {
531           source_location loc = (*ps != NULL
532                                  ? EXPR_LOCATION((*ps)->get_tree())
533                                  : UNKNOWN_LOCATION);
534           tree label = create_artificial_label(loc);
535           tree c = build3_loc(loc, CASE_LABEL_EXPR, void_type_node, NULL_TREE,
536                               NULL_TREE, label);
537           append_to_statement_list(c, &stmt_list);
538         }
539       else
540         {
541           for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
542                pcv != pc->end();
543                ++pcv)
544             {
545               tree t = (*pcv)->get_tree();
546               if (t == error_mark_node)
547                 return this->error_statement();
548               source_location loc = EXPR_LOCATION(t);
549               tree label = create_artificial_label(loc);
550               tree c = build3_loc(loc, CASE_LABEL_EXPR, void_type_node,
551                                   (*pcv)->get_tree(), NULL_TREE, label);
552               append_to_statement_list(c, &stmt_list);
553             }
554         }
555
556       if (*ps != NULL)
557         {
558           tree t = (*ps)->get_tree();
559           if (t == error_mark_node)
560             return this->error_statement();
561           append_to_statement_list(t, &stmt_list);
562         }
563     }
564
565   tree tv = value->get_tree();
566   if (tv == error_mark_node)
567     return this->error_statement();
568   tree t = build3_loc(switch_location, SWITCH_EXPR, void_type_node,
569                       tv, stmt_list, NULL_TREE);
570   return this->make_statement(t);
571 }
572
573 // Pair of statements.
574
575 Bstatement*
576 Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
577 {
578   tree stmt_list = NULL_TREE;
579   tree t = s1->get_tree();
580   if (t == error_mark_node)
581     return this->error_statement();
582   append_to_statement_list(t, &stmt_list);
583   t = s2->get_tree();
584   if (t == error_mark_node)
585     return this->error_statement();
586   append_to_statement_list(t, &stmt_list);
587   return this->make_statement(stmt_list);
588 }
589
590 // List of statements.
591
592 Bstatement*
593 Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
594 {
595   tree stmt_list = NULL_TREE;
596   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
597        p != statements.end();
598        ++p)
599     {
600       tree t = (*p)->get_tree();
601       if (t == error_mark_node)
602         return this->error_statement();
603       append_to_statement_list(t, &stmt_list);
604     }
605   return this->make_statement(stmt_list);
606 }
607
608 // Make a block.  For some reason gcc uses a dual structure for
609 // blocks: BLOCK tree nodes and BIND_EXPR tree nodes.  Since the
610 // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
611 // the Bblock.
612
613 Bblock*
614 Gcc_backend::block(Bfunction* function, Bblock* enclosing,
615                    const std::vector<Bvariable*>& vars,
616                    source_location start_location,
617                    source_location)
618 {
619   tree block_tree = make_node(BLOCK);
620   if (enclosing == NULL)
621     {
622       // FIXME: Permitting FUNCTION to be NULL is a temporary measure
623       // until we have a proper representation of the init function.
624       tree fndecl;
625       if (function == NULL)
626         fndecl = current_function_decl;
627       else
628         fndecl = function->get_tree();
629       gcc_assert(fndecl != NULL_TREE);
630
631       // We may have already created a block for local variables when
632       // we take the address of a parameter.
633       if (DECL_INITIAL(fndecl) == NULL_TREE)
634         {
635           BLOCK_SUPERCONTEXT(block_tree) = fndecl;
636           DECL_INITIAL(fndecl) = block_tree;
637         }
638       else
639         {
640           tree superblock_tree = DECL_INITIAL(fndecl);
641           BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
642           tree* pp;
643           for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
644                *pp != NULL_TREE;
645                pp = &BLOCK_CHAIN(*pp))
646             ;
647           *pp = block_tree;
648         }
649     }
650   else
651     {
652       tree superbind_tree = enclosing->get_tree();
653       tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
654       gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
655
656       BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
657       tree* pp;
658       for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
659            *pp != NULL_TREE;
660            pp = &BLOCK_CHAIN(*pp))
661         ;
662       *pp = block_tree;
663     }
664
665   tree* pp = &BLOCK_VARS(block_tree);
666   for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
667        pv != vars.end();
668        ++pv)
669     {
670       *pp = (*pv)->get_tree();
671       if (*pp != error_mark_node)
672         pp = &DECL_CHAIN(*pp);
673     }
674   *pp = NULL_TREE;
675
676   TREE_USED(block_tree) = 1;
677
678   tree bind_tree = build3_loc(start_location, BIND_EXPR, void_type_node,
679                               BLOCK_VARS(block_tree), NULL_TREE, block_tree);
680   TREE_SIDE_EFFECTS(bind_tree) = 1;
681
682   return new Bblock(bind_tree);
683 }
684
685 // Add statements to a block.
686
687 void
688 Gcc_backend::block_add_statements(Bblock* bblock,
689                                   const std::vector<Bstatement*>& statements)
690 {
691   tree stmt_list = NULL_TREE;
692   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
693        p != statements.end();
694        ++p)
695     {
696       tree s = (*p)->get_tree();
697       if (s != error_mark_node)
698         append_to_statement_list(s, &stmt_list);
699     }
700
701   tree bind_tree = bblock->get_tree();
702   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
703   BIND_EXPR_BODY(bind_tree) = stmt_list;
704 }
705
706 // Return a block as a statement.
707
708 Bstatement*
709 Gcc_backend::block_statement(Bblock* bblock)
710 {
711   tree bind_tree = bblock->get_tree();
712   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
713   return this->make_statement(bind_tree);
714 }
715
716 // Make a global variable.
717
718 Bvariable*
719 Gcc_backend::global_variable(const std::string& package_name,
720                              const std::string& unique_prefix,
721                              const std::string& name,
722                              Btype* btype,
723                              bool is_external,
724                              bool is_hidden,
725                              source_location location)
726 {
727   tree type_tree = btype->get_tree();
728   if (type_tree == error_mark_node)
729     return this->error_variable();
730
731   std::string var_name(package_name);
732   var_name.push_back('.');
733   var_name.append(name);
734   tree decl = build_decl(location, VAR_DECL,
735                          get_identifier_from_string(var_name),
736                          type_tree);
737   if (is_external)
738     DECL_EXTERNAL(decl) = 1;
739   else
740     TREE_STATIC(decl) = 1;
741   if (!is_hidden)
742     {
743       TREE_PUBLIC(decl) = 1;
744
745       std::string asm_name(unique_prefix);
746       asm_name.push_back('.');
747       asm_name.append(var_name);
748       SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
749     }
750   TREE_USED(decl) = 1;
751
752   go_preserve_from_gc(decl);
753
754   return new Bvariable(decl);
755 }
756
757 // Set the initial value of a global variable.
758
759 void
760 Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
761 {
762   tree expr_tree = expr->get_tree();
763   if (expr_tree == error_mark_node)
764     return;
765   gcc_assert(TREE_CONSTANT(expr_tree));
766   tree var_decl = var->get_tree();
767   if (var_decl == error_mark_node)
768     return;
769   DECL_INITIAL(var_decl) = expr_tree;
770 }
771
772 // Make a local variable.
773
774 Bvariable*
775 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
776                             Btype* btype, source_location location)
777 {
778   tree type_tree = btype->get_tree();
779   if (type_tree == error_mark_node)
780     return this->error_variable();
781   tree decl = build_decl(location, VAR_DECL,
782                          get_identifier_from_string(name),
783                          type_tree);
784   DECL_CONTEXT(decl) = function->get_tree();
785   TREE_USED(decl) = 1;
786   go_preserve_from_gc(decl);
787   return new Bvariable(decl);
788 }
789
790 // Make a function parameter variable.
791
792 Bvariable*
793 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
794                                 Btype* btype, source_location location)
795 {
796   tree type_tree = btype->get_tree();
797   if (type_tree == error_mark_node)
798     return this->error_variable();
799   tree decl = build_decl(location, PARM_DECL,
800                          get_identifier_from_string(name),
801                          type_tree);
802   DECL_CONTEXT(decl) = function->get_tree();
803   DECL_ARG_TYPE(decl) = type_tree;
804   TREE_USED(decl) = 1;
805   go_preserve_from_gc(decl);
806   return new Bvariable(decl);
807 }
808
809 // Make a temporary variable.
810
811 Bvariable*
812 Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
813                                 Btype* btype, Bexpression* binit,
814                                 bool is_address_taken,
815                                 source_location location,
816                                 Bstatement** pstatement)
817 {
818   tree type_tree = btype->get_tree();
819   tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
820   if (type_tree == error_mark_node || init_tree == error_mark_node)
821     {
822       *pstatement = this->error_statement();
823       return this->error_variable();
824     }
825
826   tree var;
827   // We can only use create_tmp_var if the type is not addressable.
828   if (!TREE_ADDRESSABLE(type_tree))
829     var = create_tmp_var(type_tree, "GOTMP");
830   else
831     {
832       gcc_assert(bblock != NULL);
833       var = build_decl(location, VAR_DECL,
834                        create_tmp_var_name("GOTMP"),
835                        type_tree);
836       DECL_ARTIFICIAL(var) = 1;
837       DECL_IGNORED_P(var) = 1;
838       TREE_USED(var) = 1;
839       // FIXME: Permitting function to be NULL here is a temporary
840       // measure until we have a proper representation of the init
841       // function.
842       if (function != NULL)
843         DECL_CONTEXT(var) = function->get_tree();
844       else
845         {
846           gcc_assert(current_function_decl != NULL_TREE);
847           DECL_CONTEXT(var) = current_function_decl;
848         }
849
850       // We have to add this variable to the BLOCK and the BIND_EXPR.
851       tree bind_tree = bblock->get_tree();
852       gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
853       tree block_tree = BIND_EXPR_BLOCK(bind_tree);
854       gcc_assert(TREE_CODE(block_tree) == BLOCK);
855       DECL_CHAIN(var) = BLOCK_VARS(block_tree);
856       BLOCK_VARS(block_tree) = var;
857       BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
858     }
859
860   if (init_tree != NULL_TREE)
861     DECL_INITIAL(var) = fold_convert_loc(location, type_tree, init_tree);
862
863   if (is_address_taken)
864     TREE_ADDRESSABLE(var) = 1;
865
866   *pstatement = this->make_statement(build1_loc(location, DECL_EXPR,
867                                                 void_type_node, var));
868   return new Bvariable(var);
869 }
870
871 // Make a label.
872
873 Blabel*
874 Gcc_backend::label(Bfunction* function, const std::string& name,
875                    source_location location)
876 {
877   tree decl;
878   if (name.empty())
879     decl = create_artificial_label(location);
880   else
881     {
882       tree id = get_identifier_from_string(name);
883       decl = build_decl(location, LABEL_DECL, id, void_type_node);
884       DECL_CONTEXT(decl) = function->get_tree();
885     }
886   return new Blabel(decl);
887 }
888
889 // Make a statement which defines a label.
890
891 Bstatement*
892 Gcc_backend::label_definition_statement(Blabel* label)
893 {
894   tree lab = label->get_tree();
895   tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
896                              void_type_node, lab);
897   return this->make_statement(ret);
898 }
899
900 // Make a goto statement.
901
902 Bstatement*
903 Gcc_backend::goto_statement(Blabel* label, source_location location)
904 {
905   tree lab = label->get_tree();
906   tree ret = fold_build1_loc(location, GOTO_EXPR, void_type_node, lab);
907   return this->make_statement(ret);
908 }
909
910 // Get the address of a label.
911
912 Bexpression*
913 Gcc_backend::label_address(Blabel* label, source_location location)
914 {
915   tree lab = label->get_tree();
916   TREE_USED(lab) = 1;
917   TREE_ADDRESSABLE(lab) = 1;
918   tree ret = fold_convert_loc(location, ptr_type_node,
919                               build_fold_addr_expr_loc(location, lab));
920   return this->make_expression(ret);
921 }
922
923 // The single backend.
924
925 static Gcc_backend gcc_backend;
926
927 // Return the backend generator.
928
929 Backend*
930 go_get_backend()
931 {
932   return &gcc_backend;
933 }
934
935 // FIXME: Temporary functions while converting to the new backend
936 // interface.
937
938 Btype*
939 tree_to_type(tree t)
940 {
941   return new Btype(t);
942 }
943
944 Bexpression*
945 tree_to_expr(tree t)
946 {
947   return new Bexpression(t);
948 }
949
950 Bstatement*
951 tree_to_stat(tree t)
952 {
953   return new Bstatement(t);
954 }
955
956 Bfunction*
957 tree_to_function(tree t)
958 {
959   return new Bfunction(t);
960 }
961
962 Bblock*
963 tree_to_block(tree t)
964 {
965   gcc_assert(TREE_CODE(t) == BIND_EXPR);
966   return new Bblock(t);
967 }
968
969 tree
970 type_to_tree(Btype* bt)
971 {
972   return bt->get_tree();
973 }
974
975 tree
976 expr_to_tree(Bexpression* be)
977 {
978   return be->get_tree();
979 }
980
981 tree
982 stat_to_tree(Bstatement* bs)
983 {
984   return bs->get_tree();
985 }
986
987 tree
988 block_to_tree(Bblock* bb)
989 {
990   return bb->get_tree();
991 }
992
993 tree
994 var_to_tree(Bvariable* bv)
995 {
996   return bv->get_tree();
997 }