OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [go/] [go-gcc.cc] - Blame information for rev 723

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 714 jeremybenn
// go-gcc.cc -- Go frontend to gcc IR.
2
// Copyright (C) 2011, 2012 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
  size_t
199
  type_size(Btype*);
200
 
201
  size_t
202
  type_alignment(Btype*);
203
 
204
  size_t
205
  type_field_alignment(Btype*);
206
 
207
  size_t
208
  type_field_offset(Btype*, size_t index);
209
 
210
  // Expressions.
211
 
212
  Bexpression*
213
  zero_expression(Btype*);
214
 
215
  // Statements.
216
 
217
  Bstatement*
218
  error_statement()
219
  { return this->make_statement(error_mark_node); }
220
 
221
  Bstatement*
222
  expression_statement(Bexpression*);
223
 
224
  Bstatement*
225
  init_statement(Bvariable* var, Bexpression* init);
226
 
227
  Bstatement*
228
  assignment_statement(Bexpression* lhs, Bexpression* rhs, Location);
229
 
230
  Bstatement*
231
  return_statement(Bfunction*, const std::vector<Bexpression*>&,
232
                   Location);
233
 
234
  Bstatement*
235
  if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
236
               Location);
237
 
238
  Bstatement*
239
  switch_statement(Bexpression* value,
240
                   const std::vector<std::vector<Bexpression*> >& cases,
241
                   const std::vector<Bstatement*>& statements,
242
                   Location);
243
 
244
  Bstatement*
245
  compound_statement(Bstatement*, Bstatement*);
246
 
247
  Bstatement*
248
  statement_list(const std::vector<Bstatement*>&);
249
 
250
  // Blocks.
251
 
252
  Bblock*
253
  block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
254
        Location, Location);
255
 
256
  void
257
  block_add_statements(Bblock*, const std::vector<Bstatement*>&);
258
 
259
  Bstatement*
260
  block_statement(Bblock*);
261
 
262
  // Variables.
263
 
264
  Bvariable*
265
  error_variable()
266
  { return new Bvariable(error_mark_node); }
267
 
268
  Bvariable*
269
  global_variable(const std::string& package_name,
270
                  const std::string& unique_prefix,
271
                  const std::string& name,
272
                  Btype* btype,
273
                  bool is_external,
274
                  bool is_hidden,
275
                  Location location);
276
 
277
  void
278
  global_variable_set_init(Bvariable*, Bexpression*);
279
 
280
  Bvariable*
281
  local_variable(Bfunction*, const std::string&, Btype*, bool,
282
                 Location);
283
 
284
  Bvariable*
285
  parameter_variable(Bfunction*, const std::string&, Btype*, bool,
286
                     Location);
287
 
288
  Bvariable*
289
  temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
290
                     Location, Bstatement**);
291
 
292
  Bvariable*
293
  immutable_struct(const std::string&, bool, Btype*, Location);
294
 
295
  void
296
  immutable_struct_set_init(Bvariable*, const std::string&, bool, Btype*,
297
                            Location, Bexpression*);
298
 
299
  Bvariable*
300
  immutable_struct_reference(const std::string&, Btype*, Location);
301
 
302
  // Labels.
303
 
304
  Blabel*
305
  label(Bfunction*, const std::string& name, Location);
306
 
307
  Bstatement*
308
  label_definition_statement(Blabel*);
309
 
310
  Bstatement*
311
  goto_statement(Blabel*, Location);
312
 
313
  Bexpression*
314
  label_address(Blabel*, Location);
315
 
316
 private:
317
  // Make a Bexpression from a tree.
318
  Bexpression*
319
  make_expression(tree t)
320
  { return new Bexpression(t); }
321
 
322
  // Make a Bstatement from a tree.
323
  Bstatement*
324
  make_statement(tree t)
325
  { return new Bstatement(t); }
326
 
327
  // Make a Btype from a tree.
328
  Btype*
329
  make_type(tree t)
330
  { return new Btype(t); }
331
 
332
  Btype*
333
  fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
334
 
335
  Btype*
336
  fill_in_array(Btype*, Btype*, Bexpression*);
337
};
338
 
339
// A helper function.
340
 
341
static inline tree
342
get_identifier_from_string(const std::string& str)
343
{
344
  return get_identifier_with_length(str.data(), str.length());
345
}
346
 
347
// Get an unnamed integer type.
348
 
349
Btype*
350
Gcc_backend::integer_type(bool is_unsigned, int bits)
351
{
352
  tree type;
353
  if (is_unsigned)
354
    {
355
      if (bits == INT_TYPE_SIZE)
356
        type = unsigned_type_node;
357
      else if (bits == CHAR_TYPE_SIZE)
358
        type = unsigned_char_type_node;
359
      else if (bits == SHORT_TYPE_SIZE)
360
        type = short_unsigned_type_node;
361
      else if (bits == LONG_TYPE_SIZE)
362
        type = long_unsigned_type_node;
363
      else if (bits == LONG_LONG_TYPE_SIZE)
364
        type = long_long_unsigned_type_node;
365
      else
366
        type = make_unsigned_type(bits);
367
    }
368
  else
369
    {
370
      if (bits == INT_TYPE_SIZE)
371
        type = integer_type_node;
372
      else if (bits == CHAR_TYPE_SIZE)
373
        type = signed_char_type_node;
374
      else if (bits == SHORT_TYPE_SIZE)
375
        type = short_integer_type_node;
376
      else if (bits == LONG_TYPE_SIZE)
377
        type = long_integer_type_node;
378
      else if (bits == LONG_LONG_TYPE_SIZE)
379
        type = long_long_integer_type_node;
380
      else
381
        type = make_signed_type(bits);
382
    }
383
  return this->make_type(type);
384
}
385
 
