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

Generated by: LCOV version 2.0-1

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