LCOV - code coverage report
Current view: top level - gcc/go - go-gcc.cc (source / functions) Hit Total Coverage
Test: gcc.info Lines: 1442 1518 95.0 %
Date: 2020-03-28 11:57:23 Functions: 97 98 99.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // go-gcc.cc -- Go frontend to gcc IR.
       2                 :            : // Copyright (C) 2011-2020 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                 :   62533300 :   Gcc_tree(tree t)
      58                 :   62533300 :     : t_(t)
      59                 :            :   { }
      60                 :            : 
      61                 :            :   tree
      62                 :  116290000 :   get_tree() const
      63                 :     614308 :   { return this->t_; }
      64                 :            : 
      65                 :            :   void
      66                 :          1 :   set_tree(tree t)
      67                 :          1 :   { 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                 :    4823330 :   Btype(tree t)
      78                 :    4823330 :     : Gcc_tree(t)
      79                 :            :   { }
      80                 :            : };
      81                 :            : 
      82                 :            : class Bexpression : public Gcc_tree
      83                 :            : {
      84                 :            :  public:
      85                 :   45772900 :   Bexpression(tree t)
      86                 :   45772900 :     : Gcc_tree(t)
      87                 :            :   { }
      88                 :            : };
      89                 :            : 
      90                 :            : class Bstatement : public Gcc_tree
      91                 :            : {
      92                 :            :  public:
      93                 :    8454440 :   Bstatement(tree t)
      94                 :    8454440 :     : Gcc_tree(t)
      95                 :            :   { }
      96                 :            : };
      97                 :            : 
      98                 :            : class Bfunction : public Gcc_tree
      99                 :            : {
     100                 :            :  public:
     101                 :     915827 :   Bfunction(tree t)
     102                 :     915827 :     : Gcc_tree(t)
     103                 :            :   { }
     104                 :            : };
     105                 :            : 
     106                 :            : class Bblock : public Gcc_tree
     107                 :            : {
     108                 :            :  public:
     109                 :    2401530 :   Bblock(tree t)
     110                 :    2401530 :     : Gcc_tree(t)
     111                 :            :   { }
     112                 :            : };
     113                 :            : 
     114                 :            : class Blabel : public Gcc_tree
     115                 :            : {
     116                 :            :  public:
     117                 :     165287 :   Blabel(tree t)
     118                 :     165287 :     : 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                 :    4505160 :   Bvariable(tree t)
     135                 :    4505160 :     : t_(t), orig_type_(NULL)
     136                 :            :   { }
     137                 :            : 
     138                 :      30096 :   Bvariable(tree t, tree orig_type)
     139                 :      30096 :     : 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                 :    2722530 :   get_decl() const
     149                 :    2722530 :   { 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                 :   10404100 : Bvariable::get_tree(Location location) const
     161                 :            : {
     162                 :   10404100 :   if (this->orig_type_ == NULL
     163                 :     404623 :       || this->t_ == error_mark_node
     164                 :   10808700 :       || TREE_TYPE(this->t_) == this->orig_type_)
     165                 :   10402200 :     return this->t_;
     166                 :            :   // Return *(orig_type*)&decl.  */
     167                 :       1957 :   tree t = build_fold_addr_expr_loc(location.gcc_location(), this->t_);
     168                 :       1957 :   t = fold_build1_loc(location.gcc_location(), NOP_EXPR,
     169                 :       1957 :                       build_pointer_type(this->orig_type_), t);
     170                 :       1957 :   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                 :         77 :   error_type()
     188                 :        154 :   { return this->make_type(error_mark_node); }
     189                 :            : 
     190                 :            :   Btype*
     191                 :       6039 :   void_type()
     192                 :      12078 :   { return this->make_type(void_type_node); }
     193                 :            : 
     194                 :            :   Btype*
     195                 :       6543 :   bool_type()
     196                 :      13086 :   { 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                 :       3589 :   error_expression()
     273                 :       7178 :   { return this->make_expression(error_mark_node); }
     274                 :            : 
     275                 :            :   Bexpression*
     276                 :    1043170 :   nil_pointer_expression()
     277                 :    2086340 :   { 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                 :        547 :   error_statement()
     360                 :       1094 :   { 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                 :        101 :   error_variable()
     412                 :        101 :   { 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                 :            :                   bool is_external,
     419                 :            :                   bool is_hidden,
     420                 :            :                   bool in_unique_section,
     421                 :            :                   Location location);
     422                 :            : 
     423                 :            :   void
     424                 :            :   global_variable_set_init(Bvariable*, Bexpression*);
     425                 :            : 
     426                 :            :   Bvariable*
     427                 :            :   local_variable(Bfunction*, const std::string&, Btype*, Bvariable*, bool,
     428                 :            :                  Location);
     429                 :            : 
     430                 :            :   Bvariable*
     431                 :            :   parameter_variable(Bfunction*, const std::string&, Btype*, bool,
     432                 :            :                      Location);
     433                 :            : 
     434                 :            :   Bvariable*
     435                 :            :   static_chain_variable(Bfunction*, const std::string&, Btype*, Location);
     436                 :            : 
     437                 :            :   Bvariable*
     438                 :            :   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
     439                 :            :                      Location, Bstatement**);
     440                 :            : 
     441                 :            :   Bvariable*
     442                 :            :   implicit_variable(const std::string&, const std::string&, Btype*,
     443                 :            :                     bool, bool, bool, int64_t);
     444                 :            : 
     445                 :            :   void
     446                 :            :   implicit_variable_set_init(Bvariable*, const std::string&, Btype*,
     447                 :            :                              bool, bool, bool, Bexpression*);
     448                 :            : 
     449                 :            :   Bvariable*
     450                 :            :   implicit_variable_reference(const std::string&, const std::string&, Btype*);
     451                 :            : 
     452                 :            :   Bvariable*
     453                 :            :   immutable_struct(const std::string&, const std::string&,
     454                 :            :                    bool, bool, Btype*, Location);
     455                 :            : 
     456                 :            :   void
     457                 :            :   immutable_struct_set_init(Bvariable*, const std::string&, bool, bool, Btype*,
     458                 :            :                             Location, Bexpression*);
     459                 :            : 
     460                 :            :   Bvariable*
     461                 :            :   immutable_struct_reference(const std::string&, const std::string&,
     462                 :            :                              Btype*, Location);
     463                 :            : 
     464                 :            :   // Labels.
     465                 :            : 
     466                 :            :   Blabel*
     467                 :            :   label(Bfunction*, const std::string& name, Location);
     468                 :            : 
     469                 :            :   Bstatement*
     470                 :            :   label_definition_statement(Blabel*);
     471                 :            : 
     472                 :            :   Bstatement*
     473                 :            :   goto_statement(Blabel*, Location);
     474                 :            : 
     475                 :            :   Bexpression*
     476                 :            :   label_address(Blabel*, Location);
     477                 :            : 
     478                 :            :   // Functions.
     479                 :            : 
     480                 :            :   Bfunction*
     481                 :         12 :   error_function()
     482                 :         24 :   { return this->make_function(error_mark_node); }
     483                 :            : 
     484                 :            :   Bfunction*
     485                 :            :   function(Btype* fntype, const std::string& name, const std::string& asm_name,
     486                 :            :            unsigned int flags, Location);
     487                 :            : 
     488                 :            :   Bstatement*
     489                 :            :   function_defer_statement(Bfunction* function, Bexpression* undefer,
     490                 :            :                            Bexpression* defer, Location);
     491                 :            : 
     492                 :            :   bool
     493                 :            :   function_set_parameters(Bfunction* function, const std::vector<Bvariable*>&);
     494                 :            : 
     495                 :            :   bool
     496                 :            :   function_set_body(Bfunction* function, Bstatement* code_stmt);
     497                 :            : 
     498                 :            :   Bfunction*
     499                 :            :   lookup_builtin(const std::string&);
     500                 :            : 
     501                 :            :   void
     502                 :            :   write_global_definitions(const std::vector<Btype*>&,
     503                 :            :                            const std::vector<Bexpression*>&,
     504                 :            :                            const std::vector<Bfunction*>&,
     505                 :            :                            const std::vector<Bvariable*>&);
     506                 :            : 
     507                 :            :   void
     508                 :            :   write_export_data(const char* bytes, unsigned int size);
     509                 :            : 
     510                 :            : 
     511                 :            :  private:
     512                 :            :   // Make a Bexpression from a tree.
     513                 :            :   Bexpression*
     514                 :   45772900 :   make_expression(tree t)
     515                 :    1046760 :   { return new Bexpression(t); }
     516                 :            : 
     517                 :            :   // Make a Bstatement from a tree.
     518                 :            :   Bstatement*
     519                 :    8454440 :   make_statement(tree t)
     520                 :        547 :   { return new Bstatement(t); }
     521                 :            : 
     522                 :            :   // Make a Btype from a tree.
     523                 :            :   Btype*
     524                 :    4823330 :   make_type(tree t)
     525                 :      12659 :   { return new Btype(t); }
     526                 :            : 
     527                 :            :   Bfunction*
     528                 :     435000 :   make_function(tree t)
     529                 :         12 :   { return new Bfunction(t); }
     530                 :            : 
     531                 :            :   Btype*
     532                 :            :   fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
     533                 :            : 
     534                 :            :   Btype*
     535                 :            :   fill_in_array(Btype*, Btype*, Bexpression*);
     536                 :            : 
     537                 :            :   tree
     538                 :            :   non_zero_size_type(tree);
     539                 :            : 
     540                 :            :   tree
     541                 :            :   convert_tree(tree, tree, Location);
     542                 :            : 
     543                 :            : private:
     544                 :            :   void
     545                 :            :   define_builtin(built_in_function bcode, const char* name, const char* libname,
     546                 :            :                  tree fntype, bool const_p, bool noreturn_p);
     547                 :            : 
     548                 :            :   // A mapping of the GCC built-ins exposed to GCCGo.
     549                 :            :   std::map<std::string, Bfunction*> builtin_functions_;
     550                 :            : };
     551                 :            : 
     552                 :            : // A helper function to create a GCC identifier from a C++ string.
     553                 :            : 
     554                 :            : static inline tree
     555                 :    9705730 : get_identifier_from_string(const std::string& str)
     556                 :            : {
     557                 :    5492010 :   return get_identifier_with_length(str.data(), str.length());
     558                 :            : }
     559                 :            : 
     560                 :            : // Define the built-in functions that are exposed to GCCGo.
     561                 :            : 
     562                 :       3372 : Gcc_backend::Gcc_backend()
     563                 :            : {
     564                 :            :   /* We need to define the fetch_and_add functions, since we use them
     565                 :            :      for ++ and --.  */
     566                 :       3372 :   tree t = this->integer_type(true, BITS_PER_UNIT)->get_tree();
     567                 :       3372 :   tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     568                 :       3372 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
     569                 :            :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     570                 :            :                        false, false);
     571                 :            : 
     572                 :       3372 :   t = this->integer_type(true, BITS_PER_UNIT * 2)->get_tree();
     573                 :       3372 :   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     574                 :       3372 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
     575                 :            :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     576                 :            :                        false, false);
     577                 :            : 
     578                 :       3372 :   t = this->integer_type(true, BITS_PER_UNIT * 4)->get_tree();
     579                 :       3372 :   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     580                 :       3372 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
     581                 :            :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     582                 :            :                        false, false);
     583                 :            : 
     584                 :       3372 :   t = this->integer_type(true, BITS_PER_UNIT * 8)->get_tree();
     585                 :       3372 :   p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
     586                 :       3372 :   this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
     587                 :            :                        NULL, build_function_type_list(t, p, t, NULL_TREE),
     588                 :            :                        false, false);
     589                 :            : 
     590                 :            :   // We use __builtin_expect for magic import functions.
     591                 :       3372 :   this->define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL,
     592                 :            :                        build_function_type_list(long_integer_type_node,
     593                 :            :                                                 long_integer_type_node,
     594                 :            :                                                 long_integer_type_node,
     595                 :            :                                                 NULL_TREE),
     596                 :            :                        true, false);
     597                 :            : 
     598                 :            :   // We use __builtin_memcmp for struct comparisons.
     599                 :       3372 :   this->define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
     600                 :            :                        build_function_type_list(integer_type_node,
     601                 :            :                                                 const_ptr_type_node,
     602                 :            :                                                 const_ptr_type_node,
     603                 :            :                                                 size_type_node,
     604                 :            :                                                 NULL_TREE),
     605                 :            :                        false, false);
     606                 :            : 
     607                 :            :   // We use __builtin_memmove for copying data.
     608                 :       3372 :   this->define_builtin(BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
     609                 :            :                        build_function_type_list(void_type_node,
     610                 :            :                                                 ptr_type_node,
     611                 :            :                                                 const_ptr_type_node,
     612                 :            :                                                 size_type_node,
     613                 :            :                                                 NULL_TREE),
     614                 :            :                        false, false);
     615                 :            : 
     616                 :            :   // We use __builtin_memset for zeroing data.
     617                 :       3372 :   this->define_builtin(BUILT_IN_MEMSET, "__builtin_memset", "memset",
     618                 :            :                        build_function_type_list(void_type_node,
     619                 :            :                                                 ptr_type_node,
     620                 :            :                                                 integer_type_node,
     621                 :            :                                                 size_type_node,
     622                 :            :                                                 NULL_TREE),
     623                 :            :                        false, false);
     624                 :            : 
     625                 :            :   // Used by runtime/internal/sys and math/bits.
     626                 :       3372 :   this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz",
     627                 :            :                        build_function_type_list(integer_type_node,
     628                 :            :                                                 unsigned_type_node,
     629                 :            :                                                 NULL_TREE),
     630                 :            :                        true, false);
     631                 :       3372 :   this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
     632                 :            :                        build_function_type_list(integer_type_node,
     633                 :            :                                                 long_long_unsigned_type_node,
     634                 :            :                                                 NULL_TREE),
     635                 :            :                        true, false);
     636                 :       3372 :   this->define_builtin(BUILT_IN_CLZ, "__builtin_clz", "clz",
     637                 :            :                        build_function_type_list(integer_type_node,
     638                 :            :                                                 unsigned_type_node,
     639                 :            :                                                 NULL_TREE),
     640                 :            :                        true, false);
     641                 :       3372 :   this->define_builtin(BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
     642                 :            :                        build_function_type_list(integer_type_node,
     643                 :            :                                                 long_long_unsigned_type_node,
     644                 :            :                                                 NULL_TREE),
     645                 :            :                        true, false);
     646                 :       3372 :   this->define_builtin(BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
     647                 :            :                        build_function_type_list(integer_type_node,
     648                 :            :                                                 unsigned_type_node,
     649                 :            :                                                 NULL_TREE),
     650                 :            :                        true, false);
     651                 :       3372 :   this->define_builtin(BUILT_IN_POPCOUNTLL, "__builtin_popcountll", "popcountll",
     652                 :            :                        build_function_type_list(integer_type_node,
     653                 :            :                                                 long_long_unsigned_type_node,
     654                 :            :                                                 NULL_TREE),
     655                 :            :                        true, false);
     656                 :       3372 :   this->define_builtin(BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
     657                 :            :                        build_function_type_list(uint16_type_node,
     658                 :            :                                                 uint16_type_node,
     659                 :            :                                                 NULL_TREE),
     660                 :            :                        true, false);
     661                 :       3372 :   this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
     662                 :            :                        build_function_type_list(uint32_type_node,
     663                 :            :                                                 uint32_type_node,
     664                 :            :                                                 NULL_TREE),
     665                 :            :                        true, false);
     666                 :       3372 :   this->define_builtin(BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
     667                 :            :                        build_function_type_list(uint64_type_node,
     668                 :            :                                                 uint64_type_node,
     669                 :            :                                                 NULL_TREE),
     670                 :            :                        true, false);
     671                 :            : 
     672                 :            :   // We provide some functions for the math library.
     673                 :       3372 :   tree math_function_type = build_function_type_list(double_type_node,
     674                 :            :                                                      double_type_node,
     675                 :            :                                                      NULL_TREE);
     676                 :       3372 :   tree math_function_type_long =
     677                 :       3372 :     build_function_type_list(long_double_type_node, long_double_type_node,
     678                 :            :                              NULL_TREE);
     679                 :       3372 :   tree math_function_type_two = build_function_type_list(double_type_node,
     680                 :            :                                                          double_type_node,
     681                 :            :                                                          double_type_node,
     682                 :            :                                                          NULL_TREE);
     683                 :       3372 :   tree math_function_type_long_two =
     684                 :       3372 :     build_function_type_list(long_double_type_node, long_double_type_node,
     685                 :            :                              long_double_type_node, NULL_TREE);
     686                 :       3372 :   this->define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
     687                 :            :                        math_function_type, true, false);
     688                 :       3372 :   this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
     689                 :            :                        math_function_type_long, true, false);
     690                 :       3372 :   this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
     691                 :            :                        math_function_type, true, false);
     692                 :       3372 :   this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
     693                 :            :                        math_function_type_long, true, false);
     694                 :       3372 :   this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
     695                 :            :                        math_function_type, true, false);
     696                 :       3372 :   this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
     697                 :            :                        math_function_type_long, true, false);
     698                 :       3372 :   this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
     699                 :            :                        math_function_type_two, true, false);
     700                 :       3372 :   this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
     701                 :            :                        math_function_type_long_two, true, false);
     702                 :       3372 :   this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
     703                 :            :                        math_function_type, true, false);
     704                 :       3372 :   this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
     705                 :            :                        math_function_type_long, true, false);
     706                 :       3372 :   this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
     707                 :            :                        math_function_type, true, false);
     708                 :       3372 :   this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
     709                 :            :                        math_function_type_long, true, false);
     710                 :       3372 :   this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
     711                 :            :                        math_function_type, true, false);
     712                 :       3372 :   this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
     713                 :            :                        math_function_type_long, true, false);
     714                 :       3372 :   this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
     715                 :            :                        math_function_type, true, false);
     716                 :       3372 :   this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
     717                 :            :                        math_function_type_long, true, false);
     718                 :       3372 :   this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
     719                 :            :                        math_function_type, true, false);
     720                 :       3372 :   this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
     721                 :            :                        math_function_type_long, true, false);
     722                 :       3372 :   this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
     723                 :            :                        math_function_type, true, false);
     724                 :       3372 :   this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
     725                 :            :                        math_function_type_long, true, false);
     726                 :       3372 :   this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
     727                 :            :                        math_function_type_two, true, false);
     728                 :       3372 :   this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
     729                 :            :                        math_function_type_long_two, true, false);
     730                 :       3372 :   this->define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
     731                 :            :                        build_function_type_list(double_type_node,
     732                 :            :                                                 double_type_node,
     733                 :            :                                                 integer_type_node,
     734                 :            :                                                 NULL_TREE),
     735                 :            :                        true, false);
     736                 :       3372 :   this->define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
     737                 :            :                        build_function_type_list(long_double_type_node,
     738                 :            :                                                 long_double_type_node,
     739                 :            :                                                 integer_type_node,
     740                 :            :                                                 NULL_TREE),
     741                 :            :                        true, false);
     742                 :       3372 :   this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
     743                 :            :                        math_function_type, true, false);
     744                 :       3372 :   this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
     745                 :            :                        math_function_type_long, true, false);
     746                 :       3372 :   this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
     747                 :            :                        math_function_type, true, false);
     748                 :       3372 :   this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
     749                 :            :                        math_function_type_long, true, false);
     750                 :       3372 :   this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
     751                 :            :                        math_function_type, true, false);
     752                 :       3372 :   this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
     753                 :            :                        math_function_type_long, true, false);
     754                 :       3372 :   this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
     755                 :            :                        math_function_type, true, false);
     756                 :       3372 :   this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
     757                 :            :                        math_function_type_long, true, false);
     758                 :       3372 :   this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
     759                 :            :                        math_function_type, true, false);
     760                 :       3372 :   this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
     761                 :            :                        math_function_type_long, true, false);
     762                 :       3372 :   this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
     763                 :            :                        math_function_type, true, false);
     764                 :       3372 :   this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
     765                 :            :                        math_function_type_long, true, false);
     766                 :       3372 :   this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
     767                 :            :                        math_function_type, true, false);
     768                 :       3372 :   this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
     769                 :            :                        math_function_type_long, true, false);
     770                 :       3372 :   this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
     771                 :            :                        math_function_type, true, false);
     772                 :       3372 :   this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
     773                 :            :                        math_function_type_long, true, false);
     774                 :            : 
     775                 :            :   // We use __builtin_return_address in the thunk we build for
     776                 :            :   // functions which call recover, and for runtime.getcallerpc.
     777                 :       3372 :   t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE);
     778                 :       3372 :   this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
     779                 :            :                        NULL, t, false, false);
     780                 :            : 
     781                 :            :   // The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
     782                 :       3372 :   t = build_function_type_list(ptr_type_node, NULL_TREE);
     783                 :       3372 :   this->define_builtin(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa",
     784                 :            :                        NULL, t, false, false);
     785                 :            : 
     786                 :            :   // The runtime calls __builtin_extract_return_addr when recording
     787                 :            :   // the address to which a function returns.
     788                 :       3372 :   this->define_builtin(BUILT_IN_EXTRACT_RETURN_ADDR,
     789                 :            :                        "__builtin_extract_return_addr", NULL,
     790                 :            :                        build_function_type_list(ptr_type_node,
     791                 :            :                                                 ptr_type_node,
     792                 :            :                                                 NULL_TREE),
     793                 :            :                        false, false);
     794                 :            : 
     795                 :            :   // The compiler uses __builtin_trap for some exception handling
     796                 :            :   // cases.
     797                 :       3372 :   this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL,
     798                 :            :                        build_function_type(void_type_node, void_list_node),
     799                 :            :                        false, true);
     800                 :            : 
     801                 :            :   // The runtime uses __builtin_prefetch.
     802                 :       3372 :   this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
     803                 :            :                        build_varargs_function_type_list(void_type_node,
     804                 :            :                                                         const_ptr_type_node,
     805                 :            :                                                         NULL_TREE),
     806                 :            :                        false, false);
     807                 :            : 
     808                 :            :   // The compiler uses __builtin_unreachable for cases that cannot
     809                 :            :   // occur.
     810                 :       3372 :   this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
     811                 :            :                        build_function_type(void_type_node, void_list_node),
     812                 :            :                        true, true);
     813                 :            : 
     814                 :            :   // We provide some atomic functions.
     815                 :       3372 :   t = build_function_type_list(uint32_type_node,
     816                 :            :                                ptr_type_node,
     817                 :            :                                integer_type_node,
     818                 :            :                                NULL_TREE);
     819                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL,
     820                 :            :                        t, false, false);
     821                 :            : 
     822                 :       3372 :   t = build_function_type_list(uint64_type_node,
     823                 :            :                                ptr_type_node,
     824                 :            :                                integer_type_node,
     825                 :            :                                NULL_TREE);
     826                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL,
     827                 :            :                        t, false, false);
     828                 :            : 
     829                 :       3372 :   t = build_function_type_list(void_type_node,
     830                 :            :                                ptr_type_node,
     831                 :            :                                uint32_type_node,
     832                 :            :                                integer_type_node,
     833                 :            :                                NULL_TREE);
     834                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL,
     835                 :            :                        t, false, false);
     836                 :            : 
     837                 :       3372 :   t = build_function_type_list(void_type_node,
     838                 :            :                                ptr_type_node,
     839                 :            :                                uint64_type_node,
     840                 :            :                                integer_type_node,
     841                 :            :                                NULL_TREE);
     842                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL,
     843                 :            :                        t, false, false);
     844                 :            : 
     845                 :       3372 :   t = build_function_type_list(uint32_type_node,
     846                 :            :                                ptr_type_node,
     847                 :            :                                uint32_type_node,
     848                 :            :                                integer_type_node,
     849                 :            :                                NULL_TREE);
     850                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL,
     851                 :            :                        t, false, false);
     852                 :            : 
     853                 :       3372 :   t = build_function_type_list(uint64_type_node,
     854                 :            :                                ptr_type_node,
     855                 :            :                                uint64_type_node,
     856                 :            :                                integer_type_node,
     857                 :            :                                NULL_TREE);
     858                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL,
     859                 :            :                        t, false, false);
     860                 :            : 
     861                 :       3372 :   t = build_function_type_list(boolean_type_node,
     862                 :            :                                ptr_type_node,
     863                 :            :                                ptr_type_node,
     864                 :            :                                uint32_type_node,
     865                 :            :                                boolean_type_node,
     866                 :            :                                integer_type_node,
     867                 :            :                                integer_type_node,
     868                 :            :                                NULL_TREE);
     869                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
     870                 :            :                        "__atomic_compare_exchange_4", NULL,
     871                 :            :                        t, false, false);
     872                 :            : 
     873                 :       3372 :   t = build_function_type_list(boolean_type_node,
     874                 :            :                                ptr_type_node,
     875                 :            :                                ptr_type_node,
     876                 :            :                                uint64_type_node,
     877                 :            :                                boolean_type_node,
     878                 :            :                                integer_type_node,
     879                 :            :                                integer_type_node,
     880                 :            :                                NULL_TREE);
     881                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
     882                 :            :                        "__atomic_compare_exchange_8", NULL,
     883                 :            :                        t, false, false);
     884                 :            : 
     885                 :       3372 :   t = build_function_type_list(uint32_type_node,
     886                 :            :                                ptr_type_node,
     887                 :            :                                uint32_type_node,
     888                 :            :                                integer_type_node,
     889                 :            :                                NULL_TREE);
     890                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4", NULL,
     891                 :            :                        t, false, false);
     892                 :            : 
     893                 :       3372 :   t = build_function_type_list(uint64_type_node,
     894                 :            :                                ptr_type_node,
     895                 :            :                                uint64_type_node,
     896                 :            :                                integer_type_node,
     897                 :            :                                NULL_TREE);
     898                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8", NULL,
     899                 :            :                        t, false, false);
     900                 :            : 
     901                 :       3372 :   t = build_function_type_list(unsigned_char_type_node,
     902                 :            :                                ptr_type_node,
     903                 :            :                                unsigned_char_type_node,
     904                 :            :                                integer_type_node,
     905                 :            :                                NULL_TREE);
     906                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1", NULL,
     907                 :            :                        t, false, false);
     908                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1", NULL,
     909                 :            :                        t, false, false);
     910                 :            : 
     911                 :       3372 :   t = build_function_type_list(unsigned_char_type_node,
     912                 :            :                                ptr_type_node,
     913                 :            :                                unsigned_char_type_node,
     914                 :            :                                integer_type_node,
     915                 :            :                                NULL_TREE);
     916                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
     917                 :            :                        t, false, false);
     918                 :       3372 :   this->define_builtin(BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
     919                 :            :                        t, false, false);
     920                 :       3372 : }
     921                 :            : 
     922                 :            : // Get an unnamed integer type.
     923                 :            : 
     924                 :            : Btype*
     925                 :     143222 : Gcc_backend::integer_type(bool is_unsigned, int bits)
     926                 :            : {
     927                 :     143222 :   tree type;
     928                 :     143222 :   if (is_unsigned)
     929                 :            :     {
     930                 :      85150 :       if (bits == INT_TYPE_SIZE)
     931                 :      25680 :         type = unsigned_type_node;
     932                 :      59470 :       else if (bits == CHAR_TYPE_SIZE)
     933                 :      23509 :         type = unsigned_char_type_node;
     934                 :      35961 :       else if (bits == SHORT_TYPE_SIZE)
     935                 :       8301 :         type = short_unsigned_type_node;
     936                 :      30372 :       else if (bits == LONG_TYPE_SIZE)
     937                 :      24948 :         type = long_unsigned_type_node;
     938                 :       2712 :       else if (bits == LONG_LONG_TYPE_SIZE)
     939                 :       2712 :         type = long_long_unsigned_type_node;
     940                 :            :       else
     941                 :          0 :         type = make_unsigned_type(bits);
     942                 :            :     }
     943                 :            :   else
     944                 :            :     {
     945                 :      58072 :       if (bits == INT_TYPE_SIZE)
     946                 :      23675 :         type = integer_type_node;
     947                 :      34397 :       else if (bits == CHAR_TYPE_SIZE)
     948                 :       4487 :         type = signed_char_type_node;
     949                 :      29910 :       else if (bits == SHORT_TYPE_SIZE)
     950                 :       3624 :         type = short_integer_type_node;
     951                 :      28742 :       else if (bits == LONG_TYPE_SIZE)
     952                 :      23830 :         type = long_integer_type_node;
     953                 :       2456 :       else if (bits == LONG_LONG_TYPE_SIZE)
     954                 :       2456 :         type = long_long_integer_type_node;
     955                 :            :       else
     956                 :          0 :         type = make_signed_type(bits);
     957                 :            :     }
     958                 :     143222 :   return this->make_type(type);
     959                 :            : }
     960                 :            : 
     961                 :            : // Get an unnamed float type.
     962                 :            : 
     963                 :            : Btype*
     964                 :       7194 : Gcc_backend::float_type(int bits)
     965                 :            : {
     966                 :       7194 :   tree type;
     967                 :       7194 :   if (bits == FLOAT_TYPE_SIZE)
     968                 :       3472 :     type = float_type_node;
     969                 :       3722 :   else if (bits == DOUBLE_TYPE_SIZE)
     970                 :       3722 :     type = double_type_node;
     971                 :          0 :   else if (bits == LONG_DOUBLE_TYPE_SIZE)
     972                 :          0 :     type = long_double_type_node;
     973                 :            :   else
     974                 :            :     {
     975                 :          0 :       type = make_node(REAL_TYPE);
     976                 :          0 :       TYPE_PRECISION(type) = bits;
     977                 :          0 :       layout_type(type);
     978                 :            :     }
     979                 :       7194 :   return this->make_type(type);
     980                 :            : }
     981                 :            : 
     982                 :            : // Get an unnamed complex type.
     983                 :            : 
     984                 :            : Btype*
     985                 :       6903 : Gcc_backend::complex_type(int bits)
     986                 :            : {
     987                 :       6903 :   tree type;
     988                 :       6903 :   if (bits == FLOAT_TYPE_SIZE * 2)
     989                 :       3429 :     type = complex_float_type_node;
     990                 :       3474 :   else if (bits == DOUBLE_TYPE_SIZE * 2)
     991                 :       3474 :     type = complex_double_type_node;
     992                 :          0 :   else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
     993                 :          0 :     type = complex_long_double_type_node;
     994                 :            :   else
     995                 :            :     {
     996                 :          0 :       type = make_node(REAL_TYPE);
     997                 :          0 :       TYPE_PRECISION(type) = bits / 2;
     998                 :          0 :       layout_type(type);
     999                 :          0 :       type = build_complex_type(type);
    1000                 :            :     }
    1001                 :       6903 :   return this->make_type(type);
    1002                 :            : }
    1003                 :            : 
    1004                 :            : // Get a pointer type.
    1005                 :            : 
    1006                 :            : Btype*
    1007                 :    1981470 : Gcc_backend::pointer_type(Btype* to_type)
    1008                 :            : {
    1009                 :    1981470 :   tree to_type_tree = to_type->get_tree();
    1010                 :    1981470 :   if (to_type_tree == error_mark_node)
    1011                 :          7 :     return this->error_type();
    1012                 :    1981470 :   tree type = build_pointer_type(to_type_tree);
    1013                 :    1981470 :   return this->make_type(type);
    1014                 :            : }
    1015                 :            : 
    1016                 :            : // Make a function type.
    1017                 :            : 
    1018                 :            : Btype*
    1019                 :     668513 : Gcc_backend::function_type(const Btyped_identifier& receiver,
    1020                 :            :                            const std::vector<Btyped_identifier>& parameters,
    1021                 :            :                            const std::vector<Btyped_identifier>& results,
    1022                 :            :                            Btype* result_struct,
    1023                 :            :                            Location)
    1024                 :            : {
    1025                 :     668513 :   tree args = NULL_TREE;
    1026                 :     668513 :   tree* pp = &args;
    1027                 :     668513 :   if (receiver.btype != NULL)
    1028                 :            :     {
    1029                 :     142817 :       tree t = receiver.btype->get_tree();
    1030                 :     142817 :       if (t == error_mark_node)
    1031                 :          5 :         return this->error_type();
    1032                 :     142812 :       *pp = tree_cons(NULL_TREE, t, NULL_TREE);
    1033                 :     142812 :       pp = &TREE_CHAIN(*pp);
    1034                 :            :     }
    1035                 :            : 
    1036                 :     668508 :   for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
    1037                 :    1649320 :        p != parameters.end();
    1038                 :    1649320 :        ++p)
    1039                 :            :     {
    1040                 :     980817 :       tree t = p->btype->get_tree();
    1041                 :     980817 :       if (t == error_mark_node)
    1042                 :          6 :         return this->error_type();
    1043                 :     980811 :       *pp = tree_cons(NULL_TREE, t, NULL_TREE);
    1044                 :     980811 :       pp = &TREE_CHAIN(*pp);
    1045                 :            :     }
    1046                 :            : 
    1047                 :            :   // Varargs is handled entirely at the Go level.  When converted to
    1048                 :            :   // GENERIC functions are not varargs.
    1049                 :     668502 :   *pp = void_list_node;
    1050                 :            : 
    1051                 :     668502 :   tree result;
    1052                 :     668502 :   if (results.empty())
    1053                 :     157116 :     result = void_type_node;
    1054                 :     511386 :   else if (results.size() == 1)
    1055                 :     436383 :     result = results.front().btype->get_tree();
    1056                 :            :   else
    1057                 :            :     {
    1058                 :      75003 :       gcc_assert(result_struct != NULL);
    1059                 :      75003 :       result = result_struct->get_tree();
    1060                 :            :     }
    1061                 :     668502 :   if (result == error_mark_node)
    1062                 :          1 :     return this->error_type();
    1063                 :            : 
    1064                 :            :   // The libffi library cannot represent a zero-sized object.  To
    1065                 :            :   // avoid causing confusion on 32-bit SPARC, we treat a function that
    1066                 :            :   // returns a zero-sized value as returning void.  That should do no
    1067                 :            :   // harm since there is no actual value to be returned.  See
    1068                 :            :   // https://gcc.gnu.org/PR72814 for details.
    1069                 :     668501 :   if (result != void_type_node && int_size_in_bytes(result) == 0)
    1070                 :         26 :     result = void_type_node;
    1071                 :            : 
    1072                 :     668501 :   tree fntype = build_function_type(result, args);
    1073                 :     668501 :   if (fntype == error_mark_node)
    1074                 :          0 :     return this->error_type();
    1075                 :            : 
    1076                 :     668501 :   return this->make_type(build_pointer_type(fntype));
    1077                 :            : }
    1078                 :            : 
    1079                 :            : // Make a struct type.
    1080                 :            : 
    1081                 :            : Btype*
    1082                 :     343248 : Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
    1083                 :            : {
    1084                 :     343248 :   return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE)), fields);
    1085                 :            : }
    1086                 :            : 
    1087                 :            : // Fill in the fields of a struct type.
    1088                 :            : 
    1089                 :            : Btype*
    1090                 :    1433600 : Gcc_backend::fill_in_struct(Btype* fill,
    1091                 :            :                             const std::vector<Btyped_identifier>& fields)
    1092                 :            : {
    1093                 :    1433600 :   tree fill_tree = fill->get_tree();
    1094                 :    1433600 :   tree field_trees = NULL_TREE;
    1095                 :    1433600 :   tree* pp = &field_trees;
    1096                 :    1433600 :   for (std::vector<Btyped_identifier>::const_iterator p = fields.begin();
    1097                 :    6925610 :        p != fields.end();
    1098                 :    6925610 :        ++p)
    1099                 :            :     {
    1100                 :    5492010 :       tree name_tree = get_identifier_from_string(p->name);
    1101                 :    5492010 :       tree type_tree = p->btype->get_tree();
    1102                 :    5492010 :       if (type_tree == error_mark_node)
    1103                 :          8 :         return this->error_type();
    1104                 :    5492010 :       tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
    1105                 :            :                               type_tree);
    1106                 :    5492010 :       DECL_CONTEXT(field) = fill_tree;
    1107                 :    5492010 :       *pp = field;
    1108                 :    5492010 :       pp = &DECL_CHAIN(field);
    1109                 :            :     }
    1110                 :    1433590 :   TYPE_FIELDS(fill_tree) = field_trees;
    1111                 :    1433590 :   layout_type(fill_tree);
    1112                 :            : 
    1113                 :            :   // Because Go permits converting between named struct types and
    1114                 :            :   // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
    1115                 :            :   // because we don't try to maintain TYPE_CANONICAL for struct types,
    1116                 :            :   // we need to tell the middle-end to use structural equality.
    1117                 :    1433590 :   SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
    1118                 :            : 
    1119                 :    1433590 :   return fill;
    1120                 :            : }
    1121                 :            : 
    1122                 :            : // Make an array type.
    1123                 :            : 
    1124                 :            : Btype*
    1125                 :     158880 : Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
    1126                 :            : {
    1127                 :     158880 :   return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
    1128                 :     158880 :                              element_btype, length);
    1129                 :            : }
    1130                 :            : 
    1131                 :            : // Fill in an array type.
    1132                 :            : 
    1133                 :            : Btype*
    1134                 :     168590 : Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
    1135                 :            :                            Bexpression* length)
    1136                 :            : {
    1137                 :     168590 :   tree element_type_tree = element_type->get_tree();
    1138                 :     168590 :   tree length_tree = length->get_tree();
    1139                 :     168590 :   if (element_type_tree == error_mark_node || length_tree == error_mark_node)
    1140                 :          8 :     return this->error_type();
    1141                 :            : 
    1142                 :     168582 :   gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
    1143                 :            : 
    1144                 :     168582 :   length_tree = fold_convert(sizetype, length_tree);
    1145                 :            : 
    1146                 :            :   // build_index_type takes the maximum index, which is one less than
    1147                 :            :   // the length.
    1148                 :     168582 :   tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
    1149                 :            :                                                       length_tree,
    1150                 :            :                                                       size_one_node));
    1151                 :            : 
    1152                 :     168582 :   tree fill_tree = fill->get_tree();
    1153                 :     168582 :   TREE_TYPE(fill_tree) = element_type_tree;
    1154                 :     168582 :   TYPE_DOMAIN(fill_tree) = index_type_tree;
    1155                 :     168582 :   TYPE_ADDR_SPACE(fill_tree) = TYPE_ADDR_SPACE(element_type_tree);
    1156                 :     168582 :   layout_type(fill_tree);
    1157                 :            : 
    1158                 :     168582 :   if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree))
    1159                 :      57846 :     SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
    1160                 :     110736 :   else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
    1161                 :     196272 :            || TYPE_CANONICAL(index_type_tree) != index_type_tree)
    1162                 :      50400 :     TYPE_CANONICAL(fill_tree) =
    1163                 :      25200 :       build_array_type(TYPE_CANONICAL(element_type_tree),
    1164                 :      25200 :                        TYPE_CANONICAL(index_type_tree));
    1165                 :            : 
    1166                 :            :   return fill;
    1167                 :            : }
    1168                 :            : 
    1169                 :            : // Create a placeholder for a pointer type.
    1170                 :            : 
    1171                 :            : Btype*
    1172                 :     248898 : Gcc_backend::placeholder_pointer_type(const std::string& name,
    1173                 :            :                                       Location location, bool)
    1174                 :            : {
    1175                 :     248898 :   tree ret = build_distinct_type_copy(ptr_type_node);
    1176                 :     248898 :   if (!name.empty())
    1177                 :            :     {
    1178                 :       7080 :       tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1179                 :            :                              get_identifier_from_string(name),
    1180                 :            :                              ret);
    1181                 :       7080 :       TYPE_NAME(ret) = decl;
    1182                 :            :     }
    1183                 :     248898 :   return this->make_type(ret);
    1184                 :            : }
    1185                 :            : 
    1186                 :            : // Set the real target type for a placeholder pointer type.
    1187                 :            : 
    1188                 :            : bool
    1189                 :     233619 : Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
    1190                 :            :                                           Btype* to_type)
    1191                 :            : {
    1192                 :     233619 :   tree pt = placeholder->get_tree();
    1193                 :     233619 :   if (pt == error_mark_node)
    1194                 :            :     return false;
    1195                 :     233619 :   gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
    1196                 :     233619 :   tree tt = to_type->get_tree();
    1197                 :     233619 :   if (tt == error_mark_node)
    1198                 :            :     {
    1199                 :          1 :       placeholder->set_tree(error_mark_node);
    1200                 :          1 :       return false;
    1201                 :            :     }
    1202                 :     233618 :   gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
    1203                 :     233618 :   TREE_TYPE(pt) = TREE_TYPE(tt);
    1204                 :     233618 :   TYPE_CANONICAL(pt) = TYPE_CANONICAL(tt);
    1205                 :     233618 :   if (TYPE_NAME(pt) != NULL_TREE)
    1206                 :            :     {
    1207                 :            :       // Build the data structure gcc wants to see for a typedef.
    1208                 :       3607 :       tree copy = build_variant_type_copy(pt);
    1209                 :       3607 :       TYPE_NAME(copy) = NULL_TREE;
    1210                 :       3607 :       DECL_ORIGINAL_TYPE(TYPE_NAME(pt)) = copy;
    1211                 :            :     }
    1212                 :            :   return true;
    1213                 :            : }
    1214                 :            : 
    1215                 :            : // Set the real values for a placeholder function type.
    1216                 :            : 
    1217                 :            : bool
    1218                 :          0 : Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
    1219                 :            : {
    1220                 :          0 :   return this->set_placeholder_pointer_type(placeholder, ft);
    1221                 :            : }
    1222                 :            : 
    1223                 :            : // Create a placeholder for a struct type.
    1224                 :            : 
    1225                 :            : Btype*
    1226                 :     548715 : Gcc_backend::placeholder_struct_type(const std::string& name,
    1227                 :            :                                      Location location)
    1228                 :            : {
    1229                 :     548715 :   tree ret = make_node(RECORD_TYPE);
    1230                 :     548715 :   if (!name.empty())
    1231                 :            :     {
    1232                 :     541638 :       tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1233                 :            :                              get_identifier_from_string(name),
    1234                 :            :                              ret);
    1235                 :     541638 :       TYPE_NAME(ret) = decl;
    1236                 :            : 
    1237                 :            :       // The struct type that eventually replaces this placeholder will require
    1238                 :            :       // structural equality. The placeholder must too, so that the requirement
    1239                 :            :       // for structural equality propagates to references that are constructed
    1240                 :            :       // before the replacement occurs.
    1241                 :     541638 :       SET_TYPE_STRUCTURAL_EQUALITY(ret);
    1242                 :            :     }
    1243                 :     548715 :   return this->make_type(ret);
    1244                 :            : }
    1245                 :            : 
    1246                 :            : // Fill in the fields of a placeholder struct type.
    1247                 :            : 
    1248                 :            : bool
    1249                 :     548715 : Gcc_backend::set_placeholder_struct_type(
    1250                 :            :     Btype* placeholder,
    1251                 :            :     const std::vector<Btyped_identifier>& fields)
    1252                 :            : {
    1253                 :     548715 :   tree t = placeholder->get_tree();
    1254                 :     548715 :   gcc_assert(TREE_CODE(t) == RECORD_TYPE && TYPE_FIELDS(t) == NULL_TREE);
    1255                 :     548715 :   Btype* r = this->fill_in_struct(placeholder, fields);
    1256                 :            : 
    1257                 :     548715 :   if (TYPE_NAME(t) != NULL_TREE)
    1258                 :            :     {
    1259                 :            :       // Build the data structure gcc wants to see for a typedef.
    1260                 :     541638 :       tree copy = build_distinct_type_copy(t);
    1261                 :     541638 :       TYPE_NAME(copy) = NULL_TREE;
    1262                 :     541638 :       DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
    1263                 :     541638 :       TYPE_SIZE(copy) = NULL_TREE;
    1264                 :     541638 :       Btype* bc = this->make_type(copy);
    1265                 :     541638 :       this->fill_in_struct(bc, fields);
    1266                 :     541638 :       delete bc;
    1267                 :            :     }
    1268                 :            : 
    1269                 :     548715 :   return r->get_tree() != error_mark_node;
    1270                 :            : }
    1271                 :            : 
    1272                 :            : // Create a placeholder for an array type.
    1273                 :            : 
    1274                 :            : Btype*
    1275                 :       9710 : Gcc_backend::placeholder_array_type(const std::string& name,
    1276                 :            :                                     Location location)
    1277                 :            : {
    1278                 :       9710 :   tree ret = make_node(ARRAY_TYPE);
    1279                 :       9710 :   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1280                 :            :                          get_identifier_from_string(name),
    1281                 :            :                          ret);
    1282                 :       9710 :   TYPE_NAME(ret) = decl;
    1283                 :       9710 :   return this->make_type(ret);
    1284                 :            : }
    1285                 :            : 
    1286                 :            : // Fill in the fields of a placeholder array type.
    1287                 :            : 
    1288                 :            : bool
    1289                 :       9710 : Gcc_backend::set_placeholder_array_type(Btype* placeholder,
    1290                 :            :                                         Btype* element_btype,
    1291                 :            :                                         Bexpression* length)
    1292                 :            : {
    1293                 :       9710 :   tree t = placeholder->get_tree();
    1294                 :      19420 :   gcc_assert(TREE_CODE(t) == ARRAY_TYPE && TREE_TYPE(t) == NULL_TREE);
    1295                 :       9710 :   Btype* r = this->fill_in_array(placeholder, element_btype, length);
    1296                 :            : 
    1297                 :            :   // Build the data structure gcc wants to see for a typedef.
    1298                 :       9710 :   tree copy = build_distinct_type_copy(t);
    1299                 :       9710 :   TYPE_NAME(copy) = NULL_TREE;
    1300                 :       9710 :   DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
    1301                 :            : 
    1302                 :       9710 :   return r->get_tree() != error_mark_node;
    1303                 :            : }
    1304                 :            : 
    1305                 :            : // Return a named version of a type.
    1306                 :            : 
    1307                 :            : Btype*
    1308                 :     152249 : Gcc_backend::named_type(const std::string& name, Btype* btype,
    1309                 :            :                         Location location)
    1310                 :            : {
    1311                 :     152249 :   tree type = btype->get_tree();
    1312                 :     152249 :   if (type == error_mark_node)
    1313                 :          0 :     return this->error_type();
    1314                 :            : 
    1315                 :            :   // The middle-end expects a basic type to have a name.  In Go every
    1316                 :            :   // basic type will have a name.  The first time we see a basic type,
    1317                 :            :   // give it whatever Go name we have at this point.
    1318                 :     152249 :   if (TYPE_NAME(type) == NULL_TREE
    1319                 :      57005 :       && location.gcc_location() == BUILTINS_LOCATION
    1320                 :     152249 :       && (TREE_CODE(type) == INTEGER_TYPE
    1321                 :            :           || TREE_CODE(type) == REAL_TYPE
    1322                 :      50595 :           || TREE_CODE(type) == COMPLEX_TYPE
    1323                 :      10131 :           || TREE_CODE(type) == BOOLEAN_TYPE))
    1324                 :            :     {
    1325                 :      43836 :       tree decl = build_decl(BUILTINS_LOCATION, TYPE_DECL,
    1326                 :            :                              get_identifier_from_string(name),
    1327                 :            :                              type);
    1328                 :      43836 :       TYPE_NAME(type) = decl;
    1329                 :      43836 :       return this->make_type(type);
    1330                 :            :     }
    1331                 :            : 
    1332                 :     108413 :   tree copy = build_variant_type_copy(type);
    1333                 :     108413 :   tree decl = build_decl(location.gcc_location(), TYPE_DECL,
    1334                 :            :                          get_identifier_from_string(name),
    1335                 :            :                          copy);
    1336                 :     108413 :   DECL_ORIGINAL_TYPE(decl) = type;
    1337                 :     108413 :   TYPE_NAME(copy) = decl;
    1338                 :     108413 :   return this->make_type(copy);
    1339                 :            : }
    1340                 :            : 
    1341                 :            : // Return a pointer type used as a marker for a circular type.
    1342                 :            : 
    1343                 :            : Btype*
    1344                 :         49 : Gcc_backend::circular_pointer_type(Btype*, bool)
    1345                 :            : {
    1346                 :         49 :   return this->make_type(ptr_type_node);
    1347                 :            : }
    1348                 :            : 
    1349                 :            : // Return whether we might be looking at a circular type.
    1350                 :            : 
    1351                 :            : bool
    1352                 :     442091 : Gcc_backend::is_circular_pointer_type(Btype* btype)
    1353                 :            : {
    1354                 :     442091 :   return btype->get_tree() == ptr_type_node;
    1355                 :            : }
    1356                 :            : 
    1357                 :            : // Return the size of a type.
    1358                 :            : 
    1359                 :            : int64_t
    1360                 :   22591400 : Gcc_backend::type_size(Btype* btype)
    1361                 :            : {
    1362                 :   22591400 :   tree t = btype->get_tree();
    1363                 :   22591400 :   if (t == error_mark_node)
    1364                 :            :     return 1;
    1365                 :   22591300 :   if (t == void_type_node)
    1366                 :            :     return 0;
    1367                 :   22591300 :   t = TYPE_SIZE_UNIT(t);
    1368                 :   22591300 :   gcc_assert(tree_fits_uhwi_p (t));
    1369                 :   22591300 :   unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
    1370                 :   22591300 :   int64_t ret = static_cast<int64_t>(val_wide);
    1371                 :   22591300 :   if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
    1372                 :            :     return -1;
    1373                 :            :   return ret;
    1374                 :            : }
    1375                 :            : 
    1376                 :            : // Return the alignment of a type.
    1377                 :            : 
    1378                 :            : int64_t
    1379                 :    3267140 : Gcc_backend::type_alignment(Btype* btype)
    1380                 :            : {
    1381                 :    3267140 :   tree t = btype->get_tree();
    1382                 :    3267140 :   if (t == error_mark_node)
    1383                 :            :     return 1;
    1384                 :    3267120 :   return TYPE_ALIGN_UNIT(t);
    1385                 :            : }
    1386                 :            : 
    1387                 :            : // Return the alignment of a struct field of type BTYPE.
    1388                 :            : 
    1389                 :            : int64_t
    1390                 :    1083290 : Gcc_backend::type_field_alignment(Btype* btype)
    1391                 :            : {
    1392                 :    1083290 :   tree t = btype->get_tree();
    1393                 :    1083290 :   if (t == error_mark_node)
    1394                 :            :     return 1;
    1395                 :    1083290 :   return go_field_alignment(t);
    1396                 :            : }
    1397                 :            : 
    1398                 :            : // Return the offset of a field in a struct.
    1399                 :            : 
    1400                 :            : int64_t
    1401                 :     110071 : Gcc_backend::type_field_offset(Btype* btype, size_t index)
    1402                 :            : {
    1403                 :     110071 :   tree struct_tree = btype->get_tree();
    1404                 :     110071 :   if (struct_tree == error_mark_node)
    1405                 :            :     return 0;
    1406                 :     110071 :   gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
    1407                 :     110071 :   tree field = TYPE_FIELDS(struct_tree);
    1408                 :     498574 :   for (; index > 0; --index)
    1409                 :            :     {
    1410                 :     388503 :       field = DECL_CHAIN(field);
    1411                 :     388503 :       gcc_assert(field != NULL_TREE);
    1412                 :            :     }
    1413                 :     110071 :   HOST_WIDE_INT offset_wide = int_byte_position(field);
    1414                 :     110071 :   int64_t ret = static_cast<int64_t>(offset_wide);
    1415                 :     110071 :   gcc_assert(ret == offset_wide);
    1416                 :     110071 :   return ret;
    1417                 :            : }
    1418                 :            : 
    1419                 :            : // Return the zero value for a type.
    1420                 :            : 
    1421                 :            : Bexpression*
    1422                 :     369583 : Gcc_backend::zero_expression(Btype* btype)
    1423                 :            : {
    1424                 :     369583 :   tree t = btype->get_tree();
    1425                 :     369583 :   tree ret;
    1426                 :     369583 :   if (t == error_mark_node)
    1427                 :            :     ret = error_mark_node;
    1428                 :            :   else
    1429                 :     369578 :     ret = build_zero_cst(t);
    1430                 :     369583 :   return this->make_expression(ret);
    1431                 :            : }
    1432                 :            : 
    1433                 :            : // An expression that references a variable.
    1434                 :            : 
    1435                 :            : Bexpression*
    1436                 :   10404100 : Gcc_backend::var_expression(Bvariable* var, Location location)
    1437                 :            : {
    1438                 :   10404100 :   tree ret = var->get_tree(location);
    1439                 :   10404100 :   if (ret == error_mark_node)
    1440                 :         44 :     return this->error_expression();
    1441                 :   10404100 :   return this->make_expression(ret);
    1442                 :            : }
    1443                 :            : 
    1444                 :            : // An expression that indirectly references an expression.
    1445                 :            : 
    1446                 :            : Bexpression*
    1447                 :    1268450 : Gcc_backend::indirect_expression(Btype* btype, Bexpression* expr,
    1448                 :            :                                  bool known_valid, Location location)
    1449                 :            : {
    1450                 :    1268450 :   tree expr_tree = expr->get_tree();
    1451                 :    1268450 :   tree type_tree = btype->get_tree();
    1452                 :    1268450 :   if (expr_tree == error_mark_node || type_tree == error_mark_node)
    1453                 :          0 :     return this->error_expression();
    1454                 :            : 
    1455                 :            :   // If the type of EXPR is a recursive pointer type, then we
    1456                 :            :   // need to insert a cast before indirecting.
    1457                 :    1268450 :   tree target_type_tree = TREE_TYPE(TREE_TYPE(expr_tree));
    1458                 :    1268450 :   if (VOID_TYPE_P(target_type_tree))
    1459                 :        544 :     expr_tree = fold_convert_loc(location.gcc_location(),
    1460                 :            :                                  build_pointer_type(type_tree), expr_tree);
    1461                 :            : 
    1462                 :    1268450 :   tree ret = build_fold_indirect_ref_loc(location.gcc_location(),
    1463                 :            :                                          expr_tree);
    1464                 :    1268450 :   if (known_valid)
    1465                 :     385578 :     TREE_THIS_NOTRAP(ret) = 1;
    1466                 :    1268450 :   return this->make_expression(ret);
    1467                 :            : }
    1468                 :            : 
    1469                 :            : // Return an expression that declares a constant named NAME with the
    1470                 :            : // constant value VAL in BTYPE.
    1471                 :            : 
    1472                 :            : Bexpression*
    1473                 :      20657 : Gcc_backend::named_constant_expression(Btype* btype, const std::string& name,
    1474                 :            :                                        Bexpression* val, Location location)
    1475                 :            : {
    1476                 :      20657 :   tree type_tree = btype->get_tree();
    1477                 :      20657 :   tree const_val = val->get_tree();
    1478                 :      20657 :   if (type_tree == error_mark_node || const_val == error_mark_node)
    1479                 :          0 :     return this->error_expression();
    1480                 :            : 
    1481                 :      20657 :   tree name_tree = get_identifier_from_string(name);
    1482                 :      20657 :   tree decl = build_decl(location.gcc_location(), CONST_DECL, name_tree,
    1483                 :            :                          type_tree);
    1484                 :      20657 :   DECL_INITIAL(decl) = const_val;
    1485                 :      20657 :   TREE_CONSTANT(decl) = 1;
    1486                 :      20657 :   TREE_READONLY(decl) = 1;
    1487                 :            : 
    1488                 :      20657 :   go_preserve_from_gc(decl);
    1489                 :      20657 :   return this->make_expression(decl);
    1490                 :            : }
    1491                 :            : 
    1492                 :            : // Return a typed value as a constant integer.
    1493                 :            : 
    1494                 :            : Bexpression*
    1495                 :    6520970 : Gcc_backend::integer_constant_expression(Btype* btype, mpz_t val)
    1496                 :            : {
    1497                 :    6520970 :   tree t = btype->get_tree();
    1498                 :    6520970 :   if (t == error_mark_node)
    1499                 :          0 :     return this->error_expression();
    1500                 :            : 
    1501                 :    6520970 :   tree ret = double_int_to_tree(t, mpz_get_double_int(t, val, true));
    1502                 :    6520970 :   return this->make_expression(ret);
    1503                 :            : }
    1504                 :            : 
    1505                 :            : // Return a typed value as a constant floating-point number.
    1506                 :            : 
    1507                 :            : Bexpression*
    1508                 :      29853 : Gcc_backend::float_constant_expression(Btype* btype, mpfr_t val)
    1509                 :            : {
    1510                 :      29853 :   tree t = btype->get_tree();
    1511                 :      29853 :   tree ret;
    1512                 :      29853 :   if (t == error_mark_node)
    1513                 :          0 :     return this->error_expression();
    1514                 :            : 
    1515                 :      29853 :   REAL_VALUE_TYPE r1;
    1516                 :      29853 :   real_from_mpfr(&r1, val, t, GMP_RNDN);
    1517                 :      29853 :   REAL_VALUE_TYPE r2;
    1518                 :      29853 :   real_convert(&r2, TYPE_MODE(t), &r1);
    1519                 :      29853 :   ret = build_real(t, r2);
    1520                 :      29853 :   return this->make_expression(ret);
    1521                 :            : }
    1522                 :            : 
    1523                 :            : // Return a typed real and imaginary value as a constant complex number.
    1524                 :            : 
    1525                 :            : Bexpression*
    1526                 :       3082 : Gcc_backend::complex_constant_expression(Btype* btype, mpc_t val)
    1527                 :            : {
    1528                 :       3082 :   tree t = btype->get_tree();
    1529                 :       3082 :   tree ret;
    1530                 :       3082 :   if (t == error_mark_node)
    1531                 :          0 :     return this->error_expression();
    1532                 :            : 
    1533                 :       3082 :   REAL_VALUE_TYPE r1;
    1534                 :       3082 :   real_from_mpfr(&r1, mpc_realref(val), TREE_TYPE(t), GMP_RNDN);
    1535                 :       3082 :   REAL_VALUE_TYPE r2;
    1536                 :       3082 :   real_convert(&r2, TYPE_MODE(TREE_TYPE(t)), &r1);
    1537                 :            : 
    1538                 :       3082 :   REAL_VALUE_TYPE r3;
    1539                 :       3082 :   real_from_mpfr(&r3, mpc_imagref(val), TREE_TYPE(t), GMP_RNDN);
    1540                 :       3082 :   REAL_VALUE_TYPE r4;
    1541                 :       3082 :   real_convert(&r4, TYPE_MODE(TREE_TYPE(t)), &r3);
    1542                 :            : 
    1543                 :       6164 :   ret = build_complex(t, build_real(TREE_TYPE(t), r2),
    1544                 :       3082 :                       build_real(TREE_TYPE(t), r4));
    1545                 :       3082 :   return this->make_expression(ret);
    1546                 :            : }
    1547                 :            : 
    1548                 :            : // Make a constant string expression.
    1549                 :            : 
    1550                 :            : Bexpression*
    1551                 :     944196 : Gcc_backend::string_constant_expression(const std::string& val)
    1552                 :            : {
    1553                 :     944196 :   tree index_type = build_index_type(size_int(val.length()));
    1554                 :     944196 :   tree const_char_type = build_qualified_type(unsigned_char_type_node,
    1555                 :            :                                               TYPE_QUAL_CONST);
    1556                 :     944196 :   tree string_type = build_array_type(const_char_type, index_type);
    1557                 :     944196 :   TYPE_STRING_FLAG(string_type) = 1;
    1558                 :     944196 :   tree string_val = build_string(val.length(), val.data());
    1559                 :     944196 :   TREE_TYPE(string_val) = string_type;
    1560                 :            : 
    1561                 :     944196 :   return this->make_expression(string_val);
    1562                 :            : }
    1563                 :            : 
    1564                 :            : // Make a constant boolean expression.
    1565                 :            : 
    1566                 :            : Bexpression*
    1567                 :     567154 : Gcc_backend::boolean_constant_expression(bool val)
    1568                 :            : {
    1569                 :     567154 :   tree bool_cst = val ? boolean_true_node : boolean_false_node;
    1570                 :     567154 :   return this->make_expression(bool_cst);
    1571                 :            : }
    1572                 :            : 
    1573                 :            : // Return the real part of a complex expression.
    1574                 :            : 
    1575                 :            : Bexpression*
    1576                 :        354 : Gcc_backend::real_part_expression(Bexpression* bcomplex, Location location)
    1577                 :            : {
    1578                 :        354 :   tree complex_tree = bcomplex->get_tree();
    1579                 :        354 :   if (complex_tree == error_mark_node)
    1580                 :          0 :     return this->error_expression();
    1581                 :        354 :   gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
    1582                 :        354 :   tree ret = fold_build1_loc(location.gcc_location(), REALPART_EXPR,
    1583                 :        354 :                              TREE_TYPE(TREE_TYPE(complex_tree)),
    1584                 :            :                              complex_tree);
    1585                 :        354 :   return this->make_expression(ret);
    1586                 :            : }
    1587                 :            : 
    1588                 :            : // Return the imaginary part of a complex expression.
    1589                 :            : 
    1590                 :            : Bexpression*
    1591                 :        380 : Gcc_backend::imag_part_expression(Bexpression* bcomplex, Location location)
    1592                 :            : {
    1593                 :        380 :   tree complex_tree = bcomplex->get_tree();
    1594                 :        380 :   if (complex_tree == error_mark_node)
    1595                 :          0 :     return this->error_expression();
    1596                 :        380 :   gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
    1597                 :        380 :   tree ret = fold_build1_loc(location.gcc_location(), IMAGPART_EXPR,
    1598                 :        380 :                              TREE_TYPE(TREE_TYPE(complex_tree)),
    1599                 :            :                              complex_tree);
    1600                 :        380 :   return this->make_expression(ret);
    1601                 :            : }
    1602                 :            : 
    1603                 :            : // Make a complex expression given its real and imaginary parts.
    1604                 :            : 
    1605                 :            : Bexpression*
    1606                 :       5732 : Gcc_backend::complex_expression(Bexpression* breal, Bexpression* bimag,
    1607                 :            :                                 Location location)
    1608                 :            : {
    1609                 :       5732 :   tree real_tree = breal->get_tree();
    1610                 :       5732 :   tree imag_tree = bimag->get_tree();
    1611                 :       5732 :   if (real_tree == error_mark_node || imag_tree == error_mark_node)
    1612                 :          0 :     return this->error_expression();
    1613                 :       5732 :   gcc_assert(TYPE_MAIN_VARIANT(TREE_TYPE(real_tree))
    1614                 :            :             == TYPE_MAIN_VARIANT(TREE_TYPE(imag_tree)));
    1615                 :       5732 :   gcc_assert(SCALAR_FLOAT_TYPE_P(TREE_TYPE(real_tree)));
    1616                 :       5732 :   tree ret = fold_build2_loc(location.gcc_location(), COMPLEX_EXPR,
    1617                 :       5732 :                              build_complex_type(TREE_TYPE(real_tree)),
    1618                 :            :                              real_tree, imag_tree);
    1619                 :       5732 :   return this->make_expression(ret);
    1620                 :            : }
    1621                 :            : 
    1622                 :            : // An expression that converts an expression to a different type.
    1623                 :            : 
    1624                 :            : Bexpression*
    1625                 :    8746120 : Gcc_backend::convert_expression(Btype* type, Bexpression* expr,
    1626                 :            :                                 Location location)
    1627                 :            : {
    1628                 :    8746120 :   tree type_tree = type->get_tree();
    1629                 :    8746120 :   tree expr_tree = expr->get_tree();
    1630                 :    8746120 :   if (type_tree == error_mark_node
    1631                 :    8746120 :       || expr_tree == error_mark_node
    1632                 :   17492200 :       || TREE_TYPE(expr_tree) == error_mark_node)
    1633                 :         19 :     return this->error_expression();
    1634                 :            : 
    1635                 :    8746100 :   tree ret;
    1636                 :    8746100 :   if (this->type_size(type) == 0
    1637                 :   17491400 :       || TREE_TYPE(expr_tree) == void_type_node)
    1638                 :            :     {
    1639                 :            :       // Do not convert zero-sized types.
    1640                 :            :       ret = expr_tree;
    1641                 :            :     }
    1642                 :    8745270 :   else if (TREE_CODE(type_tree) == INTEGER_TYPE)
    1643                 :    2007760 :     ret = fold(convert_to_integer(type_tree, expr_tree));
    1644                 :    6737510 :   else if (TREE_CODE(type_tree) == REAL_TYPE)
    1645                 :      30313 :     ret = fold(convert_to_real(type_tree, expr_tree));
    1646                 :    6707190 :   else if (TREE_CODE(type_tree) == COMPLEX_TYPE)
    1647                 :       7480 :     ret = fold(convert_to_complex(type_tree, expr_tree));
    1648                 :    6699710 :   else if (TREE_CODE(type_tree) == POINTER_TYPE
    1649                 :    6699710 :            && TREE_CODE(TREE_TYPE(expr_tree)) == INTEGER_TYPE)
    1650                 :       1389 :     ret = fold(convert_to_pointer(type_tree, expr_tree));
    1651                 :    6698320 :   else if (TREE_CODE(type_tree) == RECORD_TYPE
    1652                 :    6698320 :            || TREE_CODE(type_tree) == ARRAY_TYPE)
    1653                 :     942215 :     ret = fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
    1654                 :            :                           type_tree, expr_tree);
    1655                 :            :   else
    1656                 :    5756110 :     ret = fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
    1657                 :            : 
    1658                 :    8746100 :   return this->make_expression(ret);
    1659                 :            : }
    1660                 :            : 
    1661                 :            : // Get the address of a function.
    1662                 :            : 
    1663                 :            : Bexpression*
    1664                 :    1792960 : Gcc_backend::function_code_expression(Bfunction* bfunc, Location location)
    1665                 :            : {
    1666                 :    1792960 :   tree func = bfunc->get_tree();
    1667                 :    1792960 :   if (func == error_mark_node)
    1668                 :          3 :     return this->error_expression();
    1669                 :            : 
    1670                 :    1792960 :   tree ret = build_fold_addr_expr_loc(location.gcc_location(), func);
    1671                 :    1792960 :   return this->make_expression(ret);
    1672                 :            : }
    1673                 :            : 
    1674                 :            : // Get the address of an expression.
    1675                 :            : 
    1676                 :            : Bexpression*
    1677                 :    4369690 : Gcc_backend::address_expression(Bexpression* bexpr, Location location)
    1678                 :            : {
    1679                 :    4369690 :   tree expr = bexpr->get_tree();
    1680                 :    4369690 :   if (expr == error_mark_node)
    1681                 :          6 :     return this->error_expression();
    1682                 :            : 
    1683                 :    4369690 :   tree ret = build_fold_addr_expr_loc(location.gcc_location(), expr);
    1684                 :    4369690 :   return this->make_expression(ret);
    1685                 :            : }
    1686                 :            : 
    1687                 :            : // Return an expression for the field at INDEX in BSTRUCT.
    1688                 :            : 
    1689                 :            : Bexpression*
    1690                 :    2071020 : Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index,
    1691                 :            :                                      Location location)
    1692                 :            : {
    1693                 :    2071020 :   tree struct_tree = bstruct->get_tree();
    1694                 :    2071020 :   if (struct_tree == error_mark_node
    1695                 :    4142040 :       || TREE_TYPE(struct_tree) == error_mark_node)
    1696                 :          0 :     return this->error_expression();
    1697                 :    2071020 :   gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
    1698                 :    2071020 :   tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
    1699                 :    2071020 :   if (field == NULL_TREE)
    1700                 :            :   {
    1701                 :            :     // This can happen for a type which refers to itself indirectly
    1702                 :            :     // and then turns out to be erroneous.
    1703                 :          0 :     return this->error_expression();
    1704                 :            :   }
    1705                 :    5165960 :   for (unsigned int i = index; i > 0; --i)
    1706                 :            :   {
    1707                 :    3094940 :     field = DECL_CHAIN(field);
    1708                 :    3094940 :     gcc_assert(field != NULL_TREE);
    1709                 :            :   }
    1710                 :    2071020 :   if (TREE_TYPE(field) == error_mark_node)
    1711                 :          0 :     return this->error_expression();
    1712                 :    2071020 :   tree ret = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
    1713                 :    2071020 :                              TREE_TYPE(field), struct_tree, field,
    1714                 :            :                              NULL_TREE);
    1715                 :    2071020 :   if (TREE_CONSTANT(struct_tree))
    1716                 :      96849 :     TREE_CONSTANT(ret) = 1;
    1717                 :    2071020 :   return this->make_expression(ret);
    1718                 :            : }
    1719                 :            : 
    1720                 :            : // Return an expression that executes BSTAT before BEXPR.
    1721                 :            : 
    1722                 :            : Bexpression*
    1723                 :     362575 : Gcc_backend::compound_expression(Bstatement* bstat, Bexpression* bexpr,
    1724                 :            :                                  Location location)
    1725                 :            : {
    1726                 :     362575 :   tree stat = bstat->get_tree();
    1727                 :     362575 :   tree expr = bexpr->get_tree();
    1728                 :     362575 :   if (stat == error_mark_node || expr == error_mark_node)
    1729                 :         23 :     return this->error_expression();
    1730                 :     362552 :   tree ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    1731                 :     362552 :                              TREE_TYPE(expr), stat, expr);
    1732                 :     362552 :   return this->make_expression(ret);
    1733                 :            : }
    1734                 :            : 
    1735                 :            : // Return an expression that executes THEN_EXPR if CONDITION is true, or
    1736                 :            : // ELSE_EXPR otherwise.
    1737                 :            : 
    1738                 :            : Bexpression*
    1739                 :     494137 : Gcc_backend::conditional_expression(Bfunction*, Btype* btype,
    1740                 :            :                                     Bexpression* condition,
    1741                 :            :                                     Bexpression* then_expr,
    1742                 :            :                                     Bexpression* else_expr, Location location)
    1743                 :            : {
    1744                 :     494137 :   tree type_tree = btype == NULL ? void_type_node : btype->get_tree();
    1745                 :     494137 :   tree cond_tree = condition->get_tree();
    1746                 :     494137 :   tree then_tree = then_expr->get_tree();
    1747                 :     494137 :   tree else_tree = else_expr == NULL ? NULL_TREE : else_expr->get_tree();
    1748                 :     494137 :   if (type_tree == error_mark_node
    1749                 :     494137 :       || cond_tree == error_mark_node
    1750                 :     494137 :       || then_tree == error_mark_node
    1751                 :     494137 :       || else_tree == error_mark_node)
    1752                 :          0 :     return this->error_expression();
    1753                 :     494137 :   tree ret = build3_loc(location.gcc_location(), COND_EXPR, type_tree,
    1754                 :            :                         cond_tree, then_tree, else_tree);
    1755                 :     494137 :   return this->make_expression(ret);
    1756                 :            : }
    1757                 :            : 
    1758                 :            : // Return an expression for the unary operation OP EXPR.
    1759                 :            : 
    1760                 :            : Bexpression*
    1761                 :      90796 : Gcc_backend::unary_expression(Operator op, Bexpression* expr, Location location)
    1762                 :            : {
    1763                 :      90796 :   tree expr_tree = expr->get_tree();
    1764                 :      90796 :   if (expr_tree == error_mark_node
    1765                 :     181591 :       || TREE_TYPE(expr_tree) == error_mark_node)
    1766                 :          1 :     return this->error_expression();
    1767                 :            : 
    1768                 :      90795 :   tree type_tree = TREE_TYPE(expr_tree);
    1769                 :      90795 :   enum tree_code code;
    1770                 :      90795 :   switch (op)
    1771                 :            :     {
    1772                 :       9478 :     case OPERATOR_MINUS:
    1773                 :       9478 :       {
    1774                 :       9478 :         tree computed_type = excess_precision_type(type_tree);
    1775                 :       9478 :         if (computed_type != NULL_TREE)
    1776                 :            :           {
    1777                 :        369 :             expr_tree = convert(computed_type, expr_tree);
    1778                 :        369 :             type_tree = computed_type;
    1779                 :            :           }
    1780                 :            :         code = NEGATE_EXPR;
    1781                 :            :         break;
    1782                 :            :       }
    1783                 :            :     case OPERATOR_NOT:
    1784                 :            :       code = TRUTH_NOT_EXPR;
    1785                 :            :       break;
    1786                 :       2017 :     case OPERATOR_XOR:
    1787                 :       2017 :       code = BIT_NOT_EXPR;
    1788                 :       2017 :       break;
    1789                 :          0 :     default:
    1790                 :          0 :       gcc_unreachable();
    1791                 :      90795 :       break;
    1792                 :            :     }
    1793                 :            : 
    1794                 :      90795 :   tree ret = fold_build1_loc(location.gcc_location(), code, type_tree,
    1795                 :            :                              expr_tree);
    1796                 :      90795 :   return this->make_expression(ret);
    1797                 :            : }
    1798                 :            : 
    1799                 :            : // Convert a gofrontend operator to an equivalent tree_code.
    1800                 :            : 
    1801                 :            : static enum tree_code
    1802                 :    2013070 : operator_to_tree_code(Operator op, tree type)
    1803                 :            : {
    1804                 :    2013070 :   enum tree_code code;
    1805                 :    2013070 :   switch (op)
    1806                 :            :     {
    1807                 :            :     case OPERATOR_EQEQ:
    1808                 :            :       code = EQ_EXPR;
    1809                 :            :       break;
    1810                 :     144325 :     case OPERATOR_NOTEQ:
    1811                 :     144325 :       code = NE_EXPR;
    1812                 :     144325 :       break;
    1813                 :     201393 :     case OPERATOR_LT:
    1814                 :     201393 :       code = LT_EXPR;
    1815                 :     201393 :       break;
    1816                 :      85501 :     case OPERATOR_LE:
    1817                 :      85501 :       code = LE_EXPR;
    1818                 :      85501 :       break;
    1819                 :      32190 :     case OPERATOR_GT:
    1820                 :      32190 :       code = GT_EXPR;
    1821                 :      32190 :       break;
    1822                 :     207627 :     case OPERATOR_GE:
    1823                 :     207627 :       code = GE_EXPR;
    1824                 :     207627 :       break;
    1825                 :         14 :     case OPERATOR_OROR:
    1826                 :         14 :       code = TRUTH_ORIF_EXPR;
    1827                 :         14 :       break;
    1828                 :     201508 :     case OPERATOR_ANDAND:
    1829                 :     201508 :       code = TRUTH_ANDIF_EXPR;
    1830                 :     201508 :       break;
    1831                 :     122608 :     case OPERATOR_PLUS:
    1832                 :     122608 :       code = PLUS_EXPR;
    1833                 :     122608 :       break;
    1834                 :     135371 :     case OPERATOR_MINUS:
    1835                 :     135371 :       code = MINUS_EXPR;
    1836                 :     135371 :       break;
    1837                 :     110379 :     case OPERATOR_OR:
    1838                 :     110379 :       code = BIT_IOR_EXPR;
    1839                 :     110379 :       break;
    1840                 :       3072 :     case OPERATOR_XOR:
    1841                 :       3072 :       code = BIT_XOR_EXPR;
    1842                 :       3072 :       break;
    1843                 :      25995 :     case OPERATOR_MULT:
    1844                 :      25995 :       code = MULT_EXPR;
    1845                 :      25995 :       break;
    1846                 :       7420 :     case OPERATOR_DIV:
    1847                 :       7420 :       if (TREE_CODE(type) == REAL_TYPE || TREE_CODE(type) == COMPLEX_TYPE)
    1848                 :            :         code = RDIV_EXPR;
    1849                 :            :       else
    1850                 :       6014 :         code = TRUNC_DIV_EXPR;
    1851                 :            :       break;
    1852                 :       3187 :     case OPERATOR_MOD:
    1853                 :       3187 :       code = TRUNC_MOD_EXPR;
    1854                 :       3187 :       break;
    1855                 :     112557 :     case OPERATOR_LSHIFT:
    1856                 :     112557 :       code = LSHIFT_EXPR;
    1857                 :     112557 :       break;
    1858                 :      11599 :     case OPERATOR_RSHIFT:
    1859                 :      11599 :       code = RSHIFT_EXPR;
    1860                 :      11599 :       break;
    1861                 :      13063 :     case OPERATOR_AND:
    1862                 :      13063 :       code = BIT_AND_EXPR;
    1863                 :      13063 :       break;
    1864                 :       1209 :     case OPERATOR_BITCLEAR:
    1865                 :       1209 :       code = BIT_AND_EXPR;
    1866                 :       1209 :       break;
    1867                 :          0 :     default:
    1868                 :          0 :       gcc_unreachable();
    1869                 :            :     }
    1870                 :            : 
    1871                 :    2013070 :   return code;
    1872                 :            : }
    1873                 :            : 
    1874                 :            : // Return an expression for the binary operation LEFT OP RIGHT.
    1875                 :            : 
    1876                 :            : Bexpression*
    1877                 :    2013070 : Gcc_backend::binary_expression(Operator op, Bexpression* left,
    1878                 :            :                                Bexpression* right, Location location)
    1879                 :            : {
    1880                 :    2013070 :   tree left_tree = left->get_tree();
    1881                 :    2013070 :   tree right_tree = right->get_tree();
    1882                 :    2013070 :   if (left_tree == error_mark_node
    1883                 :    2013070 :       || right_tree == error_mark_node)
    1884                 :          1 :     return this->error_expression();
    1885                 :    2013070 :   enum tree_code code = operator_to_tree_code(op, TREE_TYPE(left_tree));
    1886                 :            : 
    1887                 :    2013070 :   bool use_left_type = op != OPERATOR_OROR && op != OPERATOR_ANDAND;
    1888                 :    2214590 :   tree type_tree = use_left_type ? TREE_TYPE(left_tree) : TREE_TYPE(right_tree);
    1889                 :    2013070 :   tree computed_type = excess_precision_type(type_tree);
    1890                 :    2013070 :   if (computed_type != NULL_TREE)
    1891                 :            :     {
    1892                 :       7961 :       left_tree = convert(computed_type, left_tree);
    1893                 :       7961 :       right_tree = convert(computed_type, right_tree);
    1894                 :       7961 :       type_tree = computed_type;
    1895                 :            :     }
    1896                 :            : 
    1897                 :            :   // For comparison operators, the resulting type should be boolean.
    1898                 :    2013070 :   switch (op)
    1899                 :            :     {
    1900                 :    1265090 :     case OPERATOR_EQEQ:
    1901                 :    1265090 :     case OPERATOR_NOTEQ:
    1902                 :    1265090 :     case OPERATOR_LT:
    1903                 :    1265090 :     case OPERATOR_LE:
    1904                 :    1265090 :     case OPERATOR_GT:
    1905                 :    1265090 :     case OPERATOR_GE:
    1906                 :    1265090 :       type_tree = boolean_type_node;
    1907                 :    1265090 :       break;
    1908                 :            :     default:
    1909                 :            :       break;
    1910                 :            :     }
    1911                 :            : 
    1912                 :    2013070 :   tree ret = fold_build2_loc(location.gcc_location(), code, type_tree,
    1913                 :            :                              left_tree, right_tree);
    1914                 :    2013070 :   return this->make_expression(ret);
    1915                 :            : }
    1916                 :            : 
    1917                 :            : // Return an expression that constructs BTYPE with VALS.
    1918                 :            : 
    1919                 :            : Bexpression*
    1920                 :    2546090 : Gcc_backend::constructor_expression(Btype* btype,
    1921                 :            :                                     const std::vector<Bexpression*>& vals,
    1922                 :            :                                     Location location)
    1923                 :            : {
    1924                 :    2546090 :   tree type_tree = btype->get_tree();
    1925                 :    2546090 :   if (type_tree == error_mark_node)
    1926                 :          0 :     return this->error_expression();
    1927                 :            : 
    1928                 :    2546090 :   vec<constructor_elt, va_gc> *init;
    1929                 :    2546090 :   vec_alloc(init, vals.size());
    1930                 :            : 
    1931                 :    2546090 :   tree sink = NULL_TREE;
    1932                 :    2546090 :   bool is_constant = true;
    1933                 :    2546090 :   tree field = TYPE_FIELDS(type_tree);
    1934                 :   11133900 :   for (std::vector<Bexpression*>::const_iterator p = vals.begin();
    1935                 :   11133900 :        p != vals.end();
    1936                 :    8587800 :        ++p, field = DECL_CHAIN(field))
    1937                 :            :     {
    1938                 :    8587810 :       gcc_assert(field != NULL_TREE);
    1939                 :    8587810 :       tree val = (*p)->get_tree();
    1940                 :    8587810 :       if (TREE_TYPE(field) == error_mark_node
    1941                 :    8587810 :           || val == error_mark_node
    1942                 :   17175600 :           || TREE_TYPE(val) == error_mark_node)
    1943                 :          5 :         return this->error_expression();
    1944                 :            : 
    1945                 :    8587800 :       if (int_size_in_bytes(TREE_TYPE(field)) == 0)
    1946                 :            :         {
    1947                 :            :           // GIMPLE cannot represent indices of zero-sized types so
    1948                 :            :           // trying to construct a map with zero-sized keys might lead
    1949                 :            :           // to errors.  Instead, we evaluate each expression that
    1950                 :            :           // would have been added as a map element for its
    1951                 :            :           // side-effects and construct an empty map.
    1952                 :        598 :           append_to_statement_list(val, &sink);
    1953                 :        598 :           continue;
    1954                 :            :         }
    1955                 :            : 
    1956                 :    8587200 :       constructor_elt empty = {NULL, NULL};
    1957                 :    8587200 :       constructor_elt* elt = init->quick_push(empty);
    1958                 :    8587200 :       elt->index = field;
    1959                 :    8587200 :       elt->value = this->convert_tree(TREE_TYPE(field), val, location);
    1960                 :    8587200 :       if (!TREE_CONSTANT(elt->value))
    1961                 :     606345 :         is_constant = false;
    1962                 :            :     }
    1963                 :    2546090 :   gcc_assert(field == NULL_TREE);
    1964                 :    2546090 :   tree ret = build_constructor(type_tree, init);
    1965                 :    2546090 :   if (is_constant)
    1966                 :    2174790 :     TREE_CONSTANT(ret) = 1;
    1967                 :    2546090 :   if (sink != NULL_TREE)
    1968                 :          0 :     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    1969                 :            :                           type_tree, sink, ret);
    1970                 :    2546090 :   return this->make_expression(ret);
    1971                 :            : }
    1972                 :            : 
    1973                 :            : Bexpression*
    1974                 :     378537 : Gcc_backend::array_constructor_expression(
    1975                 :            :     Btype* array_btype, const std::vector<unsigned long>& indexes,
    1976                 :            :     const std::vector<Bexpression*>& vals, Location location)
    1977                 :            : {
    1978                 :     378537 :   tree type_tree = array_btype->get_tree();
    1979                 :     378537 :   if (type_tree == error_mark_node)
    1980                 :          3 :     return this->error_expression();
    1981                 :            : 
    1982                 :     378534 :   gcc_assert(indexes.size() == vals.size());
    1983                 :            : 
    1984                 :     378534 :   tree element_type = TREE_TYPE(type_tree);
    1985                 :     378534 :   HOST_WIDE_INT element_size = int_size_in_bytes(element_type);
    1986                 :     378534 :   vec<constructor_elt, va_gc> *init;
    1987                 :     378534 :   vec_alloc(init, element_size == 0 ? 0 : vals.size());
    1988                 :            : 
    1989                 :     378534 :   tree sink = NULL_TREE;
    1990                 :     378534 :   bool is_constant = true;
    1991                 :    2140700 :   for (size_t i = 0; i < vals.size(); ++i)
    1992                 :            :     {
    1993                 :    1762160 :       tree index = size_int(indexes[i]);
    1994                 :    1762160 :       tree val = (vals[i])->get_tree();
    1995                 :            : 
    1996                 :    1762160 :       if (index == error_mark_node
    1997                 :    1762160 :           || val == error_mark_node)
    1998                 :          2 :         return this->error_expression();
    1999                 :            : 
    2000                 :    1762160 :       if (element_size == 0)
    2001                 :            :        {
    2002                 :            :          // GIMPLE cannot represent arrays of zero-sized types so trying
    2003                 :            :          // to construct an array of zero-sized values might lead to errors.
    2004                 :            :          // Instead, we evaluate each expression that would have been added as
    2005                 :            :          // an array value for its side-effects and construct an empty array.
    2006                 :          3 :          append_to_statement_list(val, &sink);
    2007                 :          3 :          continue;
    2008                 :            :        }
    2009                 :            : 
    2010                 :    1762160 :       if (!TREE_CONSTANT(val))
    2011                 :     171434 :         is_constant = false;
    2012                 :            : 
    2013                 :    1762160 :       constructor_elt empty = {NULL, NULL};
    2014                 :    1762160 :       constructor_elt* elt = init->quick_push(empty);
    2015                 :    1762160 :       elt->index = index;
    2016                 :    1762160 :       elt->value = val;
    2017                 :            :     }
    2018                 :            : 
    2019                 :     378532 :   tree ret = build_constructor(type_tree, init);
    2020                 :     378532 :   if (is_constant)
    2021                 :     307594 :     TREE_CONSTANT(ret) = 1;
    2022                 :     378532 :   if (sink != NULL_TREE)
    2023                 :          0 :     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    2024                 :            :                          type_tree, sink, ret);
    2025                 :     378532 :   return this->make_expression(ret);
    2026                 :            : }
    2027                 :            : 
    2028                 :            : // Return an expression for the address of BASE[INDEX].
    2029                 :            : 
    2030                 :            : Bexpression*
    2031                 :     140618 : Gcc_backend::pointer_offset_expression(Bexpression* base, Bexpression* index,
    2032                 :            :                                        Location location)
    2033                 :            : {
    2034                 :     140618 :   tree base_tree = base->get_tree();
    2035                 :     140618 :   tree index_tree = index->get_tree();
    2036                 :     140618 :   tree element_type_tree = TREE_TYPE(TREE_TYPE(base_tree));
    2037                 :     140618 :   if (base_tree == error_mark_node
    2038                 :     140618 :       || TREE_TYPE(base_tree) == error_mark_node
    2039                 :     140618 :       || index_tree == error_mark_node
    2040                 :     281236 :       || element_type_tree == error_mark_node)
    2041                 :          0 :     return this->error_expression();
    2042                 :            : 
    2043                 :     140618 :   tree element_size = TYPE_SIZE_UNIT(element_type_tree);
    2044                 :     140618 :   index_tree = fold_convert_loc(location.gcc_location(), sizetype, index_tree);
    2045                 :     140618 :   tree offset = fold_build2_loc(location.gcc_location(), MULT_EXPR, sizetype,
    2046                 :            :                                 index_tree, element_size);
    2047                 :     140618 :   tree ptr = fold_build2_loc(location.gcc_location(), POINTER_PLUS_EXPR,
    2048                 :     140618 :                              TREE_TYPE(base_tree), base_tree, offset);
    2049                 :     140618 :   return this->make_expression(ptr);
    2050                 :            : }
    2051                 :            : 
    2052                 :            : // Return an expression representing ARRAY[INDEX]
    2053                 :            : 
    2054                 :            : Bexpression*
    2055                 :      66370 : Gcc_backend::array_index_expression(Bexpression* array, Bexpression* index,
    2056                 :            :                                     Location location)
    2057                 :            : {
    2058                 :      66370 :   tree array_tree = array->get_tree();
    2059                 :      66370 :   tree index_tree = index->get_tree();
    2060                 :      66370 :   if (array_tree == error_mark_node
    2061                 :      66370 :       || TREE_TYPE(array_tree) == error_mark_node
    2062                 :     132740 :       || index_tree == error_mark_node)
    2063                 :          0 :     return this->error_expression();
    2064                 :            : 
    2065                 :            :   // A function call that returns a zero sized object will have been
    2066                 :            :   // changed to return void.  If we see void here, assume we are
    2067                 :            :   // dealing with a zero sized type and just evaluate the operands.
    2068                 :      66370 :   tree ret;
    2069                 :      66370 :   if (TREE_TYPE(array_tree) != void_type_node)
    2070                 :      66370 :     ret = build4_loc(location.gcc_location(), ARRAY_REF,
    2071                 :      66370 :                      TREE_TYPE(TREE_TYPE(array_tree)), array_tree,
    2072                 :            :                      index_tree, NULL_TREE, NULL_TREE);
    2073                 :            :   else
    2074                 :          0 :     ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
    2075                 :            :                           void_type_node, array_tree, index_tree);
    2076                 :            : 
    2077                 :      66370 :   return this->make_expression(ret);
    2078                 :            : }
    2079                 :            : 
    2080                 :            : // Create an expression for a call to FN_EXPR with FN_ARGS.
    2081                 :            : Bexpression*
    2082                 :    1513460 : Gcc_backend::call_expression(Bfunction*, // containing fcn for call
    2083                 :            :                              Bexpression* fn_expr,
    2084                 :            :                              const std::vector<Bexpression*>& fn_args,
    2085                 :            :                              Bexpression* chain_expr,
    2086                 :            :                              Location location)
    2087                 :            : {
    2088                 :    1513460 :   tree fn = fn_expr->get_tree();
    2089                 :    3026920 :   if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node)
    2090                 :          3 :     return this->error_expression();
    2091                 :            : 
    2092                 :    1513460 :   gcc_assert(FUNCTION_POINTER_TYPE_P(TREE_TYPE(fn)));
    2093                 :    1513460 :   tree rettype = TREE_TYPE(TREE_TYPE(TREE_TYPE(fn)));
    2094                 :            : 
    2095                 :    1513460 :   size_t nargs = fn_args.size();
    2096                 :    1513460 :   tree* args = nargs == 0 ? NULL : new tree[nargs];
    2097                 :    4251240 :   for (size_t i = 0; i < nargs; ++i)
    2098                 :            :     {
    2099                 :    2737790 :       args[i] = fn_args.at(i)->get_tree();
    2100                 :    2737790 :       if (args[i] == error_mark_node)
    2101                 :         12 :         return this->error_expression();
    2102                 :            :     }
    2103                 :            : 
    2104                 :    1513450 :   tree fndecl = fn;
    2105                 :    1513450 :   if (TREE_CODE(fndecl) == ADDR_EXPR)
    2106                 :    1466630 :     fndecl = TREE_OPERAND(fndecl, 0);
    2107                 :            : 
    2108                 :            :   // This is to support builtin math functions when using 80387 math.
    2109                 :    1513450 :   tree excess_type = NULL_TREE;
    2110                 :    1513450 :   if (optimize
    2111                 :    1379710 :       && TREE_CODE(fndecl) == FUNCTION_DECL
    2112                 :    1332920 :       && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
    2113                 :      51403 :       && DECL_IS_BUILTIN (fndecl)
    2114                 :      51403 :       && nargs > 0
    2115                 :    1563970 :       && ((SCALAR_FLOAT_TYPE_P(rettype)
    2116                 :        302 :            && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0])))
    2117                 :      50220 :           || (COMPLEX_FLOAT_TYPE_P(rettype)
    2118                 :          0 :               && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0])))))
    2119                 :            :     {
    2120                 :        302 :       excess_type = excess_precision_type(TREE_TYPE(args[0]));
    2121                 :        302 :       if (excess_type != NULL_TREE)
    2122                 :            :         {
    2123                 :        150 :           tree excess_fndecl = mathfn_built_in(excess_type,
    2124                 :            :                                                DECL_FUNCTION_CODE(fndecl));
    2125                 :        150 :           if (excess_fndecl == NULL_TREE)
    2126                 :            :             excess_type = NULL_TREE;
    2127                 :            :           else
    2128                 :            :             {
    2129                 :        150 :               fn = build_fold_addr_expr_loc(location.gcc_location(),
    2130                 :            :                                             excess_fndecl);
    2131                 :        322 :               for (size_t i = 0; i < nargs; ++i)
    2132                 :            :                 {
    2133                 :        172 :                   if (SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[i]))
    2134                 :        172 :                       || COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[i])))
    2135                 :        162 :                     args[i] = ::convert(excess_type, args[i]);
    2136                 :            :                 }
    2137                 :            :             }
    2138                 :            :         }
    2139                 :            :     }
    2140                 :            : 
    2141                 :    1513450 :   tree ret =
    2142                 :    1513600 :       build_call_array_loc(location.gcc_location(),
    2143                 :            :                            excess_type != NULL_TREE ? excess_type : rettype,
    2144                 :            :                            fn, nargs, args);
    2145                 :            : 
    2146                 :    1513450 :   if (chain_expr)
    2147                 :      18965 :     CALL_EXPR_STATIC_CHAIN (ret) = chain_expr->get_tree();
    2148                 :            : 
    2149                 :    1513450 :   if (excess_type != NULL_TREE)
    2150                 :            :     {
    2151                 :            :       // Calling convert here can undo our excess precision change.
    2152                 :            :       // That may or may not be a bug in convert_to_real.
    2153                 :        150 :       ret = build1_loc(location.gcc_location(), NOP_EXPR, rettype, ret);
    2154                 :            :     }
    2155                 :            : 
    2156                 :    1513450 :   delete[] args;
    2157                 :    1513450 :   return this->make_expression(ret);
    2158                 :            : }
    2159                 :            : 
    2160                 :            : // An expression as a statement.
    2161                 :            : 
    2162                 :            : Bstatement*
    2163                 :     851237 : Gcc_backend::expression_statement(Bfunction*, Bexpression* expr)
    2164                 :            : {
    2165                 :     851237 :   return this->make_statement(expr->get_tree());
    2166                 :            : }
    2167                 :            : 
    2168                 :            : // Variable initialization.
    2169                 :            : 
    2170                 :            : Bstatement*
    2171                 :     525057 : Gcc_backend::init_statement(Bfunction*, Bvariable* var, Bexpression* init)
    2172                 :            : {
    2173                 :     525057 :   tree var_tree = var->get_decl();
    2174                 :     525057 :   tree init_tree = init->get_tree();
    2175                 :     525057 :   if (var_tree == error_mark_node || init_tree == error_mark_node)
    2176                 :          5 :     return this->error_statement();
    2177                 :     525052 :   gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
    2178                 :            : 
    2179                 :            :   // To avoid problems with GNU ld, we don't make zero-sized
    2180                 :            :   // externally visible variables.  That might lead us to doing an
    2181                 :            :   // initialization of a zero-sized expression to a non-zero sized
    2182                 :            :   // variable, or vice-versa.  Avoid crashes by omitting the
    2183                 :            :   // initializer.  Such initializations don't mean anything anyhow.
    2184                 :     525052 :   if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0
    2185                 :     523889 :       && init_tree != NULL_TREE
    2186                 :     523889 :       && TREE_TYPE(init_tree) != void_type_node
    2187                 :    1048940 :       && int_size_in_bytes(TREE_TYPE(init_tree)) != 0)
    2188                 :            :     {
    2189                 :     523889 :       DECL_INITIAL(var_tree) = init_tree;
    2190                 :     523889 :       init_tree = NULL_TREE;
    2191                 :            :     }
    2192                 :            : 
    2193                 :     525052 :   tree ret = build1_loc(DECL_SOURCE_LOCATION(var_tree), DECL_EXPR,
    2194                 :            :                         void_type_node, var_tree);
    2195                 :     525052 :   if (init_tree != NULL_TREE)
    2196                 :       1163 :     ret = build2_loc(DECL_SOURCE_LOCATION(var_tree), COMPOUND_EXPR,
    2197                 :            :                      void_type_node, init_tree, ret);
    2198                 :            : 
    2199                 :     525052 :   return this->make_statement(ret);
    2200                 :            : }
    2201                 :            : 
    2202                 :            : // Assignment.
    2203                 :            : 
    2204                 :            : Bstatement*
    2205                 :    1176100 : Gcc_backend::assignment_statement(Bfunction* bfn, Bexpression* lhs,
    2206                 :            :                                   Bexpression* rhs, Location location)
    2207                 :            : {
    2208                 :    1176100 :   tree lhs_tree = lhs->get_tree();
    2209                 :    1176100 :   tree rhs_tree = rhs->get_tree();
    2210                 :    1176100 :   if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
    2211                 :         86 :     return this->error_statement();
    2212                 :            : 
    2213                 :            :   // To avoid problems with GNU ld, we don't make zero-sized
    2214                 :            :   // externally visible variables.  That might lead us to doing an
    2215                 :            :   // assignment of a zero-sized expression to a non-zero sized
    2216                 :            :   // expression; avoid crashes here by avoiding assignments of
    2217                 :            :   // zero-sized expressions.  Such assignments don't really mean
    2218                 :            :   // anything anyhow.
    2219                 :    1176010 :   if (TREE_TYPE(lhs_tree) == void_type_node
    2220                 :    1176010 :       || int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
    2221                 :    1171000 :       || TREE_TYPE(rhs_tree) == void_type_node
    2222                 :    2347010 :       || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
    2223                 :       5015 :     return this->compound_statement(this->expression_statement(bfn, lhs),
    2224                 :       5015 :                                     this->expression_statement(bfn, rhs));
    2225                 :            : 
    2226                 :    1171000 :   rhs_tree = this->convert_tree(TREE_TYPE(lhs_tree), rhs_tree, location);
    2227                 :            : 
    2228                 :    1171000 :   return this->make_statement(fold_build2_loc(location.gcc_location(),
    2229                 :            :                                               MODIFY_EXPR,
    2230                 :            :                                               void_type_node,
    2231                 :    1171000 :                                               lhs_tree, rhs_tree));
    2232                 :            : }
    2233                 :            : 
    2234                 :            : // Return.
    2235                 :            : 
    2236                 :            : Bstatement*
    2237                 :     315182 : Gcc_backend::return_statement(Bfunction* bfunction,
    2238                 :            :                               const std::vector<Bexpression*>& vals,
    2239                 :            :                               Location location)
    2240                 :            : {
    2241                 :     315182 :   tree fntree = bfunction->get_tree();
    2242                 :     315182 :   if (fntree == error_mark_node)
    2243                 :          0 :     return this->error_statement();
    2244                 :     315182 :   tree result = DECL_RESULT(fntree);
    2245                 :     315182 :   if (result == error_mark_node)
    2246                 :          0 :     return this->error_statement();
    2247                 :            : 
    2248                 :            :   // If the result size is zero bytes, we have set the function type
    2249                 :            :   // to have a result type of void, so don't return anything.
    2250                 :            :   // See the function_type method.
    2251                 :     315182 :   tree res_type = TREE_TYPE(result);
    2252                 :     315182 :   if (res_type == void_type_node || int_size_in_bytes(res_type) == 0)
    2253                 :            :     {
    2254                 :       9413 :       tree stmt_list = NULL_TREE;
    2255                 :       9413 :       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
    2256                 :       9417 :            p != vals.end();
    2257                 :          4 :            p++)
    2258                 :            :         {
    2259                 :          4 :           tree val = (*p)->get_tree();
    2260                 :          4 :           if (val == error_mark_node)
    2261                 :          0 :             return this->error_statement();
    2262                 :          4 :           append_to_statement_list(val, &stmt_list);
    2263                 :            :         }
    2264                 :       9413 :       tree ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
    2265                 :            :                                  void_type_node, NULL_TREE);
    2266                 :       9413 :       append_to_statement_list(ret, &stmt_list);
    2267                 :       9413 :       return this->make_statement(stmt_list);
    2268                 :            :     }
    2269                 :            : 
    2270                 :     305769 :   tree ret;
    2271                 :     305769 :   if (vals.empty())
    2272                 :          0 :     ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
    2273                 :            :                           NULL_TREE);
    2274                 :     305769 :   else if (vals.size() == 1)
    2275                 :            :     {
    2276                 :     253350 :       tree val = vals.front()->get_tree();
    2277                 :     253350 :       if (val == error_mark_node)
    2278                 :          0 :         return this->error_statement();
    2279                 :     253350 :       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
    2280                 :            :                                  void_type_node, result,
    2281                 :     253350 :                                  vals.front()->get_tree());
    2282                 :     253350 :       ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
    2283                 :            :                             void_type_node, set);
    2284                 :            :     }
    2285                 :            :   else
    2286                 :            :     {
    2287                 :            :       // To return multiple values, copy the values into a temporary
    2288                 :            :       // variable of the right structure type, and then assign the
    2289                 :            :       // temporary variable to the DECL_RESULT in the return
    2290                 :            :       // statement.
    2291                 :      52419 :       tree stmt_list = NULL_TREE;
    2292                 :      52419 :       tree rettype = TREE_TYPE(result);
    2293                 :            : 
    2294                 :      52419 :       if (DECL_STRUCT_FUNCTION(fntree) == NULL)
    2295                 :        248 :         push_struct_function(fntree);
    2296                 :            :       else
    2297                 :      52171 :         push_cfun(DECL_STRUCT_FUNCTION(fntree));
    2298                 :      52419 :       tree rettmp = create_tmp_var(rettype, "RESULT");
    2299                 :      52419 :       pop_cfun();
    2300                 :            : 
    2301                 :      52419 :       tree field = TYPE_FIELDS(rettype);
    2302                 :      52419 :       for (std::vector<Bexpression*>::const_iterator p = vals.begin();
    2303                 :     167553 :            p != vals.end();
    2304                 :     115134 :            p++, field = DECL_CHAIN(field))
    2305                 :            :         {
    2306                 :     115134 :           gcc_assert(field != NULL_TREE);
    2307                 :     115134 :           tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
    2308                 :     115134 :                                      TREE_TYPE(field), rettmp, field,
    2309                 :            :                                      NULL_TREE);
    2310                 :     115134 :           tree val = (*p)->get_tree();
    2311                 :     115134 :           if (val == error_mark_node)
    2312                 :          0 :             return this->error_statement();
    2313                 :     230268 :           tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
    2314                 :            :                                      void_type_node,
    2315                 :     115134 :                                      ref, (*p)->get_tree());
    2316                 :     115134 :           append_to_statement_list(set, &stmt_list);
    2317                 :            :         }
    2318                 :      52419 :       gcc_assert(field == NULL_TREE);
    2319                 :      52419 :       tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
    2320                 :            :                                  void_type_node,
    2321                 :            :                                  result, rettmp);
    2322                 :      52419 :       tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
    2323                 :            :                                       void_type_node, set);
    2324                 :      52419 :       append_to_statement_list(ret_expr, &stmt_list);
    2325                 :      52419 :       ret = stmt_list;
    2326                 :            :     }
    2327                 :     305769 :   return this->make_statement(ret);
    2328                 :            : }
    2329                 :            : 
    2330                 :            : // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an
    2331                 :            : // error occurs.  EXCEPT_STMT may be NULL.  FINALLY_STMT may be NULL and if not
    2332                 :            : // NULL, it will always be executed.  This is used for handling defers in Go
    2333                 :            : // functions.  In C++, the resulting code is of this form:
    2334                 :            : //   try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
    2335                 :            : 
    2336                 :            : Bstatement*
    2337                 :       7278 : Gcc_backend::exception_handler_statement(Bstatement* bstat,
    2338                 :            :                                          Bstatement* except_stmt,
    2339                 :            :                                          Bstatement* finally_stmt,
    2340                 :            :                                          Location location)
    2341                 :            : {
    2342                 :       7278 :   tree stat_tree = bstat->get_tree();
    2343                 :       7278 :   tree except_tree = except_stmt == NULL ? NULL_TREE : except_stmt->get_tree();
    2344                 :       7278 :   tree finally_tree = finally_stmt == NULL
    2345                 :       7278 :       ? NULL_TREE
    2346                 :       7278 :       : finally_stmt->get_tree();
    2347                 :            : 
    2348                 :       7278 :   if (stat_tree == error_mark_node
    2349                 :       7278 :       || except_tree == error_mark_node
    2350                 :       7278 :       || finally_tree == error_mark_node)
    2351                 :          0 :     return this->error_statement();
    2352                 :            : 
    2353                 :       7278 :   if (except_tree != NULL_TREE)
    2354                 :      14556 :     stat_tree = build2_loc(location.gcc_location(), TRY_CATCH_EXPR,
    2355                 :            :                            void_type_node, stat_tree,
    2356                 :            :                            build2_loc(location.gcc_location(), CATCH_EXPR,
    2357                 :            :                                       void_type_node, NULL, except_tree));
    2358                 :       7278 :   if (finally_tree != NULL_TREE)
    2359                 :       7278 :     stat_tree = build2_loc(location.gcc_location(), TRY_FINALLY_EXPR,
    2360                 :            :                            void_type_node, stat_tree, finally_tree);
    2361                 :       7278 :   return this->make_statement(stat_tree);
    2362                 :            : }
    2363                 :            : 
    2364                 :            : // If.
    2365                 :            : 
    2366                 :            : Bstatement*
    2367                 :     590352 : Gcc_backend::if_statement(Bfunction*, Bexpression* condition,
    2368                 :            :                           Bblock* then_block, Bblock* else_block,
    2369                 :            :                           Location location)
    2370                 :            : {
    2371                 :     590352 :   tree cond_tree = condition->get_tree();
    2372                 :     590352 :   tree then_tree = then_block->get_tree();
    2373                 :     590352 :   tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
    2374                 :     590352 :   if (cond_tree == error_mark_node
    2375                 :     590342 :       || then_tree == error_mark_node
    2376                 :     590342 :       || else_tree == error_mark_node)
    2377                 :         10 :     return this->error_statement();
    2378                 :     590342 :   tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
    2379                 :            :                         cond_tree, then_tree, else_tree);
    2380                 :     590342 :   return this->make_statement(ret);
    2381                 :            : }
    2382                 :            : 
    2383                 :            : // Switch.
    2384                 :            : 
    2385                 :            : Bstatement*
    2386                 :       7272 : Gcc_backend::switch_statement(
    2387                 :            :     Bfunction* function,
    2388                 :            :     Bexpression* value,
    2389                 :            :     const std::vector<std::vector<Bexpression*> >& cases,
    2390                 :            :     const std::vector<Bstatement*>& statements,
    2391                 :            :     Location switch_location)
    2392                 :            : {
    2393                 :       7272 :   gcc_assert(cases.size() == statements.size());
    2394                 :            : 
    2395                 :       7272 :   tree decl = function->get_tree();
    2396                 :       7272 :   if (DECL_STRUCT_FUNCTION(decl) == NULL)
    2397                 :          1 :     push_struct_function(decl);
    2398                 :            :   else
    2399                 :       7271 :     push_cfun(DECL_STRUCT_FUNCTION(decl));
    2400                 :            : 
    2401                 :       7272 :   tree stmt_list = NULL_TREE;
    2402                 :       7272 :   std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
    2403                 :      37597 :   for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
    2404                 :      37597 :        ps != statements.end();
    2405                 :      37597 :        ++ps, ++pc)
    2406                 :            :     {
    2407                 :      30326 :       if (pc->empty())
    2408                 :            :         {
    2409                 :       4386 :           location_t loc = (*ps != NULL
    2410                 :       4386 :                             ? EXPR_LOCATION((*ps)->get_tree())
    2411                 :       4386 :                             : UNKNOWN_LOCATION);
    2412                 :       4386 :           tree label = create_artificial_label(loc);
    2413                 :       4386 :           tree c = build_case_label(NULL_TREE, NULL_TREE, label);
    2414                 :       4386 :           append_to_statement_list(c, &stmt_list);
    2415                 :            :         }
    2416                 :            :       else
    2417                 :            :         {
    2418                 :      37801 :           for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
    2419                 :      63741 :                pcv != pc->end();
    2420                 :      63741 :                ++pcv)
    2421                 :            :             {
    2422                 :      37801 :               tree t = (*pcv)->get_tree();
    2423                 :      37801 :               if (t == error_mark_node)
    2424                 :          0 :                 return this->error_statement();
    2425                 :      37801 :               location_t loc = EXPR_LOCATION(t);
    2426                 :      37801 :               tree label = create_artificial_label(loc);
    2427                 :      37801 :               tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
    2428                 :      37801 :               append_to_statement_list(c, &stmt_list);
    2429                 :            :             }
    2430                 :            :         }
    2431                 :            : 
    2432                 :      30326 :       if (*ps != NULL)
    2433                 :            :         {
    2434                 :      30311 :           tree t = (*ps)->get_tree();
    2435                 :      30311 :           if (t == error_mark_node)
    2436                 :          1 :             return this->error_statement();
    2437                 :      30310 :           append_to_statement_list(t, &stmt_list);
    2438                 :            :         }
    2439                 :            :     }
    2440                 :       7271 :   pop_cfun();
    2441                 :            : 
    2442                 :       7271 :   tree tv = value->get_tree();
    2443                 :       7271 :   if (tv == error_mark_node)
    2444                 :          0 :     return this->error_statement();
    2445                 :       7271 :   tree t = build2_loc(switch_location.gcc_location(), SWITCH_EXPR,
    2446                 :            :                       NULL_TREE, tv, stmt_list);
    2447                 :       7271 :   return this->make_statement(t);
    2448                 :            : }
    2449                 :            : 
    2450                 :            : // Pair of statements.
    2451                 :            : 
    2452                 :            : Bstatement*
    2453                 :     576276 : Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
    2454                 :            : {
    2455                 :     576276 :   tree stmt_list = NULL_TREE;
    2456                 :     576276 :   tree t = s1->get_tree();
    2457                 :     576276 :   if (t == error_mark_node)
    2458                 :          4 :     return this->error_statement();
    2459                 :     576272 :   append_to_statement_list(t, &stmt_list);
    2460                 :     576272 :   t = s2->get_tree();
    2461                 :     576272 :   if (t == error_mark_node)
    2462                 :          9 :     return this->error_statement();
    2463                 :     576263 :   append_to_statement_list(t, &stmt_list);
    2464                 :            : 
    2465                 :            :   // If neither statement has any side effects, stmt_list can be NULL
    2466                 :            :   // at this point.
    2467                 :     576263 :   if (stmt_list == NULL_TREE)
    2468                 :       5013 :     stmt_list = integer_zero_node;
    2469                 :            : 
    2470                 :     576263 :   return this->make_statement(stmt_list);
    2471                 :            : }
    2472                 :            : 
    2473                 :            : // List of statements.
    2474                 :            : 
    2475                 :            : Bstatement*
    2476                 :     283000 : Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
    2477                 :            : {
    2478                 :     283000 :   tree stmt_list = NULL_TREE;
    2479                 :     590196 :   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
    2480                 :     590196 :        p != statements.end();
    2481                 :     590196 :        ++p)
    2482                 :            :     {
    2483                 :     307218 :       tree t = (*p)->get_tree();
    2484                 :     307218 :       if (t == error_mark_node)
    2485                 :         22 :         return this->error_statement();
    2486                 :     307196 :       append_to_statement_list(t, &stmt_list);
    2487                 :            :     }
    2488                 :     282978 :   return this->make_statement(stmt_list);
    2489                 :            : }
    2490                 :            : 
    2491                 :            : // Make a block.  For some reason gcc uses a dual structure for
    2492                 :            : // blocks: BLOCK tree nodes and BIND_EXPR tree nodes.  Since the
    2493                 :            : // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
    2494                 :            : // the Bblock.
    2495                 :            : 
    2496                 :            : Bblock*
    2497                 :    2401530 : Gcc_backend::block(Bfunction* function, Bblock* enclosing,
    2498                 :            :                    const std::vector<Bvariable*>& vars,
    2499                 :            :                    Location start_location,
    2500                 :            :                    Location)
    2501                 :            : {
    2502                 :    2401530 :   tree block_tree = make_node(BLOCK);
    2503                 :    2401530 :   if (enclosing == NULL)
    2504                 :            :     {
    2505                 :     456657 :       tree fndecl = function->get_tree();
    2506                 :     456657 :       gcc_assert(fndecl != NULL_TREE);
    2507                 :            : 
    2508                 :            :       // We may have already created a block for local variables when
    2509                 :            :       // we take the address of a parameter.
    2510                 :     456657 :       if (DECL_INITIAL(fndecl) == NULL_TREE)
    2511                 :            :         {
    2512                 :     250637 :           BLOCK_SUPERCONTEXT(block_tree) = fndecl;
    2513                 :     250637 :           DECL_INITIAL(fndecl) = block_tree;
    2514                 :            :         }
    2515                 :            :       else
    2516                 :            :         {
    2517                 :     206020 :           tree superblock_tree = DECL_INITIAL(fndecl);
    2518                 :     206020 :           BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
    2519                 :     206020 :           tree* pp;
    2520                 :     206020 :           for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
    2521                 :    1127580 :                *pp != NULL_TREE;
    2522                 :     921560 :                pp = &BLOCK_CHAIN(*pp))
    2523                 :            :             ;
    2524                 :     206020 :           *pp = block_tree;
    2525                 :            :         }
    2526                 :            :     }
    2527                 :            :   else
    2528                 :            :     {
    2529                 :    1944870 :       tree superbind_tree = enclosing->get_tree();
    2530                 :    1944870 :       tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
    2531                 :    1944870 :       gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
    2532                 :            : 
    2533                 :    1944870 :       BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
    2534                 :    1944870 :       tree* pp;
    2535                 :    1944870 :       for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
    2536                 :    7529240 :            *pp != NULL_TREE;
    2537                 :    5584370 :            pp = &BLOCK_CHAIN(*pp))
    2538                 :            :         ;
    2539                 :    1944870 :       *pp = block_tree;
    2540                 :            :     }
    2541                 :            : 
    2542                 :    2401530 :   tree* pp = &BLOCK_VARS(block_tree);
    2543                 :    2926610 :   for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
    2544                 :    2926610 :        pv != vars.end();
    2545                 :    2926610 :        ++pv)
    2546                 :            :     {
    2547                 :     525084 :       *pp = (*pv)->get_decl();
    2548                 :     525084 :       if (*pp != error_mark_node)
    2549                 :     525059 :         pp = &DECL_CHAIN(*pp);
    2550                 :            :     }
    2551                 :    2401530 :   *pp = NULL_TREE;
    2552                 :            : 
    2553                 :    2401530 :   TREE_USED(block_tree) = 1;
    2554                 :            : 
    2555                 :    2401530 :   tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
    2556                 :    2401530 :                               void_type_node, BLOCK_VARS(block_tree),
    2557                 :            :                               NULL_TREE, block_tree);
    2558                 :    2401530 :   TREE_SIDE_EFFECTS(bind_tree) = 1;
    2559                 :    2401530 :   return new Bblock(bind_tree);
    2560                 :            : }
    2561                 :            : 
    2562                 :            : // Add statements to a block.
    2563                 :            : 
    2564                 :            : void
    2565                 :    2398830 : Gcc_backend::block_add_statements(Bblock* bblock,
    2566                 :            :                                   const std::vector<Bstatement*>& statements)
    2567                 :            : {
    2568                 :    2398830 :   tree stmt_list = NULL_TREE;
    2569                 :    8712740 :   for (std::vector<Bstatement*>::const_iterator p = statements.begin();
    2570                 :    8712740 :        p != statements.end();
    2571                 :    8712740 :        ++p)
    2572                 :            :     {
    2573                 :    6313910 :       tree s = (*p)->get_tree();
    2574                 :    6313910 :       if (s != error_mark_node)
    2575                 :    6310170 :         append_to_statement_list(s, &stmt_list);
    2576                 :            :     }
    2577                 :            : 
    2578                 :    2398830 :   tree bind_tree = bblock->get_tree();
    2579                 :    2398830 :   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
    2580                 :    2398830 :   BIND_EXPR_BODY(bind_tree) = stmt_list;
    2581                 :    2398830 : }
    2582                 :            : 
    2583                 :            : // Return a block as a statement.
    2584                 :            : 
    2585                 :            : Bstatement*
    2586                 :    1605670 : Gcc_backend::block_statement(Bblock* bblock)
    2587                 :            : {
    2588                 :    1605670 :   tree bind_tree = bblock->get_tree();
    2589                 :    1605670 :   gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
    2590                 :    1605670 :   return this->make_statement(bind_tree);
    2591                 :            : }
    2592                 :            : 
    2593                 :            : // This is not static because we declare it with GTY(()) in go-c.h.
    2594                 :            : tree go_non_zero_struct;
    2595                 :            : 
    2596                 :            : // Return a type corresponding to TYPE with non-zero size.
    2597                 :            : 
    2598                 :            : tree
    2599                 :        356 : Gcc_backend::non_zero_size_type(tree type)
    2600                 :            : {
    2601                 :        356 :   if (int_size_in_bytes(type) != 0)
    2602                 :            :     return type;
    2603                 :            : 
    2604                 :        354 :   switch (TREE_CODE(type))
    2605                 :            :     {
    2606                 :        348 :     case RECORD_TYPE:
    2607                 :        348 :       if (TYPE_FIELDS(type) != NULL_TREE)
    2608                 :            :         {
    2609                 :          1 :           tree ns = make_node(RECORD_TYPE);
    2610                 :          1 :           tree field_trees = NULL_TREE;
    2611                 :          1 :           tree *pp = &field_trees;
    2612                 :          1 :           for (tree field = TYPE_FIELDS(type);
    2613                 :          5 :                field != NULL_TREE;
    2614                 :          4 :                field = DECL_CHAIN(field))
    2615                 :            :             {
    2616                 :          4 :               tree ft = TREE_TYPE(field);
    2617                 :          4 :               if (field == TYPE_FIELDS(type))
    2618                 :          1 :                 ft = non_zero_size_type(ft);
    2619                 :          4 :               tree f = build_decl(DECL_SOURCE_LOCATION(field), FIELD_DECL,
    2620                 :          4 :                                   DECL_NAME(field), ft);
    2621                 :          4 :               DECL_CONTEXT(f) = ns;
    2622                 :          4 :               *pp = f;
    2623                 :          4 :               pp = &DECL_CHAIN(f);
    2624                 :            :             }
    2625                 :          1 :           TYPE_FIELDS(ns) = field_trees;
    2626                 :          1 :           layout_type(ns);
    2627                 :          1 :           return ns;
    2628                 :            :         }
    2629                 :            : 
    2630                 :        347 :       if (go_non_zero_struct == NULL_TREE)
    2631                 :            :         {
    2632                 :        243 :           type = make_node(RECORD_TYPE);
    2633                 :        243 :           tree field = build_decl(UNKNOWN_LOCATION, FIELD_DECL,
    2634                 :            :                                   get_identifier("dummy"),
    2635                 :            :                                   boolean_type_node);
    2636                 :        243 :           DECL_CONTEXT(field) = type;
    2637                 :        243 :           TYPE_FIELDS(type) = field;
    2638                 :        243 :           layout_type(type);
    2639                 :        243 :           go_non_zero_struct = type;
    2640                 :            :         }
    2641                 :        347 :       return go_non_zero_struct;
    2642                 :            : 
    2643                 :          6 :     case ARRAY_TYPE:
    2644                 :          6 :       {
    2645                 :          6 :         tree element_type = non_zero_size_type(TREE_TYPE(type));
    2646                 :          6 :         return build_array_type_nelts(element_type, 1);
    2647                 :            :       }
    2648                 :            : 
    2649                 :          0 :     default:
    2650                 :          0 :       gcc_unreachable();
    2651                 :            :     }
    2652                 :            : 
    2653                 :            :   gcc_unreachable();
    2654                 :            : }
    2655                 :            : 
    2656                 :            : // Convert EXPR_TREE to TYPE_TREE.  Sometimes the same unnamed Go type
    2657                 :            : // can be created multiple times and thus have multiple tree
    2658                 :            : // representations.  Make sure this does not confuse the middle-end.
    2659                 :            : 
    2660                 :            : tree
    2661                 :   11717900 : Gcc_backend::convert_tree(tree type_tree, tree expr_tree, Location location)
    2662                 :            : {
    2663                 :   11717900 :   if (type_tree == TREE_TYPE(expr_tree))
    2664                 :            :     return expr_tree;
    2665                 :            : 
    2666                 :    2372530 :   if (type_tree == error_mark_node
    2667                 :    2372530 :       || expr_tree == error_mark_node
    2668                 :    4745060 :       || TREE_TYPE(expr_tree) == error_mark_node)
    2669                 :            :     return error_mark_node;
    2670                 :            : 
    2671                 :    2372530 :   gcc_assert(TREE_CODE(type_tree) == TREE_CODE(TREE_TYPE(expr_tree)));
    2672                 :    2372530 :   if (POINTER_TYPE_P(type_tree)
    2673                 :    2372530 :       || INTEGRAL_TYPE_P(type_tree)
    2674                 :     156697 :       || SCALAR_FLOAT_TYPE_P(type_tree)
    2675                 :    2529230 :       || COMPLEX_FLOAT_TYPE_P(type_tree))
    2676                 :    2215830 :     return fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
    2677                 :     156697 :   else if (TREE_CODE(type_tree) == RECORD_TYPE
    2678                 :     156697 :            || TREE_CODE(type_tree) == ARRAY_TYPE)
    2679                 :            :     {
    2680                 :     156697 :       gcc_assert(int_size_in_bytes(type_tree)
    2681                 :            :                  == int_size_in_bytes(TREE_TYPE(expr_tree)));
    2682                 :     156697 :       if (TYPE_MAIN_VARIANT(type_tree)
    2683                 :     156697 :           == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree)))
    2684                 :      86363 :         return fold_build1_loc(location.gcc_location(), NOP_EXPR,
    2685                 :      86363 :                                type_tree, expr_tree);
    2686                 :      70334 :       return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
    2687                 :      70334 :                              type_tree, expr_tree);
    2688                 :            :     }
    2689                 :            : 
    2690                 :          0 :   gcc_unreachable();
    2691                 :            : }
    2692                 :            : 
    2693                 :            : // Make a global variable.
    2694                 :            : 
    2695                 :            : Bvariable*
    2696                 :      30103 : Gcc_backend::global_variable(const std::string& var_name,
    2697                 :            :                              const std::string& asm_name,
    2698                 :            :                              Btype* btype,
    2699                 :            :                              bool is_external,
    2700                 :            :                              bool is_hidden,
    2701                 :            :                              bool in_unique_section,
    2702                 :            :                              Location location)
    2703                 :            : {
    2704                 :      30103 :   tree type_tree = btype->get_tree();
    2705                 :      30103 :   if (type_tree == error_mark_node)
    2706                 :          7 :     return this->error_variable();
    2707                 :            : 
    2708                 :            :   // The GNU linker does not like dynamic variables with zero size.
    2709                 :      30096 :   tree orig_type_tree = type_tree;
    2710                 :      30096 :   if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
    2711                 :        349 :     type_tree = this->non_zero_size_type(type_tree);
    2712                 :            : 
    2713                 :      30096 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    2714                 :            :                          get_identifier_from_string(var_name),
    2715                 :            :                          type_tree);
    2716                 :      30096 :   if (is_external)
    2717                 :       7707 :     DECL_EXTERNAL(decl) = 1;
    2718                 :            :   else
    2719                 :      22389 :     TREE_STATIC(decl) = 1;
    2720                 :      30096 :   if (!is_hidden)
    2721                 :            :     {
    2722                 :      14491 :       TREE_PUBLIC(decl) = 1;
    2723                 :      14491 :       SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    2724                 :            :     }
    2725                 :            :   else
    2726                 :            :     {
    2727                 :      15605 :       SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    2728                 :            :     }
    2729                 :            : 
    2730                 :      30096 :   TREE_USED(decl) = 1;
    2731                 :            : 
    2732                 :      30096 :   if (in_unique_section)
    2733                 :          0 :     resolve_unique_section (decl, 0, 1);
    2734                 :            : 
    2735                 :      30096 :   go_preserve_from_gc(decl);
    2736                 :            : 
    2737                 :      30096 :   return new Bvariable(decl, orig_type_tree);
    2738                 :            : }
    2739                 :            : 
    2740                 :            : // Set the initial value of a global variable.
    2741                 :            : 
    2742                 :            : void
    2743                 :       6305 : Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
    2744                 :            : {
    2745                 :       6305 :   tree expr_tree = expr->get_tree();
    2746                 :       6305 :   if (expr_tree == error_mark_node)
    2747                 :            :     return;
    2748                 :       6305 :   gcc_assert(TREE_CONSTANT(expr_tree));
    2749                 :       6305 :   tree var_decl = var->get_decl();
    2750                 :       6305 :   if (var_decl == error_mark_node)
    2751                 :            :     return;
    2752                 :       6305 :   DECL_INITIAL(var_decl) = expr_tree;
    2753                 :            : 
    2754                 :            :   // If this variable goes in a unique section, it may need to go into
    2755                 :            :   // a different one now that DECL_INITIAL is set.
    2756                 :       6305 :   if (symtab_node::get(var_decl)
    2757                 :       6305 :       && symtab_node::get(var_decl)->implicit_section)
    2758                 :            :     {
    2759                 :          0 :       set_decl_section_name (var_decl, NULL);
    2760                 :          0 :       resolve_unique_section (var_decl,
    2761                 :            :                               compute_reloc_for_constant (expr_tree),
    2762                 :            :                               1);
    2763                 :            :     }
    2764                 :            : }
    2765                 :            : 
    2766                 :            : // Make a local variable.
    2767                 :            : 
    2768                 :            : Bvariable*
    2769                 :     525068 : Gcc_backend::local_variable(Bfunction* function, const std::string& name,
    2770                 :            :                             Btype* btype, Bvariable* decl_var, 
    2771                 :            :                             bool is_address_taken, Location location)
    2772                 :            : {
    2773                 :     525068 :   tree type_tree = btype->get_tree();
    2774                 :     525068 :   if (type_tree == error_mark_node)
    2775                 :          4 :     return this->error_variable();
    2776                 :     525064 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    2777                 :            :                          get_identifier_from_string(name),
    2778                 :            :                          type_tree);
    2779                 :     525064 :   DECL_CONTEXT(decl) = function->get_tree();
    2780                 :     525064 :   TREE_USED(decl) = 1;
    2781                 :     525064 :   if (is_address_taken)
    2782                 :      20923 :     TREE_ADDRESSABLE(decl) = 1;
    2783                 :     525064 :   if (decl_var != NULL)
    2784                 :            :     {
    2785                 :       5189 :       DECL_HAS_VALUE_EXPR_P(decl) = 1;
    2786                 :       5189 :       SET_DECL_VALUE_EXPR(decl, decl_var->get_decl());
    2787                 :            :     }
    2788                 :     525064 :   go_preserve_from_gc(decl);
    2789                 :     525064 :   return new Bvariable(decl);
    2790                 :            : }
    2791                 :            : 
    2792                 :            : // Make a function parameter variable.
    2793                 :            : 
    2794                 :            : Bvariable*
    2795                 :     395764 : Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
    2796                 :            :                                 Btype* btype, bool is_address_taken,
    2797                 :            :                                 Location location)
    2798                 :            : {
    2799                 :     395764 :   tree type_tree = btype->get_tree();
    2800                 :     395764 :   if (type_tree == error_mark_node)
    2801                 :          5 :     return this->error_variable();
    2802                 :     395759 :   tree decl = build_decl(location.gcc_location(), PARM_DECL,
    2803                 :            :                          get_identifier_from_string(name),
    2804                 :            :                          type_tree);
    2805                 :     395759 :   DECL_CONTEXT(decl) = function->get_tree();
    2806                 :     395759 :   DECL_ARG_TYPE(decl) = type_tree;
    2807                 :     395759 :   TREE_USED(decl) = 1;
    2808                 :     395759 :   if (is_address_taken)
    2809                 :       6411 :     TREE_ADDRESSABLE(decl) = 1;
    2810                 :     395759 :   go_preserve_from_gc(decl);
    2811                 :     395759 :   return new Bvariable(decl);
    2812                 :            : }
    2813                 :            : 
    2814                 :            : // Make a static chain variable.
    2815                 :            : 
    2816                 :            : Bvariable*
    2817                 :      11325 : Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
    2818                 :            :                                    Btype* btype, Location location)
    2819                 :            : {
    2820                 :      11325 :   tree type_tree = btype->get_tree();
    2821                 :      11325 :   if (type_tree == error_mark_node)
    2822                 :          0 :     return this->error_variable();
    2823                 :      11325 :   tree decl = build_decl(location.gcc_location(), PARM_DECL,
    2824                 :            :                          get_identifier_from_string(name), type_tree);
    2825                 :      11325 :   tree fndecl = function->get_tree();
    2826                 :      11325 :   DECL_CONTEXT(decl) = fndecl;
    2827                 :      11325 :   DECL_ARG_TYPE(decl) = type_tree;
    2828                 :      11325 :   TREE_USED(decl) = 1;
    2829                 :      11325 :   DECL_ARTIFICIAL(decl) = 1;
    2830                 :      11325 :   DECL_IGNORED_P(decl) = 1;
    2831                 :      11325 :   TREE_READONLY(decl) = 1;
    2832                 :            : 
    2833                 :      11325 :   struct function *f = DECL_STRUCT_FUNCTION(fndecl);
    2834                 :      11325 :   if (f == NULL)
    2835                 :            :     {
    2836                 :      11325 :       push_struct_function(fndecl);
    2837                 :      11325 :       pop_cfun();
    2838                 :      11325 :       f = DECL_STRUCT_FUNCTION(fndecl);
    2839                 :            :     }
    2840                 :      11325 :   gcc_assert(f->static_chain_decl == NULL);
    2841                 :      11325 :   f->static_chain_decl = decl;
    2842                 :      11325 :   DECL_STATIC_CHAIN(fndecl) = 1;
    2843                 :            : 
    2844                 :      11325 :   go_preserve_from_gc(decl);
    2845                 :      11325 :   return new Bvariable(decl);
    2846                 :            : }
    2847                 :            : 
    2848                 :            : // Make a temporary variable.
    2849                 :            : 
    2850                 :            : Bvariable*
    2851                 :    2139410 : Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
    2852                 :            :                                 Btype* btype, Bexpression* binit,
    2853                 :            :                                 bool is_address_taken,
    2854                 :            :                                 Location location,
    2855                 :            :                                 Bstatement** pstatement)
    2856                 :            : {
    2857                 :    2139410 :   gcc_assert(function != NULL);
    2858                 :    2139410 :   tree decl = function->get_tree();
    2859                 :    2139410 :   tree type_tree = btype->get_tree();
    2860                 :    2139410 :   tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
    2861                 :    2139410 :   if (type_tree == error_mark_node
    2862                 :    2139410 :       || init_tree == error_mark_node
    2863                 :    2139410 :       || decl == error_mark_node)
    2864                 :            :     {
    2865                 :          3 :       *pstatement = this->error_statement();
    2866                 :          3 :       return this->error_variable();
    2867                 :            :     }
    2868                 :            : 
    2869                 :    2139410 :   tree var;
    2870                 :            :   // We can only use create_tmp_var if the type is not addressable.
    2871                 :    2139410 :   if (!TREE_ADDRESSABLE(type_tree))
    2872                 :            :     {
    2873                 :    2139410 :       if (DECL_STRUCT_FUNCTION(decl) == NULL)
    2874                 :     192262 :         push_struct_function(decl);
    2875                 :            :       else
    2876                 :    1947150 :         push_cfun(DECL_STRUCT_FUNCTION(decl));
    2877                 :            : 
    2878                 :    2139410 :       var = create_tmp_var(type_tree, "GOTMP");
    2879                 :    2139410 :       pop_cfun();
    2880                 :            :     }
    2881                 :            :   else
    2882                 :            :     {
    2883                 :          0 :       gcc_assert(bblock != NULL);
    2884                 :          0 :       var = build_decl(location.gcc_location(), VAR_DECL,
    2885                 :            :                        create_tmp_var_name("GOTMP"),
    2886                 :            :                        type_tree);
    2887                 :          0 :       DECL_ARTIFICIAL(var) = 1;
    2888                 :          0 :       DECL_IGNORED_P(var) = 1;
    2889                 :          0 :       TREE_USED(var) = 1;
    2890                 :          0 :       DECL_CONTEXT(var) = decl;
    2891                 :            : 
    2892                 :            :       // We have to add this variable to the BLOCK and the BIND_EXPR.
    2893                 :          0 :       tree bind_tree = bblock->get_tree();
    2894                 :          0 :       gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
    2895                 :          0 :       tree block_tree = BIND_EXPR_BLOCK(bind_tree);
    2896                 :          0 :       gcc_assert(TREE_CODE(block_tree) == BLOCK);
    2897                 :          0 :       DECL_CHAIN(var) = BLOCK_VARS(block_tree);
    2898                 :          0 :       BLOCK_VARS(block_tree) = var;
    2899                 :          0 :       BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
    2900                 :            :     }
    2901                 :            : 
    2902                 :    2139410 :   if (this->type_size(btype) != 0
    2903                 :    2136730 :       && init_tree != NULL_TREE
    2904                 :    4099150 :       && TREE_TYPE(init_tree) != void_type_node)
    2905                 :    1959740 :     DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location);
    2906                 :            : 
    2907                 :    2139410 :   if (is_address_taken)
    2908                 :     353678 :     TREE_ADDRESSABLE(var) = 1;
    2909                 :            : 
    2910                 :    4278820 :   *pstatement = this->make_statement(build1_loc(location.gcc_location(),
    2911                 :            :                                                 DECL_EXPR,
    2912                 :            :                                                 void_type_node, var));
    2913                 :            : 
    2914                 :            :   // For a zero sized type, don't initialize VAR with BINIT, but still
    2915                 :            :   // evaluate BINIT for its side effects.
    2916                 :    2139410 :   if (init_tree != NULL_TREE
    2917                 :    2139410 :       && (this->type_size(btype) == 0
    2918                 :    1959740 :           || TREE_TYPE(init_tree) == void_type_node))
    2919                 :       1287 :     *pstatement =
    2920                 :       1287 :       this->compound_statement(this->expression_statement(function, binit),
    2921                 :       1287 :                                *pstatement);
    2922                 :            : 
    2923                 :    2139410 :   return new Bvariable(var);
    2924                 :            : }
    2925                 :            : 
    2926                 :            : // Create an implicit variable that is compiler-defined.  This is used when
    2927                 :            : // generating GC root variables and storing the values of a slice initializer.
    2928                 :            : 
    2929                 :            : Bvariable*
    2930                 :     284885 : Gcc_backend::implicit_variable(const std::string& name,
    2931                 :            :                                const std::string& asm_name,
    2932                 :            :                                Btype* type, bool is_hidden, bool is_constant,
    2933                 :            :                                bool is_common, int64_t alignment)
    2934                 :            : {
    2935                 :     284885 :   tree type_tree = type->get_tree();
    2936                 :     284885 :   if (type_tree == error_mark_node)
    2937                 :          0 :     return this->error_variable();
    2938                 :            : 
    2939                 :     284885 :   tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
    2940                 :            :                          get_identifier_from_string(name), type_tree);
    2941                 :     284885 :   DECL_EXTERNAL(decl) = 0;
    2942                 :     284885 :   TREE_PUBLIC(decl) = !is_hidden;
    2943                 :     284885 :   TREE_STATIC(decl) = 1;
    2944                 :     284885 :   TREE_USED(decl) = 1;
    2945                 :     284885 :   DECL_ARTIFICIAL(decl) = 1;
    2946                 :     284885 :   if (is_common)
    2947                 :            :     {
    2948                 :      20360 :       DECL_COMMON(decl) = 1;
    2949                 :            : 
    2950                 :            :       // When the initializer for one implicit_variable refers to another,
    2951                 :            :       // it needs to know the visibility of the referenced struct so that
    2952                 :            :       // compute_reloc_for_constant will return the right value.  On many
    2953                 :            :       // systems calling make_decl_one_only will mark the decl as weak,
    2954                 :            :       // which will change the return value of compute_reloc_for_constant.
    2955                 :            :       // We can't reliably call make_decl_one_only yet, because we don't
    2956                 :            :       // yet know the initializer.  This issue doesn't arise in C because
    2957                 :            :       // Go initializers, unlike C initializers, can be indirectly
    2958                 :            :       // recursive.  To ensure that compute_reloc_for_constant computes
    2959                 :            :       // the right value if some other initializer refers to this one, we
    2960                 :            :       // mark this symbol as weak here.  We undo that below in
    2961                 :            :       // immutable_struct_set_init before calling mark_decl_one_only.
    2962                 :      20360 :       DECL_WEAK(decl) = 1;
    2963                 :            :     }
    2964                 :     284885 :   if (is_constant)
    2965                 :            :     {
    2966                 :     275338 :       TREE_READONLY(decl) = 1;
    2967                 :     275338 :       TREE_CONSTANT(decl) = 1;
    2968                 :            :     }
    2969                 :     284885 :   if (alignment != 0)
    2970                 :            :     {
    2971                 :          3 :       SET_DECL_ALIGN(decl, alignment * BITS_PER_UNIT);
    2972                 :          3 :       DECL_USER_ALIGN(decl) = 1;
    2973                 :            :     }
    2974                 :     284885 :   if (! asm_name.empty())
    2975                 :       4838 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    2976                 :            : 
    2977                 :     284885 :   go_preserve_from_gc(decl);
    2978                 :     284885 :   return new Bvariable(decl);
    2979                 :            : }
    2980                 :            : 
    2981                 :            : // Set the initalizer for a variable created by implicit_variable.
    2982                 :            : // This is where we finish compiling the variable.
    2983                 :            : 
    2984                 :            : void
    2985                 :     284885 : Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
    2986                 :            :                                         Btype*, bool, bool, bool is_common,
    2987                 :            :                                         Bexpression* init)
    2988                 :            : {
    2989                 :     284885 :   tree decl = var->get_decl();
    2990                 :     284885 :   tree init_tree;
    2991                 :     284885 :   if (init == NULL)
    2992                 :            :     init_tree = NULL_TREE;
    2993                 :            :   else
    2994                 :     284882 :     init_tree = init->get_tree();
    2995                 :     284885 :   if (decl == error_mark_node || init_tree == error_mark_node)
    2996                 :            :     return;
    2997                 :            : 
    2998                 :     284885 :   DECL_INITIAL(decl) = init_tree;
    2999                 :            : 
    3000                 :            :   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
    3001                 :            :   // See the comment where DECL_WEAK is set in implicit_variable.
    3002                 :     284885 :   if (is_common)
    3003                 :            :     {
    3004                 :      20360 :       DECL_WEAK(decl) = 0;
    3005                 :      20360 :       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
    3006                 :            :     }
    3007                 :            : 
    3008                 :     284885 :   resolve_unique_section(decl, 2, 1);
    3009                 :            : 
    3010                 :     284885 :   rest_of_decl_compilation(decl, 1, 0);
    3011                 :            : }
    3012                 :            : 
    3013                 :            : // Return a reference to an implicit variable defined in another package.
    3014                 :            : 
    3015                 :            : Bvariable*
    3016                 :      36107 : Gcc_backend::implicit_variable_reference(const std::string& name,
    3017                 :            :                                          const std::string& asm_name,
    3018                 :            :                                          Btype* btype)
    3019                 :            : {
    3020                 :      36107 :   tree type_tree = btype->get_tree();
    3021                 :      36107 :   if (type_tree == error_mark_node)
    3022                 :          0 :     return this->error_variable();
    3023                 :            : 
    3024                 :      36107 :   tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
    3025                 :            :                          get_identifier_from_string(name), type_tree);
    3026                 :      36107 :   DECL_EXTERNAL(decl) = 1;
    3027                 :      36107 :   TREE_PUBLIC(decl) = 1;
    3028                 :      36107 :   TREE_STATIC(decl) = 0;
    3029                 :      36107 :   DECL_ARTIFICIAL(decl) = 1;
    3030                 :      36107 :   if (! asm_name.empty())
    3031                 :      36107 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3032                 :      36107 :   go_preserve_from_gc(decl);
    3033                 :      36107 :   return new Bvariable(decl);
    3034                 :            : }
    3035                 :            : 
    3036                 :            : // Create a named immutable initialized data structure.
    3037                 :            : 
    3038                 :            : Bvariable*
    3039                 :     958537 : Gcc_backend::immutable_struct(const std::string& name,
    3040                 :            :                               const std::string& asm_name,
    3041                 :            :                               bool is_hidden,
    3042                 :            :                               bool is_common, Btype* btype, Location location)
    3043                 :            : {
    3044                 :     958537 :   tree type_tree = btype->get_tree();
    3045                 :     958537 :   if (type_tree == error_mark_node)
    3046                 :          3 :     return this->error_variable();
    3047                 :     958534 :   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
    3048                 :     958534 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    3049                 :            :                          get_identifier_from_string(name),
    3050                 :            :                          build_qualified_type(type_tree, TYPE_QUAL_CONST));
    3051                 :     958534 :   TREE_STATIC(decl) = 1;
    3052                 :     958534 :   TREE_USED(decl) = 1;
    3053                 :     958534 :   TREE_READONLY(decl) = 1;
    3054                 :     958534 :   TREE_CONSTANT(decl) = 1;
    3055                 :     958534 :   DECL_ARTIFICIAL(decl) = 1;
    3056                 :     958534 :   if (!is_hidden)
    3057                 :     276589 :     TREE_PUBLIC(decl) = 1;
    3058                 :     958534 :   if (! asm_name.empty())
    3059                 :     113401 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3060                 :            : 
    3061                 :            :   // When the initializer for one immutable_struct refers to another,
    3062                 :            :   // it needs to know the visibility of the referenced struct so that
    3063                 :            :   // compute_reloc_for_constant will return the right value.  On many
    3064                 :            :   // systems calling make_decl_one_only will mark the decl as weak,
    3065                 :            :   // which will change the return value of compute_reloc_for_constant.
    3066                 :            :   // We can't reliably call make_decl_one_only yet, because we don't
    3067                 :            :   // yet know the initializer.  This issue doesn't arise in C because
    3068                 :            :   // Go initializers, unlike C initializers, can be indirectly
    3069                 :            :   // recursive.  To ensure that compute_reloc_for_constant computes
    3070                 :            :   // the right value if some other initializer refers to this one, we
    3071                 :            :   // mark this symbol as weak here.  We undo that below in
    3072                 :            :   // immutable_struct_set_init before calling mark_decl_one_only.
    3073                 :     958534 :   if (is_common)
    3074                 :     201457 :     DECL_WEAK(decl) = 1;
    3075                 :            : 
    3076                 :            :   // We don't call rest_of_decl_compilation until we have the
    3077                 :            :   // initializer.
    3078                 :            : 
    3079                 :     958534 :   go_preserve_from_gc(decl);
    3080                 :     958534 :   return new Bvariable(decl);
    3081                 :            : }
    3082                 :            : 
    3083                 :            : // Set the initializer for a variable created by immutable_struct.
    3084                 :            : // This is where we finish compiling the variable.
    3085                 :            : 
    3086                 :            : void
    3087                 :     958537 : Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
    3088                 :            :                                        bool, bool is_common, Btype*, Location,
    3089                 :            :                                        Bexpression* initializer)
    3090                 :            : {
    3091                 :     958537 :   tree decl = var->get_decl();
    3092                 :     958537 :   tree init_tree = initializer->get_tree();
    3093                 :     958537 :   if (decl == error_mark_node || init_tree == error_mark_node)
    3094                 :            :     return;
    3095                 :            : 
    3096                 :     958533 :   DECL_INITIAL(decl) = init_tree;
    3097                 :            : 
    3098                 :            :   // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
    3099                 :            :   // See the comment where DECL_WEAK is set in immutable_struct.
    3100                 :     958533 :   if (is_common)
    3101                 :            :     {
    3102                 :     201456 :       DECL_WEAK(decl) = 0;
    3103                 :     201456 :       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
    3104                 :            :     }
    3105                 :            : 
    3106                 :            :   // These variables are often unneeded in the final program, so put
    3107                 :            :   // them in their own section so that linker GC can discard them.
    3108                 :     958533 :   resolve_unique_section(decl,
    3109                 :            :                          compute_reloc_for_constant (init_tree),
    3110                 :            :                          1);
    3111                 :            : 
    3112                 :     958533 :   rest_of_decl_compilation(decl, 1, 0);
    3113                 :            : }
    3114                 :            : 
    3115                 :            : // Return a reference to an immutable initialized data structure
    3116                 :            : // defined in another package.
    3117                 :            : 
    3118                 :            : Bvariable*
    3119                 :     153982 : Gcc_backend::immutable_struct_reference(const std::string& name,
    3120                 :            :                                         const std::string& asm_name,
    3121                 :            :                                         Btype* btype,
    3122                 :            :                                         Location location)
    3123                 :            : {
    3124                 :     153982 :   tree type_tree = btype->get_tree();
    3125                 :     153982 :   if (type_tree == error_mark_node)
    3126                 :          0 :     return this->error_variable();
    3127                 :     153982 :   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
    3128                 :     153982 :   tree decl = build_decl(location.gcc_location(), VAR_DECL,
    3129                 :            :                          get_identifier_from_string(name),
    3130                 :            :                          build_qualified_type(type_tree, TYPE_QUAL_CONST));
    3131                 :     153982 :   TREE_READONLY(decl) = 1;
    3132                 :     153982 :   TREE_CONSTANT(decl) = 1;
    3133                 :     153982 :   DECL_ARTIFICIAL(decl) = 1;
    3134                 :     153982 :   TREE_PUBLIC(decl) = 1;
    3135                 :     153982 :   DECL_EXTERNAL(decl) = 1;
    3136                 :     153982 :   if (! asm_name.empty())
    3137                 :      34567 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3138                 :     153982 :   go_preserve_from_gc(decl);
    3139                 :     153982 :   return new Bvariable(decl);
    3140                 :            : }
    3141                 :            : 
    3142                 :            : // Make a label.
    3143                 :            : 
    3144                 :            : Blabel*
    3145                 :     165287 : Gcc_backend::label(Bfunction* function, const std::string& name,
    3146                 :            :                    Location location)
    3147                 :            : {
    3148                 :     165287 :   tree decl;
    3149                 :     165287 :   if (name.empty())
    3150                 :            :     {
    3151                 :     157546 :       tree func_tree = function->get_tree();
    3152                 :     157546 :       if (DECL_STRUCT_FUNCTION(func_tree) == NULL)
    3153                 :       7750 :         push_struct_function(func_tree);
    3154                 :            :       else
    3155                 :     149796 :         push_cfun(DECL_STRUCT_FUNCTION(func_tree));
    3156                 :            : 
    3157                 :     157546 :       decl = create_artificial_label(location.gcc_location());
    3158                 :            : 
    3159                 :     157546 :       pop_cfun();
    3160                 :            :     }
    3161                 :            :   else
    3162                 :            :     {
    3163                 :       7741 :       tree id = get_identifier_from_string(name);
    3164                 :       7741 :       decl = build_decl(location.gcc_location(), LABEL_DECL, id,
    3165                 :            :                         void_type_node);
    3166                 :       7741 :       DECL_CONTEXT(decl) = function->get_tree();
    3167                 :            :     }
    3168                 :     165287 :   return new Blabel(decl);
    3169                 :            : }
    3170                 :            : 
    3171                 :            : // Make a statement which defines a label.
    3172                 :            : 
    3173                 :            : Bstatement*
    3174                 :     165287 : Gcc_backend::label_definition_statement(Blabel* label)
    3175                 :            : {
    3176                 :     165287 :   tree lab = label->get_tree();
    3177                 :     165287 :   tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
    3178                 :            :                              void_type_node, lab);
    3179                 :     165287 :   return this->make_statement(ret);
    3180                 :            : }
    3181                 :            : 
    3182                 :            : // Make a goto statement.
    3183                 :            : 
    3184                 :            : Bstatement*
    3185                 :     209652 : Gcc_backend::goto_statement(Blabel* label, Location location)
    3186                 :            : {
    3187                 :     209652 :   tree lab = label->get_tree();
    3188                 :     209652 :   tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
    3189                 :            :                              lab);
    3190                 :     209652 :   return this->make_statement(ret);
    3191                 :            : }
    3192                 :            : 
    3193                 :            : // Get the address of a label.
    3194                 :            : 
    3195                 :            : Bexpression*
    3196                 :       6234 : Gcc_backend::label_address(Blabel* label, Location location)
    3197                 :            : {
    3198                 :       6234 :   tree lab = label->get_tree();
    3199                 :       6234 :   TREE_USED(lab) = 1;
    3200                 :       6234 :   TREE_ADDRESSABLE(lab) = 1;
    3201                 :       6234 :   tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
    3202                 :            :                               build_fold_addr_expr_loc(location.gcc_location(),
    3203                 :            :                                                        lab));
    3204                 :       6234 :   return this->make_expression(ret);
    3205                 :            : }
    3206                 :            : 
    3207                 :            : // Declare or define a new function.
    3208                 :            : 
    3209                 :            : Bfunction*
    3210                 :     480839 : Gcc_backend::function(Btype* fntype, const std::string& name,
    3211                 :            :                       const std::string& asm_name, unsigned int flags,
    3212                 :            :                       Location location)
    3213                 :            : {
    3214                 :     480839 :   tree functype = fntype->get_tree();
    3215                 :     480839 :   if (functype != error_mark_node)
    3216                 :            :     {
    3217                 :     961654 :       gcc_assert(FUNCTION_POINTER_TYPE_P(functype));
    3218                 :     480839 :       functype = TREE_TYPE(functype);
    3219                 :            :     }
    3220                 :     480839 :   tree id = get_identifier_from_string(name);
    3221                 :     480839 :   if (functype == error_mark_node || id == error_mark_node)
    3222                 :         12 :     return this->error_function();
    3223                 :            : 
    3224                 :     480827 :   tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype);
    3225                 :     480827 :   if (! asm_name.empty())
    3226                 :     379043 :     SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
    3227                 :     480827 :   if ((flags & function_is_visible) != 0)
    3228                 :     352064 :     TREE_PUBLIC(decl) = 1;
    3229                 :     480827 :   if ((flags & function_is_declaration) != 0)
    3230                 :     230190 :     DECL_EXTERNAL(decl) = 1;
    3231                 :            :   else
    3232                 :            :     {
    3233                 :     250637 :       tree restype = TREE_TYPE(functype);
    3234                 :     250637 :       tree resdecl =
    3235                 :     250637 :           build_decl(location.gcc_location(), RESULT_DECL, NULL_TREE, restype);
    3236                 :     250637 :       DECL_ARTIFICIAL(resdecl) = 1;
    3237                 :     250637 :       DECL_IGNORED_P(resdecl) = 1;
    3238                 :     250637 :       DECL_CONTEXT(resdecl) = decl;
    3239                 :     250637 :       DECL_RESULT(decl) = resdecl;
    3240                 :            :     }
    3241                 :     480827 :   if ((flags & function_is_inlinable) == 0)
    3242                 :       7700 :     DECL_UNINLINABLE(decl) = 1;
    3243                 :     480827 :   if ((flags & function_no_split_stack) != 0)
    3244                 :            :     {
    3245                 :       1987 :       tree attr = get_identifier ("no_split_stack");
    3246                 :       1987 :       DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
    3247                 :            :     }
    3248                 :     480827 :   if ((flags & function_does_not_return) != 0)
    3249                 :      12933 :     TREE_THIS_VOLATILE(decl) = 1;
    3250                 :     480827 :   if ((flags & function_in_unique_section) != 0)
    3251                 :          0 :     resolve_unique_section(decl, 0, 1);
    3252                 :     480827 :   if ((flags & function_only_inline) != 0)
    3253                 :            :     {
    3254                 :      10536 :       TREE_PUBLIC (decl) = 1;
    3255                 :      10536 :       DECL_EXTERNAL(decl) = 1;
    3256                 :      10536 :       DECL_DECLARED_INLINE_P(decl) = 1;
    3257                 :            :     }
    3258                 :            : 
    3259                 :            :   // Optimize thunk functions for size.  A thunk created for a defer
    3260                 :            :   // statement that may call recover looks like:
    3261                 :            :   //     if runtime.setdeferretaddr(L1) {
    3262                 :            :   //         goto L1
    3263                 :            :   //     }
    3264                 :            :   //     realfn()
    3265                 :            :   // L1:
    3266                 :            :   // The idea is that L1 should be the address to which realfn
    3267                 :            :   // returns.  This only works if this little function is not over
    3268                 :            :   // optimized.  At some point GCC started duplicating the epilogue in
    3269                 :            :   // the basic-block reordering pass, breaking this assumption.
    3270                 :            :   // Optimizing the function for size avoids duplicating the epilogue.
    3271                 :            :   // This optimization shouldn't matter for any thunk since all thunks
    3272                 :            :   // are small.
    3273                 :     480827 :   size_t pos = name.find("..thunk");
    3274                 :     480827 :   if (pos != std::string::npos)
    3275                 :            :     {
    3276                 :      39639 :       for (pos += 7; pos < name.length(); ++pos)
    3277                 :            :         {
    3278                 :      26533 :           if (name[pos] < '0' || name[pos] > '9')
    3279                 :            :             break;
    3280                 :            :         }
    3281                 :      13106 :       if (pos == name.length())
    3282                 :            :         {
    3283                 :      13106 :           struct cl_optimization cur_opts;
    3284                 :      13106 :           cl_optimization_save(&cur_opts, &global_options);
    3285                 :      13106 :           global_options.x_optimize_size = 1;
    3286                 :      13106 :           global_options.x_optimize_fast = 0;
    3287                 :      13106 :           global_options.x_optimize_debug = 0;
    3288                 :      13106 :           DECL_FUNCTION_SPECIFIC_OPTIMIZATION(decl) =
    3289                 :      13106 :             build_optimization_node(&global_options);
    3290                 :      13106 :           cl_optimization_restore(&global_options, &cur_opts);
    3291                 :            :         }
    3292                 :            :     }
    3293                 :            : 
    3294                 :     480827 :   go_preserve_from_gc(decl);
    3295                 :     480827 :   return new Bfunction(decl);
    3296                 :            : }
    3297                 :            : 
    3298                 :            : // Create a statement that runs all deferred calls for FUNCTION.  This should
    3299                 :            : // be a statement that looks like this in C++:
    3300                 :            : //   finish:
    3301                 :            : //     try { UNDEFER; } catch { CHECK_DEFER; goto finish; }
    3302                 :            : 
    3303                 :            : Bstatement*
    3304                 :       7278 : Gcc_backend::function_defer_statement(Bfunction* function, Bexpression* undefer,
    3305                 :            :                                       Bexpression* defer, Location location)
    3306                 :            : {
    3307                 :       7278 :   tree undefer_tree = undefer->get_tree();
    3308                 :       7278 :   tree defer_tree = defer->get_tree();
    3309                 :       7278 :   tree fntree = function->get_tree();
    3310                 :            : 
    3311                 :       7278 :   if (undefer_tree == error_mark_node
    3312                 :       7278 :       || defer_tree == error_mark_node
    3313                 :       7278 :       || fntree == error_mark_node)
    3314                 :          0 :     return this->error_statement();
    3315                 :            : 
    3316                 :       7278 :   if (DECL_STRUCT_FUNCTION(fntree) == NULL)
    3317                 :          0 :     push_struct_function(fntree);
    3318                 :            :   else
    3319                 :       7278 :     push_cfun(DECL_STRUCT_FUNCTION(fntree));
    3320                 :            : 
    3321                 :       7278 :   tree stmt_list = NULL;
    3322                 :       7278 :   Blabel* blabel = this->label(function, "", location);
    3323                 :       7278 :   Bstatement* label_def = this->label_definition_statement(blabel);
    3324                 :       7278 :   append_to_statement_list(label_def->get_tree(), &stmt_list);
    3325                 :            : 
    3326                 :       7278 :   Bstatement* jump_stmt = this->goto_statement(blabel, location);
    3327                 :       7278 :   tree jump = jump_stmt->get_tree();
    3328                 :       7278 :   tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer_tree, jump);
    3329                 :       7278 :   catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body);
    3330                 :       7278 :   tree try_catch =
    3331                 :       7278 :       build2(TRY_CATCH_EXPR, void_type_node, undefer_tree, catch_body);
    3332                 :       7278 :   append_to_statement_list(try_catch, &stmt_list);
    3333                 :       7278 :   pop_cfun();
    3334                 :            : 
    3335                 :       7278 :   return this->make_statement(stmt_list);
    3336                 :            : }
    3337                 :            : 
    3338                 :            : // Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
    3339                 :            : // This will only be called for a function definition.
    3340                 :            : 
    3341                 :            : bool
    3342                 :     247957 : Gcc_backend::function_set_parameters(Bfunction* function,
    3343                 :            :                                      const std::vector<Bvariable*>& param_vars)
    3344                 :            : {
    3345                 :     247957 :   tree func_tree = function->get_tree();
    3346                 :     247957 :   if (func_tree == error_mark_node)
    3347                 :            :     return false;
    3348                 :            : 
    3349                 :     247945 :   tree params = NULL_TREE;
    3350                 :     247945 :   tree *pp = &params;
    3351                 :     247945 :   for (std::vector<Bvariable*>::const_iterator pv = param_vars.begin();
    3352                 :     643701 :        pv != param_vars.end();
    3353                 :     643701 :        ++pv)
    3354                 :            :     {
    3355                 :     395756 :       *pp = (*pv)->get_decl();
    3356                 :     395756 :       gcc_assert(*pp != error_mark_node);
    3357                 :     395756 :       pp = &DECL_CHAIN(*pp);
    3358                 :            :     }
    3359                 :     247945 :   *pp = NULL_TREE;
    3360                 :     247945 :   DECL_ARGUMENTS(func_tree) = params;
    3361                 :     247945 :   return true;
    3362                 :            : }
    3363                 :            : 
    3364                 :            : // Set the function body for FUNCTION using the code in CODE_BLOCK.
    3365                 :            : 
    3366                 :            : bool
    3367                 :     250637 : Gcc_backend::function_set_body(Bfunction* function, Bstatement* code_stmt)
    3368                 :            : {
    3369                 :     250637 :   tree func_tree = function->get_tree();
    3370                 :     250637 :   tree code = code_stmt->get_tree();
    3371                 :            : 
    3372                 :     250637 :   if (func_tree == error_mark_node || code == error_mark_node)
    3373                 :            :     return false;
    3374                 :     250615 :   DECL_SAVED_TREE(func_tree) = code;
    3375                 :     250615 :   return true;
    3376                 :            : }
    3377                 :            : 
    3378                 :            : // Look up a named built-in function in the current backend implementation.
    3379                 :            : // Returns NULL if no built-in function by that name exists.
    3380                 :            : 
    3381                 :            : Bfunction*
    3382                 :     106558 : Gcc_backend::lookup_builtin(const std::string& name)
    3383                 :            : {
    3384                 :     208342 :   if (this->builtin_functions_.count(name) != 0)
    3385                 :       4774 :     return this->builtin_functions_[name];
    3386                 :            :   return NULL;
    3387                 :            : }
    3388                 :            : 
    3389                 :            : // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
    3390                 :            : // FUNCTION_DECLS, and VARIABLE_DECLS declared globally, as well as
    3391                 :            : // emit early debugging information.
    3392                 :            : 
    3393                 :            : void
    3394                 :       3110 : Gcc_backend::write_global_definitions(
    3395                 :            :     const std::vector<Btype*>& type_decls,
    3396                 :            :     const std::vector<Bexpression*>& constant_decls,
    3397                 :            :     const std::vector<Bfunction*>& function_decls,
    3398                 :            :     const std::vector<Bvariable*>& variable_decls)
    3399                 :            : {
    3400                 :       3110 :   size_t count_definitions = type_decls.size() + constant_decls.size()
    3401                 :       3110 :       + function_decls.size() + variable_decls.size();
    3402                 :            : 
    3403                 :       3110 :   tree* defs = new tree[count_definitions];
    3404                 :            : 
    3405                 :            :   // Convert all non-erroneous declarations into Gimple form.
    3406                 :       3110 :   size_t i = 0;
    3407                 :      24827 :   for (std::vector<Bvariable*>::const_iterator p = variable_decls.begin();
    3408                 :      24827 :        p != variable_decls.end();
    3409                 :      24827 :        ++p)
    3410                 :            :     {
    3411                 :      21717 :       tree v = (*p)->get_decl();
    3412                 :      21717 :       if (v != error_mark_node)
    3413                 :            :         {
    3414                 :      21717 :           defs[i] = v;
    3415                 :      21717 :           go_preserve_from_gc(defs[i]);
    3416                 :      21717 :           ++i;
    3417                 :            :         }
    3418                 :            :     }
    3419                 :            : 
    3420                 :      29099 :   for (std::vector<Btype*>::const_iterator p = type_decls.begin();
    3421                 :      29099 :        p != type_decls.end();
    3422                 :      29099 :        ++p)
    3423                 :            :     {
    3424                 :      25989 :       tree type_tree = (*p)->get_tree();
    3425                 :      25989 :       if (type_tree != error_mark_node
    3426                 :      25989 :           && IS_TYPE_OR_DECL_P(type_tree))
    3427                 :            :         {
    3428                 :      25989 :           defs[i] = TYPE_NAME(type_tree);
    3429                 :      25989 :           gcc_assert(defs[i] != NULL);
    3430                 :      25989 :           go_preserve_from_gc(defs[i]);
    3431                 :      25989 :           ++i;
    3432                 :            :         }
    3433                 :            :     }
    3434                 :      23720 :   for (std::vector<Bexpression*>::const_iterator p = constant_decls.begin();
    3435                 :      23720 :        p != constant_decls.end();
    3436                 :      23720 :        ++p)
    3437                 :            :     {
    3438                 :      20610 :       if ((*p)->get_tree() != error_mark_node)
    3439                 :            :         {
    3440                 :      20610 :           defs[i] = (*p)->get_tree();
    3441                 :      20610 :           go_preserve_from_gc(defs[i]);
    3442                 :      20610 :           ++i;
    3443                 :            :         }
    3444                 :            :     }
    3445                 :     247146 :   for (std::vector<Bfunction*>::const_iterator p = function_decls.begin();
    3446                 :     247146 :        p != function_decls.end();
    3447                 :     247146 :        ++p)
    3448                 :            :     {
    3449                 :     244036 :       tree decl = (*p)->get_tree();
    3450                 :     244036 :       if (decl != error_mark_node)
    3451                 :            :         {
    3452                 :     244036 :           go_preserve_from_gc(decl);
    3453                 :     244036 :           if (DECL_STRUCT_FUNCTION(decl) == NULL)
    3454                 :      38148 :             allocate_struct_function(decl, false);
    3455                 :     244036 :           cgraph_node::finalize_function(decl, true);
    3456                 :            : 
    3457                 :     244036 :           defs[i] = decl;
    3458                 :     244036 :           ++i;
    3459                 :            :         }
    3460                 :            :     }
    3461                 :            : 
    3462                 :            :   // Pass everything back to the middle-end.
    3463                 :            : 
    3464                 :       3110 :   wrapup_global_declarations(defs, i);
    3465                 :            : 
    3466                 :       3110 :   delete[] defs;
    3467                 :       3110 : }
    3468                 :            : 
    3469                 :            : void
    3470                 :    5335370 : Gcc_backend::write_export_data(const char* bytes, unsigned int size)
    3471                 :            : {
    3472                 :    5335370 :   go_write_export_data(bytes, size);
    3473                 :    5335370 : }
    3474                 :            : 
    3475                 :            : 
    3476                 :            : // Define a builtin function.  BCODE is the builtin function code
    3477                 :            : // defined by builtins.def.  NAME is the name of the builtin function.
    3478                 :            : // LIBNAME is the name of the corresponding library function, and is
    3479                 :            : // NULL if there isn't one.  FNTYPE is the type of the function.
    3480                 :            : // CONST_P is true if the function has the const attribute.
    3481                 :            : // NORETURN_P is true if the function has the noreturn attribute.
    3482                 :            : 
    3483                 :            : void
    3484                 :     259644 : Gcc_backend::define_builtin(built_in_function bcode, const char* name,
    3485                 :            :                             const char* libname, tree fntype, bool const_p,
    3486                 :            :                             bool noreturn_p)
    3487                 :            : {
    3488                 :     259644 :   tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL,
    3489                 :            :                                    libname, NULL_TREE);
    3490                 :     259644 :   if (const_p)
    3491                 :     171972 :     TREE_READONLY(decl) = 1;
    3492                 :     259644 :   if (noreturn_p)
    3493                 :       6744 :     TREE_THIS_VOLATILE(decl) = 1;
    3494                 :     259644 :   set_builtin_decl(bcode, decl, true);
    3495                 :     259644 :   this->builtin_functions_[name] = this->make_function(decl);
    3496                 :     259644 :   if (libname != NULL)
    3497                 :            :     {
    3498                 :     175344 :       decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL,
    3499                 :            :                                   NULL, NULL_TREE);
    3500                 :     175344 :       if (const_p)
    3501                 :     165228 :         TREE_READONLY(decl) = 1;
    3502                 :     175344 :       if (noreturn_p)
    3503                 :          0 :         TREE_THIS_VOLATILE(decl) = 1;
    3504                 :     175344 :       this->builtin_functions_[libname] = this->make_function(decl);
    3505                 :            :     }
    3506                 :     259644 : }
    3507                 :            : 
    3508                 :            : // Return the backend generator.
    3509                 :            : 
    3510                 :            : Backend*
    3511                 :       3372 : go_get_backend()
    3512                 :            : {
    3513                 :       3372 :   return new Gcc_backend();
    3514                 :            : }

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.