386
// Get an unnamed float type.
387
 
388
Btype*
389
Gcc_backend::float_type(int bits)
390
{
391
  tree type;
392
  if (bits == FLOAT_TYPE_SIZE)
393
    type = float_type_node;
394
  else if (bits == DOUBLE_TYPE_SIZE)
395
    type = double_type_node;
396
  else if (bits == LONG_DOUBLE_TYPE_SIZE)
397
    type = long_double_type_node;
398
  else
399
    {
400
      type = make_node(REAL_TYPE);
401
      TYPE_PRECISION(type) = bits;
402
      layout_type(type);
403
    }
404
  return this->make_type(type);
405
}
406
 
407
// Get an unnamed complex type.
408
 
409
Btype*
410
Gcc_backend::complex_type(int bits)
411
{
412
  tree type;
413
  if (bits == FLOAT_TYPE_SIZE * 2)
414
    type = complex_float_type_node;
415
  else if (bits == DOUBLE_TYPE_SIZE * 2)
416
    type = complex_double_type_node;
417
  else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
418
    type = complex_long_double_type_node;
419
  else
420
    {
421
      type = make_node(REAL_TYPE);
422
      TYPE_PRECISION(type) = bits / 2;
423
      layout_type(type);
424
      type = build_complex_type(type);
425
    }
426
  return this->make_type(type);
427
}
428
 
429
// Get a pointer type.
430
 
431
Btype*
432
Gcc_backend::pointer_type(Btype* to_type)
433
{
434
  tree to_type_tree = to_type->get_tree();
435
  if (to_type_tree == error_mark_node)
436
    return this->error_type();
437
  tree type = build_pointer_type(to_type_tree);
438
  return this->make_type(type);
439
}
440
 
441
// Make a function type.
442
 
443
Btype*
444
Gcc_backend::function_type(const Btyped_identifier& receiver,
445
                           const std::vector<Btyped_identifier>& parameters,
446
                           const std::vector<Btyped_identifier>& results,
447
                           Location location)
448
{
449
  tree args = NULL_TREE;
450
  tree* pp = &args;
451
  if (receiver.btype != NULL)
452
    {
453
      tree t = receiver.btype->get_tree();
454
      if (t == error_mark_node)
455
        return this->error_type();
456
      *pp = tree_cons(NULL_TREE, t, NULL_TREE);
457
      pp = &TREE_CHAIN(*pp);
458
    }
459
 
460
  for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
461
       p != parameters.end();
462
       ++p)
463
    {
464
      tree t = p->btype->get_tree();
465
      if (t == error_mark_node)
466
        return this->error_type();
467
      *pp = tree_cons(NULL_TREE, t, NULL_TREE);
468
      pp = &TREE_CHAIN(*pp);
469
    }
470
 
471
  // Varargs is handled entirely at the Go level.  When converted to
472
  // GENERIC functions are not varargs.
473
  *pp = void_list_node;
474
 
475
  tree result;
476
  if (results.empty())
477
    result = void_type_node;
478
  else if (results.size() == 1)
479
    result = results.front().btype->get_tree();
480
  else
481
    {
482
      result = make_node(RECORD_TYPE);
483
      tree field_trees = NULL_TREE;
484
      pp = &field_trees;
485
      for (std::vector<Btyped_identifier>::const_iterator p = results.begin();
486
           p != results.end();
487
           ++p)
488
        {
489
          const std::string name = (p->name.empty()
490
                                    ? "UNNAMED"
491
                                    : p->name);
492
          tree name_tree = get_identifier_from_string(name);
493
          tree field_type_tree = p->btype->get_tree();
494
          if (field_type_tree == error_mark_node)
495
            return this->error_type();
496
          gcc_assert(TYPE_SIZE(field_type_tree) != NULL_TREE);
497
          tree field = build_decl(location.gcc_location(), FIELD_DECL,
498
                                  name_tree, field_type_tree);
499
          DECL_CONTEXT(field) = result;
500
          *pp = field;
501
          pp = &DECL_CHAIN(field);
502
        }
503
      TYPE_FIELDS(result) = field_trees;
504
      layout_type(result);
505
    }
506
  if (result == error_mark_node)
507
    return this->error_type();
508
 
509
  tree fntype = build_function_type(result, args);
510
  if (fntype == error_mark_node)
511
    return this->error_type();
512
 
513
  return this->make_type(build_pointer_type(fntype));
514
}
515
 
516
// Make a struct type.
517
 
518
Btype*
519
Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
520
{
521
  return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE)), fields);
522
}
523
 
524
// Fill in the fields of a struct type.
525
 
526
Btype*
527
Gcc_backend::fill_in_struct(Btype* fill,
528
                            const std::vector<Btyped_identifier>& fields)
529
{
530
  tree fill_tree = fill->get_tree();
531
  tree field_trees = NULL_TREE;
532
  tree* pp = &field_trees;
533
  for (std::vector<Btyped_identifier>::const_iterator p = fields.begin();
534
       p != fields.end();
535
       ++p)
536
    {
537
      tree name_tree = get_identifier_from_string(p->name);
538
      tree type_tree = p->btype->get_tree();
539
      if (type_tree == error_mark_node)
540
        return this->error_type();
541
      tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
542
                              type_tree);
543
      DECL_CONTEXT(field) = fill_tree;
544
      *pp = field;
545
      pp = &DECL_CHAIN(field);
546
    }
547
  TYPE_FIELDS(fill_tree) = field_trees;
