LCOV - code coverage report
Current view: top level - gcc/go - go-gcc.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.3 % 1573 1499
Test Date: 2026-02-28 14:20:25 Functions: 99.0 % 99 98
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // go-gcc.cc -- Go frontend to gcc IR.
       2              : // Copyright (C) 2011-2026 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              : #include "tree.h"
      28              : #include "opts.h"
      29              : #include "fold-const.h"
      30              : #include "stringpool.h"
      31              : #include "stor-layout.h"
      32              : #include "varasm.h"
      33              : #include "tree-iterator.h"
      34              : #include "tm.h"
      35              : #include "function.h"
      36              : #include "cgraph.h"
      37              : #include "convert.h"
      38              : #include "gimple-expr.h"
      39              : #include "gimplify.h"
      40              : #include "langhooks.h"
      41              : #include "toplev.h"
      42              : #include "output.h"
      43              : #include "realmpfr.h"
      44              : #include "builtins.h"
      45              : 
      46              : #include "go-c.h"
      47              : #include "go-gcc.h"
      48              : 
      49              : #include "gogo.h"
      50              : #include "backend.h"
      51              : 
      52              : // A class wrapping a tree.
      53              : 
      54              : class Gcc_tree
      55              : {
      56              :  public:
      57     72647912 :   Gcc_tree(tree t)
      58     72647912 :     : t_(t)
      59              :   { }
      60              : 
      61              :   tree
      62    136786653 :   get_tree() const
      63       587266 :   { return this->t_; }
      64              : 
      65              :   void
      66            2 :   set_tree(tree t)
      67            2 :   { this->t_ = t; }
      68              : 
      69              :  private:
      70              :   tree t_;
      71              : };
      72              : 
      73              : // In gcc, types, expressions, and statements are all trees.
      74              : class Btype : public Gcc_tree
      75              : {
      76              :  public:
      77      6231391 :   Btype(tree t)
      78      6231391 :     : Gcc_tree(t)
      79              :   { }
      80              : };
      81              : 
      82              : class Bexpression : public Gcc_tree
      83              : {
      84              :  public:
      85     52314512 :   Bexpression(tree t)
      86     52314512 :     : Gcc_tree(t)
      87              :   { }
      88              : };
      89              : 
      90              : class Bstatement : public Gcc_tree
      91              : {
      92              :  public:
      93      9800748 :   Bstatement(tree t)
      94      9800748 :     : Gcc_tree(t)
      95              :   { }
      96              : };
      97              : 
      98              : class Bfunction : public Gcc_tree
      99              : {
     100              :  public:
     101      1247947 :   Bfunction(tree t)
     102      1247947 :     : Gcc_tree(t)
     103              :   { }
     104              : };
     105              : 
     106              : class Bblock : public Gcc_tree
     107              : {
     108              :  public:
     109      2860150 :   Bblock(tree t)
     110      2860150 :     : Gcc_tree(t)
     111              :   { }
     112              : };
     113              : 
     114              : class Blabel : public Gcc_tree
     115              : {
     116              :  public:
     117       193164 :   Blabel(tree t)
     118       193164 :     : Gcc_tree(t)
     119              :   { }
     120              : };
     121              : 
     122              : // Bvariable is a bit more complicated, because of zero-sized types.
     123              : // The GNU linker does not permit dynamic variables with zero size.
     124              : // When we see such a variable, we generate a version of the type with
     125              : // non-zero size.  However, when referring to the global variable, we
     126              : // want an expression of zero size; otherwise, if, say, the global
     127              : // variable is passed to a function, we will be passing a
     128              : // non-zero-sized value to a zero-sized value, which can lead to a
     129              : // miscompilation.
     130              : 
     131              : class Bvariable
     132              : {
     133              :  public:
     134      5123751 :   Bvariable(tree t)
     135      5123751 :     : t_(t), orig_type_(NULL)
     136              :   { }
     137              : 
     138        34340 :   Bvariable(tree t, tree orig_type)
     139        34340 :     : t_(t), orig_type_(orig_type)
     140              :   { }
     141              : 
     142              :   // Get the tree for use as an expression.
     143              :   tree
     144              :   get_tree(Location) const;
     145              : 
     146              :   // Get the actual decl;
     147              :   tree
     148      3266300 :   get_decl() const
     149      3266300 :   { return this->t_; }
     150              : 
     151              :  private:
     152              :   tree t_;
     153              :   tree orig_type_;
     154              : };
     155              : 
     156              : // Get the tree of a variable for use as an expression.  If this is a
     157              : // zero-sized global, create an expression that refers to the decl but
     158              : // has zero size.
     159              : tree
     160     12126028 : Bvariable::get_tree(Location location) const
     161              : {
     162     12126028 :   if (this->orig_type_ == NULL
     163       474762 :       || this->t_ == error_mark_node
     164     12600790 :       || TREE_TYPE(this->t_) == this->orig_type_)
     165     12123872 :     return this->t_;
     166              :   // Return *(orig_type*)&decl.  */
     167         2156 :   tree t = build_fold_addr_expr_loc(location.gcc_location(), this->t_);
     168         2156 :   t = fold_build1_loc(location.gcc_location(), NOP_EXPR,
     169         2156 :                       build_pointer_type(this->orig_type_), t);
     170         2156 :   return build_fold_indirect_ref_loc(location.gcc_location(), t);
     171              : }
     172              : 
     173              : // This file implements the interface between the Go frontend proper
     174              : // and the gcc IR.  This implements specific instantiations of
     175              : // abstract classes defined by the Go frontend proper.  The Go
     176              : // frontend proper class methods of these classes to generate the
     177              : // backend representation.
     178              : 
     179              : class Gcc_backend : public Backend
     180              : {
     181              :  public:
     182              :   Gcc_backend();
     183              : 
     184              :   // Types.
     185              : 
     186              :   Btype*
     187          172 :   error_type()
     188          344 :   { return this->make_type(error_mark_node); }
     189              : 
     190              :   Btype*
     191         7816 :   void_type()
     192        15632 :   { return this->make_type(void_type_node); }
     193              : 
     194              :   Btype*
     195         6768 :   bool_type()
     196        13536 :   { return this->make_type(boolean_type_node); }
     197              : 
     198              :   Btype*
     199              :   integer_type(bool, int);
     200              : 
     201              :   Btype*
     202              :   float_type(int);
     203              : 
     204              :   Btype*
     205              :   complex_type(int);
     206              : 
     207              :   Btype*
     208              :   pointer_type(Btype*);
     209              : 
     210              :   Btype*
     211              :   function_type(const Btyped_identifier&,
     212              :                 const std::vector<Btyped_identifier>&,
     213              :                 const std::vector<Btyped_identifier>&,
     214              :                 Btype*,
     215              :                 const Location);
     216              : 
     217              :   Btype*
     218              :   struct_type(const std::vector<Btyped_identifier>&);
     219              : 
     220              :   Btype*
     221              :   array_type(Btype*, Bexpression*);
     222              : 
     223              :   Btype*
     224              :   placeholder_pointer_type(const std::string&, Location, bool);
     225              : 
     226              :   bool
     227              :   set_placeholder_pointer_type(Btype*, Btype*);
     228              : 
     229              :   bool
     230              :   set_placeholder_function_type(Btype*, Btype*);
     231              : 
     232              :   Btype*
     233              :   placeholder_struct_type(const std::string&, Location);
     234              : 
     235              :   bool
     236              :   set_placeholder_struct_type(Btype* placeholder,
     237              :                               const std::vector<Btyped_identifier>&);
     238              : 
     239              :   Btype*
     240              :   placeholder_array_type(const std::string&, Location);
     241              : 
     242              :   bool
     243              :   set_placeholder_array_type(Btype*, Btype*, Bexpression*);
     244              : 
     245              :   Btype*
     246              :   named_type(const std::string&, Btype*, Location);
     247              : 
     248              :   Btype*
     249              :   circular_pointer_type(Btype*, bool);
     250              : 
     251              :   bool
     252              :   is_circular_pointer_type(Btype*);
     253              : 
     254              :   int64_t
     255              :   type_size(Btype*);
     256              : 
     257              :   int64_t
     258              :   type_alignment(Btype*);
     259              : 
     260              :   int64_t
     261              :   type_field_alignment(Btype*);
     262              : 
     263              :   int64_t
     264              :   type_field_offset(Btype*, size_t index);
     265              : 
     266              :   // Expressions.
     267              : 
     268              :   Bexpression*
     269              :   zero_expression(Btype*);
     270              : 
     271              :   Bexpression*
     272         3834 :   error_expression()
     273         7668 :   { return this->make_expression(error_mark_node); }
     274              : 
     275              :   Bexpression*
     276      1242556 :   nil_pointer_expression()
     277      2485112 :   { return this->make_expression(null_pointer_node); }
     278              : 
     279              :   Bexpression*
     280              :   var_expression(Bvariable* var, Location);
     281              : 
     282              :   Bexpression*
     283              :   indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location);
     284              : 
     285              :   Bexpression*
     286              :   named_constant_expression(Btype* btype, const std::string& name,
     287              :                             Bexpression* val, Location);
     288              : 
     289              :   Bexpression*
     290              :   integer_constant_expression(Btype* btype, mpz_t val);
     291              : 
     292              :   Bexpression*
     293              :   float_constant_expression(Btype* btype, mpfr_t val);
     294              : 
     295              :   Bexpression*
     296              :   complex_constant_expression(Btype* btype, mpc_t val);
     297              : 
     298              :   Bexpression*
     299              :   string_constant_expression(const std::string& val);
     300              : 
     301              :   Bexpression*
     302              :   boolean_constant_expression(bool val);
     303              : 
     304              :   Bexpression*
     305              :   real_part_expression(Bexpression* bcomplex, Location);
     306              : 
     307              :   Bexpression*
     308              :   imag_part_expression(Bexpression* bcomplex, Location);
     309              : 
     310              :   Bexpression*
     311              :   complex_expression(Bexpression* breal, Bexpression* bimag, Location);
     312              : 
     313              :   Bexpression*
     314              :   convert_expression(Btype* type, Bexpression* expr, Location);
     315              : 
     316              :   Bexpression*
     317              :   function_code_expression(Bfunction*, Location);
     318              : 
     319              :   Bexpression*
     320              :   address_expression(Bexpression*, Location);
     321              : 
     322              :   Bexpression*
     323              :   struct_field_expression(Bexpression*, size_t, Location);
     324              : 
     325              :   Bexpression*
     326              :   compound_expression(Bstatement*, Bexpression*, Location);
     327              : 
     328              :   Bexpression*
     329              :   conditional_expression(Bfunction*, Btype*, Bexpression*, Bexpression*,
     330              :                          Bexpression*, Location);
     331              : 
     332              :   Bexpression*
     333              :   unary_expression(Operator, Bexpression*, Location);
     334              : 
     335              :   Bexpression*
     336              :   binary_expression(Operator, Bexpression*, Bexpression*, Location);
     337              : 
     338              :   Bexpression*
     339              :   constructor_expression(Btype*, const std::vector<Bexpression*>&, Location);
     340              : 
     341              :   Bexpression*
     342              :   array_constructor_expression(Btype*, const std::vector<unsigned long>&,
     343              :                                const std::vector<Bexpression*>&, Location);
     344              : 
     345              :   Bexpression*
     346              :   pointer_offset_expression(Bexpression* base, Bexpression* offset, Location);
     347              : 
     348              :   Bexpression*
     349              :   array_index_expression(Bexpression* array, Bexpression* index, Location);
     350              : 
     351              :   Bexpression*
     352              :   call_expression(Bfunction* caller, Bexpression* fn,
     353              :                   const std::vector<Bexpression*>& args,
     354              :                   Bexpression* static_chain, Location);
     355              : 
     356              :   // Statements.
     357              : 
     358              :   Bstatement*
     359          786 :   error_statement()
     360         1572 :   { return this->make_statement(error_mark_node); }
     361              : 
     362              :   Bstatement*
     363              :   expression_statement(Bfunction*, Bexpression*);
     364              : 
     365              :   Bstatement*
     366              :   init_statement(Bfunction*, Bvariable* var, Bexpression* init);
     367              : 
     368              :   Bstatement*
     369              :   assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
     370              :                        Location);
     371              : 
     372              :   Bstatement*
     373              :   return_statement(Bfunction*, const std::vector<Bexpression*>&,
     374              :                    Location);
     375              : 
     376              :   Bstatement*
     377              :   if_statement(Bfunction*, Bexpression* condition, Bblock* then_block,
     378              :                Bblock* else_block, Location);
     379              : 
     380              :   Bstatement*
     381              :   switch_statement(Bfunction* function, Bexpression* value,
     382              :                    const std::vector<std::vector<Bexpression*> >& cases,
     383              :                    const std::vector<Bstatement*>& statements,
     384              :                    Location);
     385              : 
     386              :   Bstatement*
     387              :   compound_statement(Bstatement*, Bstatement*);
     388              : 
     389              :   Bstatement*
     390              :   statement_list(const std::vector<Bstatement*>&);
     391              : 
     392              :   Bstatement*
     393              :   exception_handler_statement(Bstatement* bstat, Bstatement* except_stmt,
     394              :                               Bstatement* finally_stmt, Location);
     395              : 
     396              :   // Blocks.
     397              : 
     398              :   Bblock*
     399              :   block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
     400              :         Location, Location);
     401              : 
     402              :   void
     403              :   block_add_statements(Bblock*, const std::vector<Bstatement*>&);
     404              : 
     405              :   Bstatement*
     406              :   block_statement(Bblock*);
     407              : 
     408              :   // Variables.
     409              : 
     410              :   Bvariable*
     411          176 :   error_variable()
     412          176 :   { return new Bvariable(error_mark_node); }
     413              : 
     414              :   Bvariable*
     415              :   global_variable(const std::string& var_name,
     416              :                   const std::string& asm_name,
     417              :                   Btype* btype,
     418              :                   unsigned int flags,
     419              :                   Location location);
     420              : 
     421              :   void
     422              :   global_variable_set_init(Bvariable*, Bexpression*);
     423              : 
     424              :   Bvariable*
     425              :   local_variable(Bfunction*, const std::string&, Btype*, Bvariable*,
     426              :                  unsigned int, Location);
     427              : 
     428              :   Bvariable*
     429              :   parameter_variable(Bfunction*, const std::string&, Btype*, unsigned int,
     430              :                      Location);
     431              : 
     432              :   Bvariable*
     433              :   static_chain_variable(Bfunction*, const std::string&, Btype*, unsigned int,
     434              :                         Location);
     435              : 
     436              :   Bvariable*
     437              :   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, unsigned int,
     438              :                      Location, Bstatement**);
     439              : 
     440              :   Bvariable*
     441              :   implicit_variable(const std::string&, const std::string&, Btype*,
     442              :                     unsigned int, int64_t);
     443              : 
     444              :   void
     445              :   implicit_variable_set_init(Bvariable*, const std::string&, Btype*,
     446              :                              unsigned int, Bexpression*);
     447              : 
     448              :   Bvariable*
     449              :   implicit_variable_reference(const std::string&, const std::string&, Btype*);
     450              : 
     451              :   Bvariable*
     452              :   immutable_struct(const std::string&, const std::string&,
     453              :                    unsigned int, Btype*, Location);
     454              : 
     455              :   void
     456              :   immutable_struct_set_init(Bvariable*, const std::string&, unsigned int,
     457              :                             Btype*, Location, Bexpression*);
     458              : 
     459              :   Bvariable*
     460              :   immutable_struct_reference(const std::string&, const std::string&,
     461              :                              Btype*, Location);
     462              : 
     463              :   // Labels.
     464              : 
     465              :   Blabel*
     466              :   label(Bfunction*, const std::string& name, Location);
     467              : 
     468              :   Bstatement*
     469              :   label_definition_statement(Blabel*);
     470              : 
     471              :   Bstatement*
     472              :   goto_statement(Blabel*, Location);
     473              : 
     474              :   Bexpression*
     475              :   label_address(Blabel*, Location);
     476              : 
     477              :   // Functions.
     478              : 
     479              :   Bfunction*
     480           14 :   error_function()
     481           28 :   { return this->make_function(error_mark_node); }
     482              : 
     483              :   Bfunction*
     484              :   function(Btype* fntype, const std::string& name, const std::string& asm_name,
     485              :            unsigned int flags, Location);
     486              : 
     487              :   Bstatement*
     488              :   function_defer_statement(Bfunction* function, Bexpression* undefer,
     489              :                            Bexpression* defer, Location);
     490              : 
     491              :   bool
     492              :   function_set_parameters(Bfunction* function, const std::vector<Bvariable*>&);
     493              : 
     494              :   bool
     495              :   function_set_body(Bfunction* function, Bstatement* code_stmt);
     496              : 
     497              :   Bfunction*
     498              :   lookup_builtin(const std::string&);
     499              : 
     500              :   void
     501              :   write_global_definitions(const std::vector<Btype*>&,
     502              :                            const std::vector<Bexpression*>&,
     503              :                            const std::vector<Bfunction*>&,
     504              :                            const std::vector<Bvariable*>&);
     505              : 
     506              :   void
     507              :   write_export_data(const char* bytes, unsigned int size);
     508              : 
     509              : 
     510              :  private:
     511              :   // Make a Bexpression from a tree.
     512              :   Bexpression*
     513     52314512 :   make_expression(tree t)
     514      1246390 :   { return new Bexpression(t); }
     515              : 
     516              :   // Make a Bstatement from a tree.
     517              :   Bstatement*
     518      9800748 :   make_statement(tree t)
     519          786 :   { return new Bstatement(t); }
     520              : 
     521              :   // Make a Btype from a tree.
     522              :   Btype*
     523      6231391 :   make_type(tree t)
     524        14756 :   { return new Btype(t); }
     525              : 
     526              :   Bfunction*
     527       636516 :   make_function(tree t)
     528           14 :   { return new Bfunction(t); }
     529              : 
     530              :   Btype*
     531              :   fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
     532              : 
     533              :   Btype*
     534              :   fill_in_array(Btype*, Btype*, Bexpression*);
     535              : 
     536              :   tree
     537              :   non_zero_size_type(tree);
     538              : 
     539              :   tree
     540              :   convert_tree(tree, tree, Location);
     541              : 
     542              : private:
     543              :   static const int builtin_cold = 1 << 0;
     544              :   static const int builtin_const = 1 << 1;
     545              :   static const int builtin_leaf = 1 << 2;
     546              :   static const int builtin_nonnull = 1 << 3;
     547              :   static const int builtin_noreturn = 1 << 4;
     548              :   static const int builtin_nothrow = 1 << 5;
     549              :   static const int builtin_novops = 1 << 6;
     550              :   static const int builtin_pure = 1 << 7;
     551              : 
     552              :   void
     553              :   define_builtin(built_in_function bcode, const char* name, const char* libname,
     554              :                  tree fntype, int flags);
     555              : 
     556              :   void
     557              :   set_attributes(tree decl, int flags);
     558              : 
     559              :   // A mapping of the GCC built-ins exposed to GCCGo.
     560              :   std::map<std::string, Bfunction*> builtin_functions_;
     561              : };
     562              : 
     563              : // A helper function to create a GCC identifier from a C++ string.
     564              : 
     565              : static inline tree
     566     12622191 : get_identifier_from_string(const std::string& str)
     567              : {
     568     12622191 :   return get_identifier_with_length(str.data(), str.length());
     569              : }
     570              : 
     571              : // Define the built-in functions that are exposed to GCCGo.
     572              : 
     573         4646 : Gcc_backend::Gcc_backend()
     574              : {
     575              :   /* We need to define the fetch_and_add functions, since we use them
     576              :      for ++ and --.  */
     577         4646 :   tree t = this->integer_type(true, BITS_PER_UNIT)->get_tree();
     578         4646 :   tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     579         4646 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
     580              :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     581              :                        builtin_leaf);
     582              : 
     583         4646 :   t = this->integer_type(true, BITS_PER_UNIT * 2)->get_tree();
     584         4646 :   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     585         4646 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
     586              :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     587              :                        builtin_leaf);
     588              : 
     589         4646 :   t = this->integer_type(true, BITS_PER_UNIT * 4)->get_tree();
     590         4646 :   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     591         4646 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
     592              :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     593              :                        builtin_leaf);
     594              : 
     595         4646 :   t = this->integer_type(true, BITS_PER_UNIT * 8)->get_tree();
     596         4646 :   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     597         4646 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
     598              :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     599              :                        builtin_leaf);
     600              : 
     601              :   // We use __builtin_expect for magic import functions.
     602         4646 :   this->define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL,
     603              :                        build_function_type_list(long_integer_type_node,
     604              :                                                 long_integer_type_node,
     605              :                                                 long_integer_type_node,
     606              :                                                 NULL_TREE),
     607              :                        builtin_const | builtin_nothrow | builtin_leaf);
     608              : 
     609              :   // We use __builtin_memcmp for struct comparisons.
     610         4646 :   this->define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
     611              :                        build_function_type_list(integer_type_node,
     612              :                                                 const_ptr_type_node,
     613              :                                                 const_ptr_type_node,
     614              :                                                 size_type_node,
     615              :                                                 NULL_TREE),
     616              :                        builtin_pure | builtin_nothrow | builtin_nonnull);
     617              : 
     618              :   // We use __builtin_memmove for copying data.
     619         4646 :   this->define_builtin(BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
     620              :                        build_function_type_list(void_type_node,
     621              :                                                 ptr_type_node,
     622              :                                                 const_ptr_type_node,
     623              :                                                 size_type_node,
     624              :                                                 NULL_TREE),
     625              :                        builtin_nothrow | builtin_nonnull);
     626              : 
     627              :   // We use __builtin_memset for zeroing data.
     628         4646 :   this->define_builtin(BUILT_IN_MEMSET, "__builtin_memset", "memset",
     629              :                        build_function_type_list(void_type_node,
     630              :                                                 ptr_type_node,
     631              :                                                 integer_type_node,
     632              :                                                 size_type_node,
     633              :                                                 NULL_TREE),
     634              :                        builtin_nothrow | builtin_nonnull);
     635              : 
     636              :   // Used by runtime/internal/sys and math/bits.
     637         4646 :   this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz",
     638              :                        build_function_type_list(integer_type_node,
     639              :                                                 unsigned_type_node,
     640              :                                                 NULL_TREE),
     641              :                        builtin_const | builtin_nothrow | builtin_leaf);
     642         4646 :   this->define_builtin(BUILT_IN_CTZL, "__builtin_ctzl", "ctzl",
     643              :                       build_function_type_list(integer_type_node,
     644              :                                                long_unsigned_type_node,
     645              :                                                NULL_TREE),
     646              :                       builtin_const | builtin_nothrow | builtin_leaf);
     647         4646 :   this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
     648              :                        build_function_type_list(integer_type_node,
     649              :                                                 long_long_unsigned_type_node,
     650              :                                                 NULL_TREE),
     651              :                        builtin_const | builtin_nothrow | builtin_leaf);
     652         4646 :   this->define_builtin(BUILT_IN_CLZ, "__builtin_clz", "clz",
     653              :                        build_function_type_list(integer_type_node,
     654              :                                                 unsigned_type_node,
     655              :                                                 NULL_TREE),
     656              :                        builtin_const | builtin_nothrow | builtin_leaf);
     657         4646 :   this->define_builtin(BUILT_IN_CLZL, "__builtin_clzl", "clzl",
     658              :                       build_function_type_list(integer_type_node,
     659              :                                                long_unsigned_type_node,
     660              :                                                NULL_TREE),
     661              :                       builtin_const | builtin_nothrow | builtin_leaf);
     662         4646 :   this->define_builtin(BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
     663              :                        build_function_type_list(integer_type_node,
     664              :                                                 long_long_unsigned_type_node,
     665              :                                                 NULL_TREE),
     666              :                        builtin_const | builtin_nothrow | builtin_leaf);
     667         4646 :   this->define_builtin(BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
     668              :                        build_function_type_list(integer_type_node,
     669              :                                                 unsigned_type_node,
     670              :                                                 NULL_TREE),
     671              :                        builtin_const | builtin_nothrow | builtin_leaf);
     672         4646 :   this->define_builtin(BUILT_IN_POPCOUNTLL, "__builtin_popcountll", "popcountll",
     673              :                        build_function_type_list(integer_type_node,
     674              :                                                 long_long_unsigned_type_node,
     675              :                                                 NULL_TREE),
     676              :                        builtin_const | builtin_nothrow | builtin_leaf);
     677         4646 :   this->define_builtin(BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
     678              :                        build_function_type_list(uint16_type_node,
     679              :                                                 uint16_type_node,
     680              :                                                 NULL_TREE),
     681              :                        builtin_const | builtin_nothrow | builtin_leaf);
     682         4646 :   this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
     683              :                        build_function_type_list(uint32_type_node,
     684              :                                                 uint32_type_node,
     685              :                                                 NULL_TREE),
     686              :                        builtin_const | builtin_nothrow | builtin_leaf);
     687         4646 :   this->define_builtin(BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
     688              :                        build_function_type_list(uint64_type_node,
     689              :                                                 uint64_type_node,
     690              :                                                 NULL_TREE),
     691              :                        builtin_const | builtin_nothrow | builtin_leaf);
     692              : 
     693              :   // We provide some functions for the math library.
     694         4646 :   tree math_function_type = build_function_type_list(double_type_node,
     695              :                                                      double_type_node,
     696              :                                                      NULL_TREE);
     697         4646 :   tree math_function_type_long =
     698         4646 :     build_function_type_list(long_double_type_node, long_double_type_node,
     699              :                              NULL_TREE);
     700         4646 :   tree math_function_type_two = build_function_type_list(double_type_node,
     701              :                                                          double_type_node,
     702              :                                                          double_type_node,
     703              :                                                          NULL_TREE);
     704         4646 :   tree math_function_type_long_two =
     705         4646 :     build_function_type_list(long_double_type_node, long_double_type_node,
     706              :                              long_double_type_node, NULL_TREE);
     707         4646 :   this->define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
     708              :                        math_function_type, builtin_const);
     709         4646 :   this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
     710              :                        math_function_type_long, builtin_const);
     711         4646 :   this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
     712              :                        math_function_type, builtin_const);
     713         4646 :   this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
     714              :                        math_function_type_long, builtin_const);
     715         4646 :   this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
     716              :                        math_function_type, builtin_const);
     717         4646 :   this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
     718              :                        math_function_type_long, builtin_const);
     719         4646 :   this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
     720              :                        math_function_type_two, builtin_const);
     721         4646 :   this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
     722              :                        math_function_type_long_two, builtin_const);
     723         4646 :   this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
     724              :                        math_function_type, builtin_const);
     725         4646 :   this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
     726              :                        math_function_type_long, builtin_const);
     727         4646 :   this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
     728              :                        math_function_type, builtin_const);
     729         4646 :   this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
     730              :                        math_function_type_long, builtin_const);
     731         4646 :   this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
     732              :                        math_function_type, builtin_const);
     733         4646 :   this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
     734              :                        math_function_type_long, builtin_const);
     735         4646 :   this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
     736              :                        math_function_type, builtin_const);
     737         4646 :   this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
     738              :                        math_function_type_long, builtin_const);
     739         4646 :   this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
     740              :                        math_function_type, builtin_const);
     741         4646 :   this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
     742              :                        math_function_type_long, builtin_const);
     743         4646 :   this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
     744              :                        math_function_type, builtin_const);
     745         4646 :   this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
     746              :                        math_function_type_long, builtin_const);
     747         4646 :   this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
     748              :                        math_function_type_two, builtin_const);
     749         4646 :   this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
     750              :                        math_function_type_long_two, builtin_const);
     751         4646 :   this->define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
     752              :                        build_function_type_list(double_type_node,
     753              :                                                 double_type_node,
     754              :                                                 integer_type_node,
     755              :                                                 NULL_TREE),
     756              :                        builtin_const);
     757         4646 :   this->define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
     758              :                        build_function_type_list(long_double_type_node,
     759              :                                                 long_double_type_node,
     760              :                                                 integer_type_node,
     761              :                                                 NULL_TREE),
     762              :                        builtin_const);
     763         4646 :   this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
     764              :                        math_function_type, builtin_const);
     765         4646 :   this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
     766              :                        math_function_type_long, builtin_const);
     767         4646 :   this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
     768              :                        math_function_type, builtin_const);
     769         4646 :   this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
     770              :                        math_function_type_long, builtin_const);
     771         4646 :   this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
     772              :                        math_function_type, builtin_const);
     773         4646 :   this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
     774              :                        math_function_type_long, builtin_const);
     775         4646 :   this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
     776              :                        math_function_type, builtin_const);
     777         4646 :   this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
     778              :                        math_function_type_long, builtin_const);
     779         4646 :   this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
     780              :                        math_function_type, builtin_const);
     781         4646 :   this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
     782              :                        math_function_type_long, builtin_const);
     783         4646 :   this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
     784              :                        math_function_type, builtin_const);
     785         4646 :   this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
     786              :                        math_function_type_long, builtin_const);
     787         4646 :   this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
     788              :                        math_function_type, builtin_const);
     789         4646 :   this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
     790              :                        math_function_type_long, builtin_const);
     791         4646 :   this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
     792              :                        math_function_type, builtin_const);
     793         4646 :   this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
     794              :                        math_function_type_long, builtin_const);
     795              : 
     796              :   // We use __builtin_return_address in the thunk we build for
     797              :   // functions which call recover, and for runtime.getcallerpc.
     798         4646 :   t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE);
     799         4646 :   this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
     800              :                        NULL, t, builtin_leaf);
     801              : 
     802              :   // The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
     803         4646 :   t = build_function_type_list(ptr_type_node, NULL_TREE);
     804         4646 :   this->define_builtin(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa",
     805              :                        NULL, t, 0);
     806              : 
     807              :   // The runtime calls __builtin_extract_return_addr when recording
     808              :   // the address to which a function returns.
     809         4646 :   this->define_builtin(BUILT_IN_EXTRACT_RETURN_ADDR,
     810              :                        "__builtin_extract_return_addr", NULL,
     811              :                        build_function_type_list(ptr_type_node,
     812              :                                                 ptr_type_node,
     813              :                                                 NULL_TREE),
     814              :                        builtin_leaf);
     815              : 
     816              :   // The compiler uses __builtin_trap for some exception handling
     817              :   // cases.
     818         4646 :   this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL,
     819              :                        build_function_type(void_type_node, void_list_node),
     820              :                        (builtin_noreturn | builtin_nothrow | builtin_leaf
     821              :                         | builtin_cold));
     822              : 
     823              :   // The runtime uses __builtin_prefetch.
     824         4646 :   this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
     825              :                        build_varargs_function_type_list(void_type_node,
     826              :                                                         const_ptr_type_node,
     827              :                                                         NULL_TREE),
     828              :                        builtin_novops | builtin_leaf);
     829              : 
     830              :   // The compiler uses __builtin_unreachable for cases that cannot
     831              :   // occur.
     832         4646 :   this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
     833              :                        build_function_type(void_type_node, void_list_node),
     834              :                        (builtin_const | builtin_noreturn | builtin_nothrow
     835              :                         | builtin_leaf | builtin_cold));
     836              : 
     837              :   // We provide some atomic functions.
     838         4646 :   t = build_function_type_list(uint32_type_node,
     839              :                                ptr_type_node,
     840              :                                integer_type_node,
     841              :                                NULL_TREE);
     842         4646 :   this->define_builtin(BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL,
     843              :                        t, builtin_leaf);
     844              : 
     845         4646 :   t = build_function_type_list(uint64_type_node,
     846              :                                ptr_type_node,
     847              :                                integer_type_node,
     848              :                                NULL_TREE);
     849         4646 :   this->define_builtin(BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL,
     850              :                        t, builtin_leaf);
     851              : 
     852         4646 :   t = build_function_type_list(void_type_node,
     853              :                                ptr_type_node,
     854              :                                uint32_type_node,
     855              :                                integer_type_node,
     856              :                                NULL_TREE);
     857         4646 :   this->define_builtin(BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL,
     858              :                        t, builtin_leaf);
     859              : 
     860         4646 :   t = build_function_type_list(void_type_node,
     861              :                                ptr_type_node,
     862              :                                uint64_type_node,
     863              :                                integer_type_node,
     864              :                                NULL_TREE);
     865         4646 :   this->define_builtin(BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL,
     866              :                        t, builtin_leaf);
     867              : 
     868         4646 :   t = build_function_type_list(uint32_type_node,
     869              :                                ptr_type_node,
     870              :                                uint32_type_node,
     871              :                                integer_type_node,
     872              :                                NULL_TREE);
     873         4646 :   this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL,
     874              :                        t, builtin_leaf);
     875              : 
     876         4646 :   t = build_function_type_list(uint64_type_node,
     877              :                                ptr_type_node,
     878              :                                uint64_type_node,
     879              :                                integer_type_node,
     880              :                                NULL_TREE);
     881         4646 :   this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL,
     882              :                        t, builtin_leaf);
     883              : 
     884         4646 :   t = build_function_type_list(boolean_type_node,
     885              :                                ptr_type_node,
     886              :                                ptr_type_node,
     887              :                                uint32_type_node,
     888              :                                boolean_type_node,
     889              :                                integer_type_node,
     890              :                                integer_type_node,
     891              :                                NULL_TREE);
     892         4646 :   this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
     893              :                        "__atomic_compare_exchange_4", NULL,
     894              :                        t, builtin_leaf);
     895              : 
     896         4646 :   t = build_function_type_list(boolean_type_node,
     897              :                                ptr_type_node,
     898              :                                ptr_type_node,
     899              :                                uint64_type_node,
     900              :                                boolean_type_node,
     901              :                                integer_type_node,
     902              :                                integer_type_node,
     903              :                                NULL_TREE);
     904         4646 :   this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
     905              :                        "__atomic_compare_exchange_8", NULL,
     906              :                        t, builtin_leaf);
     907              : 
     908         4646 :   t = build_function_type_list(uint32_type_node,
     909              :                                ptr_type_node,
     910              :                                uint32_type_node,
     911              :                                integer_type_node,
     912              :                                NULL_TREE);
     913         4646 :   this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
     914              :                        NULL, t, builtin_leaf);
     915         4646 :   this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_4, "__atomic_fetch_add_4",
     916              :                        NULL, t, builtin_leaf);
     917              : 
     918         4646 :   t = build_function_type_list(uint64_type_node,
     919              :                                ptr_type_node,
     920              :                                uint64_type_node,
     921              :                                integer_type_node,
     922              :                                NULL_TREE);
     923         4646 :   this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
     924              :                        NULL, t, builtin_leaf);
     925         4646 :   this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_8, "__atomic_fetch_add_8",
     926              :                        NULL, t, builtin_leaf);
     927              : 
     928         4646 :   t = build_function_type_list(unsigned_char_type_node,
     929              :                                ptr_type_node,
     930              :                                integer_type_node,
     931              :                                NULL_TREE);
     932         4646 :   this->define_builtin(BUILT_IN_ATOMIC_LOAD_1, "__atomic_load_1", NULL, t,
     933              :                        builtin_leaf);
     934              : 
     935         4646 :   t = build_function_type_list(void_type_node,
     936              :                                ptr_type_node,
     937              :                                unsigned_char_type_node,
     938              :                                integer_type_node,
     939              :                                NULL_TREE);
     940         4646 :   this->define_builtin(BUILT_IN_ATOMIC_STORE_1, "__atomic_store_1", NULL,
     941              :                        t, builtin_leaf);
     942              : 
     943         4646 :   t = build_function_type_list(unsigned_char_type_node,
     944              :                                ptr_type_node,
     945              :                                unsigned_char_type_node,
     946              :                                integer_type_node,
     947              :                                NULL_TREE);
     948         4646 :   this->define_builtin(BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1", NULL,
     949              :                        t, builtin_leaf);
     950         4646 :   this->define_builtin(BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1", NULL,
     951              :                        t, builtin_leaf);
     952              : 
     953         4646 :   t = build_function_type_list(unsigned_char_type_node,
     954              :                                ptr_type_node,
     955              :                                unsigned_char_type_node,
     956              :                                integer_type_node,
     957              :                                NULL_TREE);
     958         4646 :   this->define_builtin(BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
     959              :                        t, builtin_leaf);
     960         4646 :   this->define_builtin(BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
     961              :                        t, builtin_leaf);
     962         4646 : }
     963              : 
     964              : // Get an unnamed integer type.
     965              : 
     966              : Btype*
     967       196657 : Gcc_backend::integer_type(bool is_unsigned, int bits)
     968              : {
     969       196657 :   tree type;
     970       196657 :   if (is_unsigned)
     971              :     {
     972       118717 :       if (bits == INT_TYPE_SIZE)
     973        35735 :         type = unsigned_type_node;
     974        82982 :       else if (bits == CHAR_TYPE_SIZE)
     975        32228 :         type = unsigned_char_type_node;
     976        50754 :       else if (bits == SHORT_TYPE_SIZE)
     977        10917 :         type = short_unsigned_type_node;
     978        43356 :       else if (bits == LONG_TYPE_SIZE)
     979        36318 :         type = long_unsigned_type_node;
     980         3519 :       else if (bits == LONG_LONG_TYPE_SIZE)
     981         3519 :         type = long_long_unsigned_type_node;
     982              :       else
     983            0 :         type = make_unsigned_type(bits);
     984              :     }
     985              :   else
     986              :     {
     987        77940 :       if (bits == INT_TYPE_SIZE)
     988        30426 :         type = integer_type_node;
     989        47514 :       else if (bits == CHAR_TYPE_SIZE)
     990         5905 :         type = signed_char_type_node;
     991        41609 :       else if (bits == SHORT_TYPE_SIZE)
     992         4928 :         type = short_integer_type_node;
     993        39502 :       else if (bits == LONG_TYPE_SIZE)
     994        33860 :         type = long_integer_type_node;
     995         2821 :       else if (bits == LONG_LONG_TYPE_SIZE)
     996         2821 :         type = long_long_integer_type_node;
     997              :       else
     998            0 :         type = make_signed_type(bits);
     999              :     }
    1000       196657 :   return this->make_type(type);
    1001              : }
    1002              : 
    1003              : // Get an unnamed float type.
    1004              : 
    1005              : Btype*
    1006         9827 : Gcc_backend::float_type(int bits)
    1007              : {
    1008         9827 :   tree type;
    1009         9827 :   if (bits == TYPE_PRECISION (float_type_node))
    1010              :     type = float_type_node;
    1011         5058 :   else if (bits == TYPE_PRECISION (double_type_node))
    1012              :     type = double_type_node;
    1013            0 :   else if (bits == TYPE_PRECISION (long_double_type_node))
    1014              :     type = long_double_type_node;
    1015              :   else
    1016              :     {
    1017            0 :       type = make_node(REAL_TYPE);
    1018            0 :       TYPE_PRECISION(type) = bits;
    1019            0 :       layout_type(type);
    1020              :     }
    1021         9827 :   return this->make_type(type);
    1022              : }
    1023              : 
    1024              : // Get an unnamed complex type.
    1025              : 
    1026              : Btype*
    1027         9466 : Gcc_backend::complex_type(int bits)
    1028              : {
    1029         9466 :   tree type;
    1030         9466 :   if (bits == TYPE_PRECISION (float_type_node) * 2)
    1031         4706 :     type = complex_float_type_node;
    1032         4760 :   else if (bits == TYPE_PRECISION (double_type_node) * 2)
    1033         4760 :     type = complex_double_type_node;
    1034            0 :   else if (bits == TYPE_PRECISION (long_double_type_node) * 2)
    1035            0 :     type = complex_long_double_type_node;
    1036              :   else
    1037              :     {
    1038            0 :       type = make_node(REAL_TYPE);
    1039            0 :       TYPE_PRECISION(type) = bits / 2;
    1040            0 :       layout_type(type);
    1041            0 :       type = build_complex_type(type);
    1042              :     }
    1043         9466 :   return this->make_type(type);
    1044              : }
    1045              : 
    1046              : // Get a pointer type.
    1047              : 
    1048              : Btype*
    1049      2390569 : Gcc_backend::pointer_type(Btype* to_type)
    1050              : {
    1051      2390569 :   tree to_type_tree = to_type->get_tree();
    1052      2390569 :   if (to_type_tree == error_mark_node)
    1053           13 :     return this->error_type();
    1054      2390556 :   tree type = build_pointer_type(to_type_tree);
    1055      2390556 :   return this->make_type(type);
    1056              : }
    1057              : 
    1058              : // Make a function type.
    1059              : 
    1060              : Btype*
    1061       883623 : Gcc_backend::function_type(const Btyped_identifier& receiver,
    1062              :                            const std::vector<Btyped_identifier>& parameters,
    1063              :                            const std::vector<Btyped_identifier>& results,
    1064              :                            Btype* result_struct,
    1065              :                            Location)
    1066              : {
    1067       883623 :   tree args = NULL_TREE;
    1068       883623 :   tree* pp = &args;
    1069       883623 :   if (receiver.btype != NULL)
    1070              :     {
    1071       198072 :       tree t = receiver.btype->get_tree();
    1072       198072 :       if (t == error_mark_node)
    1073            5 :         return this->error_type();
    1074       198067 :       *pp = tree_cons(NULL_TREE, t, NULL_TREE);
    1075       198067 :       pp = &TREE_CHAIN(*pp);
    1076              :     }
    1077              : 
    1078       883618 :   for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
    1079      2170812 :        p != parameters.end();
    1080      1287194 :        ++p)
    1081              :     {
    1082      1287202 :       tree t = p->btype->get_tree();
    1083      1287202 :       if (t == error_mark_node)
    1084            8 :         return this->error_type();
    1085      1287194 :       *pp = tree_cons(NULL_TREE, t, NULL_TREE);
    1086      1287194 :       pp = &TREE_CHAIN(*pp);
    1087              :     }
    1088              : 
    1089              :   // Varargs is handled entirely at the Go level.  When converted to
    1090              :   // GENERIC functions are not varargs.
    1091       883610 :   *pp = void_list_node;
    1092              : 
    1093       883610 :   tree result;
    1094       883610 :   if (results.empty())
    1095       195286 :     result = void_type_node;
    1096       688324 :   else if (results.size() == 1)
    1097       587266 :     result = results.front().btype->get_tree();
    1098              :   else
    1099              :     {
    1100       101058 :       gcc_assert(result_struct != NULL);
    1101       101058 :       result = result_struct->get_tree();
    1102              :     }
    1103       883610 :   if (result == error_mark_node)
    1104            2 :     return this->error_type();
    1105              : 
    1106              :   // The libffi library cannot represent a zero-sized object.  To
    1107              :   // avoid causing confusion on 32-bit SPARC, we treat a function that
    1108              :   // returns a zero-sized value as returning void.  That should do no
    1109              :   // harm since there is no actual value to be returned.  See
    1110              :   // https://gcc.gnu.org/PR72814 for details.
    1111       883608 :   if (result != void_type_node && int_size_in_bytes(result) == 0)
    1112           31 :     result = void_type_node;
    1113              : 
    1114       883608 :   tree fntype = build_function_type(result, args);
    1115       883608 :   if (fntype == error_mark_node)
    1116            0 :     return this->error_type();
    1117              : 
    1118       883608 :   return this->make_type(build_pointer_type(fntype));
    1119              : }
    1120              : 
    1121              : // Make a struct type.
    1122              : 
    1123              : Btype*
    1124       476489 : Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
    1125              : {
    1126       476489 :   return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE)), fields);
    1127              : }
    1128              : 
    1129              : // Fill in the fields of a struct type.
    1130              : 
    1131              : Btype*
    1132      1964054 : Gcc_backend::fill_in_struct(Btype* fill,
    1133              :                             const std::vector<Btyped_identifier>& fields)
    1134              : {
    1135      1964054 :   tree fill_tree = fill->get_tree();
    1136      1964054 :   tree field_trees = NULL_TREE;
    1137      1964054 :   tree* pp = &field_trees;
    1138      1964054 :   for (std::vector<Btyped_identifier>::const_iterator p = fields.begin();
    1139      9475218 :        p != fields.end();
    1140      7511164 :        ++p)
    1141              :     {
    1142      7511178 :       tree name_tree = get_identifier_from_string(p->name);
    1143      7511178 :       tree type_tree = p->btype->get_tree();
    1144      7511178 :       if (type_tree == error_mark_node)
    1145           14 :         return this->error_type();
    1146      7511164 :       tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
    1147              :                               type_tree);
    1148      7511164 :       DECL_CONTEXT(field) = fill_tree;
    1149      7511164 :       *pp = field;
    1150      7511164 :       pp = &DECL_CHAIN(field);
    1151              :     }
    1152      1964040 :   TYPE_FIELDS(fill_tree) = field_trees;
    1153      1964040 :   layout_type(fill_tree);
    1154              : 
    1155              :   // Because Go permits converting between named struct types and
    1156              :   // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
    1157              :   // because we don't try to maintain TYPE_CANONICAL for struct types,
    1158              :   // we need to tell the middle-end to use structural equality.
    1159      1964040 :   SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
    1160              : 
    1161      1964040 :   return fill;
    1162              : }
    1163              : 
    1164              : // Make an array type.
    1165              : 
    1166              : Btype*
    1167       203537 : Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
    1168              : {
    1169       203537 :   return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
    1170       203537 :                              element_btype, length);
    1171              : }
    1172              : 
    1173              : // Fill in an array type.
    1174              : 
    1175              : Btype*
    1176       215933 : Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
    1177              :                            Bexpression* length)
    1178              : {
    1179       215933 :   tree element_type_tree = element_type->get_tree();
    1180       215933 :   tree length_tree = length->get_tree();
    1181       215933 :   if (element_type_tree == error_mark_node || length_tree == error_mark_node)
    1182            2 :     return this->error_type();
    1183              : 
    1184       215931 :   gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
    1185              : 
    1186       215931 :   length_tree = fold_convert(sizetype, length_tree);
    1187              : 
    1188              :   // build_index_type takes the maximum index, which is one less than
    1189              :   // the length.
    1190       215931 :   tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
    1191              :                                                       length_tree,
    1192              :                                                       size_one_node));
    1193              : 
    1194       215931 :   tree fill_tree = fill->get_tree();
    1195       215931 :   TREE_TYPE(fill_tree) = element_type_tree;
    1196       215931 :   TYPE_DOMAIN(fill_tree) = index_type_tree;
    1197       215931 :   TYPE_ADDR_SPACE(fill_tree) = TYPE_ADDR_SPACE(element_type_tree);
    1198       215931 :   layout_type(fill_tree);
    1199              : 
    1200       215931 :   if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree))
    1201        73215 :     SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
    1202       142716 :   else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
    1203       142716 :            || TYPE_CANONICAL(index_type_tree) != index_type_tree)
    1204        32051 :     TYPE_CANONICAL(fill_tree) =
    1205        32051 :       build_array_type(TYPE_CANONICAL(element_type_tree),
    1206        32051 :                        TYPE_CANONICAL(index_type_tree));
    1207              : 
    1208              :   return fill;
    1209              : }
    1210              : 
    1211              : // Create a placeholder for a pointer type.
    1212              : 
    1213              : Btype*
    1214       332783 : Gcc_backend::placeholder_pointer_type(const std::string& name,
    1215              :                                       Location location, bool)
    1216              : {
    1217       332783 :   tree ret = build_distinct_type_copy(ptr_type_node);
    1218       332783 :   if (!name.empty())
    1219              :     {
    1220        19048 :       tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1221              :                              get_identifier_from_string(name),
    1222              :                              ret);
    1223         9524 :       TYPE_NAME(ret) = decl;
    1224              :     }
    1225       332783 :   return this->make_type(ret);
    1226              : }
    1227              : 
    1228              : // Set the real target type for a placeholder pointer type.
    1229              : 
    1230              : bool
    1231       312212 : Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
    1232              :                                           Btype* to_type)
    1233              : {
    1234       312212 :   tree pt = placeholder->get_tree();
    1235       312212 :   if (pt == error_mark_node)
    1236              :     return false;
    1237       312212 :   gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
    1238       312212 :   tree tt = to_type->get_tree();
    1239       312212 :   if (tt == error_mark_node)
    1240              :     {
    1241            2 :       placeholder->set_tree(error_mark_node);
    1242            2 :       return false;
    1243              :     }
    1244       312210 :   gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
    1245       312210 :   TREE_TYPE(pt) = TREE_TYPE(tt);
    1246       312210 :   TYPE_CANONICAL(pt) = TYPE_CANONICAL(tt);
    1247       312210 :   if (TYPE_NAME(pt) != NULL_TREE)
    1248              :     {
    1249              :       // Build the data structure gcc wants to see for a typedef.
    1250         4817 :       tree copy = build_variant_type_copy(pt);
    1251         4817 :       TYPE_NAME(copy) = NULL_TREE;
    1252         4817 :       DECL_ORIGINAL_TYPE(TYPE_NAME(pt)) = copy;
    1253              :     }
    1254              :   return true;
    1255              : }
    1256              : 
    1257              : // Set the real values for a placeholder function type.
    1258              : 
    1259              : bool
    1260            0 : Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
    1261              : {
    1262            0 :   return this->set_placeholder_pointer_type(placeholder, ft);
    1263              : }
    1264              : 
    1265              : // Create a placeholder for a struct type.
    1266              : 
    1267              : Btype*
    1268       747865 : Gcc_backend::placeholder_struct_type(const std::string& name,
    1269              :                                      Location location)
    1270              : {
    1271       747865 :   tree ret = make_node(RECORD_TYPE);
    1272       747865 :   if (!name.empty())
    1273              :     {
    1274      1479400 :       tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1275              :                              get_identifier_from_string(name),
    1276              :                              ret);
    1277       739700 :       TYPE_NAME(ret) = decl;
    1278              : 
    1279              :       // The struct type that eventually replaces this placeholder will require
    1280              :       // structural equality. The placeholder must too, so that the requirement
    1281              :       // for structural equality propagates to references that are constructed
    1282              :       // before the replacement occurs.
    1283       739700 :       SET_TYPE_STRUCTURAL_EQUALITY(ret);
    1284              :     }
    1285       747865 :   return this->make_type(ret);
    1286              : }
    1287              : 
    1288              : // Fill in the fields of a placeholder struct type.
    1289              : 
    1290              : bool
    1291       747865 : Gcc_backend::set_placeholder_struct_type(
    1292              :     Btype* placeholder,
    1293              :     const std::vector<Btyped_identifier>& fields)
    1294              : {
    1295       747865 :   tree t = placeholder->get_tree();
    1296       747865 :   gcc_assert(TREE_CODE(t) == RECORD_TYPE && TYPE_FIELDS(t) == NULL_TREE);
    1297       747865 :   Btype* r = this->fill_in_struct(placeholder, fields);
    1298              : 
    1299       747865 :   if (TYPE_NAME(t) != NULL_TREE)
    1300              :     {
    1301              :       // Build the data structure gcc wants to see for a typedef.
    1302       739700 :       tree copy = build_distinct_type_copy(t);
    1303       739700 :       TYPE_NAME(copy) = NULL_TREE;
    1304       739700 :       DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
    1305       739700 :       TYPE_SIZE(copy) = NULL_TREE;
    1306       739700 :       Btype* bc = this->make_type(copy);
    1307       739700 :       this->fill_in_struct(bc, fields);
    1308       739700 :       delete bc;
    1309              :     }
    1310              : 
    1311       747865 :   return r->get_tree() != error_mark_node;
    1312              : }
    1313              : 
    1314              : // Create a placeholder for an array type.
    1315              : 
    1316              : Btype*
    1317        12396 : Gcc_backend::placeholder_array_type(const std::string& name,
    1318              :                                     Location location)
    1319              : {
    1320        12396 :   tree ret = make_node(ARRAY_TYPE);
    1321        24792 :   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1322              :                          get_identifier_from_string(name),
    1323              :                          ret);
    1324        12396 :   TYPE_NAME(ret) = decl;
    1325        12396 :   return this->make_type(ret);
    1326              : }
    1327              : 
    1328              : // Fill in the fields of a placeholder array type.
    1329              : 
    1330              : bool
    1331        12396 : Gcc_backend::set_placeholder_array_type(Btype* placeholder,
    1332              :                                         Btype* element_btype,
    1333              :                                         Bexpression* length)
    1334              : {
    1335        12396 :   tree t = placeholder->get_tree();
    1336        12396 :   gcc_assert(TREE_CODE(t) == ARRAY_TYPE && TREE_TYPE(t) == NULL_TREE);
    1337        12396 :   Btype* r = this->fill_in_array(placeholder, element_btype, length);
    1338              : 
    1339              :   // Build the data structure gcc wants to see for a typedef.
    1340        12396 :   tree copy = build_distinct_type_copy(t);
    1341        12396 :   TYPE_NAME(copy) = NULL_TREE;
    1342        12396 :   DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
    1343              : 
    1344        12396 :   return r->get_tree() != error_mark_node;
    1345              : }
    1346              : 
    1347              : // Return a named version of a type.
    1348              : 
    1349              : Btype*
    1350       213702 : Gcc_backend::named_type(const std::string& name, Btype* btype,
    1351              :                         Location location)
    1352              : {
    1353       213702 :   tree type = btype->get_tree();
    1354       213702 :   if (type == error_mark_node)
    1355            0 :     return this->error_type();
    1356              : 
    1357              :   // The middle-end expects a basic type to have a name.  In Go every
    1358              :   // basic type will have a name.  The first time we see a basic type,
    1359              :   // give it whatever Go name we have at this point.
    1360       213702 :   if (TYPE_NAME(type) == NULL_TREE
    1361        81833 :       && location.gcc_location() == BUILTINS_LOCATION
    1362       213702 :       && (TREE_CODE(type) == INTEGER_TYPE
    1363        73667 :           || TREE_CODE(type) == REAL_TYPE
    1364              :           || TREE_CODE(type) == COMPLEX_TYPE
    1365              :           || TREE_CODE(type) == BOOLEAN_TYPE))
    1366              :     {
    1367       120796 :       tree decl = build_decl(BUILTINS_LOCATION, TYPE_DECL,
    1368              :                              get_identifier_from_string(name),
    1369              :                              type);
    1370        60398 :       TYPE_NAME(type) = decl;
    1371        60398 :       return this->make_type(type);
    1372              :     }
    1373              : 
    1374       153304 :   tree copy = build_variant_type_copy(type);
    1375       306608 :   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1376              :                          get_identifier_from_string(name),
    1377              :                          copy);
    1378       153304 :   DECL_ORIGINAL_TYPE(decl) = type;
    1379       153304 :   TYPE_NAME(copy) = decl;
    1380       153304 :   return this->make_type(copy);
    1381              : }
    1382              : 
    1383              : // Return a pointer type used as a marker for a circular type.
    1384              : 
    1385              : Btype*
    1386           49 : Gcc_backend::circular_pointer_type(Btype*, bool)
    1387              : {
    1388           49 :   return this->make_type(ptr_type_node);
    1389              : }
    1390              : 
    1391              : // Return whether we might be looking at a circular type.
    1392              : 
    1393              : bool
    1394       541144 : Gcc_backend::is_circular_pointer_type(Btype* btype)
    1395              : {
    1396       541144 :   return btype->get_tree() == ptr_type_node;
    1397              : }
    1398              : 
    1399              : // Return the size of a type.
    1400              : 
    1401              : int64_t
    1402     26482664 : Gcc_backend::type_size(Btype* btype)
    1403              : {
    1404     26482664 :   tree t = btype->get_tree();
    1405     26482664 :   if (t == error_mark_node)
    1406              :     return 1;
    1407     26482654 :   if (t == void_type_node)
    1408              :     return 0;
    1409     26482654 :   t = TYPE_SIZE_UNIT(t);
    1410     26482654 :   gcc_assert(tree_fits_uhwi_p (t));
    1411     26482654 :   unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
    1412     26482654 :   int64_t ret = static_cast<int64_t>(val_wide);
    1413     26482654 :   if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
    1414              :     return -1;
    1415              :   return ret;
    1416              : }
    1417              : 
    1418              : // Return the alignment of a type.
    1419              : 
    1420              : int64_t
    1421      4552603 : Gcc_backend::type_alignment(Btype* btype)
    1422              : {
    1423      4552603 :   tree t = btype->get_tree();
    1424      4552603 :   if (t == error_mark_node)
    1425              :     return 1;
    1426      4552601 :   return TYPE_ALIGN_UNIT(t);
    1427              : }
    1428              : 
    1429              : // Return the alignment of a struct field of type BTYPE.
    1430              : 
    1431              : int64_t
    1432      1187050 : Gcc_backend::type_field_alignment(Btype* btype)
    1433              : {
    1434      1187050 :   tree t = btype->get_tree();
    1435      1187050 :   if (t == error_mark_node)
    1436              :     return 1;
    1437      1187050 :   return go_field_alignment(t);
    1438              : }
    1439              : 
    1440              : // Return the offset of a field in a struct.
    1441              : 
    1442              : int64_t
    1443       127112 : Gcc_backend::type_field_offset(Btype* btype, size_t index)
    1444              : {
    1445       127112 :   tree struct_tree = btype->get_tree();
    1446       127112 :   if (struct_tree == error_mark_node)
    1447              :     return 0;
    1448       127112 :   gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
    1449       127112 :   tree field = TYPE_FIELDS(struct_tree);
    1450       589929 :   for (; index > 0; --index)
    1451              :     {
    1452       462817 :       field = DECL_CHAIN(field);
    1453       462817 :       gcc_assert(field != NULL_TREE);
    1454              :     }
    1455       127112 :   HOST_WIDE_INT offset_wide = int_byte_position(field);
    1456       127112 :   int64_t ret = static_cast<int64_t>(offset_wide);
    1457       127112 :   gcc_assert(ret == offset_wide);
    1458       127112 :   return ret;
    1459              : }
    1460              : 
    1461              : // Return the zero value for a type.
    1462              : 
    1463              : Bexpression*
    1464       465564 : Gcc_backend::zero_expression(Btype* btype)
    1465              : {
    1466       465564 :   tree t = btype->get_tree();
    1467       465564 :   tree ret;
    1468       465564 :   if (t == error_mark_node)
    1469              :     ret = error_mark_node;
    1470              :   else
    1471       465557 :     ret = build_zero_cst(t);
    1472       465564 :   return this->make_expression(ret);
    1473              : }
    1474              : 
    1475              : // An expression that references a variable.
    1476              : 
    1477              : Bexpression*
    1478     12126028 : Gcc_backend::var_expression(Bvariable* var, Location location)
    1479              : {
    1480     12126028 :   tree ret = var->get_tree(location);
    1481     12126028 :   if (ret == error_mark_node)
    1482           42 :     return this->error_expression();
    1483     12125986 :   return this->make_expression(ret);
    1484              : }
    1485              : 
    1486              : // An expression that indirectly references an expression.
    1487              : 
    1488              : Bexpression*
    1489      1469344 : Gcc_backend::indirect_expression(Btype* btype, Bexpression* expr,
    1490              :                                  bool known_valid, Location location)
    1491              : {
    1492      1469344 :   tree expr_tree = expr->get_tree();
    1493      1469344 :   tree type_tree = btype->get_tree();
    1494      1469344 :   if (expr_tree == error_mark_node || type_tree == error_mark_node)
    1495            7 :     return this->error_expression();
    1496              : 
    1497              :   // If the type of EXPR is a recursive pointer type, then we
    1498              :   // need to insert a cast before indirecting.
    1499      1469337 :   tree target_type_tree = TREE_TYPE(TREE_TYPE(expr_tree));
    1500      1469337 :   if (VOID_TYPE_P(target_type_tree))
    1501          547 :     expr_tree = fold_convert_loc(location.gcc_location(),
    1502              :                                  build_pointer_type(type_tree), expr_tree);
    1503              : 
    1504      1469337 :   tree ret = build_fold_indirect_ref_loc(location.gcc_location(),
    1505              :                                          expr_tree);
    1506      1469337 :   if (known_valid)
    1507       271220 :     TREE_THIS_NOTRAP(ret) = 1;
    1508      1469337 :   return this->make_expression(ret);
    1509              : }
    1510              : 
    1511              : // Return an expression that declares a constant named NAME with the
    1512              : // constant value VAL in BTYPE.
    1513              : 
    1514              : Bexpression*
    1515        23399 : Gcc_backend::named_constant_expression(Btype* btype, const std::string& name,
    1516              :                                        Bexpression* val, Location location)
    1517              : {
    1518        23399 :   tree type_tree = btype->get_tree();
    1519        23399 :   tree const_val = val->get_tree();
    1520        23399 :   if (type_tree == error_mark_node || const_val == error_mark_node)
    1521           13 :     return this->error_expression();
    1522              : 
    1523        23386 :   tree name_tree = get_identifier_from_string(name);
    1524        23386 :   tree decl = build_decl(location.gcc_location(), CONST_DECL, name_tree,
    1525              :                          type_tree);
    1526        23386 :   DECL_INITIAL(decl) = const_val;
    1527        23386 :   TREE_CONSTANT(decl) = 1;
    1528        23386 :   TREE_READONLY(decl) = 1;
    1529              : 
    1530        23386 :   go_preserve_from_gc(decl);
    1531        23386 :   return this->make_expression(decl);
    1532              : }
    1533              : 
    1534              : // Return a typed value as a constant integer.
    1535              : 
    1536              : Bexpression*
    1537      7287570 : Gcc_backend::integer_constant_expression(Btype* btype, mpz_t val)
    1538              : {
    1539      7287570 :   tree t = btype->get_tree();
    1540      7287570 :   if (t == error_mark_node)
    1541            0 :     return this->error_expression();
    1542              : 
    1543      7287570 :   tree ret = double_int_to_tree(t, mpz_get_double_int(t, val, true));
    1544      7287570 :   return this->make_expression(ret);
    1545              : }
    1546              : 
    1547              : // Return a typed value as a constant floating-point number.
    1548              : 
    1549              : Bexpression*
    1550        33424 : Gcc_backend::float_constant_expression(Btype* btype, mpfr_t val)
    1551              : {
    1552        33424 :   tree t = btype->get_tree();
    1553        33424 :   tree ret;
    1554        33424 :   if (t == error_mark_node)
    1555            0 :     return this->error_expression();
    1556              : 
    1557        33424 :   REAL_VALUE_TYPE r1;
    1558        33424 :   real_from_mpfr(&r1, val, t, GMP_RNDN);
    1559        33424 :   REAL_VALUE_TYPE r2;
    1560        33424 :   real_convert(&r2, TYPE_MODE(t), &r1);
    1561        33424 :   ret = build_real(t, r2);
    1562        33424 :   return this->make_expression(ret);
    1563              : }
    1564              : 
    1565              : // Return a typed real and imaginary value as a constant complex number.
    1566              : 
    1567              : Bexpression*
    1568         2944 : Gcc_backend::complex_constant_expression(Btype* btype, mpc_t val)
    1569              : {
    1570         2944 :   tree t = btype->get_tree();
    1571         2944 :   tree ret;
    1572         2944 :   if (t == error_mark_node)
    1573            0 :     return this->error_expression();
    1574              : 
    1575         2944 :   REAL_VALUE_TYPE r1;
    1576         2944 :   real_from_mpfr(&r1, mpc_realref(val), TREE_TYPE(t), GMP_RNDN);
    1577         2944 :   REAL_VALUE_TYPE r2;
    1578         2944 :   real_convert(&r2, TYPE_MODE(TREE_TYPE(t)), &r1);
    1579              : 
    1580         2944 :   REAL_VALUE_TYPE r3;
    1581         2944 :   real_from_mpfr(&r3, mpc_imagref(val), TREE_TYPE(t), GMP_RNDN);
    1582         2944 :   REAL_VALUE_TYPE r4;
    1583         2944 :   real_convert(&r4, TYPE_MODE(TREE_TYPE(t)), &r3);
    1584              : 
    1585         2944 :   ret = build_complex(t, build_real(TREE_TYPE(t), r2),
    1586         2944 :                       build_real(TREE_TYPE(t), r4));
    1587         2944 :   return this->make_expression(ret);
    1588              : }
    1589              : 
    1590              : // Make a constant string expression.
    1591              : 
    1592              : Bexpression*
    1593       986390 : Gcc_backend::string_constant_expression(const std::string& val)
    1594              : {
    1595       986390 :   tree index_type = build_index_type(size_int(val.length()));
    1596       986390 :   tree const_char_type = build_qualified_type(unsigned_char_type_node,
    1597              :                                               TYPE_QUAL_CONST);
    1598       986390 :   tree string_type = build_array_type(const_char_type, index_type);
    1599       986390 :   TYPE_STRING_FLAG(string_type) = 1;
    1600       986390 :   tree string_val = build_string(val.length(), val.data());
    1601       986390 :   TREE_TYPE(string_val) = string_type;
    1602              : 
    1603       986390 :   return this->make_expression(string_val);
    1604              : }
    1605              : 
    1606              : // Make a constant boolean expression.
    1607              : 
    1608              : Bexpression*
    1609       652834 : Gcc_backend::boolean_constant_expression(bool val)
    1610              : {
    1611       652834 :   tree bool_cst = val ? boolean_true_node : boolean_false_node;
    1612       652834 :   return this->make_expression(bool_cst);
    1613              : }
    1614              : 
    1615              : // Return the real part of a complex expression.
    1616              : 
    1617              : Bexpression*
    1618          460 : Gcc_backend::real_part_expression(Bexpression* bcomplex, Location location)
    1619              : {
    1620          460 :   tree complex_tree = bcomplex->get_tree();
    1621          460 :   if (complex_tree == error_mark_node)
    1622            0 :     return this->error_expression();
    1623          460 :   gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
    1624          460 :   tree ret = fold_build1_loc(location.gcc_location(), REALPART_EXPR,
    1625          460 :                              TREE_TYPE(TREE_TYPE(complex_tree)),
    1626              :                              complex_tree);
    1627          460 :   return this->make_expression(ret);
    1628              : }
    1629              : 
    1630              : // Return the imaginary part of a complex expression.
    1631              : 
    1632              : Bexpression*
    1633          526 : Gcc_backend::imag_part_expression(Bexpression* bcomplex, Location location)
    1634              : {
    1635          526 :   tree complex_tree = bcomplex->get_tree();
    1636          526 :   if (complex_tree == error_mark_node)
    1637            0 :     return this->error_expression();
    1638          526 :   gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
    1639          526 :   tree ret = fold_build1_loc(location.gcc_location(), IMAGPART_EXPR,
    1640          526 :                              TREE_TYPE(TREE_TYPE(complex_tree)),
    1641              :                              complex_tree);
    1642          526 :   return this->make_expression(ret);
    1643              : }
    1644              : 
    1645              : // Make a complex expression given its real and imaginary parts.
    1646              : 
    1647              : Bexpression*
    1648        12165 : Gcc_backend::complex_expression(Bexpression* breal, Bexpression* bimag,
    1649              :                                 Location location)
    1650              : {
    1651        12165 :   tree real_tree = breal->get_tree();
    1652        12165 :   tree imag_tree = bimag->get_tree();
    1653        12165 :   if (real_tree == error_mark_node || imag_tree == error_mark_node)
    1654            0 :     return this->error_expression();
    1655        12165 :   gcc_assert(TYPE_MAIN_VARIANT(TREE_TYPE(real_tree))
    1656              :             == TYPE_MAIN_VARIANT(TREE_TYPE(imag_tree)));
    1657        12165 :   gcc_assert(SCALAR_FLOAT_TYPE_P(TREE_TYPE(real_tree)));
    1658        12165 :   tree ret = fold_build2_loc(location.gcc_location(), COMPLEX_EXPR,
    1659        12165 :                              build_complex_type(TREE_TYPE(real_tree)),
    1660              :                              real_tree, imag_tree);
    1661        12165 :   return this->make_expression(ret);
    1662              : }
    1663              : 
    1664              : // An expression that converts an expression to a different type.
    1665              : 
    1666              : Bexpression*
    1667      9621194 : Gcc_backend::convert_expression(Btype* type, Bexpression* expr,
    1668              :                                 Location location)
    1669              : {
    1670      9621194 :   tree type_tree = type->get_tree();
    1671      9621194 :   tree expr_tree = expr->get_tree();
    1672      9621194 :   if (type_tree == error_mark_node
    1673      9621187 :       || expr_tree == error_mark_node
    1674     19242353 :       || TREE_TYPE(expr_tree) == error_mark_node)
    1675           35 :     return this->error_expression();
    1676              : 
    1677      9621159 :   tree ret;
    1678      9621159 :   if (this->type_size(type) == 0
    1679      9621159 :       || TREE_TYPE(expr_tree) == void_type_node)
    1680              :     {
    1681              :       // Do not convert zero-sized types.
    1682              :       ret = expr_tree;
    1683              :     }
    1684      9619908 :   else if (TREE_CODE(type_tree) == INTEGER_TYPE)
    1685      2372454 :     ret = fold(convert_to_integer(type_tree, expr_tree));
    1686      7247454 :   else if (TREE_CODE(type_tree) == REAL_TYPE)
    1687        32302 :     ret = fold(convert_to_real(type_tree, expr_tree));
    1688      7215152 :   else if (TREE_CODE(type_tree) == COMPLEX_TYPE)
    1689         1447 :     ret = fold(convert_to_complex(type_tree, expr_tree));
    1690      7213705 :   else if (TREE_CODE(type_tree) == POINTER_TYPE
    1691      7213705 :            && TREE_CODE(TREE_TYPE(expr_tree)) == INTEGER_TYPE)
    1692         1578 :     ret = fold(convert_to_pointer(type_tree, expr_tree));
    1693      7212127 :   else if (TREE_CODE(type_tree) == RECORD_TYPE
    1694      7212127 :            || TREE_CODE(type_tree) == ARRAY_TYPE)
    1695       925398 :     ret = fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
    1696              :                           type_tree, expr_tree);
    1697              :   else
    1698      6286729 :     ret = fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
    1699              : 
    1700      9621159 :   return this->make_expression(ret);
    1701              : }
    1702              : 
    1703              : // Get the address of a function.
    1704              : 
    1705              : Bexpression*
    1706      2174988 : Gcc_backend::function_code_expression(Bfunction* bfunc, Location location)
    1707              : {
    1708      2174988 :   tree func = bfunc->get_tree();
    1709      2174988 :   if (func == error_mark_node)
    1710            3 :     return this->error_expression();
    1711              : 
    1712      2174985 :   tree ret = build_fold_addr_expr_loc(location.gcc_location(), func);
    1713      2174985 :   return this->make_expression(ret);
    1714              : }
    1715              : 
    1716              : // Get the address of an expression.
    1717              : 
    1718              : Bexpression*
    1719      5032195 : Gcc_backend::address_expression(Bexpression* bexpr, Location location)
    1720              : {
    1721      5032195 :   tree expr = bexpr->get_tree();
    1722      5032195 :   if (expr == error_mark_node)
    1723           14 :     return this->error_expression();
    1724              : 
    1725      5032181 :   tree ret = build_fold_addr_expr_loc(location.gcc_location(), expr);
    1726      5032181 :   return this->make_expression(ret);
    1727              : }
    1728              : 
    1729              : // Return an expression for the field at INDEX in BSTRUCT.
    1730              : 
    1731              : Bexpression*
    1732      2430823 : Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index,
    1733              :                                      Location location)
    1734              : {
    1735      2430823 :   tree struct_tree = bstruct->get_tree();
    1736      2430823 :   if (struct_tree == error_mark_node
    1737      2430823 :       || TREE_TYPE(struct_tree) == error_mark_node)
    1738            3 :     return this->error_expression();
    1739              : 
    1740              :   // A function call that returns a zero-sized object will have been
    1741              :   // changed to return void.  A zero-sized object can have a
    1742              :   // (zero-sized) field, so support that case.
    1743      2430820 :   if (TREE_TYPE(struct_tree) == void_type_node)
    1744              :     return bstruct;
    1745              : 
    1746      2430820 :   gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
    1747      2430820 :   tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
    1748      2430820 :   if (field == NULL_TREE)
    1749              :   {
    1750              :     // This can happen for a type which refers to itself indirectly
    1751              :     // and then turns out to be erroneous.
    1752            0 :     return this->error_expression();
    1753              :   }
    1754      6044421 :   for (unsigned int i = index; i > 0; --i)
    1755              :   {
    1756      3613601 :     field = DECL_CHAIN(field);
    1757      3613601 :     gcc_assert(field != NULL_TREE);
    1758              :   }
    1759      2430820 :   if (TREE_TYPE(field) == error_mark_node)
    1760            0 :     return this->error_expression();
    1761      2430820 :   tree ret = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
    1762      2430820 :                              TREE_TYPE(field), struct_tree, field,
    1763              :                              NULL_TREE);
    1764      2430820 :   if (TREE_CONSTANT(struct_tree))
    1765          135 :     TREE_CONSTANT(ret) = 1;
    1766      2430820 :   return this->make_expression(ret);
    1767              : }
    1768              : 
    1769              : // Return an expression that executes BSTAT before BEXPR.
    1770              : 
    1771              : Bexpression*
    1772       450088 : Gcc_backend::compound_expression(Bstatement* bstat, Bexpression* bexpr,
    1773              :                                  Location location)
    1774              : {
    1775       450088 :   tree stat = bstat->get_tree();
    1776       450088 :   tree expr = bexpr->get_tree();
    1777       450088 :   if (stat == error_mark_node || expr == error_mark_node)
    1778            9 :     return this->error_expression();
    1779       450079 :   tree ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    1780       450079 :                              TREE_TYPE(expr), stat, expr);
    1781       450079 :   return this->make_expression(ret);
    1782              : }
    1783              : 
    1784              : // Return an expression that executes THEN_EXPR if CONDITION is true, or
    1785              : // ELSE_EXPR otherwise.
    1786              : 
    1787              : Bexpression*
    1788       558018 : Gcc_backend::conditional_expression(Bfunction*, Btype* btype,
    1789              :                                     Bexpression* condition,
    1790              :                                     Bexpression* then_expr,
    1791              :                                     Bexpression* else_expr, Location location)
    1792              : {
    1793       558018 :   tree type_tree = btype == NULL ? void_type_node : btype->get_tree();
    1794       558018 :   tree cond_tree = condition->get_tree();
    1795       558018 :   tree then_tree = then_expr->get_tree();
    1796       558018 :   tree else_tree = else_expr == NULL ? NULL_TREE : else_expr->get_tree();
    1797       558018 :   if (type_tree == error_mark_node
    1798       558018 :       || cond_tree == error_mark_node
    1799       558018 :       || then_tree == error_mark_node
    1800       558018 :       || else_tree == error_mark_node)
    1801            0 :     return this->error_expression();
    1802       558018 :   tree ret = build3_loc(location.gcc_location(), COND_EXPR, type_tree,
    1803              :                         cond_tree, then_tree, else_tree);
    1804       558018 :   return this->make_expression(ret);
    1805              : }
    1806              : 
    1807              : // Return an expression for the unary operation OP EXPR.
    1808              : 
    1809              : Bexpression*
    1810       108286 : Gcc_backend::unary_expression(Operator op, Bexpression* expr, Location location)
    1811              : {
    1812       108286 :   tree expr_tree = expr->get_tree();
    1813       108286 :   if (expr_tree == error_mark_node
    1814       108286 :       || TREE_TYPE(expr_tree) == error_mark_node)
    1815            1 :     return this->error_expression();
    1816              : 
    1817       108285 :   tree type_tree = TREE_TYPE(expr_tree);
    1818       108285 :   enum tree_code code;
    1819       108285 :   switch (op)
    1820              :     {
    1821        10894 :     case OPERATOR_MINUS:
    1822        10894 :       {
    1823        10894 :         tree computed_type = excess_precision_type(type_tree);
    1824        10894 :         if (computed_type != NULL_TREE)
    1825              :           {
    1826          464 :             expr_tree = convert(computed_type, expr_tree);
    1827          464 :             type_tree = computed_type;
    1828              :           }
    1829              :         code = NEGATE_EXPR;
    1830              :         break;
    1831              :       }
    1832              :     case OPERATOR_NOT:
    1833              :       code = TRUTH_NOT_EXPR;
    1834              :       break;
    1835         3062 :     case OPERATOR_XOR:
    1836         3062 :       code = BIT_NOT_EXPR;
    1837         3062 :       break;
    1838            0 :     default:
    1839            0 :       gcc_unreachable();
    1840       108285 :       break;
    1841              :     }
    1842              : 
    1843       108285 :   tree ret = fold_build1_loc(location.gcc_location(), code, type_tree,
    1844              :                              expr_tree);
    1845       108285 :   return this->make_expression(ret);
    1846              : }
    1847              : 
    1848              : // Convert a gofrontend operator to an equivalent tree_code.
    1849              : 
    1850              : static enum tree_code
    1851      2288269 : operator_to_tree_code(Operator op, tree type)
    1852              : {
    1853      2288269 :   enum tree_code code;
    1854      2288269 :   switch (op)
    1855              :     {
    1856              :     case OPERATOR_EQEQ:
    1857              :       code = EQ_EXPR;
    1858              :       break;
    1859       162273 :     case OPERATOR_NOTEQ:
    1860       162273 :       code = NE_EXPR;
    1861       162273 :       break;
    1862       222537 :     case OPERATOR_LT:
    1863       222537 :       code = LT_EXPR;
    1864       222537 :       break;
    1865        92034 :     case OPERATOR_LE:
    1866        92034 :       code = LE_EXPR;
    1867        92034 :       break;
    1868        37325 :     case OPERATOR_GT:
    1869        37325 :       code = GT_EXPR;
    1870        37325 :       break;
    1871       225125 :     case OPERATOR_GE:
    1872       225125 :       code = GE_EXPR;
    1873       225125 :       break;
    1874           16 :     case OPERATOR_OROR:
    1875           16 :       code = TRUTH_ORIF_EXPR;
    1876           16 :       break;
    1877       217786 :     case OPERATOR_ANDAND:
    1878       217786 :       code = TRUTH_ANDIF_EXPR;
    1879       217786 :       break;
    1880       142275 :     case OPERATOR_PLUS:
    1881       142275 :       code = PLUS_EXPR;
    1882       142275 :       break;
    1883       150242 :     case OPERATOR_MINUS:
    1884       150242 :       code = MINUS_EXPR;
    1885       150242 :       break;
    1886       127644 :     case OPERATOR_OR:
    1887       127644 :       code = BIT_IOR_EXPR;
    1888       127644 :       break;
    1889         3908 :     case OPERATOR_XOR:
    1890         3908 :       code = BIT_XOR_EXPR;
    1891         3908 :       break;
    1892        28250 :     case OPERATOR_MULT:
    1893        28250 :       code = MULT_EXPR;
    1894        28250 :       break;
    1895         8928 :     case OPERATOR_DIV:
    1896         8928 :       if (TREE_CODE(type) == REAL_TYPE || TREE_CODE(type) == COMPLEX_TYPE)
    1897              :         code = RDIV_EXPR;
    1898              :       else
    1899      2288269 :         code = TRUNC_DIV_EXPR;
    1900              :       break;
    1901         4242 :     case OPERATOR_MOD:
    1902         4242 :       code = TRUNC_MOD_EXPR;
    1903         4242 :       break;
    1904       129893 :     case OPERATOR_LSHIFT:
    1905       129893 :       code = LSHIFT_EXPR;
    1906       129893 :       break;
    1907        13650 :     case OPERATOR_RSHIFT:
    1908        13650 :       code = RSHIFT_EXPR;
    1909        13650 :       break;
    1910              :     case OPERATOR_AND:
    1911        17617 :       code = BIT_AND_EXPR;
    1912              :       break;
    1913              :     case OPERATOR_BITCLEAR:
    1914        17617 :       code = BIT_AND_EXPR;
    1915              :       break;
    1916            0 :     default:
    1917            0 :       gcc_unreachable();
    1918              :     }
    1919              : 
    1920      2288269 :   return code;
    1921              : }
    1922              : 
    1923              : // Return an expression for the binary operation LEFT OP RIGHT.
    1924              : 
    1925              : Bexpression*
    1926      2288270 : Gcc_backend::binary_expression(Operator op, Bexpression* left,
    1927              :                                Bexpression* right, Location location)
    1928              : {
    1929      2288270 :   tree left_tree = left->get_tree();
    1930      2288270 :   tree right_tree = right->get_tree();
    1931      2288270 :   if (left_tree == error_mark_node
    1932      2288270 :       || right_tree == error_mark_node)
    1933            1 :     return this->error_expression();
    1934      2288269 :   enum tree_code code = operator_to_tree_code(op, TREE_TYPE(left_tree));
    1935              : 
    1936      2288269 :   bool use_left_type = op != OPERATOR_OROR && op != OPERATOR_ANDAND;
    1937      2288269 :   tree type_tree = use_left_type ? TREE_TYPE(left_tree) : TREE_TYPE(right_tree);
    1938      2288269 :   tree computed_type = excess_precision_type(type_tree);
    1939      2288269 :   if (computed_type != NULL_TREE)
    1940              :     {
    1941         8586 :       left_tree = convert(computed_type, left_tree);
    1942         8586 :       right_tree = convert(computed_type, right_tree);
    1943         8586 :       type_tree = computed_type;
    1944              :     }
    1945              : 
    1946              :   // For comparison operators, the resulting type should be boolean.
    1947      2288269 :   switch (op)
    1948              :     {
    1949      1443818 :     case OPERATOR_EQEQ:
    1950      1443818 :     case OPERATOR_NOTEQ:
    1951      1443818 :     case OPERATOR_LT:
    1952      1443818 :     case OPERATOR_LE:
    1953      1443818 :     case OPERATOR_GT:
    1954      1443818 :     case OPERATOR_GE:
    1955      1443818 :       type_tree = boolean_type_node;
    1956      1443818 :       break;
    1957              :     default:
    1958              :       break;
    1959              :     }
    1960              : 
    1961      2288269 :   tree ret = fold_build2_loc(location.gcc_location(), code, type_tree,
    1962              :                              left_tree, right_tree);
    1963      2288269 :   return this->make_expression(ret);
    1964              : }
    1965              : 
    1966              : // Return an expression that constructs BTYPE with VALS.
    1967              : 
    1968              : Bexpression*
    1969      2874821 : Gcc_backend::constructor_expression(Btype* btype,
    1970              :                                     const std::vector<Bexpression*>& vals,
    1971              :                                     Location location)
    1972              : {
    1973      2874821 :   tree type_tree = btype->get_tree();
    1974      2874821 :   if (type_tree == error_mark_node)
    1975            0 :     return this->error_expression();
    1976              : 
    1977      2874821 :   vec<constructor_elt, va_gc> *init;
    1978      2874821 :   vec_alloc(init, vals.size());
    1979              : 
    1980      2874821 :   tree sink = NULL_TREE;
    1981      2874821 :   bool is_constant = true;
    1982      2874821 :   tree field = TYPE_FIELDS(type_tree);
    1983      2874821 :   for (std::vector<Bexpression*>::const_iterator p = vals.begin();
    1984     12737756 :        p != vals.end();
    1985      9862935 :        ++p, field = DECL_CHAIN(field))
    1986              :     {
    1987      9862951 :       gcc_assert(field != NULL_TREE);
    1988      9862951 :       tree val = (*p)->get_tree();
    1989      9862951 :       if (TREE_TYPE(field) == error_mark_node
    1990      9862951 :           || val == error_mark_node
    1991     19725886 :           || TREE_TYPE(val) == error_mark_node)
    1992           16 :         return this->error_expression();
    1993              : 
    1994      9862935 :       if (int_size_in_bytes(TREE_TYPE(field)) == 0)
    1995              :         {
    1996              :           // GIMPLE cannot represent indices of zero-sized types so
    1997              :           // trying to construct a map with zero-sized keys might lead
    1998              :           // to errors.  Instead, we evaluate each expression that
    1999              :           // would have been added as a map element for its
    2000              :           // side-effects and construct an empty map.
    2001          810 :           append_to_statement_list(val, &sink);
    2002          810 :           continue;
    2003              :         }
    2004              : 
    2005      9862125 :       constructor_elt empty = {NULL, NULL};
    2006      9862125 :       constructor_elt* elt = init->quick_push(empty);
    2007      9862125 :       elt->index = field;
    2008      9862125 :       elt->value = this->convert_tree(TREE_TYPE(field), val, location);
    2009      9862125 :       if (!TREE_CONSTANT(elt->value))
    2010       597767 :         is_constant = false;
    2011              :     }
    2012      2874805 :   gcc_assert(field == NULL_TREE);
    2013      2874805 :   tree ret = build_constructor(type_tree, init);
    2014      2874805 :   if (is_constant)
    2015      2463483 :     TREE_CONSTANT(ret) = 1;
    2016      2874805 :   if (sink != NULL_TREE)
    2017            0 :     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    2018              :                           type_tree, sink, ret);
    2019      2874805 :   return this->make_expression(ret);
    2020              : }
    2021              : 
    2022              : Bexpression*
    2023       440930 : Gcc_backend::array_constructor_expression(
    2024              :     Btype* array_btype, const std::vector<unsigned long>& indexes,
    2025              :     const std::vector<Bexpression*>& vals, Location location)
    2026              : {
    2027       440930 :   tree type_tree = array_btype->get_tree();
    2028       440930 :   if (type_tree == error_mark_node)
    2029            1 :     return this->error_expression();
    2030              : 
    2031       440929 :   gcc_assert(indexes.size() == vals.size());
    2032              : 
    2033       440929 :   tree element_type = TREE_TYPE(type_tree);
    2034       440929 :   HOST_WIDE_INT element_size = int_size_in_bytes(element_type);
    2035       440929 :   vec<constructor_elt, va_gc> *init;
    2036       881795 :   vec_alloc(init, element_size == 0 ? 0 : vals.size());
    2037              : 
    2038       440929 :   tree sink = NULL_TREE;
    2039       440929 :   bool is_constant = true;
    2040      2372867 :   for (size_t i = 0; i < vals.size(); ++i)
    2041              :     {
    2042      1931943 :       tree index = size_int(indexes[i]);
    2043      1931943 :       tree val = (vals[i])->get_tree();
    2044              : 
    2045      1931943 :       if (index == error_mark_node
    2046      1931943 :           || val == error_mark_node)
    2047            5 :         return this->error_expression();
    2048              : 
    2049      1931938 :       if (element_size == 0)
    2050              :        {
    2051              :          // GIMPLE cannot represent arrays of zero-sized types so trying
    2052              :          // to construct an array of zero-sized values might lead to errors.
    2053              :          // Instead, we evaluate each expression that would have been added as
    2054              :          // an array value for its side-effects and construct an empty array.
    2055            9 :          append_to_statement_list(val, &sink);
    2056            9 :          continue;
    2057              :        }
    2058              : 
    2059      1931929 :       if (!TREE_CONSTANT(val))
    2060       156463 :         is_constant = false;
    2061              : 
    2062      1931929 :       constructor_elt empty = {NULL, NULL};
    2063      1931929 :       constructor_elt* elt = init->quick_push(empty);
    2064      1931929 :       elt->index = index;
    2065      1931929 :       elt->value = val;
    2066              :     }
    2067              : 
    2068       440924 :   tree ret = build_constructor(type_tree, init);
    2069       440924 :   if (is_constant)
    2070       364902 :     TREE_CONSTANT(ret) = 1;
    2071       440924 :   if (sink != NULL_TREE)
    2072            0 :     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    2073              :                          type_tree, sink, ret);
    2074       440924 :   return this->make_expression(ret);
    2075              : }
    2076              : 
    2077              : // Return an expression for the address of BASE[INDEX].
    2078              : 
    2079              : Bexpression*
    2080       160626 : Gcc_backend::pointer_offset_expression(Bexpression* base, Bexpression* index,
    2081              :                                        Location location)
    2082              : {
    2083       160626 :   tree base_tree = base->get_tree();
    2084       160626 :   tree index_tree = index->get_tree();
    2085       160626 :   tree element_type_tree = TREE_TYPE(TREE_TYPE(base_tree));
    2086       160626 :   if (base_tree == error_mark_node
    2087       160626 :       || TREE_TYPE(base_tree) == error_mark_node
    2088       160626 :       || index_tree == error_mark_node
    2089       321252 :       || element_type_tree == error_mark_node)
    2090            0 :     return this->error_expression();
    2091              : 
    2092       160626 :   tree element_size = TYPE_SIZE_UNIT(element_type_tree);
    2093       160626 :   index_tree = fold_convert_loc(location.gcc_location(), sizetype, index_tree);
    2094       160626 :   tree offset = fold_build2_loc(location.gcc_location(), MULT_EXPR, sizetype,
    2095              :                                 index_tree, element_size);
    2096       160626 :   tree ptr = fold_build2_loc(location.gcc_location(), POINTER_PLUS_EXPR,
    2097       160626 :                              TREE_TYPE(base_tree), base_tree, offset);
    2098       160626 :   return this->make_expression(ptr);
    2099              : }
    2100              : 
    2101              : // Return an expression representing ARRAY[INDEX]
    2102              : 
    2103              : Bexpression*
    2104        66928 : Gcc_backend::array_index_expression(Bexpression* array, Bexpression* index,
    2105              :                                     Location location)
    2106              : {
    2107        66928 :   tree array_tree = array->get_tree();
    2108        66928 :   tree index_tree = index->get_tree();
    2109        66928 :   if (array_tree == error_mark_node
    2110        66928 :       || TREE_TYPE(array_tree) == error_mark_node
    2111       133856 :       || index_tree == error_mark_node)
    2112            0 :     return this->error_expression();
    2113              : 
    2114              :   // A function call that returns a zero sized object will have been
    2115              :   // changed to return void.  If we see void here, assume we are
    2116              :   // dealing with a zero sized type and just evaluate the operands.
    2117        66928 :   tree ret;
    2118        66928 :   if (TREE_TYPE(array_tree) != void_type_node)
    2119        66927 :     ret = build4_loc(location.gcc_location(), ARRAY_REF,
    2120        66927 :                      TREE_TYPE(TREE_TYPE(array_tree)), array_tree,
    2121              :                      index_tree, NULL_TREE, NULL_TREE);
    2122              :   else
    2123            1 :     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    2124              :                           void_type_node, array_tree, index_tree);
    2125              : 
    2126        66928 :   return this->make_expression(ret);
    2127              : }
    2128              : 
    2129              : // Create an expression for a call to FN_EXPR with FN_ARGS.
    2130              : Bexpression*
    2131      1791631 : Gcc_backend::call_expression(Bfunction*, // containing fcn for call
    2132              :                              Bexpression* fn_expr,
    2133              :                              const std::vector<Bexpression*>& fn_args,
    2134              :                              Bexpression* chain_expr,
    2135              :                              Location location)
    2136              : {
    2137      1791631 :   tree fn = fn_expr->get_tree();
    2138      1791631 :   if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node)
    2139            4 :     return this->error_expression();
    2140              : 
    2141      1791627 :   gcc_assert(FUNCTION_POINTER_TYPE_P(TREE_TYPE(fn)));
    2142      1791627 :   tree rettype = TREE_TYPE(TREE_TYPE(TREE_TYPE(fn)));
    2143              : 
    2144      1791627 :   size_t nargs = fn_args.size();
    2145      1791627 :   tree* args = nargs == 0 ? NULL : new tree[nargs];
    2146      5002690 :   for (size_t i = 0; i < nargs; ++i)
    2147              :     {
    2148      3211073 :       args[i] = fn_args.at(i)->get_tree();
    2149      3211073 :       if (args[i] == error_mark_node)
    2150           10 :         return this->error_expression();
    2151      3211063 :       if (TREE_TYPE(args[i]) == void_type_node)
    2152              :         {
    2153              :           // This can happen for a case like f(g()) where g returns a
    2154              :           // zero-sized type, because in that case we've changed g to
    2155              :           // return void.
    2156            0 :           tree t = TYPE_ARG_TYPES(TREE_TYPE(TREE_TYPE(fn)));
    2157            0 :           for (size_t j = 0; j < i; ++j)
    2158            0 :             t = TREE_CHAIN(t);
    2159            0 :           tree arg_type = TREE_TYPE(TREE_VALUE(t));
    2160            0 :           args[i] = fold_build2_loc(EXPR_LOCATION(args[i]), COMPOUND_EXPR,
    2161              :                                     arg_type, args[i],
    2162              :                                     build_zero_cst(arg_type));
    2163              :         }
    2164              :     }
    2165              : 
    2166      1791617 :   tree fndecl = fn;
    2167      1791617 :   if (TREE_CODE(fndecl) == ADDR_EXPR)
    2168      1737349 :     fndecl = TREE_OPERAND(fndecl, 0);
    2169              : 
    2170              :   // This is to support builtin math functions when using 80387 math.
    2171      1791617 :   tree excess_type = NULL_TREE;
    2172      1791617 :   if (optimize
    2173      1632296 :       && TREE_CODE(fndecl) == FUNCTION_DECL
    2174      1578046 :       && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
    2175        59544 :       && DECL_IS_UNDECLARED_BUILTIN (fndecl)
    2176        59544 :       && nargs > 0
    2177      1850169 :       && ((SCALAR_FLOAT_TYPE_P(rettype)
    2178          341 :            && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0])))
    2179        58211 :           || (COMPLEX_FLOAT_TYPE_P(rettype)
    2180            0 :               && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0])))))
    2181              :     {
    2182          341 :       excess_type = excess_precision_type(TREE_TYPE(args[0]));
    2183          341 :       if (excess_type != NULL_TREE)
    2184              :         {
    2185          164 :           tree excess_fndecl = mathfn_built_in(excess_type,
    2186              :                                                DECL_FUNCTION_CODE(fndecl));
    2187          164 :           if (excess_fndecl == NULL_TREE)
    2188              :             excess_type = NULL_TREE;
    2189              :           else
    2190              :             {
    2191          164 :               fn = build_fold_addr_expr_loc(location.gcc_location(),
    2192              :                                             excess_fndecl);
    2193          351 :               for (size_t i = 0; i < nargs; ++i)
    2194              :                 {
    2195          187 :                   if (SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[i]))
    2196          187 :                       || COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[i])))
    2197          176 :                     args[i] = ::convert(excess_type, args[i]);
    2198              :                 }
    2199              :             }
    2200              :         }
    2201              :     }
    2202              : 
    2203      1791617 :   tree ret =
    2204      1791617 :       build_call_array_loc(location.gcc_location(),
    2205              :                            excess_type != NULL_TREE ? excess_type : rettype,
    2206              :                            fn, nargs, args);
    2207              : 
    2208      1791617 :   if (chain_expr)
    2209        23187 :     CALL_EXPR_STATIC_CHAIN (ret) = chain_expr->get_tree();
    2210              : 
    2211      1791617 :   if (excess_type != NULL_TREE)
    2212              :     {
    2213              :       // Calling convert here can undo our excess precision change.
    2214              :       // That may or may not be a bug in convert_to_real.
    2215          164 :       ret = build1_loc(location.gcc_location(), NOP_EXPR, rettype, ret);
    2216              :     }
    2217              : 
    2218      1791617 :   delete[] args;
    2219      1791617 :   return this->make_expression(ret);
    2220              : }
    2221              : 
    2222              : // An expression as a statement.
    2223              : 
    2224              : Bstatement*
    2225      1009936 : Gcc_backend::expression_statement(Bfunction*, Bexpression* expr)
    2226              : {
    2227      1009936 :   return this->make_statement(expr->get_tree());
    2228              : }
    2229              : 
    2230              : // Variable initialization.
    2231              : 
    2232              : Bstatement*
    2233       645336 : Gcc_backend::init_statement(Bfunction*, Bvariable* var, Bexpression* init)
    2234              : {
    2235       645336 :   tree var_tree = var->get_decl();
    2236       645336 :   tree init_tree = init->get_tree();
    2237       645336 :   if (var_tree == error_mark_node || init_tree == error_mark_node)
    2238            6 :     return this->error_statement();
    2239       645330 :   gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
    2240              : 
    2241              :   // To avoid problems with GNU ld, we don't make zero-sized
    2242              :   // externally visible variables.  That might lead us to doing an
    2243              :   // initialization of a zero-sized expression to a non-zero sized
    2244              :   // variable, or vice-versa.  Avoid crashes by omitting the
    2245              :   // initializer.  Such initializations don't mean anything anyhow.
    2246       645330 :   if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0
    2247       644018 :       && init_tree != NULL_TREE
    2248       644018 :       && TREE_TYPE(init_tree) != void_type_node
    2249      1289348 :       && int_size_in_bytes(TREE_TYPE(init_tree)) != 0)
    2250              :     {
    2251       644018 :       DECL_INITIAL(var_tree) = init_tree;
    2252       644018 :       init_tree = NULL_TREE;
    2253              :     }
    2254              : 
    2255       645330 :   tree ret = build1_loc(DECL_SOURCE_LOCATION(var_tree), DECL_EXPR,
    2256              :                         void_type_node, var_tree);
    2257       645330 :   if (init_tree != NULL_TREE)
    2258         1312 :     ret = build2_loc(DECL_SOURCE_LOCATION(var_tree), COMPOUND_EXPR,
    2259              :                      void_type_node, init_tree, ret);
    2260              : 
    2261       645330 :   return this->make_statement(ret);
    2262              : }
    2263              : 
    2264              : // Assignment.
    2265              : 
    2266              : Bstatement*
    2267      1406234 : Gcc_backend::assignment_statement(Bfunction* bfn, Bexpression* lhs,
    2268              :                                   Bexpression* rhs, Location location)
    2269              : {
    2270      1406234 :   tree lhs_tree = lhs->get_tree();
    2271      1406234 :   tree rhs_tree = rhs->get_tree();
    2272      1406234 :   if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
    2273          121 :     return this->error_statement();
    2274              : 
    2275              :   // To avoid problems with GNU ld, we don't make zero-sized
    2276              :   // externally visible variables.  That might lead us to doing an
    2277              :   // assignment of a zero-sized expression to a non-zero sized
    2278              :   // expression; avoid crashes here by avoiding assignments of
    2279              :   // zero-sized expressions.  Such assignments don't really mean
    2280              :   // anything anyhow.
    2281      1406113 :   if (TREE_TYPE(lhs_tree) == void_type_node
    2282      1406113 :       || int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
    2283      1400695 :       || TREE_TYPE(rhs_tree) == void_type_node
    2284      2806808 :       || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
    2285         5418 :     return this->compound_statement(this->expression_statement(bfn, lhs),
    2286        10836 :                                     this->expression_statement(bfn, rhs));
    2287              : 
    2288      1400695 :   rhs_tree = this->convert_tree(TREE_TYPE(lhs_tree), rhs_tree, location);
    2289              : 
    2290      1400695 :   return this->make_statement(fold_build2_loc(location.gcc_location(),
    2291              :                                               MODIFY_EXPR,
    2292              :                                               void_type_node,
    2293      1400695 :                                               lhs_tree, rhs_tree));
    2294              : }
    2295              : 
    2296              : // Return.
    2297              : 
    2298              : Bstatement*
    2299       377106 : Gcc_backend::return_statement(Bfunction* bfunction,
    2300              :                               const std::vector<Bexpression*>& vals,
    2301              :                               Location location)
    2302              : {
    2303       377106 :   tree fntree = bfunction->get_tree();
    2304       377106 :   if (fntree == error_mark_node)
    2305            0 :     return this->error_statement();
    2306       377106 :   tree result = DECL_RESULT(fntree);
    2307       377106 :   if (result == error_mark_node)
    2308            0 :     return this->error_statement();
    2309              : 
    2310              :   // If the result size is zero bytes, we have set the function type
    2311              :   // to have a result type of void, so don't return anything.
    2312              :   // See the function_type method.
    2313       377106 :   tree res_type = TREE_TYPE(result);
    2314       377106 :   if (res_type == void_type_node || int_size_in_bytes(res_type) == 0)
    2315              :     {
    2316        10956 :       tree stmt_list = NULL_TREE;
    2317        10970 :       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
    2318        10970 :            p != vals.end();
    2319           14 :            p++)
    2320              :         {
    2321           14 :           tree val = (*p)->get_tree();
    2322           14 :           if (val == error_mark_node)
    2323            0 :             return this->error_statement();
    2324           14 :           append_to_statement_list(val, &stmt_list);
    2325              :         }
    2326        10956 :       tree ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
    2327              :                                  void_type_node, NULL_TREE);
    2328        10956 :       append_to_statement_list(ret, &stmt_list);
    2329        10956 :       return this->make_statement(stmt_list);
    2330              :     }
    2331              : 
    2332       366150 :   tree ret;
    2333       366150 :   if (vals.empty())
    2334            0 :     ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
    2335              :                           NULL_TREE);
    2336       366150 :   else if (vals.size() == 1)
    2337              :     {
    2338       304375 :       tree val = vals.front()->get_tree();
    2339       304375 :       if (val == error_mark_node)
    2340            0 :         return this->error_statement();
    2341       304375 :       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
    2342              :                                  void_type_node, result,
    2343       304375 :                                  vals.front()->get_tree());
    2344       304375 :       ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
    2345              :                             void_type_node, set);
    2346              :     }
    2347              :   else
    2348              :     {
    2349              :       // To return multiple values, copy the values into a temporary
    2350              :       // variable of the right structure type, and then assign the
    2351              :       // temporary variable to the DECL_RESULT in the return
    2352              :       // statement.
    2353        61775 :       tree stmt_list = NULL_TREE;
    2354        61775 :       tree rettype = TREE_TYPE(result);
    2355              : 
    2356        61775 :       if (DECL_STRUCT_FUNCTION(fntree) == NULL)
    2357          283 :         push_struct_function(fntree);
    2358              :       else
    2359        61492 :         push_cfun(DECL_STRUCT_FUNCTION(fntree));
    2360        61775 :       tree rettmp = create_tmp_var(rettype, "RESULT");
    2361        61775 :       pop_cfun();
    2362              : 
    2363        61775 :       tree field = TYPE_FIELDS(rettype);
    2364        61775 :       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
    2365       198361 :            p != vals.end();
    2366       136586 :            p++, field = DECL_CHAIN(field))
    2367              :         {
    2368       136586 :           gcc_assert(field != NULL_TREE);
    2369       136586 :           tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
    2370       136586 :                                      TREE_TYPE(field), rettmp, field,
    2371              :                                      NULL_TREE);
    2372       136586 :           tree val = (*p)->get_tree();
    2373       136586 :           if (val == error_mark_node)
    2374            0 :             return this->error_statement();
    2375       273172 :           tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
    2376              :                                      void_type_node,
    2377       136586 :                                      ref, (*p)->get_tree());
    2378       136586 :           append_to_statement_list(set, &stmt_list);
    2379              :         }
    2380        61775 :       gcc_assert(field == NULL_TREE);
    2381        61775 :       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
    2382              :                                  void_type_node,
    2383              :                                  result, rettmp);
    2384        61775 :       tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
    2385              :                                       void_type_node, set);
    2386        61775 :       append_to_statement_list(ret_expr, &stmt_list);
    2387        61775 :       ret = stmt_list;
    2388              :     }
    2389       366150 :   return this->make_statement(ret);
    2390              : }
    2391              : 
    2392              : // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an
    2393              : // error occurs.  EXCEPT_STMT may be NULL.  FINALLY_STMT may be NULL and if not
    2394              : // NULL, it will always be executed.  This is used for handling defers in Go
    2395              : // functions.  In C++, the resulting code is of this form:
    2396              : //   try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
    2397              : 
    2398              : Bstatement*
    2399         8353 : Gcc_backend::exception_handler_statement(Bstatement* bstat,
    2400              :                                          Bstatement* except_stmt,
    2401              :                                          Bstatement* finally_stmt,
    2402              :                                          Location location)
    2403              : {
    2404         8353 :   tree stat_tree = bstat->get_tree();
    2405         8353 :   tree except_tree = except_stmt == NULL ? NULL_TREE : except_stmt->get_tree();
    2406         8353 :   tree finally_tree = finally_stmt == NULL
    2407         8353 :       ? NULL_TREE
    2408         8353 :       : finally_stmt->get_tree();
    2409              : 
    2410         8353 :   if (stat_tree == error_mark_node
    2411         8353 :       || except_tree == error_mark_node
    2412         8353 :       || finally_tree == error_mark_node)
    2413            0 :     return this->error_statement();
    2414              : 
    2415         8353 :   if (except_tree != NULL_TREE)
    2416         8353 :     stat_tree = build2_loc(location.gcc_location(), TRY_CATCH_EXPR,
    2417              :                            void_type_node, stat_tree,
    2418              :                            build2_loc(location.gcc_location(), CATCH_EXPR,
    2419              :                                       void_type_node, NULL, except_tree));
    2420         8353 :   if (finally_tree != NULL_TREE)
    2421         8353 :     stat_tree = build2_loc(location.gcc_location(), TRY_FINALLY_EXPR,
    2422              :                            void_type_node, stat_tree, finally_tree);
    2423         8353 :   return this->make_statement(stat_tree);
    2424              : }
    2425              : 
    2426              : // If.
    2427              : 
    2428              : Bstatement*
    2429       698859 : Gcc_backend::if_statement(Bfunction*, Bexpression* condition,
    2430              :                           Bblock* then_block, Bblock* else_block,
    2431              :                           Location location)
    2432              : {
    2433       698859 :   tree cond_tree = condition->get_tree();
    2434       698859 :   tree then_tree = then_block->get_tree();
    2435       698859 :   tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
    2436       698859 :   if (cond_tree == error_mark_node
    2437       698855 :       || then_tree == error_mark_node
    2438       698855 :       || else_tree == error_mark_node)
    2439            4 :     return this->error_statement();
    2440       698855 :   tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
    2441              :                         cond_tree, then_tree, else_tree);
    2442       698855 :   return this->make_statement(ret);
    2443              : }
    2444              : 
    2445              : // Switch.
    2446              : 
    2447              : Bstatement*
    2448         7785 : Gcc_backend::switch_statement(
    2449              :     Bfunction* function,
    2450              :     Bexpression* value,
    2451              :     const std::vector<std::vector<Bexpression*> >& cases,
    2452              :     const std::vector<Bstatement*>& statements,
    2453              :     Location switch_location)
    2454              : {
    2455         7785 :   gcc_assert(cases.size() == statements.size());
    2456              : 
    2457         7785 :   tree decl = function->get_tree();
    2458         7785 :   if (DECL_STRUCT_FUNCTION(decl) == NULL)
    2459            2 :     push_struct_function(decl);
    2460              :   else
    2461         7783 :     push_cfun(DECL_STRUCT_FUNCTION(decl));
    2462              : 
    2463         7785 :   tree stmt_list = NULL_TREE;
    2464         7785 :   std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
    2465         7785 :   for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
    2466        39947 :        ps != statements.end();
    2467        32162 :        ++ps, ++pc)
    2468              :     {
    2469        32165 :       if (pc->empty())
    2470              :         {
    2471         4631 :           location_t loc = (*ps != NULL
    2472         4631 :                             ? EXPR_LOCATION((*ps)->get_tree())
    2473         1994 :                             : UNKNOWN_LOCATION);
    2474         4631 :           tree label = create_artificial_label(loc);
    2475         4631 :           tree c = build_case_label(NULL_TREE, NULL_TREE, label);
    2476         4631 :           append_to_statement_list(c, &stmt_list);
    2477              :         }
    2478              :       else
    2479              :         {
    2480        39894 :           for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
    2481        67428 :                pcv != pc->end();
    2482        39894 :                ++pcv)
    2483              :             {
    2484        39895 :               tree t = (*pcv)->get_tree();
    2485        39895 :               if (t == error_mark_node)
    2486            1 :                 return this->error_statement();
    2487        39894 :               location_t loc = EXPR_LOCATION(t);
    2488        39894 :               tree label = create_artificial_label(loc);
    2489        39894 :               tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
    2490        39894 :               append_to_statement_list(c, &stmt_list);
    2491              :             }
    2492              :         }
    2493              : 
    2494        32164 :       if (*ps != NULL)
    2495              :         {
    2496        32147 :           tree t = (*ps)->get_tree();
    2497        32147 :           if (t == error_mark_node)
    2498            2 :             return this->error_statement();
    2499        32145 :           append_to_statement_list(t, &stmt_list);
    2500              :         }
    2501              :     }
    2502         7782 :   pop_cfun();
    2503              : 
    2504         7782 :   tree tv = value->get_tree();
    2505         7782 :   if (tv == error_mark_node)
    2506            0 :     return this->error_statement();
    2507         7782 :   tree t = build2_loc(switch_location.gcc_location(), SWITCH_EXPR,
    2508              :                       NULL_TREE, tv, stmt_list);
    2509         7782 :   return this->make_statement(t);
    2510              : }
    2511              : 
    2512              : // Pair of statements.
    2513              : 
    2514              : Bstatement*
    2515       674464 : Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
    2516              : {
    2517       674464 :   tree stmt_list = NULL_TREE;
    2518       674464 :   tree t = s1->get_tree();
    2519       674464 :   if (t == error_mark_node)
    2520            9 :     return this->error_statement();
    2521       674455 :   append_to_statement_list(t, &stmt_list);
    2522       674455 :   t = s2->get_tree();
    2523       674455 :   if (t == error_mark_node)
    2524            8 :     return this->error_statement();
    2525       674447 :   append_to_statement_list(t, &stmt_list);
    2526              : 
    2527              :   // If neither statement has any side effects, stmt_list can be NULL
    2528              :   // at this point.
    2529       674447 :   if (stmt_list == NULL_TREE)
    2530         5415 :     stmt_list = integer_zero_node;
    2531              : 
    2532       674447 :   return this->make_statement(stmt_list);
    2533              : }
    2534              : 
    2535              : // List of statements.
    2536              : 
    2537              : Bstatement*
    2538       337371 : Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
    2539              : {
    2540       337371 :   tree stmt_list = NULL_TREE;
    2541       713012 :   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
    2542       713012 :        p != statements.end();
    2543       375641 :        ++p)
    2544              :     {
    2545       375686 :       tree t = (*p)->get_tree();
    2546       375686 :       if (t == error_mark_node)
    2547           45 :         return this->error_statement();
    2548       375641 :       append_to_statement_list(t, &stmt_list);
    2549              :     }
    2550       337326 :   return this->make_statement(stmt_list);
    2551              : }
    2552              : 
    2553              : // Make a block.  For some reason gcc uses a dual structure for
    2554              : // blocks: BLOCK tree nodes and BIND_EXPR tree nodes.  Since the
    2555              : // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
    2556              : // the Bblock.
    2557              : 
    2558              : Bblock*
    2559      2860150 : Gcc_backend::block(Bfunction* function, Bblock* enclosing,
    2560              :                    const std::vector<Bvariable*>& vars,
    2561              :                    Location start_location,
    2562              :                    Location)
    2563              : {
    2564      2860150 :   tree block_tree = make_node(BLOCK);
    2565      2860150 :   if (enclosing == NULL)
    2566              :     {
    2567       551806 :       tree fndecl = function->get_tree();
    2568       551806 :       gcc_assert(fndecl != NULL_TREE);
    2569              : 
    2570              :       // We may have already created a block for local variables when
    2571              :       // we take the address of a parameter.
    2572       551806 :       if (DECL_INITIAL(fndecl) == NULL_TREE)
    2573              :         {
    2574       298929 :           BLOCK_SUPERCONTEXT(block_tree) = fndecl;
    2575       298929 :           DECL_INITIAL(fndecl) = block_tree;
    2576              :         }
    2577              :       else
    2578              :         {
    2579       252877 :           tree superblock_tree = DECL_INITIAL(fndecl);
    2580       252877 :           BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
    2581       252877 :           tree* pp;
    2582       252877 :           for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
    2583      1565537 :                *pp != NULL_TREE;
    2584      1312660 :                pp = &BLOCK_CHAIN(*pp))
    2585              :             ;
    2586       252877 :           *pp = block_tree;
    2587              :         }
    2588              :     }
    2589              :   else
    2590              :     {
    2591      2308344 :       tree superbind_tree = enclosing->get_tree();
    2592      2308344 :       tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
    2593      2308344 :       gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
    2594              : 
    2595      2308344 :       BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
    2596      2308344 :       tree* pp;
    2597      2308344 :       for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
    2598     34294820 :            *pp != NULL_TREE;
    2599     31986476 :            pp = &BLOCK_CHAIN(*pp))
    2600              :         ;
    2601      2308344 :       *pp = block_tree;
    2602              :     }
    2603              : 
    2604      2860150 :   tree* pp = &BLOCK_VARS(block_tree);
    2605      3505536 :   for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
    2606      3505536 :        pv != vars.end();
    2607       645386 :        ++pv)
    2608              :     {
    2609       645386 :       *pp = (*pv)->get_decl();
    2610       645386 :       if (*pp != error_mark_node)
    2611       645343 :         pp = &DECL_CHAIN(*pp);
    2612              :     }
    2613      2860150 :   *pp = NULL_TREE;
    2614              : 
    2615      2860150 :   TREE_USED(block_tree) = 1;
    2616              : 
    2617      2860150 :   tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
    2618      2860150 :                               void_type_node, BLOCK_VARS(block_tree),
    2619              :                               NULL_TREE, block_tree);
    2620      2860150 :   TREE_SIDE_EFFECTS(bind_tree) = 1;
    2621      2860150 :   return new Bblock(bind_tree);
    2622              : }
    2623              : 
    2624              : // Add statements to a block.
    2625              : 
    2626              : void
    2627      2856701 : Gcc_backend::block_add_statements(Bblock* bblock,
    2628              :                                   const std::vector<Bstatement*>& statements)
    2629              : {
    2630      2856701 :   tree stmt_list = NULL_TREE;
    2631     10108420 :   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
    2632     10108420 :        p != statements.end();
    2633      7251719 :        ++p)
    2634              :     {
    2635      7251719 :       tree s = (*p)->get_tree();
    2636      7251719 :       if (s != error_mark_node)
    2637      7247738 :         append_to_statement_list(s, &stmt_list);
    2638              :     }
    2639              : 
    2640      2856701 :   tree bind_tree = bblock->get_tree();
    2641      2856701 :   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
    2642      2856701 :   BIND_EXPR_BODY(bind_tree) = stmt_list;
    2643      2856701 : }
    2644              : 
    2645              : // Return a block as a statement.
    2646              : 
    2647              : Bstatement*
    2648      1922250 : Gcc_backend::block_statement(Bblock* bblock)
    2649              : {
    2650      1922250 :   tree bind_tree = bblock->get_tree();
    2651      1922250 :   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
    2652      1922250 :   return this->make_statement(bind_tree);
    2653              : }
    2654              : 
    2655              : // This is not static because we declare it with GTY(()) in go-c.h.
    2656              : tree go_non_zero_struct;
    2657              : 
    2658              : // Return a type corresponding to TYPE with non-zero size.
    2659              : 
    2660              : tree
    2661          415 : Gcc_backend::non_zero_size_type(tree type)
    2662              : {
    2663          415 :   if (int_size_in_bytes(type) != 0)
    2664              :     return type;
    2665              : 
    2666          413 :   switch (TREE_CODE(type))
    2667              :     {
    2668          410 :     case RECORD_TYPE:
    2669          410 :       if (TYPE_FIELDS(type) != NULL_TREE)
    2670              :         {
    2671            2 :           tree ns = make_node(RECORD_TYPE);
    2672            2 :           tree field_trees = NULL_TREE;
    2673            2 :           tree *pp = &field_trees;
    2674            2 :           for (tree field = TYPE_FIELDS(type);
    2675            4 :                field != NULL_TREE;
    2676            2 :                field = DECL_CHAIN(field))
    2677              :             {
    2678            2 :               tree ft = TREE_TYPE(field);
    2679            2 :               if (field == TYPE_FIELDS(type))
    2680            2 :                 ft = non_zero_size_type(ft);
    2681            2 :               tree f = build_decl(DECL_SOURCE_LOCATION(field), FIELD_DECL,
    2682            2 :                                   DECL_NAME(field), ft);
    2683            2 :               DECL_CONTEXT(f) = ns;
    2684            2 :               *pp = f;
    2685            2 :               pp = &DECL_CHAIN(f);
    2686              :             }
    2687            2 :           TYPE_FIELDS(ns) = field_trees;
    2688            2 :           layout_type(ns);
    2689            2 :           return ns;
    2690              :         }
    2691              : 
    2692          408 :       if (go_non_zero_struct == NULL_TREE)
    2693              :         {
    2694          298 :           type = make_node(RECORD_TYPE);
    2695          298 :           tree field = build_decl(UNKNOWN_LOCATION, FIELD_DECL,
    2696              :                                   get_identifier("dummy"),
    2697              :                                   boolean_type_node);
    2698          298 :           DECL_CONTEXT(field) = type;
    2699          298 :           TYPE_FIELDS(type) = field;
    2700          298 :           layout_type(type);
    2701          298 :           go_non_zero_struct = type;
    2702              :         }
    2703          408 :       return go_non_zero_struct;
    2704              : 
    2705            3 :     case ARRAY_TYPE:
    2706            3 :       {
    2707            3 :         tree element_type = non_zero_size_type(TREE_TYPE(type));
    2708            3 :         return build_array_type_nelts(element_type, 1);
    2709              :       }
    2710              : 
    2711            0 :     default:
    2712            0 :       gcc_unreachable();
    2713              :     }
    2714              : 
    2715              :   gcc_unreachable();
    2716              : }
    2717              : 
    2718              : // Convert EXPR_TREE to TYPE_TREE.  Sometimes the same unnamed Go type
    2719              : // can be created multiple times and thus have multiple tree
    2720              : // representations.  Make sure this does not confuse the middle-end.
    2721              : 
    2722              : tree
    2723     13310590 : Gcc_backend::convert_tree(tree type_tree, tree expr_tree, Location location)
    2724              : {
    2725     13310590 :   if (type_tree == TREE_TYPE(expr_tree))
    2726              :     return expr_tree;
    2727              : 
    2728      3356168 :   if (type_tree == error_mark_node
    2729      3356168 :       || expr_tree == error_mark_node
    2730      6712336 :       || TREE_TYPE(expr_tree) == error_mark_node)
    2731              :     return error_mark_node;
    2732              : 
    2733      3356168 :   gcc_assert(TREE_CODE(type_tree) == TREE_CODE(TREE_TYPE(expr_tree)));
    2734      3356168 :   if (POINTER_TYPE_P(type_tree)
    2735      3356168 :       || INTEGRAL_TYPE_P(type_tree)
    2736       233558 :       || SCALAR_FLOAT_TYPE_P(type_tree)
    2737      3589726 :       || COMPLEX_FLOAT_TYPE_P(type_tree))
    2738      3122612 :     return fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
    2739       233556 :   else if (TREE_CODE(type_tree) == RECORD_TYPE
    2740       233556 :            || TREE_CODE(type_tree) == ARRAY_TYPE)
    2741              :     {
    2742       233556 :       gcc_assert(int_size_in_bytes(type_tree)
    2743              :                  == int_size_in_bytes(TREE_TYPE(expr_tree)));
    2744       233556 :       if (TYPE_MAIN_VARIANT(type_tree)
    2745       233556 :           == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree)))
    2746       140587 :         return fold_build1_loc(location.gcc_location(), NOP_EXPR,
    2747       140587 :                                type_tree, expr_tree);
    2748        92969 :       return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
    2749        92969 :                              type_tree, expr_tree);
    2750              :     }
    2751              : 
    2752            0 :   gcc_unreachable();
    2753              : }
    2754              : 
    2755              : // Make a global variable.
    2756              : 
    2757              : Bvariable*
    2758        34342 : Gcc_backend::global_variable(const std::string& var_name,
    2759              :                              const std::string& asm_name,
    2760              :                              Btype* btype,
    2761              :                              unsigned int flags,
    2762              :                              Location location)
    2763              : {
    2764        34342 :   tree type_tree = btype->get_tree();
    2765        34342 :   if (type_tree == error_mark_node)
    2766            2 :     return this->error_variable();
    2767              : 
    2768              :   // The GNU linker does not like dynamic variables with zero size.
    2769        34340 :   tree orig_type_tree = type_tree;
    2770        34340 :   bool is_external = (flags & variable_is_external) != 0;
    2771        34340 :   bool is_hidden = (flags & variable_is_hidden) != 0;
    2772        34340 :   if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
    2773          410 :     type_tree = this->non_zero_size_type(type_tree);
    2774              : 
    2775        68680 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    2776              :                          get_identifier_from_string(var_name),
    2777              :                          type_tree);
    2778        34340 :   if ((flags & variable_is_external) != 0)
    2779              :     {
    2780         9045 :       DECL_EXTERNAL(decl) = 1;
    2781         9045 :       flags &=~ variable_is_external;
    2782              :     }
    2783              :   else
    2784        25295 :     TREE_STATIC(decl) = 1;
    2785              : 
    2786        34340 :   if ((flags & variable_is_hidden) == 0)
    2787        16416 :     TREE_PUBLIC(decl) = 1;
    2788              :   else
    2789        17924 :     flags &=~ variable_is_hidden;
    2790              : 
    2791        34340 :   if ((flags & variable_address_is_taken) != 0)
    2792              :     {
    2793         3542 :       TREE_ADDRESSABLE(decl) = 1;
    2794         3542 :       flags &=~ variable_address_is_taken;
    2795              :     }
    2796              : 
    2797              :   // We take the address in Bvariable::get_tree if orig_type_tree is
    2798              :   // different from type_tree.
    2799        34340 :   if (orig_type_tree != type_tree)
    2800          410 :     TREE_ADDRESSABLE(decl) = 1;
    2801              : 
    2802        68680 :   SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    2803              : 
    2804        34340 :   TREE_USED(decl) = 1;
    2805              : 
    2806        34340 :   if ((flags & variable_in_unique_section) != 0)
    2807              :     {
    2808            0 :       resolve_unique_section (decl, 0, 1);
    2809            0 :       flags &=~ variable_in_unique_section;
    2810              :     }
    2811              : 
    2812        34340 :   gcc_assert(flags == 0);
    2813              : 
    2814        34340 :   go_preserve_from_gc(decl);
    2815              : 
    2816        34340 :   return new Bvariable(decl, orig_type_tree);
    2817              : }
    2818              : 
    2819              : // Set the initial value of a global variable.
    2820              : 
    2821              : void
    2822         7290 : Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
    2823              : {
    2824         7290 :   tree expr_tree = expr->get_tree();
    2825         7290 :   if (expr_tree == error_mark_node)
    2826              :     return;
    2827         7290 :   gcc_assert(TREE_CONSTANT(expr_tree));
    2828         7290 :   tree var_decl = var->get_decl();
    2829         7290 :   if (var_decl == error_mark_node)
    2830              :     return;
    2831         7290 :   DECL_INITIAL(var_decl) = expr_tree;
    2832              : 
    2833              :   // If this variable goes in a unique section, it may need to go into
    2834              :   // a different one now that DECL_INITIAL is set.
    2835         7290 :   if (symtab_node::get(var_decl)
    2836         7290 :       && symtab_node::get(var_decl)->implicit_section)
    2837              :     {
    2838            0 :       set_decl_section_name (var_decl, (const char *) NULL);
    2839            0 :       resolve_unique_section (var_decl,
    2840              :                               compute_reloc_for_constant (expr_tree),
    2841              :                               1);
    2842              :     }
    2843              : }
    2844              : 
    2845              : // Make a local variable.
    2846              : 
    2847              : Bvariable*
    2848       645352 : Gcc_backend::local_variable(Bfunction* function, const std::string& name,
    2849              :                             Btype* btype, Bvariable* decl_var,
    2850              :                             unsigned int flags, Location location)
    2851              : {
    2852       645352 :   tree type_tree = btype->get_tree();
    2853       645352 :   if (type_tree == error_mark_node)
    2854            4 :     return this->error_variable();
    2855      1290696 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    2856              :                          get_identifier_from_string(name),
    2857              :                          type_tree);
    2858       645348 :   DECL_CONTEXT(decl) = function->get_tree();
    2859       645348 :   TREE_USED(decl) = 1;
    2860       645348 :   if ((flags & variable_address_is_taken) != 0)
    2861              :     {
    2862        25283 :       TREE_ADDRESSABLE(decl) = 1;
    2863        25283 :       flags &=~ variable_address_is_taken;
    2864              :     }
    2865       645348 :   if (decl_var != NULL)
    2866              :     {
    2867         6520 :       DECL_HAS_VALUE_EXPR_P(decl) = 1;
    2868         6520 :       SET_DECL_VALUE_EXPR(decl, decl_var->get_decl());
    2869              :     }
    2870       645348 :   go_assert(flags == 0);
    2871       645348 :   go_preserve_from_gc(decl);
    2872       645348 :   return new Bvariable(decl);
    2873              : }
    2874              : 
    2875              : // Make a function parameter variable.
    2876              : 
    2877              : Bvariable*
    2878       474160 : Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
    2879              :                                 Btype* btype, unsigned int flags,
    2880              :                                 Location location)
    2881              : {
    2882       474160 :   tree type_tree = btype->get_tree();
    2883       474160 :   if (type_tree == error_mark_node)
    2884            6 :     return this->error_variable();
    2885       948308 :   tree decl = build_decl(location.gcc_location(), PARM_DECL,
    2886              :                          get_identifier_from_string(name),
    2887              :                          type_tree);
    2888       474154 :   DECL_CONTEXT(decl) = function->get_tree();
    2889       474154 :   DECL_ARG_TYPE(decl) = type_tree;
    2890       474154 :   TREE_USED(decl) = 1;
    2891       474154 :   if ((flags & variable_address_is_taken) != 0)
    2892              :     {
    2893         8144 :       TREE_ADDRESSABLE(decl) = 1;
    2894         8144 :       flags &=~ variable_address_is_taken;
    2895              :     }
    2896       474154 :   go_assert(flags == 0);
    2897       474154 :   go_preserve_from_gc(decl);
    2898       474154 :   return new Bvariable(decl);
    2899              : }
    2900              : 
    2901              : // Make a static chain variable.
    2902              : 
    2903              : Bvariable*
    2904        14291 : Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
    2905              :                                    Btype* btype, unsigned int flags,
    2906              :                                    Location location)
    2907              : {
    2908        14291 :   tree type_tree = btype->get_tree();
    2909        14291 :   if (type_tree == error_mark_node)
    2910            1 :     return this->error_variable();
    2911        28580 :   tree decl = build_decl(location.gcc_location(), PARM_DECL,
    2912              :                          get_identifier_from_string(name), type_tree);
    2913        14290 :   tree fndecl = function->get_tree();
    2914        14290 :   DECL_CONTEXT(decl) = fndecl;
    2915        14290 :   DECL_ARG_TYPE(decl) = type_tree;
    2916        14290 :   TREE_USED(decl) = 1;
    2917        14290 :   DECL_ARTIFICIAL(decl) = 1;
    2918        14290 :   DECL_IGNORED_P(decl) = 1;
    2919        14290 :   DECL_NAMELESS(decl) = 1;
    2920        14290 :   TREE_READONLY(decl) = 1;
    2921              : 
    2922        14290 :   struct function *f = DECL_STRUCT_FUNCTION(fndecl);
    2923        14290 :   if (f == NULL)
    2924              :     {
    2925        14290 :       push_struct_function(fndecl);
    2926        14290 :       pop_cfun();
    2927        14290 :       f = DECL_STRUCT_FUNCTION(fndecl);
    2928              :     }
    2929        14290 :   gcc_assert(f->static_chain_decl == NULL);
    2930        14290 :   f->static_chain_decl = decl;
    2931        14290 :   DECL_STATIC_CHAIN(fndecl) = 1;
    2932        14290 :   go_assert(flags == 0);
    2933              : 
    2934        14290 :   go_preserve_from_gc(decl);
    2935        14290 :   return new Bvariable(decl);
    2936              : }
    2937              : 
    2938              : // Make a temporary variable.
    2939              : 
    2940              : Bvariable*
    2941      2273380 : Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
    2942              :                                 Btype* btype, Bexpression* binit,
    2943              :                                 unsigned int flags,
    2944              :                                 Location location,
    2945              :                                 Bstatement** pstatement)
    2946              : {
    2947      2273380 :   gcc_assert(function != NULL);
    2948      2273380 :   tree decl = function->get_tree();
    2949      2273380 :   tree type_tree = btype->get_tree();
    2950      2273380 :   tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
    2951      2273380 :   if (type_tree == error_mark_node
    2952      2273379 :       || init_tree == error_mark_node
    2953      2273374 :       || decl == error_mark_node)
    2954              :     {
    2955            6 :       *pstatement = this->error_statement();
    2956            6 :       return this->error_variable();
    2957              :     }
    2958              : 
    2959      2273374 :   tree var;
    2960              :   // We can only use create_tmp_var if the type is not addressable.
    2961      2273374 :   if (!TREE_ADDRESSABLE(type_tree))
    2962              :     {
    2963      2273374 :       if (DECL_STRUCT_FUNCTION(decl) == NULL)
    2964       230353 :         push_struct_function(decl);
    2965              :       else
    2966      2043021 :         push_cfun(DECL_STRUCT_FUNCTION(decl));
    2967              : 
    2968      2273374 :       var = create_tmp_var(type_tree, "GOTMP");
    2969      2273374 :       pop_cfun();
    2970              :     }
    2971              :   else
    2972              :     {
    2973            0 :       gcc_assert(bblock != NULL);
    2974            0 :       var = build_decl(location.gcc_location(), VAR_DECL,
    2975              :                        create_tmp_var_name("GOTMP"),
    2976              :                        type_tree);
    2977            0 :       DECL_ARTIFICIAL(var) = 1;
    2978            0 :       DECL_IGNORED_P(var) = 1;
    2979            0 :       DECL_NAMELESS(var) = 1;
    2980            0 :       TREE_USED(var) = 1;
    2981            0 :       DECL_CONTEXT(var) = decl;
    2982              : 
    2983              :       // We have to add this variable to the BLOCK and the BIND_EXPR.
    2984            0 :       tree bind_tree = bblock->get_tree();
    2985            0 :       gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
    2986            0 :       tree block_tree = BIND_EXPR_BLOCK(bind_tree);
    2987            0 :       gcc_assert(TREE_CODE(block_tree) == BLOCK);
    2988            0 :       DECL_CHAIN(var) = BLOCK_VARS(block_tree);
    2989            0 :       BLOCK_VARS(block_tree) = var;
    2990            0 :       BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
    2991              :     }
    2992              : 
    2993      2273374 :   if (this->type_size(btype) != 0
    2994      2269815 :       && init_tree != NULL_TREE
    2995      4321145 :       && TREE_TYPE(init_tree) != void_type_node)
    2996      2047770 :     DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location);
    2997              : 
    2998      2273374 :   if ((flags & variable_address_is_taken) != 0)
    2999              :     {
    3000       413098 :       TREE_ADDRESSABLE(var) = 1;
    3001       413098 :       flags &=~ variable_address_is_taken;
    3002              :     }
    3003              : 
    3004      2273374 :   gcc_assert(flags == 0);
    3005              : 
    3006      2273374 :   *pstatement = this->make_statement(build1_loc(location.gcc_location(),
    3007              :                                                 DECL_EXPR,
    3008              :                                                 void_type_node, var));
    3009              : 
    3010              :   // For a zero sized type, don't initialize VAR with BINIT, but still
    3011              :   // evaluate BINIT for its side effects.
    3012      2273374 :   if (init_tree != NULL_TREE
    3013      2273374 :       && (this->type_size(btype) == 0
    3014      2047771 :           || TREE_TYPE(init_tree) == void_type_node))
    3015         1372 :     *pstatement =
    3016         1372 :       this->compound_statement(this->expression_statement(function, binit),
    3017              :                                *pstatement);
    3018              : 
    3019      2273374 :   return new Bvariable(var);
    3020              : }
    3021              : 
    3022              : // Create an implicit variable that is compiler-defined.  This is used when
    3023              : // generating GC root variables and storing the values of a slice initializer.
    3024              : 
    3025              : Bvariable*
    3026       334170 : Gcc_backend::implicit_variable(const std::string& name,
    3027              :                                const std::string& asm_name,
    3028              :                                Btype* type, unsigned int flags,
    3029              :                                int64_t alignment)
    3030              : {
    3031       334170 :   tree type_tree = type->get_tree();
    3032       334170 :   if (type_tree == error_mark_node)
    3033            0 :     return this->error_variable();
    3034              : 
    3035       668340 :   tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
    3036              :                          get_identifier_from_string(name), type_tree);
    3037       334170 :   DECL_EXTERNAL(decl) = 0;
    3038       334170 :   if ((flags & variable_is_hidden) != 0)
    3039       305894 :     flags &=~ variable_is_hidden;
    3040              :   else
    3041        28276 :     TREE_PUBLIC(decl) = 1;
    3042       334170 :   TREE_STATIC(decl) = 1;
    3043       334170 :   TREE_USED(decl) = 1;
    3044       334170 :   DECL_ARTIFICIAL(decl) = 1;
    3045       334170 :   if ((flags & variable_is_common) != 0)
    3046              :     {
    3047        23630 :       DECL_COMMON(decl) = 1;
    3048              : 
    3049              :       // When the initializer for one implicit_variable refers to another,
    3050              :       // it needs to know the visibility of the referenced struct so that
    3051              :       // compute_reloc_for_constant will return the right value.  On many
    3052              :       // systems calling make_decl_one_only will mark the decl as weak,
    3053              :       // which will change the return value of compute_reloc_for_constant.
    3054              :       // We can't reliably call make_decl_one_only yet, because we don't
    3055              :       // yet know the initializer.  This issue doesn't arise in C because
    3056              :       // Go initializers, unlike C initializers, can be indirectly
    3057              :       // recursive.  To ensure that compute_reloc_for_constant computes
    3058              :       // the right value if some other initializer refers to this one, we
    3059              :       // mark this symbol as weak here.  We undo that below in
    3060              :       // immutable_struct_set_init before calling mark_decl_one_only.
    3061        23630 :       DECL_WEAK(decl) = 1;
    3062              : 
    3063        23630 :       flags &=~ variable_is_common;
    3064              :     }
    3065       334170 :   if ((flags & variable_is_constant) != 0)
    3066              :     {
    3067       323193 :       TREE_READONLY(decl) = 1;
    3068       323193 :       TREE_CONSTANT(decl) = 1;
    3069       323193 :       flags &=~ variable_is_constant;
    3070              :     }
    3071       334170 :   if ((flags & variable_address_is_taken) != 0)
    3072              :     {
    3073       303971 :       TREE_ADDRESSABLE(decl) = 1;
    3074       303971 :       flags &=~ variable_address_is_taken;
    3075              :     }
    3076       334170 :   if (alignment != 0)
    3077              :     {
    3078            3 :       SET_DECL_ALIGN(decl, alignment * BITS_PER_UNIT);
    3079            3 :       DECL_USER_ALIGN(decl) = 1;
    3080              :     }
    3081       334170 :   if (! asm_name.empty())
    3082        13070 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3083       334170 :   gcc_assert(flags == 0);
    3084              : 
    3085       334170 :   go_preserve_from_gc(decl);
    3086       334170 :   return new Bvariable(decl);
    3087              : }
    3088              : 
    3089              : // Set the initalizer for a variable created by implicit_variable.
    3090              : // This is where we finish compiling the variable.
    3091              : 
    3092              : void
    3093       334170 : Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
    3094              :                                         Btype*, unsigned int flags,
    3095              :                                         Bexpression* init)
    3096              : {
    3097       334170 :   tree decl = var->get_decl();
    3098       334170 :   tree init_tree;
    3099       334170 :   if (init == NULL)
    3100              :     init_tree = NULL_TREE;
    3101              :   else
    3102       334167 :     init_tree = init->get_tree();
    3103       334170 :   if (decl == error_mark_node || init_tree == error_mark_node)
    3104              :     return;
    3105              : 
    3106       334168 :   DECL_INITIAL(decl) = init_tree;
    3107              : 
    3108              :   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
    3109              :   // See the comment where DECL_WEAK is set in implicit_variable.
    3110       334168 :   if ((flags & variable_is_common) != 0)
    3111              :     {
    3112        23630 :       DECL_WEAK(decl) = 0;
    3113        23630 :       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
    3114              :     }
    3115              : 
    3116       334168 :   resolve_unique_section(decl, 2, 1);
    3117              : 
    3118       334168 :   rest_of_decl_compilation(decl, 1, 0);
    3119              : }
    3120              : 
    3121              : // Return a reference to an implicit variable defined in another package.
    3122              : 
    3123              : Bvariable*
    3124        64317 : Gcc_backend::implicit_variable_reference(const std::string& name,
    3125              :                                          const std::string& asm_name,
    3126              :                                          Btype* btype)
    3127              : {
    3128        64317 :   tree type_tree = btype->get_tree();
    3129        64317 :   if (type_tree == error_mark_node)
    3130            0 :     return this->error_variable();
    3131              : 
    3132       128634 :   tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
    3133              :                          get_identifier_from_string(name), type_tree);
    3134        64317 :   DECL_EXTERNAL(decl) = 1;
    3135        64317 :   TREE_PUBLIC(decl) = 1;
    3136        64317 :   TREE_STATIC(decl) = 0;
    3137        64317 :   DECL_ARTIFICIAL(decl) = 1;
    3138        64317 :   if (! asm_name.empty())
    3139       128634 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3140        64317 :   go_preserve_from_gc(decl);
    3141        64317 :   return new Bvariable(decl);
    3142              : }
    3143              : 
    3144              : // Create a named immutable initialized data structure.
    3145              : 
    3146              : Bvariable*
    3147      1128959 : Gcc_backend::immutable_struct(const std::string& name,
    3148              :                               const std::string& asm_name,
    3149              :                               unsigned int flags, Btype* btype,
    3150              :                               Location location)
    3151              : {
    3152      1128959 :   tree type_tree = btype->get_tree();
    3153      1128959 :   if (type_tree == error_mark_node)
    3154            5 :     return this->error_variable();
    3155      1128954 :   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
    3156      2257908 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    3157              :                          get_identifier_from_string(name),
    3158              :                          build_qualified_type(type_tree, TYPE_QUAL_CONST));
    3159      1128954 :   TREE_STATIC(decl) = 1;
    3160      1128954 :   TREE_USED(decl) = 1;
    3161      1128954 :   TREE_READONLY(decl) = 1;
    3162      1128954 :   TREE_CONSTANT(decl) = 1;
    3163      1128954 :   DECL_ARTIFICIAL(decl) = 1;
    3164      1128954 :   if ((flags & variable_is_hidden) != 0)
    3165       754193 :     flags &=~ variable_is_hidden;
    3166              :   else
    3167       374761 :     TREE_PUBLIC(decl) = 1;
    3168      1128954 :   if (! asm_name.empty())
    3169       484850 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3170      1128954 :   if ((flags & variable_address_is_taken) != 0)
    3171              :     {
    3172       707362 :       TREE_ADDRESSABLE(decl) = 1;
    3173       707362 :       flags &=~ variable_address_is_taken;
    3174              :     }
    3175              : 
    3176              :   // When the initializer for one immutable_struct refers to another,
    3177              :   // it needs to know the visibility of the referenced struct so that
    3178              :   // compute_reloc_for_constant will return the right value.  On many
    3179              :   // systems calling make_decl_one_only will mark the decl as weak,
    3180              :   // which will change the return value of compute_reloc_for_constant.
    3181              :   // We can't reliably call make_decl_one_only yet, because we don't
    3182              :   // yet know the initializer.  This issue doesn't arise in C because
    3183              :   // Go initializers, unlike C initializers, can be indirectly
    3184              :   // recursive.  To ensure that compute_reloc_for_constant computes
    3185              :   // the right value if some other initializer refers to this one, we
    3186              :   // mark this symbol as weak here.  We undo that below in
    3187              :   // immutable_struct_set_init before calling mark_decl_one_only.
    3188      1128954 :   if ((flags & variable_is_common) != 0)
    3189              :     {
    3190       215187 :       DECL_WEAK(decl) = 1;
    3191       215187 :       flags &=~ variable_is_common;
    3192              :     }
    3193              : 
    3194      1128954 :   gcc_assert(flags == 0);
    3195              : 
    3196              :   // We don't call rest_of_decl_compilation until we have the
    3197              :   // initializer.
    3198              : 
    3199      1128954 :   go_preserve_from_gc(decl);
    3200      1128954 :   return new Bvariable(decl);
    3201              : }
    3202              : 
    3203              : // Set the initializer for a variable created by immutable_struct.
    3204              : // This is where we finish compiling the variable.
    3205              : 
    3206              : void
    3207      1128959 : Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
    3208              :                                        unsigned int flags, Btype*, Location,
    3209              :                                        Bexpression* initializer)
    3210              : {
    3211      1128959 :   tree decl = var->get_decl();
    3212      1128959 :   tree init_tree = initializer->get_tree();
    3213      1128959 :   if (decl == error_mark_node || init_tree == error_mark_node)
    3214              :     return;
    3215              : 
    3216      1128953 :   DECL_INITIAL(decl) = init_tree;
    3217              : 
    3218              :   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
    3219              :   // See the comment where DECL_WEAK is set in immutable_struct.
    3220      1128953 :   if ((flags & variable_is_common) != 0)
    3221              :     {
    3222       215186 :       DECL_WEAK(decl) = 0;
    3223       215186 :       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
    3224              :     }
    3225              : 
    3226              :   // These variables are often unneeded in the final program, so put
    3227              :   // them in their own section so that linker GC can discard them.
    3228      1128953 :   resolve_unique_section(decl,
    3229              :                          compute_reloc_for_constant (init_tree),
    3230              :                          1);
    3231              : 
    3232      1128953 :   rest_of_decl_compilation(decl, 1, 0);
    3233              : }
    3234              : 
    3235              : // Return a reference to an immutable initialized data structure
    3236              : // defined in another package.
    3237              : 
    3238              : Bvariable*
    3239       188968 : Gcc_backend::immutable_struct_reference(const std::string& name,
    3240              :                                         const std::string& asm_name,
    3241              :                                         Btype* btype,
    3242              :                                         Location location)
    3243              : {
    3244       188968 :   tree type_tree = btype->get_tree();
    3245       188968 :   if (type_tree == error_mark_node)
    3246            0 :     return this->error_variable();
    3247       188968 :   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
    3248       377936 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    3249              :                          get_identifier_from_string(name),
    3250              :                          build_qualified_type(type_tree, TYPE_QUAL_CONST));
    3251       188968 :   TREE_READONLY(decl) = 1;
    3252       188968 :   TREE_CONSTANT(decl) = 1;
    3253       188968 :   DECL_ARTIFICIAL(decl) = 1;
    3254       188968 :   TREE_PUBLIC(decl) = 1;
    3255       188968 :   DECL_EXTERNAL(decl) = 1;
    3256       188968 :   if (! asm_name.empty())
    3257        69060 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3258       188968 :   go_preserve_from_gc(decl);
    3259       188968 :   return new Bvariable(decl);
    3260              : }
    3261              : 
    3262              : // Make a label.
    3263              : 
    3264              : Blabel*
    3265       193164 : Gcc_backend::label(Bfunction* function, const std::string& name,
    3266              :                    Location location)
    3267              : {
    3268       193164 :   tree decl;
    3269       193164 :   if (name.empty())
    3270              :     {
    3271       182752 :       tree func_tree = function->get_tree();
    3272       182752 :       if (DECL_STRUCT_FUNCTION(func_tree) == NULL)
    3273         8399 :         push_struct_function(func_tree);
    3274              :       else
    3275       174353 :         push_cfun(DECL_STRUCT_FUNCTION(func_tree));
    3276              : 
    3277       182752 :       decl = create_artificial_label(location.gcc_location());
    3278              : 
    3279       182752 :       pop_cfun();
    3280              :     }
    3281              :   else
    3282              :     {
    3283        10412 :       tree id = get_identifier_from_string(name);
    3284        10412 :       decl = build_decl(location.gcc_location(), LABEL_DECL, id,
    3285              :                         void_type_node);
    3286        10412 :       DECL_CONTEXT(decl) = function->get_tree();
    3287              :     }
    3288       193164 :   return new Blabel(decl);
    3289              : }
    3290              : 
    3291              : // Make a statement which defines a label.
    3292              : 
    3293              : Bstatement*
    3294       193164 : Gcc_backend::label_definition_statement(Blabel* label)
    3295              : {
    3296       193164 :   tree lab = label->get_tree();
    3297       193164 :   tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
    3298              :                              void_type_node, lab);
    3299       193164 :   return this->make_statement(ret);
    3300              : }
    3301              : 
    3302              : // Make a goto statement.
    3303              : 
    3304              : Bstatement*
    3305       242991 : Gcc_backend::goto_statement(Blabel* label, Location location)
    3306              : {
    3307       242991 :   tree lab = label->get_tree();
    3308       242991 :   tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
    3309              :                              lab);
    3310       242991 :   return this->make_statement(ret);
    3311              : }
    3312              : 
    3313              : // Get the address of a label.
    3314              : 
    3315              : Bexpression*
    3316         8840 : Gcc_backend::label_address(Blabel* label, Location location)
    3317              : {
    3318         8840 :   tree lab = label->get_tree();
    3319         8840 :   TREE_USED(lab) = 1;
    3320         8840 :   TREE_ADDRESSABLE(lab) = 1;
    3321         8840 :   tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
    3322              :                               build_fold_addr_expr_loc(location.gcc_location(),
    3323              :                                                        lab));
    3324         8840 :   return this->make_expression(ret);
    3325              : }
    3326              : 
    3327              : // Declare or define a new function.
    3328              : 
    3329              : Bfunction*
    3330       611445 : Gcc_backend::function(Btype* fntype, const std::string& name,
    3331              :                       const std::string& asm_name, unsigned int flags,
    3332              :                       Location location)
    3333              : {
    3334       611445 :   tree functype = fntype->get_tree();
    3335       611445 :   if (functype != error_mark_node)
    3336              :     {
    3337       611431 :       gcc_assert(FUNCTION_POINTER_TYPE_P(functype));
    3338       611431 :       functype = TREE_TYPE(functype);
    3339              :     }
    3340       611445 :   tree id = get_identifier_from_string(name);
    3341       611445 :   if (functype == error_mark_node || id == error_mark_node)
    3342           14 :     return this->error_function();
    3343              : 
    3344       611431 :   tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype);
    3345       611431 :   if (! asm_name.empty())
    3346       447520 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3347       611431 :   if ((flags & function_is_visible) != 0)
    3348       528198 :     TREE_PUBLIC(decl) = 1;
    3349       611431 :   if ((flags & function_is_declaration) != 0)
    3350       312498 :     DECL_EXTERNAL(decl) = 1;
    3351              :   else
    3352              :     {
    3353       298933 :       tree restype = TREE_TYPE(functype);
    3354       298933 :       tree resdecl =
    3355       298933 :           build_decl(location.gcc_location(), RESULT_DECL, NULL_TREE, restype);
    3356       298933 :       DECL_ARTIFICIAL(resdecl) = 1;
    3357       298933 :       DECL_IGNORED_P(resdecl) = 1;
    3358       298933 :       DECL_NAMELESS(resdecl) = 1;
    3359       298933 :       DECL_CONTEXT(resdecl) = decl;
    3360       298933 :       DECL_RESULT(decl) = resdecl;
    3361              :     }
    3362       611431 :   if ((flags & function_is_inlinable) == 0)
    3363        10863 :     DECL_UNINLINABLE(decl) = 1;
    3364       611431 :   if ((flags & function_no_split_stack) != 0)
    3365              :     {
    3366         2264 :       tree attr = get_identifier ("no_split_stack");
    3367         2264 :       DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
    3368              :     }
    3369       611431 :   if ((flags & function_does_not_return) != 0)
    3370        16108 :     TREE_THIS_VOLATILE(decl) = 1;
    3371       611431 :   if ((flags & function_in_unique_section) != 0)
    3372            3 :     resolve_unique_section(decl, 0, 1);
    3373       611431 :   if ((flags & function_only_inline) != 0)
    3374              :     {
    3375        12247 :       TREE_PUBLIC (decl) = 1;
    3376        12247 :       DECL_EXTERNAL(decl) = 1;
    3377        12247 :       DECL_DECLARED_INLINE_P(decl) = 1;
    3378              :     }
    3379              : 
    3380              :   // Optimize thunk functions for size.  A thunk created for a defer
    3381              :   // statement that may call recover looks like:
    3382              :   //     if runtime.setdeferretaddr(L1) {
    3383              :   //         goto L1
    3384              :   //     }
    3385              :   //     realfn()
    3386              :   // L1:
    3387              :   // The idea is that L1 should be the address to which realfn
    3388              :   // returns.  This only works if this little function is not over
    3389              :   // optimized.  At some point GCC started duplicating the epilogue in
    3390              :   // the basic-block reordering pass, breaking this assumption.
    3391              :   // Optimizing the function for size avoids duplicating the epilogue.
    3392              :   // This optimization shouldn't matter for any thunk since all thunks
    3393              :   // are small.
    3394       611431 :   size_t pos = name.find("..thunk");
    3395       611431 :   if (pos != std::string::npos)
    3396              :     {
    3397        44954 :       for (pos += 7; pos < name.length(); ++pos)
    3398              :         {
    3399        30007 :           if (name[pos] < '0' || name[pos] > '9')
    3400              :             break;
    3401              :         }
    3402        14947 :       if (pos == name.length())
    3403              :         {
    3404        14947 :           struct cl_optimization cur_opts;
    3405        14947 :           cl_optimization_save(&cur_opts, &global_options,
    3406              :                                &global_options_set);
    3407        14947 :           global_options.x_optimize_size = 1;
    3408        14947 :           global_options.x_optimize_fast = 0;
    3409        14947 :           global_options.x_optimize_debug = 0;
    3410        29894 :           DECL_FUNCTION_SPECIFIC_OPTIMIZATION(decl) =
    3411        14947 :             build_optimization_node(&global_options, &global_options_set);
    3412        14947 :           cl_optimization_restore(&global_options, &global_options_set,
    3413              :                                   &cur_opts);
    3414              :         }
    3415              :     }
    3416              : 
    3417       611431 :   go_preserve_from_gc(decl);
    3418       611431 :   return new Bfunction(decl);
    3419              : }
    3420              : 
    3421              : // Create a statement that runs all deferred calls for FUNCTION.  This should
    3422              : // be a statement that looks like this in C++:
    3423              : //   finish:
    3424              : //     try { UNDEFER; } catch { CHECK_DEFER; goto finish; }
    3425              : 
    3426              : Bstatement*
    3427         8353 : Gcc_backend::function_defer_statement(Bfunction* function, Bexpression* undefer,
    3428              :                                       Bexpression* defer, Location location)
    3429              : {
    3430         8353 :   tree undefer_tree = undefer->get_tree();
    3431         8353 :   tree defer_tree = defer->get_tree();
    3432         8353 :   tree fntree = function->get_tree();
    3433              : 
    3434         8353 :   if (undefer_tree == error_mark_node
    3435         8353 :       || defer_tree == error_mark_node
    3436         8353 :       || fntree == error_mark_node)
    3437            0 :     return this->error_statement();
    3438              : 
    3439         8353 :   if (DECL_STRUCT_FUNCTION(fntree) == NULL)
    3440            0 :     push_struct_function(fntree);
    3441              :   else
    3442         8353 :     push_cfun(DECL_STRUCT_FUNCTION(fntree));
    3443              : 
    3444         8353 :   tree stmt_list = NULL;
    3445         8353 :   Blabel* blabel = this->label(function, "", location);
    3446         8353 :   Bstatement* label_def = this->label_definition_statement(blabel);
    3447         8353 :   append_to_statement_list(label_def->get_tree(), &stmt_list);
    3448              : 
    3449         8353 :   Bstatement* jump_stmt = this->goto_statement(blabel, location);
    3450         8353 :   tree jump = jump_stmt->get_tree();
    3451         8353 :   tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer_tree, jump);
    3452         8353 :   catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body);
    3453         8353 :   tree try_catch =
    3454         8353 :       build2(TRY_CATCH_EXPR, void_type_node, undefer_tree, catch_body);
    3455         8353 :   append_to_statement_list(try_catch, &stmt_list);
    3456         8353 :   pop_cfun();
    3457              : 
    3458         8353 :   return this->make_statement(stmt_list);
    3459              : }
    3460              : 
    3461              : // Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
    3462              : // This will only be called for a function definition.
    3463              : 
    3464              : bool
    3465       295494 : Gcc_backend::function_set_parameters(Bfunction* function,
    3466              :                                      const std::vector<Bvariable*>& param_vars)
    3467              : {
    3468       295494 :   tree func_tree = function->get_tree();
    3469       295494 :   if (func_tree == error_mark_node)
    3470              :     return false;
    3471              : 
    3472       295480 :   tree params = NULL_TREE;
    3473       295480 :   tree *pp = &params;
    3474       295480 :   for (std::vector<Bvariable*>::const_iterator pv = param_vars.begin();
    3475       769631 :        pv != param_vars.end();
    3476       474151 :        ++pv)
    3477              :     {
    3478       474151 :       *pp = (*pv)->get_decl();
    3479       474151 :       gcc_assert(*pp != error_mark_node);
    3480       474151 :       pp = &DECL_CHAIN(*pp);
    3481              :     }
    3482       295480 :   *pp = NULL_TREE;
    3483       295480 :   DECL_ARGUMENTS(func_tree) = params;
    3484       295480 :   return true;
    3485              : }
    3486              : 
    3487              : // Set the function body for FUNCTION using the code in CODE_BLOCK.
    3488              : 
    3489              : bool
    3490       298929 : Gcc_backend::function_set_body(Bfunction* function, Bstatement* code_stmt)
    3491              : {
    3492       298929 :   tree func_tree = function->get_tree();
    3493       298929 :   tree code = code_stmt->get_tree();
    3494              : 
    3495       298929 :   if (func_tree == error_mark_node || code == error_mark_node)
    3496              :     return false;
    3497       298888 :   DECL_SAVED_TREE(func_tree) = code;
    3498       298888 :   return true;
    3499              : }
    3500              : 
    3501              : // Look up a named built-in function in the current backend implementation.
    3502              : // Returns NULL if no built-in function by that name exists.
    3503              : 
    3504              : Bfunction*
    3505       130264 : Gcc_backend::lookup_builtin(const std::string& name)
    3506              : {
    3507       130264 :   if (this->builtin_functions_.count(name) != 0)
    3508         5835 :     return this->builtin_functions_[name];
    3509              :   return NULL;
    3510              : }
    3511              : 
    3512              : // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
    3513              : // FUNCTION_DECLS, and VARIABLE_DECLS declared globally, as well as
    3514              : // emit early debugging information.
    3515              : 
    3516              : void
    3517         4217 : Gcc_backend::write_global_definitions(
    3518              :     const std::vector<Btype*>& type_decls,
    3519              :     const std::vector<Bexpression*>& constant_decls,
    3520              :     const std::vector<Bfunction*>& function_decls,
    3521              :     const std::vector<Bvariable*>& variable_decls)
    3522              : {
    3523         4217 :   size_t count_definitions = type_decls.size() + constant_decls.size()
    3524         4217 :       + function_decls.size() + variable_decls.size();
    3525              : 
    3526         4217 :   tree* defs = new tree[count_definitions];
    3527              : 
    3528              :   // Convert all non-erroneous declarations into Gimple form.
    3529         4217 :   size_t i = 0;
    3530        28705 :   for (std::vector<Bvariable*>::const_iterator p = variable_decls.begin();
    3531        28705 :        p != variable_decls.end();
    3532        24488 :        ++p)
    3533              :     {
    3534        24488 :       tree v = (*p)->get_decl();
    3535        24488 :       if (v != error_mark_node)
    3536              :         {
    3537        24488 :           defs[i] = v;
    3538        24488 :           go_preserve_from_gc(defs[i]);
    3539        24488 :           ++i;
    3540              :         }
    3541              :     }
    3542              : 
    3543        33783 :   for (std::vector<Btype*>::const_iterator p = type_decls.begin();
    3544        33783 :        p != type_decls.end();
    3545        29566 :        ++p)
    3546              :     {
    3547        29566 :       tree type_tree = (*p)->get_tree();
    3548        29566 :       if (type_tree != error_mark_node
    3549        29566 :           && IS_TYPE_OR_DECL_P(type_tree))
    3550              :         {
    3551        29566 :           defs[i] = TYPE_NAME(type_tree);
    3552        29566 :           gcc_assert(defs[i] != NULL);
    3553        29566 :           go_preserve_from_gc(defs[i]);
    3554        29566 :           ++i;
    3555              :         }
    3556              :     }
    3557        27550 :   for (std::vector<Bexpression*>::const_iterator p = constant_decls.begin();
    3558        27550 :        p != constant_decls.end();
    3559        23333 :        ++p)
    3560              :     {
    3561        23333 :       if ((*p)->get_tree() != error_mark_node)
    3562              :         {
    3563        23333 :           defs[i] = (*p)->get_tree();
    3564        23333 :           go_preserve_from_gc(defs[i]);
    3565        23333 :           ++i;
    3566              :         }
    3567              :     }
    3568       294738 :   for (std::vector<Bfunction*>::const_iterator p = function_decls.begin();
    3569       294738 :        p != function_decls.end();
    3570       290521 :        ++p)
    3571              :     {
    3572       290521 :       tree decl = (*p)->get_tree();
    3573       290521 :       if (decl != error_mark_node)
    3574              :         {
    3575       290521 :           go_preserve_from_gc(decl);
    3576       290521 :           if (DECL_STRUCT_FUNCTION(decl) == NULL)
    3577        44364 :             allocate_struct_function(decl, false);
    3578       290521 :           cgraph_node::finalize_function(decl, true);
    3579              : 
    3580       290521 :           defs[i] = decl;
    3581       290521 :           ++i;
    3582              :         }
    3583              :     }
    3584              : 
    3585              :   // Pass everything back to the middle-end.
    3586              : 
    3587         4217 :   wrapup_global_declarations(defs, i);
    3588              : 
    3589         4217 :   delete[] defs;
    3590         4217 : }
    3591              : 
    3592              : void
    3593      7159500 : Gcc_backend::write_export_data(const char* bytes, unsigned int size)
    3594              : {
    3595      7159500 :   go_write_export_data(bytes, size);
    3596      7159500 : }
    3597              : 
    3598              : 
    3599              : // Define a builtin function.  BCODE is the builtin function code
    3600              : // defined by builtins.def.  NAME is the name of the builtin function.
    3601              : // LIBNAME is the name of the corresponding library function, and is
    3602              : // NULL if there isn't one.  FNTYPE is the type of the function.
    3603              : // FLAGS are the attributes to add, a bitset of builtin_xxx consts.
    3604              : 
    3605              : void
    3606       385618 : Gcc_backend::define_builtin(built_in_function bcode, const char* name,
    3607              :                             const char* libname, tree fntype, int flags)
    3608              : {
    3609       385618 :   tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL,
    3610              :                                    libname, NULL_TREE);
    3611       385618 :   this->set_attributes(decl, flags);
    3612       385618 :   set_builtin_decl(bcode, decl, true);
    3613       385618 :   this->builtin_functions_[name] = this->make_function(decl);
    3614       385618 :   if (libname != NULL)
    3615              :     {
    3616       250884 :       decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL,
    3617              :                                   NULL, NULL_TREE);
    3618       250884 :       this->set_attributes(decl, flags);
    3619       250884 :       this->builtin_functions_[libname] = this->make_function(decl);
    3620              :     }
    3621       385618 : }
    3622              : 
    3623              : // Set the attributes of DECL based on FLAGS.
    3624              : 
    3625              : void
    3626       636502 : Gcc_backend::set_attributes(tree decl, int flags)
    3627              : {
    3628       636502 :   if ((flags & builtin_const) != 0)
    3629       483184 :     TREE_READONLY(decl) = 1;
    3630       636502 :   if ((flags & builtin_pure) != 0)
    3631         9292 :     DECL_PURE_P(decl) = 1;
    3632       636502 :   if ((flags & builtin_nothrow) != 0)
    3633       144026 :     TREE_NOTHROW (decl) = 1;
    3634       636502 :   if ((flags & builtin_noreturn) != 0)
    3635         9292 :     TREE_THIS_VOLATILE(decl) = 1;
    3636       636502 :   if ((flags & builtin_novops) != 0)
    3637         4646 :     DECL_IS_NOVOPS(decl) = 1;
    3638       636502 :   if ((flags & builtin_leaf) != 0)
    3639       232300 :     DECL_ATTRIBUTES(decl) = tree_cons(get_identifier("leaf"), NULL_TREE,
    3640       232300 :                                       DECL_ATTRIBUTES(decl));
    3641       636502 :   if ((flags & builtin_nonnull) != 0)
    3642        27876 :     DECL_ATTRIBUTES(decl) = tree_cons(get_identifier("nonnull"), NULL_TREE,
    3643        27876 :                                       DECL_ATTRIBUTES(decl));
    3644       636502 :   if ((flags & builtin_cold) != 0)
    3645         9292 :     DECL_ATTRIBUTES(decl) = tree_cons(get_identifier("cold"), NULL_TREE,
    3646         9292 :                                       DECL_ATTRIBUTES(decl));
    3647       636502 : }
    3648              : 
    3649              : // Return the backend generator.
    3650              : 
    3651              : Backend*
    3652         4646 : go_get_backend()
    3653              : {
    3654         4646 :   return new Gcc_backend();
    3655              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.