548
  layout_type(fill_tree);
549
  return fill;
550
}
551
 
552
// Make an array type.
553
 
554
Btype*
555
Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
556
{
557
  return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
558
                             element_btype, length);
559
}
560
 
561
// Fill in an array type.
562
 
563
Btype*
564
Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
565
                           Bexpression* length)
566
{
567
  tree element_type_tree = element_type->get_tree();
568
  tree length_tree = length->get_tree();
569
  if (element_type_tree == error_mark_node || length_tree == error_mark_node)
570
    return this->error_type();
571
 
572
  gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
573
 
574
  length_tree = fold_convert(sizetype, length_tree);
575
 
576
  // build_index_type takes the maximum index, which is one less than
577
  // the length.
578
  tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
579
                                                      length_tree,
580
                                                      size_one_node));
581
 
582
  tree fill_tree = fill->get_tree();
583
  TREE_TYPE(fill_tree) = element_type_tree;
584
  TYPE_DOMAIN(fill_tree) = index_type_tree;
585
  TYPE_ADDR_SPACE(fill_tree) = TYPE_ADDR_SPACE(element_type_tree);
586
  layout_type(fill_tree);
587
 
588
  if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree))
589
    SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
590
  else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
591
           || TYPE_CANONICAL(index_type_tree) != index_type_tree)
592
    TYPE_CANONICAL(fill_tree) =
593
      build_array_type(TYPE_CANONICAL(element_type_tree),
594
                       TYPE_CANONICAL(index_type_tree));
595
 
596
  return fill;
597
}
598
 
599
// Create a placeholder for a pointer type.
600
 
601
Btype*
602
Gcc_backend::placeholder_pointer_type(const std::string& name,
603
                                      Location location, bool)
604
{
605
  tree ret = build_distinct_type_copy(ptr_type_node);
606
  if (!name.empty())
607
    {
608
      tree decl = build_decl(location.gcc_location(), TYPE_DECL,
609
                             get_identifier_from_string(name),
610
                             ret);
611
      TYPE_NAME(ret) = decl;
612
    }
613
  return this->make_type(ret);
614
}
615
 
616
// Set the real target type for a placeholder pointer type.
617
 
618
bool
619
Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
620
                                          Btype* to_type)
621
{
622
  tree pt = placeholder->get_tree();
623
  if (pt == error_mark_node)
624
    return false;
625
  gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
626
  tree tt = to_type->get_tree();
627
  if (tt == error_mark_node)
628
    {
629
      TREE_TYPE(pt) = tt;
630
      return false;
631
    }
632
  gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
633
  TREE_TYPE(pt) = TREE_TYPE(tt);
634
  if (TYPE_NAME(pt) != NULL_TREE)
635
    {
636
      // Build the data structure gcc wants to see for a typedef.
637
      tree copy = build_variant_type_copy(pt);
638
      TYPE_NAME(copy) = NULL_TREE;
639
      DECL_ORIGINAL_TYPE(TYPE_NAME(pt)) = copy;
640
    }
641
  return true;
642
}
643
 
644
// Set the real values for a placeholder function type.
645
 
646
bool
647
Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
648
{
649
  return this->set_placeholder_pointer_type(placeholder, ft);
650
}
651
 
652
// Create a placeholder for a struct type.
653
 
654
Btype*
655
Gcc_backend::placeholder_struct_type(const std::string& name,
656
                                     Location location)
657
{
658
  tree ret = make_node(RECORD_TYPE);
659
  if (!name.empty())
660
    {
661
      tree decl = build_decl(location.gcc_location(), TYPE_DECL,
662
                             get_identifier_from_string(name),
663
                             ret);
664
      TYPE_NAME(ret) = decl;
665
    }
666
  return this->make_type(ret);
667
}
668
 
669
// Fill in the fields of a placeholder struct type.
670
 
671
bool
672
Gcc_backend::set_placeholder_struct_type(
673
    Btype* placeholder,
674
    const std::vector<Btyped_identifier>& fields)
675
{
676
  tree t = placeholder->get_tree();
677
  gcc_assert(TREE_CODE(t) == RECORD_TYPE && TYPE_FIELDS(t) == NULL_TREE);
678
  Btype* r = this->fill_in_struct(placeholder, fields);
679
 
680
  if (TYPE_NAME(t) != NULL_TREE)
681
    {
682
      // Build the data structure gcc wants to see for a typedef.
683
      tree copy = build_distinct_type_copy(t);
684
      TYPE_NAME(copy) = NULL_TREE;
685
      DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
686
    }
687
 
688
  return r->get_tree() != error_mark_node;
689
}
690
 
691
// Create a placeholder for an array type.
692
 
693
Btype*
694
Gcc_backend::placeholder_array_type(const std::string& name,
695
                                    Location location)
696
{
697
  tree ret = make_node(ARRAY_TYPE);
698
  tree decl = build_decl(location.gcc_location(), TYPE_DECL,
699
                         get_identifier_from_string(name),
700
                         ret);
701
  TYPE_NAME(ret) = decl;
702
  return this->make_type(ret);
703
}
704
 
705
// Fill in the fields of a placeholder array type.
706
 
707
bool
708
Gcc_backend::set_placeholder_array_type(Btype* placeholder,
709
                                        Btype* element_btype,
710
                                        Bexpression* length)
711
{
712
  tree t = placeholder->get_tree();
713
  gcc_assert(TREE_CODE(t) == ARRAY_TYPE && TREE_TYPE(t) == NULL_TREE);
714
  Btype* r = this->fill_in_array(placeholder, element_btype, length);
715
 
716
  // Build the data structure gcc wants to see for a typedef.
717
  tree copy = build_distinct_type_copy(t);
718
  TYPE_NAME(copy) = NULL_TREE;
719
  DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
720
 
721
  return r->get_tree() != error_mark_node;
722
}
723
 
724
// Return a named version of a type.
725
 
726
Btype*
727
Gcc_backend::named_type(const std::string& name, Btype* btype,
728
                        Location location)
729
{
730
  tree type = btype->get_tree();
731
  if (type == error_mark_node)
732
    return this->error_type();
733
 
734
  // The middle-end expects a basic type to have a name.  In Go every
735
  // basic type will have a name.  The first time we see a basic type,
736
  // give it whatever Go name we have at this point.
737
  if (TYPE_NAME(type) == NULL_TREE
738
      && location.gcc_location() == BUILTINS_LOCATION
739
      && (TREE_CODE(type) == INTEGER_TYPE
740
          || TREE_CODE(type) == REAL_TYPE
741
          || TREE_CODE(type) == COMPLEX_TYPE
742
          || TREE_CODE(type) == BOOLEAN_TYPE))
743
    {
744
      tree decl = build_decl(BUILTINS_LOCATION, TYPE_DECL,
745
                             get_identifier_from_string(name),
746
                             type);
747
      TYPE_NAME(type) = decl;
748
      return this->make_type(type);
749
    }
750
 
751
  tree copy = build_variant_type_copy(type);
752
  tree decl = build_decl(location.gcc_location(), TYPE_DECL,
753
                         get_identifier_from_string(name),
754
                         copy);
755
  DECL_ORIGINAL_TYPE(decl) = type;
756
  TYPE_NAME(copy) = decl;
757
  return this->make_type(copy);
758
}
759
 
760
// Return a pointer type used as a marker for a circular type.
761
 
762
Btype*
763
Gcc_backend::circular_pointer_type(Btype*, bool)
764
{
765
  return this->make_type(ptr_type_node);
766
}
767
 
768
// Return whether we might be looking at a circular type.
769
 
770
bool
771
Gcc_backend::is_circular_pointer_type(Btype* btype)
772
{
773
  return btype->get_tree() == ptr_type_node;
774
}
775
 
776
// Return the size of a type.
777
 
778
size_t
779
Gcc_backend::type_size(Btype* btype)
780
{
781
  tree t = btype->get_tree();
782
  if (t == error_mark_node)
783
    return 1;
784
  t = TYPE_SIZE_UNIT(t);
785
  gcc_assert(TREE_CODE(t) == INTEGER_CST);
786
  gcc_assert(TREE_INT_CST_HIGH(t) == 0);
787
  unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
788
  size_t ret = static_cast<size_t>(val_wide);
789
  gcc_assert(ret == val_wide);
790
  return ret;
791
}
792
 
793
// Return the alignment of a type.
794
 
795
size_t
796
Gcc_backend::type_alignment(Btype* btype)
797
{
798
  tree t = btype->get_tree();
799
  if (t == error_mark_node)
800
    return 1;
801
  return TYPE_ALIGN_UNIT(t);
802
}
803
 
804
// Return the alignment of a struct field of type BTYPE.
805
 
806
size_t
807
Gcc_backend::type_field_alignment(Btype* btype)
808
{
809
  tree t = btype->get_tree();
810
  if (t == error_mark_node)
811
    return 1;
812
  return go_field_alignment(t);
813
}
814
 
815
// Return the offset of a field in a struct.
816
 
817
size_t
818
Gcc_backend::type_field_offset(Btype* btype, size_t index)
819
{
820
  tree struct_tree = btype->get_tree();
821
  if (struct_tree == error_mark_node)
822
    return 0;
823
  gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
824
  tree field = TYPE_FIELDS(struct_tree);
825
  for (; index > 0; --index)
826
    {
827
      field = DECL_CHAIN(field);
828
      gcc_assert(field != NULL_TREE);
829
    }
830
  HOST_WIDE_INT offset_wide = int_byte_position(field);
831
  gcc_assert(offset_wide >= 0);
832
  size_t ret = static_cast<size_t>(offset_wide);
833
  gcc_assert(ret == static_cast<unsigned HOST_WIDE_INT>(offset_wide));
834
  return ret;
835
}
836
 
837
// Return the zero value for a type.
838
 
839
Bexpression*
840
Gcc_backend::zero_expression(Btype* btype)
841
{
842
  tree t = btype->get_tree();
843
  tree ret;
844
  if (t == error_mark_node)
845
    ret = error_mark_node;
846
  else
847
    ret = build_zero_cst(t);
848
  return tree_to_expr(ret);
849
}
850
 
851
// An expression as a statement.
852
 
853
Bstatement*
854
Gcc_backend::expression_statement(Bexpression* expr)
855
{
856
  return this->make_statement(expr->get_tree());
857
}
858
 
859
// Variable initialization.
860
 
861
Bstatement*
862
Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
863
{
864
  tree var_tree = var->get_tree();
865
  tree init_tree = init->get_tree();
866
  if (var_tree == error_mark_node || init_tree == error_mark_node)
867
    return this->error_statement();
868
  gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
869
  DECL_INITIAL(var_tree) = init_tree;
870
  return this->make_statement(build1_loc(DECL_SOURCE_LOCATION(var_tree),
871
                                         DECL_EXPR, void_type_node, var_tree));
872
}
873
 
874
// Assignment.
875
 
876
Bstatement*
877
Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
878
                                  Location location)
879
{
880
  tree lhs_tree = lhs->get_tree();
881
  tree rhs_tree = rhs->get_tree();
882
  if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
883
    return this->error_statement();
884
  return this->make_statement(fold_build2_loc(location.gcc_location(),
885
                                              MODIFY_EXPR,
886
                                              void_type_node,
887
                                              lhs_tree, rhs_tree));
888
}
889
 
890
// Return.
891
 
892
Bstatement*
893
Gcc_backend::return_statement(Bfunction* bfunction,
894
                              const std::vector<Bexpression*>& vals,
895
                              Location location)
896
{
897
  tree fntree = bfunction->get_tree();
898
  if (fntree == error_mark_node)
899
    return this->error_statement();
900
  tree result = DECL_RESULT(fntree);
901
  if (result == error_mark_node)
902
    return this->error_statement();
903
  tree ret;
904
  if (vals.empty())
905
    ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
906
                          NULL_TREE);
907
  else if (vals.size() == 1)
908
    {
909
      tree val = vals.front()->get_tree();
910
      if (val == error_mark_node)
911
        return this->error_statement();
912
      tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
913
                                 void_type_node, result,
914
                                 vals.front()->get_tree());
915
      ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
916
                            void_type_node, set);
917
    }
918
  else
919
    {
920
      // To return multiple values, copy the values into a temporary
921
      // variable of the right structure type, and then assign the
922
      // temporary variable to the DECL_RESULT in the return
923
      // statement.
924
      tree stmt_list = NULL_TREE;
925
      tree rettype = TREE_TYPE(result);
926
      tree rettmp = create_tmp_var(rettype, "RESULT");
927
      tree field = TYPE_FIELDS(rettype);
928
      for (std::vector<Bexpression*>::const_iterator p = vals.begin();
929
           p != vals.end();
930
           p++, field = DECL_CHAIN(field))
931
        {
932
          gcc_assert(field != NULL_TREE);
933
          tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
934
                                     TREE_TYPE(field), rettmp, field,
935
                                     NULL_TREE);
936
          tree val = (*p)->get_tree();
937
          if (val == error_mark_node)
938
            return this->error_statement();
939
          tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
940
                                     void_type_node,
941
                                     ref, (*p)->get_tree());
942
          append_to_statement_list(set, &stmt_list);
943
        }
944
      gcc_assert(field == NULL_TREE);
945
      tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
946
                                 void_type_node,
947
                                 result, rettmp);
948
      tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
949
                                      void_type_node, set);
950
      append_to_statement_list(ret_expr, &stmt_list);
951
      ret = stmt_list;
952
    }
953
  return this->make_statement(ret);
954
}
955
 
956
// If.
957
 
958
Bstatement*
959
Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
960
                          Bblock* else_block, Location location)
961
{
962
  tree cond_tree = condition->get_tree();
963
  tree then_tree = then_block->get_tree();
964
  tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
965
  if (cond_tree == error_mark_node
966
      || then_tree == error_mark_node
967
      || else_tree == error_mark_node)
968
    return this->error_statement();
969
  tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
970
                        cond_tree, then_tree, else_tree);
971
  return this->make_statement(ret);
972
}
973
 
974
// Switch.
975
 
976
Bstatement*
977
Gcc_backend::switch_statement(
978
    Bexpression* value,
979
    const std::vector<std::vector<Bexpression*> >& cases,
980
    const std::vector<Bstatement*>& statements,
981
    Location switch_location)
982
{
983
  gcc_assert(cases.size() == statements.size());
984
 
985
  tree stmt_list = NULL_TREE;
986
  std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
987
  for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
988
       ps != statements.end();
989
       ++ps, ++pc)
990
    {
991
      if (pc->empty())
992
        {
993
          source_location loc = (*ps != NULL
994
                                 ? EXPR_LOCATION((*ps)->get_tree())
995
                                 : UNKNOWN_LOCATION);
996
          tree label = create_artificial_label(loc);
997
          tree c = build_case_label(NULL_TREE, NULL_TREE, label);
998
          append_to_statement_list(c, &stmt_list);
999
        }
1000
      else
1001
        {
1002
          for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
1003
               pcv != pc->end();
1004
               ++pcv)
1005
            {
1006
              tree t = (*pcv)->get_tree();
1007
              if (t == error_mark_node)
1008
                return this->error_statement();
1009
              source_location loc = EXPR_LOCATION(t);
1010
              tree label = create_artificial_label(loc);
1011
              tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
1012
              append_to_statement_list(c, &stmt_list);
1013
            }
1014
        }
1015
 
1016
      if (*ps != NULL)
1017
        {
1018
          tree t = (*ps)->get_tree();
1019
          if (t == error_mark_node)
1020
            return this->error_statement();
1021
          append_to_statement_list(t, &stmt_list);
1022
        }
1023
    }
1024
 
1025
  tree tv = value->get_tree();
1026
  if (tv == error_mark_node)
1027
    return this->error_statement();
1028
  tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR,
1029
                      void_type_node, tv, stmt_list, NULL_TREE);
1030
  return this->make_statement(t);
1031
}
1032
 
1033
// Pair of statements.
1034
 
1035
Bstatement*
1036
Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
1037
{
1038
  tree stmt_list = NULL_TREE;
1039
  tree t = s1->get_tree();
1040
  if (t == error_mark_node)
1041
    return this->error_statement();
1042
  append_to_statement_list(t, &stmt_list);
1043
  t = s2->get_tree();
1044
  if (t == error_mark_node)
1045
    return this->error_statement();
1046
  append_to_statement_list(t, &stmt_list);
1047
  return this->make_statement(stmt_list);
1048
}
1049
 
1050
// List of statements.
1051
 
1052
Bstatement*
1053
Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
1054
{
1055
  tree stmt_list = NULL_TREE;
1056
  for (std::vector<Bstatement*>::const_iterator p = statements.begin();
1057
       p != statements.end();
1058
       ++p)
1059
    {
1060
      tree t = (*p)->get_tree();
1061
      if (t == error_mark_node)
1062
        return this->error_statement();
1063
      append_to_statement_list(t, &stmt_list);
1064
    }
1065
  return this->make_statement(stmt_list);
1066
}
1067
 
1068
// Make a block.  For some reason gcc uses a dual structure for
1069
// blocks: BLOCK tree nodes and BIND_EXPR tree nodes.  Since the
1070
// BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
1071
// the Bblock.
1072
 
1073
Bblock*
1074
Gcc_backend::block(Bfunction* function, Bblock* enclosing,
1075
                   const std::vector<Bvariable*>& vars,
1076
                   Location start_location,
1077
                   Location)
1078
{
1079
  tree block_tree = make_node(BLOCK);
1080
  if (enclosing == NULL)
1081
    {
1082
      // FIXME: Permitting FUNCTION to be NULL is a temporary measure
1083
      // until we have a proper representation of the init function.
1084
      tree fndecl;
1085
      if (function == NULL)
1086
        fndecl = current_function_decl;
1087
      else
1088
        fndecl = function->get_tree();
1089
      gcc_assert(fndecl != NULL_TREE);
1090
 
1091
      // We may have already created a block for local variables when
1092
      // we take the address of a parameter.
1093
      if (DECL_INITIAL(fndecl) == NULL_TREE)
1094
        {
1095
          BLOCK_SUPERCONTEXT(block_tree) = fndecl;
1096
          DECL_INITIAL(fndecl) = block_tree;
1097
        }
1098
      else
1099
        {
1100
          tree superblock_tree = DECL_INITIAL(fndecl);
1101
          BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
1102
          tree* pp;
1103
          for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
1104
               *pp != NULL_TREE;
1105
               pp = &BLOCK_CHAIN(*pp))
1106
            ;
1107
          *pp = block_tree;
1108
        }
1109
    }
1110
  else
1111
    {
1112
      tree superbind_tree = enclosing->get_tree();
1113
      tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
1114
      gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
1115
 
1116
      BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
1117
      tree* pp;
1118
      for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
1119
           *pp != NULL_TREE;
1120
           pp = &BLOCK_CHAIN(*pp))
1121
        ;
1122
      *pp = block_tree;
1123
    }
1124
 
1125
  tree* pp = &BLOCK_VARS(block_tree);
1126
  for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
1127
       pv != vars.end();
1128
       ++pv)
1129
    {
1130
      *pp = (*pv)->get_tree();
1131
      if (*pp != error_mark_node)
1132
        pp = &DECL_CHAIN(*pp);
1133
    }
1134
  *pp = NULL_TREE;
1135
 
1136
  TREE_USED(block_tree) = 1;
1137
 
1138
  tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
1139
                              void_type_node, BLOCK_VARS(block_tree),
1140
                              NULL_TREE, block_tree);
1141
  TREE_SIDE_EFFECTS(bind_tree) = 1;
1142
 
1143
  return new Bblock(bind_tree);
1144
}
1145
 
1146
// Add statements to a block.
1147
 
1148
void
1149
Gcc_backend::block_add_statements(Bblock* bblock,
1150
                                  const std::vector<Bstatement*>& statements)
1151
{
1152
  tree stmt_list = NULL_TREE;
1153
  for (std::vector<Bstatement*>::const_iterator p = statements.begin();
1154
       p != statements.end();
1155
       ++p)
1156
    {
1157
      tree s = (*p)->get_tree();
1158
      if (s != error_mark_node)
1159
        append_to_statement_list(s, &stmt_list);
1160
    }
1161
 
1162
  tree bind_tree = bblock->get_tree();
1163
  gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1164
  BIND_EXPR_BODY(bind_tree) = stmt_list;
1165
}
1166
 
1167
// Return a block as a statement.
1168
 
1169
Bstatement*
1170
Gcc_backend::block_statement(Bblock* bblock)
1171
{
1172
  tree bind_tree = bblock->get_tree();
1173
  gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1174
  return this->make_statement(bind_tree);
1175
}
1176
 
1177
// Make a global variable.
1178
 
1179
Bvariable*
1180
Gcc_backend::global_variable(const std::string& package_name,
1181
                             const std::string& unique_prefix,
1182
                             const std::string& name,
1183
                             Btype* btype,
1184
                             bool is_external,
1185
                             bool is_hidden,
1186
                             Location location)
1187
{
1188
  tree type_tree = btype->get_tree();
1189
  if (type_tree == error_mark_node)
1190
    return this->error_variable();
1191
 
1192
  std::string var_name(package_name);
1193
  var_name.push_back('.');
1194
  var_name.append(name);
1195
  tree decl = build_decl(location.gcc_location(), VAR_DECL,
1196
                         get_identifier_from_string(var_name),
1197
                         type_tree);
1198
  if (is_external)
1199
    DECL_EXTERNAL(decl) = 1;
1200
  else
1201
    TREE_STATIC(decl) = 1;
1202
  if (!is_hidden)
1203
    {
1204
      TREE_PUBLIC(decl) = 1;
1205
 
1206
      std::string asm_name(unique_prefix);
1207
      asm_name.push_back('.');
1208
      asm_name.append(var_name);
1209
      SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
1210
    }
1211
  TREE_USED(decl) = 1;
1212
 
1213
  go_preserve_from_gc(decl);
1214
 
1215
  return new Bvariable(decl);
1216
}
1217
 
1218
// Set the initial value of a global variable.
1219
 
1220
void
1221
Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
1222
{
1223
  tree expr_tree = expr->get_tree();
1224
  if (expr_tree == error_mark_node)
1225
    return;
1226
  gcc_assert(TREE_CONSTANT(expr_tree));
1227
  tree var_decl = var->get_tree();
1228
  if (var_decl == error_mark_node)
1229
    return;
1230
  DECL_INITIAL(var_decl) = expr_tree;
1231
}
1232
 
1233
// Make a local variable.
1234
 
1235
Bvariable*
1236
Gcc_backend::local_variable(Bfunction* function, const std::string& name,
1237
                            Btype* btype, bool is_address_taken,
1238
                            Location location)
1239
{
1240
  tree type_tree = btype->get_tree();
1241
  if (type_tree == error_mark_node)
1242
    return this->error_variable();
1243
  tree decl = build_decl(location.gcc_location(), VAR_DECL,
1244
                         get_identifier_from_string(name),
1245
                         type_tree);
1246
  DECL_CONTEXT(decl) = function->get_tree();
1247
  TREE_USED(decl) = 1;
1248
  if (is_address_taken)
1249
    TREE_ADDRESSABLE(decl) = 1;
1250
  go_preserve_from_gc(decl);
1251
  return new Bvariable(decl);
1252
}
1253
 
1254
// Make a function parameter variable.
1255
 
1256
Bvariable*
1257
Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
1258
                                Btype* btype, bool is_address_taken,
1259
                                Location location)
1260
{
1261
  tree type_tree = btype->get_tree();
1262
  if (type_tree == error_mark_node)
1263
    return this->error_variable();
1264
  tree decl = build_decl(location.gcc_location(), PARM_DECL,
1265
                         get_identifier_from_string(name),
1266
                         type_tree);
1267
  DECL_CONTEXT(decl) = function->get_tree();
1268
  DECL_ARG_TYPE(decl) = type_tree;
1269
  TREE_USED(decl) = 1;
1270
  if (is_address_taken)
1271
    TREE_ADDRESSABLE(decl) = 1;
1272
  go_preserve_from_gc(decl);
1273
  return new Bvariable(decl);
1274
}
1275
 
1276
// Make a temporary variable.
1277
 
1278
Bvariable*
1279
Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
1280
                                Btype* btype, Bexpression* binit,
1281
                                bool is_address_taken,
1282
                                Location location,
1283
                                Bstatement** pstatement)
1284
{
1285
  tree type_tree = btype->get_tree();
1286
  tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
1287
  if (type_tree == error_mark_node || init_tree == error_mark_node)
1288
    {
1289
      *pstatement = this->error_statement();
1290
      return this->error_variable();
1291
    }
1292
 
1293
  tree var;
1294
  // We can only use create_tmp_var if the type is not addressable.
1295
  if (!TREE_ADDRESSABLE(type_tree))
1296
    var = create_tmp_var(type_tree, "GOTMP");
1297
  else
1298
    {
1299
      gcc_assert(bblock != NULL);
1300
      var = build_decl(location.gcc_location(), VAR_DECL,
1301
                       create_tmp_var_name("GOTMP"),
1302
                       type_tree);
1303
      DECL_ARTIFICIAL(var) = 1;
1304
      DECL_IGNORED_P(var) = 1;
1305
      TREE_USED(var) = 1;
1306
      // FIXME: Permitting function to be NULL here is a temporary
1307
      // measure until we have a proper representation of the init
1308
      // function.
1309
      if (function != NULL)
1310
        DECL_CONTEXT(var) = function->get_tree();
1311
      else
1312
        {
1313
          gcc_assert(current_function_decl != NULL_TREE);
1314
          DECL_CONTEXT(var) = current_function_decl;
1315
        }
1316
 
1317
      // We have to add this variable to the BLOCK and the BIND_EXPR.
1318
      tree bind_tree = bblock->get_tree();
1319
      gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
1320
      tree block_tree = BIND_EXPR_BLOCK(bind_tree);
1321
      gcc_assert(TREE_CODE(block_tree) == BLOCK);
1322
      DECL_CHAIN(var) = BLOCK_VARS(block_tree);
1323
      BLOCK_VARS(block_tree) = var;
1324
      BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
1325
    }
1326
 
1327
  if (init_tree != NULL_TREE)
1328
    DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree,
1329
                                         init_tree);
1330
 
1331
  if (is_address_taken)
1332
    TREE_ADDRESSABLE(var) = 1;
1333
 
1334
  *pstatement = this->make_statement(build1_loc(location.gcc_location(),
1335
                                                DECL_EXPR,
1336
                                                void_type_node, var));
1337
  return new Bvariable(var);
1338
}
1339
 
1340
// Create a named immutable initialized data structure.
1341
 
1342
Bvariable*
1343
Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype,
1344
                              Location location)
1345
{
1346
  tree type_tree = btype->get_tree();
1347
  if (type_tree == error_mark_node)
1348
    return this->error_variable();
1349
  gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
1350
  tree decl = build_decl(location.gcc_location(), VAR_DECL,
1351
                         get_identifier_from_string(name),
1352
                         build_qualified_type(type_tree, TYPE_QUAL_CONST));
1353
  TREE_STATIC(decl) = 1;
1354
  TREE_READONLY(decl) = 1;
1355
  TREE_CONSTANT(decl) = 1;
1356
  TREE_USED(decl) = 1;
1357
  DECL_ARTIFICIAL(decl) = 1;
1358
 
1359
  // We don't call rest_of_decl_compilation until we have the
1360
  // initializer.
1361
 
1362
  go_preserve_from_gc(decl);
1363
  return new Bvariable(decl);
1364
}
1365
 
1366
// Set the initializer for a variable created by immutable_struct.
1367
// This is where we finish compiling the variable.
1368
 
1369
void
1370
Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
1371
                                       bool is_common, Btype*,
1372
                                       Location,
1373
                                       Bexpression* initializer)
1374
{
1375
  tree decl = var->get_tree();
1376
  tree init_tree = initializer->get_tree();
1377
  if (decl == error_mark_node || init_tree == error_mark_node)
1378
    return;
1379
 
1380
  DECL_INITIAL(decl) = init_tree;
1381
 
1382
  // We can't call make_decl_one_only until we set DECL_INITIAL.
1383
  if (!is_common)
1384
    TREE_PUBLIC(decl) = 1;
1385
  else
1386
    {
1387
      make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
1388
      resolve_unique_section(decl, 1, 0);
1389
    }
1390
 
1391
  rest_of_decl_compilation(decl, 1, 0);
1392
}
1393
 
1394
// Return a reference to an immutable initialized data structure
1395
// defined in another package.
1396
 
1397
Bvariable*
1398
Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
1399
                                        Location location)
1400
{
1401
  tree type_tree = btype->get_tree();
1402
  if (type_tree == error_mark_node)
1403
    return this->error_variable();
1404
  gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
1405
  tree decl = build_decl(location.gcc_location(), VAR_DECL,
1406
                         get_identifier_from_string(name),
1407
                         build_qualified_type(type_tree, TYPE_QUAL_CONST));
1408
  TREE_READONLY(decl) = 1;
1409
  TREE_CONSTANT(decl) = 1;
1410
  DECL_ARTIFICIAL(decl) = 1;
1411
  TREE_PUBLIC(decl) = 1;
1412
  DECL_EXTERNAL(decl) = 1;
1413
  go_preserve_from_gc(decl);
1414
  return new Bvariable(decl);
1415
}
1416
 
1417
// Make a label.
1418
 
1419
Blabel*
1420
Gcc_backend::label(Bfunction* function, const std::string& name,
1421
                   Location location)
1422
{
1423
  tree decl;
1424
  if (name.empty())
1425
    decl = create_artificial_label(location.gcc_location());
1426
  else
1427
    {
1428
      tree id = get_identifier_from_string(name);
1429
      decl = build_decl(location.gcc_location(), LABEL_DECL, id,
1430
                        void_type_node);
1431
      DECL_CONTEXT(decl) = function->get_tree();
1432
    }
1433
  return new Blabel(decl);
1434
}
1435
 
1436
// Make a statement which defines a label.
1437
 
1438
Bstatement*
1439
Gcc_backend::label_definition_statement(Blabel* label)
1440
{
1441
  tree lab = label->get_tree();
1442
  tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
1443
                             void_type_node, lab);
1444
  return this->make_statement(ret);
1445
}
1446
 
1447
// Make a goto statement.
1448
 
1449
Bstatement*
1450
Gcc_backend::goto_statement(Blabel* label, Location location)
1451
{
1452
  tree lab = label->get_tree();
1453
  tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
1454
                             lab);
1455
  return this->make_statement(ret);
1456
}
1457
 
1458
// Get the address of a label.
1459
 
1460
Bexpression*
1461
Gcc_backend::label_address(Blabel* label, Location location)
1462
{
1463
  tree lab = label->get_tree();
1464
  TREE_USED(lab) = 1;
1465
  TREE_ADDRESSABLE(lab) = 1;
1466
  tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
1467
                              build_fold_addr_expr_loc(location.gcc_location(),
1468
                                                       lab));
1469
  return this->make_expression(ret);
1470
}
1471
 
1472
// The single backend.
1473
 
1474
static Gcc_backend gcc_backend;
1475
 
1476
// Return the backend generator.
1477
 
1478
Backend*
1479
go_get_backend()
1480
{
1481
  return &gcc_backend;
1482
}
1483
 
1484
// FIXME: Temporary functions while converting to the new backend
1485
// interface.
1486
 
1487
Btype*
1488
tree_to_type(tree t)
1489
{
1490
  return new Btype(t);
1491
}
1492
 
1493
Bexpression*
1494
tree_to_expr(tree t)
1495
{
1496
  return new Bexpression(t);
1497
}
1498
 
1499
Bstatement*
1500
tree_to_stat(tree t)
1501
{
1502
  return new Bstatement(t);
1503
}
1504
 
1505
Bfunction*
1506
tree_to_function(tree t)
1507
{
1508
  return new Bfunction(t);
1509
}
1510
 
1511
Bblock*
1512
tree_to_block(tree t)
1513
{
1514
  gcc_assert(TREE_CODE(t) == BIND_EXPR);
1515
  return new Bblock(t);
1516
}
1517
 
1518
tree
1519
type_to_tree(Btype* bt)
1520
{
1521
  return bt->get_tree();
1522
}
1523
 
1524
tree
1525
expr_to_tree(Bexpression* be)
1526
{
1527
  return be->get_tree();
1528
}
1529
 
1530
tree
1531
stat_to_tree(Bstatement* bs)
1532
{
1533
  return bs->get_tree();
1534
}
1535
 
1536
tree
1537
block_to_tree(Bblock* bb)
1538
{
1539
  return bb->get_tree();
1540
}
1541
 
1542
tree
1543
var_to_tree(Bvariable* bv)
1544
{
1545
  return bv->get_tree();
1546
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.