LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - expressions.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.3 % 11166 9527
Test Date: 2026-02-28 14:20:25 Functions: 82.7 % 728 602
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // expressions.cc -- Go frontend expression handling.
       2              : 
       3              : // Copyright 2009 The Go Authors. All rights reserved.
       4              : // Use of this source code is governed by a BSD-style
       5              : // license that can be found in the LICENSE file.
       6              : 
       7              : #include "go-system.h"
       8              : 
       9              : #include <algorithm>
      10              : 
      11              : #include "go-c.h"
      12              : #include "gogo.h"
      13              : #include "go-diagnostics.h"
      14              : #include "go-encode-id.h"
      15              : #include "types.h"
      16              : #include "export.h"
      17              : #include "import.h"
      18              : #include "statements.h"
      19              : #include "lex.h"
      20              : #include "runtime.h"
      21              : #include "backend.h"
      22              : #include "expressions.h"
      23              : #include "ast-dump.h"
      24              : 
      25              : // Class Expression.
      26              : 
      27     51552131 : Expression::Expression(Expression_classification classification,
      28     51552131 :                        Location location)
      29     51552131 :   : classification_(classification), location_(location)
      30              : {
      31     51552131 : }
      32              : 
      33       200723 : Expression::~Expression()
      34              : {
      35       200723 : }
      36              : 
      37              : // Traverse the expressions.
      38              : 
      39              : int
      40    237123108 : Expression::traverse(Expression** pexpr, Traverse* traverse)
      41              : {
      42    237123108 :   Expression* expr = *pexpr;
      43    237123108 :   if ((traverse->traverse_mask() & Traverse::traverse_expressions) != 0)
      44              :     {
      45    178416906 :       int t = traverse->expression(pexpr);
      46    178416906 :       if (t == TRAVERSE_EXIT)
      47              :         return TRAVERSE_EXIT;
      48    176684517 :       else if (t == TRAVERSE_SKIP_COMPONENTS)
      49              :         return TRAVERSE_CONTINUE;
      50              :     }
      51    165731039 :   return expr->do_traverse(traverse);
      52              : }
      53              : 
      54              : // Traverse subexpressions of this expression.
      55              : 
      56              : int
      57     71958171 : Expression::traverse_subexpressions(Traverse* traverse)
      58              : {
      59     71958171 :   return this->do_traverse(traverse);
      60              : }
      61              : 
      62              : // A traversal used to set the location of subexpressions.
      63              : 
      64        18170 : class Set_location : public Traverse
      65              : {
      66              :  public:
      67         9085 :   Set_location(Location loc)
      68         9085 :     : Traverse(traverse_expressions),
      69         9085 :       loc_(loc)
      70              :   { }
      71              : 
      72              :   int
      73              :   expression(Expression** pexpr);
      74              : 
      75              :  private:
      76              :   Location loc_;
      77              : };
      78              : 
      79              : // Set the location of an expression.
      80              : 
      81              : int
      82         5614 : Set_location::expression(Expression** pexpr)
      83              : {
      84              :   // Some expressions are shared or don't have an independent
      85              :   // location, so we shouldn't change their location.  This is the set
      86              :   // of expressions for which do_copy is just "return this" or
      87              :   // otherwise does not pass down the location.
      88         5614 :   switch ((*pexpr)->classification())
      89              :     {
      90              :     case Expression::EXPRESSION_ERROR:
      91              :     case Expression::EXPRESSION_VAR_REFERENCE:
      92              :     case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
      93              :     case Expression::EXPRESSION_STRING:
      94              :     case Expression::EXPRESSION_FUNC_DESCRIPTOR:
      95              :     case Expression::EXPRESSION_TYPE:
      96              :     case Expression::EXPRESSION_BOOLEAN:
      97              :     case Expression::EXPRESSION_CONST_REFERENCE:
      98              :     case Expression::EXPRESSION_NIL:
      99              :     case Expression::EXPRESSION_TYPE_DESCRIPTOR:
     100              :     case Expression::EXPRESSION_GC_SYMBOL:
     101              :     case Expression::EXPRESSION_PTRMASK_SYMBOL:
     102              :     case Expression::EXPRESSION_TYPE_INFO:
     103              :     case Expression::EXPRESSION_STRUCT_FIELD_OFFSET:
     104              :       return TRAVERSE_CONTINUE;
     105         5607 :     default:
     106         5607 :       break;
     107              :     }
     108              : 
     109         5607 :   (*pexpr)->location_ = this->loc_;
     110         5607 :   return TRAVERSE_CONTINUE;
     111              : }
     112              : 
     113              : // Set the location of an expression and its subexpressions.
     114              : 
     115              : void
     116         9085 : Expression::set_location(Location loc)
     117              : {
     118         9085 :   this->location_ = loc;
     119         9085 :   Set_location sl(loc);
     120         9085 :   this->traverse_subexpressions(&sl);
     121         9085 : }
     122              : 
     123              : // Default implementation for do_traverse for child classes.
     124              : 
     125              : int
     126     69456858 : Expression::do_traverse(Traverse*)
     127              : {
     128     69456858 :   return TRAVERSE_CONTINUE;
     129              : }
     130              : 
     131              : // This virtual function is called by the parser if the value of this
     132              : // expression is being discarded.  By default, we give an error.
     133              : // Expressions with side effects override.
     134              : 
     135              : bool
     136           18 : Expression::do_discarding_value()
     137              : {
     138           18 :   this->unused_value_error();
     139           18 :   return false;
     140              : }
     141              : 
     142              : // This virtual function is called to export expressions.  This will
     143              : // only be used by expressions which may be constant.
     144              : 
     145              : void
     146            0 : Expression::do_export(Export_function_body*) const
     147              : {
     148            0 :   go_unreachable();
     149              : }
     150              : 
     151              : // Write a name to the export data.
     152              : 
     153              : void
     154        13427 : Expression::export_name(Export_function_body* efb, const Named_object* no)
     155              : {
     156        13427 :   if (no->package() != NULL)
     157              :     {
     158         4700 :       char buf[50];
     159         4700 :       snprintf(buf, sizeof buf, "<p%d>", efb->package_index(no->package()));
     160         4700 :       efb->write_c_string(buf);
     161              :     }
     162              : 
     163        13427 :   if (!Gogo::is_hidden_name(no->name()))
     164         5679 :     efb->write_string(no->name());
     165              :   else
     166              :     {
     167         7748 :       efb->write_c_string(".");
     168         7748 :       efb->write_string(Gogo::unpack_hidden_name(no->name()));
     169              :     }
     170        13427 : }
     171              : 
     172              : // Give an error saying that the value of the expression is not used.
     173              : 
     174              : void
     175           95 : Expression::unused_value_error()
     176              : {
     177           95 :   if (this->type()->is_error())
     178              :     {
     179           13 :       go_assert(saw_errors());
     180           13 :       this->set_is_error();
     181              :     }
     182              :   else
     183           82 :     this->report_error(_("value computed is not used"));
     184           95 : }
     185              : 
     186              : // Note that this expression is an error.  This is called by children
     187              : // when they discover an error.
     188              : 
     189              : void
     190         5305 : Expression::set_is_error()
     191              : {
     192         5305 :   this->classification_ = EXPRESSION_ERROR;
     193         5305 : }
     194              : 
     195              : // For children to call to report an error conveniently.
     196              : 
     197              : void
     198         1291 : Expression::report_error(const char* msg)
     199              : {
     200         1291 :   go_error_at(this->location_, "%s", msg);
     201         1291 :   this->set_is_error();
     202         1291 : }
     203              : 
     204              : // A convenience function for handling a type in do_is_untyped.  If
     205              : // TYPE is not abstract, return false.  Otherwise set *PTYPE to TYPE
     206              : // and return true.
     207              : 
     208              : bool
     209      1390308 : Expression::is_untyped_type(Type* type, Type** ptype)
     210              : {
     211      1390308 :   if (!type->is_abstract())
     212              :     return false;
     213        53489 :   *ptype = type;
     214        53489 :   return true;
     215              : }
     216              : 
     217              : // Report whether this is a type expression.
     218              : 
     219              : bool
     220     26640545 : Expression::is_type_expression() const
     221              : {
     222     26640545 :   if (this->classification_ == EXPRESSION_TYPE)
     223              :     return true;
     224     26450893 :   if (this->unknown_expression() != NULL)
     225              :     {
     226       833639 :       Named_object* no = this->unknown_expression()->named_object();
     227       833639 :       if (no->is_unknown())
     228              :         {
     229       634300 :           no = no->unknown_value()->real_named_object();
     230       634300 :           if (no == NULL)
     231              :             return false;
     232              :         }
     233       250035 :       return no->is_type();
     234              :     }
     235     25617254 :   if (this->unary_expression() != NULL
     236       149942 :       && this->unary_expression()->op() == OPERATOR_MULT
     237        35160 :       && this->unary_expression()->operand()->is_type_expression())
     238              :     return true;
     239              :   return false;
     240              : }
     241              : 
     242              : // Set types of variables and constants.  This is implemented by the
     243              : // child class.
     244              : 
     245              : void
     246     38447493 : Expression::determine_type(Gogo* gogo, const Type_context* context)
     247              : {
     248     38447493 :   this->do_determine_type(gogo, context);
     249     38447493 : }
     250              : 
     251              : // Set types when there is no context.
     252              : 
     253              : void
     254     14367869 : Expression::determine_type_no_context(Gogo* gogo)
     255              : {
     256     14367869 :   Type_context context;
     257     14367869 :   this->do_determine_type(gogo, &context);
     258     14367869 : }
     259              : 
     260              : // Return true if two expressions refer to the same variable or struct
     261              : // field.  This can only be true when there are no side effects.
     262              : 
     263              : bool
     264        47768 : Expression::is_same_variable(Expression* a, Expression* b)
     265              : {
     266        47768 :   if (a->classification() != b->classification())
     267              :     return false;
     268              : 
     269        43769 :   Var_expression* av = a->var_expression();
     270        43769 :   if (av != NULL)
     271        30528 :     return av->named_object() == b->var_expression()->named_object();
     272              : 
     273        13241 :   Field_reference_expression* af = a->field_reference_expression();
     274        13241 :   if (af != NULL)
     275              :     {
     276         6441 :       Field_reference_expression* bf = b->field_reference_expression();
     277         6441 :       return (af->field_index() == bf->field_index()
     278         6441 :               && Expression::is_same_variable(af->expr(), bf->expr()));
     279              :     }
     280              : 
     281         6800 :   Unary_expression* au = a->unary_expression();
     282         6800 :   if (au != NULL)
     283              :     {
     284         6083 :       Unary_expression* bu = b->unary_expression();
     285         6083 :       return (au->op() == OPERATOR_MULT
     286         6083 :               && bu->op() == OPERATOR_MULT
     287        12166 :               && Expression::is_same_variable(au->operand(),
     288              :                                               bu->operand()));
     289              :     }
     290              : 
     291          717 :   Array_index_expression* aie = a->array_index_expression();
     292          717 :   if (aie != NULL)
     293              :     {
     294           86 :       Array_index_expression* bie = b->array_index_expression();
     295           86 :       return (aie->end() == NULL
     296           86 :               && bie->end() == NULL
     297           86 :               && Expression::is_same_variable(aie->array(), bie->array())
     298          172 :               && Expression::is_same_variable(aie->start(), bie->start()));
     299              :     }
     300              : 
     301          631 :   Numeric_constant aval;
     302          631 :   if (a->numeric_constant_value(&aval))
     303              :     {
     304           28 :       Numeric_constant bval;
     305           28 :       if (b->numeric_constant_value(&bval))
     306           28 :         return aval.equals(bval);
     307           28 :     }
     308              : 
     309              :   return false;
     310          631 : }
     311              : 
     312              : // Return an expression handling any conversions which must be done during
     313              : // assignment.
     314              : 
     315              : Expression*
     316     12781511 : Expression::convert_for_assignment(Gogo* gogo, Type* lhs_type,
     317              :                                    Expression* rhs, Location location)
     318              : {
     319     12781511 :   Type* rhs_type = rhs->type();
     320     12781511 :   if (lhs_type->is_error()
     321     12781506 :       || rhs_type->is_error()
     322     25563010 :       || rhs->is_error_expression())
     323           13 :     return Expression::make_error(location);
     324              : 
     325     12781498 :   bool are_identical = Type::are_identical(lhs_type, rhs_type,
     326              :                                            (Type::COMPARE_ERRORS
     327              :                                             | Type::COMPARE_TAGS),
     328              :                                            NULL);
     329     12781498 :   Expression* ret;
     330     12781498 :   if (!are_identical && lhs_type->interface_type() != NULL)
     331              :     {
     332              :       // Type to interface conversions have been made explicit early.
     333        26024 :       go_assert(rhs_type->interface_type() != NULL);
     334        26024 :       ret = Expression::convert_interface_to_interface(gogo, lhs_type, rhs,
     335              :                                                        false, location);
     336              :     }
     337     12755474 :   else if (!are_identical && rhs_type->interface_type() != NULL)
     338        12525 :     ret = Expression::convert_interface_to_type(gogo, lhs_type, rhs, location);
     339     12742949 :   else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
     340              :     {
     341              :       // Assigning nil to a slice.
     342        19166 :       Expression* nil = Expression::make_nil(location);
     343        19166 :       Expression* zero = Expression::make_integer_ul(0, NULL, location);
     344        19166 :       ret = Expression::make_slice_value(lhs_type, nil, zero, zero, location);
     345              :     }
     346     12723783 :   else if (rhs_type->is_nil_type())
     347       852297 :     ret = Expression::make_nil(location);
     348     11871486 :   else if (are_identical)
     349              :     {
     350     11668909 :       if (lhs_type->forwarded() != rhs_type->forwarded())
     351              :         {
     352              :           // Different but identical types require an explicit
     353              :           // conversion.  This happens with type aliases.
     354       474035 :           return Expression::make_cast(lhs_type, rhs, location);
     355              :         }
     356              : 
     357              :       // No conversion is needed.
     358              :       return rhs;
     359              :     }
     360       202577 :   else if (lhs_type->points_to() != NULL)
     361        13359 :     ret = Expression::make_unsafe_cast(lhs_type, rhs, location);
     362       189218 :   else if (lhs_type->is_numeric_type())
     363       144058 :     ret = Expression::make_cast(lhs_type, rhs, location);
     364        45196 :   else if ((lhs_type->struct_type() != NULL
     365        45124 :             && rhs_type->struct_type() != NULL)
     366         3434 :            || (lhs_type->array_type() != NULL
     367         3470 :                && rhs_type->array_type() != NULL))
     368              :     {
     369              :       // This conversion must be permitted by Go, or we wouldn't have
     370              :       // gotten here.
     371         3470 :       ret = Expression::make_unsafe_cast(lhs_type, rhs, location);
     372              :     }
     373              :   else
     374        41690 :     return rhs;
     375              : 
     376      1070899 :   Type_context context(lhs_type, false);
     377      1070899 :   ret->determine_type(gogo, &context);
     378      1070899 :   return ret;
     379              : }
     380              : 
     381              : // Return an expression for a conversion from a non-interface type to an
     382              : // interface type.  If ON_STACK is true, it can allocate the storage on
     383              : // stack.
     384              : 
     385              : Expression*
     386       201200 : Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
     387              :                                       bool on_stack, Location location)
     388              : {
     389       201200 :   Interface_type* lhs_interface_type = lhs_type->interface_type();
     390       201200 :   bool lhs_is_empty = lhs_interface_type->is_empty();
     391              : 
     392              :   // Since RHS_TYPE is a static type, we can create the interface
     393              :   // method table at compile time.
     394              : 
     395              :   // When setting an interface to nil, we just set both fields to
     396              :   // NULL.
     397       201200 :   Type* rhs_type = rhs->type();
     398       201200 :   if (rhs_type->is_nil_type())
     399              :     {
     400        28459 :       Expression* nil = Expression::make_nil(location);
     401        28459 :       return Expression::make_interface_value(lhs_type, nil, nil, location);
     402              :     }
     403              : 
     404              :   // This should have been checked already.
     405       172741 :   if (!lhs_interface_type->implements_interface(rhs_type, NULL))
     406              :     {
     407            0 :       go_assert(saw_errors());
     408            0 :       return Expression::make_error(location);
     409              :     }
     410              : 
     411              :   // An interface is a tuple.  If LHS_TYPE is an empty interface type,
     412              :   // then the first field is the type descriptor for RHS_TYPE.
     413              :   // Otherwise it is the interface method table for RHS_TYPE.
     414       172741 :   Expression* first_field;
     415       172741 :   if (lhs_is_empty)
     416       129332 :     first_field = Expression::make_type_descriptor(rhs_type, location);
     417              :   else
     418              :     {
     419              :       // Build the interface method table for this interface and this
     420              :       // object type: a list of function pointers for each interface
     421              :       // method.
     422        43409 :       Named_type* rhs_named_type = rhs_type->named_type();
     423        43409 :       Struct_type* rhs_struct_type = rhs_type->struct_type();
     424        43409 :       bool is_pointer = false;
     425        43409 :       if (rhs_named_type == NULL && rhs_struct_type == NULL)
     426              :         {
     427        59638 :           rhs_named_type = rhs_type->deref()->named_type();
     428        59638 :           rhs_struct_type = rhs_type->deref()->struct_type();
     429              :           is_pointer = true;
     430              :         }
     431        43409 :       if (rhs_named_type != NULL)
     432        43285 :         first_field =
     433        43285 :           rhs_named_type->interface_method_table(lhs_interface_type,
     434              :                                                  is_pointer);
     435          124 :       else if (rhs_struct_type != NULL)
     436          124 :         first_field =
     437          124 :           rhs_struct_type->interface_method_table(lhs_interface_type,
     438              :                                                   is_pointer);
     439              :       else
     440            0 :         first_field = Expression::make_nil(location);
     441              :     }
     442              : 
     443       172741 :   Expression* obj;
     444       172741 :   if (rhs_type->is_direct_iface_type())
     445              :     {
     446              :       // We are assigning a pointer to the interface; the interface
     447              :       // holds the pointer itself.
     448        47262 :       obj = unpack_direct_iface(rhs, location);
     449              :     }
     450              :   else
     451              :     {
     452              :       // We are assigning a non-pointer value to the interface; the
     453              :       // interface gets a copy of the value in the heap if it escapes.
     454              : 
     455              :       // An exception is &global if global is notinheap, which is a
     456              :       // pointer value but not a direct-iface type and we can't simply
     457              :       // take its address.
     458       125479 :       bool is_address = (rhs->unary_expression() != NULL
     459          735 :                          && rhs->unary_expression()->op() == OPERATOR_AND);
     460              : 
     461       125479 :       if (rhs->is_constant() && !is_address)
     462        31942 :         obj = Expression::make_unary(OPERATOR_AND, rhs, location);
     463              :       else
     464              :         {
     465        93537 :           obj = Expression::make_heap_expression(rhs, location);
     466        93537 :           if (on_stack)
     467          597 :             obj->heap_expression()->set_allocate_on_stack();
     468              :         }
     469              :     }
     470              : 
     471       172741 :   return Expression::make_interface_value(lhs_type, first_field, obj, location);
     472              : }
     473              : 
     474              : // Return an expression for the pointer-typed value of a direct interface
     475              : // type.  Specifically, for single field struct or array, get the single
     476              : // field, and do this recursively.  The reason for this is that we don't
     477              : // want to assign a struct or an array to a pointer-typed field.  The
     478              : // backend may not like that.
     479              : 
     480              : Expression*
     481        57906 : Expression::unpack_direct_iface(Expression* rhs, Location loc)
     482              : {
     483        62190 :   Struct_type* st = rhs->type()->struct_type();
     484        62190 :   if (st != NULL)
     485              :     {
     486         4284 :       go_assert(st->field_count() == 1);
     487         4284 :       Expression* field = Expression::make_field_reference(rhs, 0, loc);
     488         4284 :       return unpack_direct_iface(field, loc);
     489              :     }
     490        57906 :   Array_type* at = rhs->type()->array_type();
     491          814 :   if (at != NULL)
     492              :     {
     493          814 :       int64_t len;
     494          814 :       bool ok = at->int_length(&len);
     495          814 :       go_assert(ok && len == 1);
     496          814 :       Type* int_type = Type::lookup_integer_type("int");
     497          814 :       Expression* index = Expression::make_integer_ul(0, int_type, loc);
     498          814 :       Expression* elem = Expression::make_array_index(rhs, index, NULL, NULL, loc);
     499          814 :       return unpack_direct_iface(elem, loc);
     500              :     }
     501              :   return rhs;
     502              : }
     503              : 
     504              : // The opposite of unpack_direct_iface.
     505              : 
     506              : Expression*
     507        13513 : Expression::pack_direct_iface(Type* t, Expression* rhs, Location loc)
     508              : {
     509        13513 :   if (rhs->type() == t)
     510              :     return rhs;
     511        13513 :   Struct_type* st = t->struct_type();
     512        13513 :   if (st != NULL)
     513              :     {
     514         1665 :       Expression_list* vals = new Expression_list();
     515         1665 :       vals->push_back(pack_direct_iface(st->field(0)->type(), rhs, loc));
     516         1665 :       return Expression::make_struct_composite_literal(t, vals, loc);
     517              :     }
     518        11848 :   Array_type* at = t->array_type();
     519        11848 :   if (at != NULL)
     520              :     {
     521            4 :       Expression_list* vals = new Expression_list();
     522            4 :       vals->push_back(pack_direct_iface(at->element_type(), rhs, loc));
     523            4 :       return Expression::make_array_composite_literal(t, vals, loc);
     524              :     }
     525        11844 :   return Expression::make_unsafe_cast(t, rhs, loc);
     526              : }
     527              : 
     528              : // Return an expression for the type descriptor of RHS.
     529              : 
     530              : Expression*
     531        54471 : Expression::get_interface_type_descriptor(Expression* rhs)
     532              : {
     533        54471 :   go_assert(rhs->type()->interface_type() != NULL);
     534        54471 :   Location location = rhs->location();
     535              : 
     536              :   // The type descriptor is the first field of an empty interface.
     537       108942 :   if (rhs->type()->interface_type()->is_empty())
     538         8989 :     return Expression::make_interface_info(rhs, INTERFACE_INFO_TYPE_DESCRIPTOR,
     539         8989 :                                            location);
     540              : 
     541        45482 :   Expression* mtable =
     542        45482 :       Expression::make_interface_info(rhs, INTERFACE_INFO_METHODS, location);
     543              : 
     544        45482 :   Expression* descriptor =
     545        45482 :       Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, location);
     546        45482 :   descriptor = Expression::make_field_reference(descriptor, 0, location);
     547        45482 :   Expression* nil = Expression::make_nil(location);
     548              : 
     549        45482 :   Expression* eq =
     550        45482 :       Expression::make_binary(OPERATOR_EQEQ, mtable, nil, location);
     551        45482 :   return Expression::make_conditional(eq, nil, descriptor, location);
     552              : }
     553              : 
     554              : // Return an expression for the conversion of an interface type to an
     555              : // interface type.
     556              : 
     557              : Expression*
     558        27040 : Expression::convert_interface_to_interface(Gogo* gogo, Type *lhs_type,
     559              :                                            Expression* rhs,
     560              :                                            bool for_type_guard,
     561              :                                            Location location)
     562              : {
     563        27040 :   if (Type::are_identical(lhs_type, rhs->type(),
     564              :                           Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
     565              :                           NULL))
     566              :     return rhs;
     567              : 
     568        27035 :   Interface_type* lhs_interface_type = lhs_type->interface_type();
     569        27035 :   bool lhs_is_empty = lhs_interface_type->is_empty();
     570              : 
     571              :   // In the general case this requires runtime examination of the type
     572              :   // method table to match it up with the interface methods.
     573              : 
     574              :   // FIXME: If all of the methods in the right hand side interface
     575              :   // also appear in the left hand side interface, then we don't need
     576              :   // to do a runtime check, although we still need to build a new
     577              :   // method table.
     578              : 
     579              :   // We are going to evaluate RHS multiple times.
     580        27035 :   go_assert(rhs->is_multi_eval_safe());
     581              : 
     582              :   // Get the type descriptor for the right hand side.  This will be
     583              :   // NULL for a nil interface.
     584        27035 :   Expression* rhs_type_expr = Expression::get_interface_type_descriptor(rhs);
     585        27035 :   Expression* lhs_type_expr =
     586        27035 :       Expression::make_type_descriptor(lhs_type, location);
     587              : 
     588        27035 :   Expression* first_field;
     589        27035 :   if (for_type_guard)
     590              :     {
     591              :       // A type assertion fails when converting a nil interface.
     592         1011 :       first_field = Runtime::make_call(gogo, Runtime::ASSERTITAB, location, 2,
     593              :                                        lhs_type_expr, rhs_type_expr);
     594              :     }
     595        26024 :   else if (lhs_is_empty)
     596              :     {
     597              :       // A conversion to an empty interface always succeeds, and the
     598              :       // first field is just the type descriptor of the object.
     599              :       first_field = rhs_type_expr;
     600              :     }
     601              :   else
     602              :     {
     603              :       // A conversion to a non-empty interface may fail, but unlike a
     604              :       // type assertion converting nil will always succeed.
     605         4304 :       first_field = Runtime::make_call(gogo, Runtime::REQUIREITAB, location, 2,
     606              :                                        lhs_type_expr, rhs_type_expr);
     607              :     }
     608              : 
     609              :   // The second field is simply the object pointer.
     610        27035 :   Expression* obj =
     611        27035 :       Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT, location);
     612        27035 :   Expression* ret = Expression::make_interface_value(lhs_type, first_field,
     613              :                                                      obj, location);
     614        27035 :   Type_context context(lhs_type, false);
     615        27035 :   ret->determine_type(gogo, &context);
     616        27035 :   return ret;
     617              : }
     618              : 
     619              : // Return an expression for the conversion of an interface type to a
     620              : // non-interface type.
     621              : 
     622              : Expression*
     623        12525 : Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rhs,
     624              :                                       Location location)
     625              : {
     626              :   // We are going to evaluate RHS multiple times.
     627        12525 :   go_assert(rhs->is_multi_eval_safe());
     628              : 
     629              :   // Build an expression to check that the type is valid.  It will
     630              :   // panic with an appropriate runtime type error if the type is not
     631              :   // valid.
     632              :   // (lhs_type == rhs_type ? nil /*dummy*/ :
     633              :   //    panicdottype(lhs_type, rhs_type, inter_type))
     634              :   // For some Oses, we need to call runtime.eqtype instead of
     635              :   // lhs_type == rhs_type, as we may have unmerged type descriptors
     636              :   // from shared libraries.
     637        12525 :   Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type,
     638              :                                                                 location);
     639        12525 :   Expression* rhs_descriptor =
     640        12525 :       Expression::get_interface_type_descriptor(rhs);
     641              : 
     642        12525 :   Type* rhs_type = rhs->type();
     643        12525 :   Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
     644              :                                                                 location);
     645              : 
     646        12525 :   Expression* cond;
     647        12525 :   if (gogo->need_eqtype()) {
     648            0 :     cond = Runtime::make_call(gogo, Runtime::EQTYPE, location,
     649              :                               2, lhs_type_expr,
     650              :                               rhs_descriptor);
     651              :   } else {
     652        12525 :     cond = Expression::make_binary(OPERATOR_EQEQ, lhs_type_expr,
     653              :                                    rhs_descriptor, location);
     654              :   }
     655              : 
     656        12525 :   rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
     657        12525 :   Expression* panic = Runtime::make_call(gogo, Runtime::PANICDOTTYPE, location,
     658              :                                          3, lhs_type_expr->copy(),
     659              :                                          rhs_descriptor,
     660              :                                          rhs_inter_expr);
     661        12525 :   Expression* nil = Expression::make_nil(location);
     662        12525 :   Expression* check = Expression::make_conditional(cond, nil, panic,
     663              :                                                    location);
     664              : 
     665              :   // If the conversion succeeds, pull out the value.
     666        12525 :   Expression* obj = Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT,
     667              :                                                     location);
     668              : 
     669              :   // If the value is a direct interface, then it is the value we want.
     670              :   // Otherwise it points to the value.
     671        12525 :   if (lhs_type->is_direct_iface_type())
     672         9828 :     obj = Expression::pack_direct_iface(lhs_type, obj, location);
     673              :   else
     674              :     {
     675         2697 :       obj = Expression::make_unsafe_cast(Type::make_pointer_type(lhs_type), obj,
     676              :                                          location);
     677         2697 :       obj = Expression::make_dereference(obj, NIL_CHECK_NOT_NEEDED,
     678              :                                          location);
     679              :     }
     680        12525 :   return Expression::make_compound(check, obj, location);
     681              : }
     682              : 
     683              : // Convert an expression to its backend representation.  This is implemented by
     684              : // the child class.  Not that it is not in general safe to call this multiple
     685              : // times for a single expression, but that we don't catch such errors.
     686              : 
     687              : Bexpression*
     688     40338841 : Expression::get_backend(Translate_context* context)
     689              : {
     690              :   // The child may have marked this expression as having an error.
     691     40338841 :   if (this->classification_ == EXPRESSION_ERROR)
     692              :     {
     693         3629 :       go_assert(saw_errors());
     694         3629 :       return context->backend()->error_expression();
     695              :     }
     696              : 
     697     40335212 :   return this->do_get_backend(context);
     698              : }
     699              : 
     700              : // Return a backend expression for VAL.
     701              : Bexpression*
     702      6051042 : Expression::backend_numeric_constant_expression(Translate_context* context,
     703              :                                                 Numeric_constant* val)
     704              : {
     705      6051042 :   Gogo* gogo = context->gogo();
     706      6051042 :   Type* type = val->type();
     707      6051042 :   if (type == NULL)
     708            0 :     return gogo->backend()->error_expression();
     709              : 
     710      6051042 :   Btype* btype = type->get_backend(gogo);
     711      6051042 :   Bexpression* ret;
     712      6051042 :   if (type->integer_type() != NULL)
     713              :     {
     714      6014674 :       mpz_t ival;
     715      6014674 :       if (!val->to_int(&ival))
     716              :         {
     717            0 :           go_assert(saw_errors());
     718            0 :           return gogo->backend()->error_expression();
     719              :         }
     720      6014674 :       ret = gogo->backend()->integer_constant_expression(btype, ival);
     721      6014674 :       mpz_clear(ival);
     722              :     }
     723        36368 :   else if (type->float_type() != NULL)
     724              :     {
     725        33424 :       mpfr_t fval;
     726        33424 :       if (!val->to_float(&fval))
     727              :         {
     728            0 :           go_assert(saw_errors());
     729            0 :           return gogo->backend()->error_expression();
     730              :         }
     731        33424 :       ret = gogo->backend()->float_constant_expression(btype, fval);
     732        33424 :       mpfr_clear(fval);
     733              :     }
     734         2944 :   else if (type->complex_type() != NULL)
     735              :     {
     736         2944 :       mpc_t cval;
     737         2944 :       if (!val->to_complex(&cval))
     738              :         {
     739            0 :           go_assert(saw_errors());
     740            0 :           return gogo->backend()->error_expression();
     741              :         }
     742         2944 :       ret = gogo->backend()->complex_constant_expression(btype, cval);
     743         2944 :       mpc_clear(cval);
     744              :     }
     745              :   else
     746            0 :     go_unreachable();
     747              : 
     748              :   return ret;
     749              : }
     750              : 
     751              : // Insert bounds checks for an index expression.  Check that that VAL
     752              : // >= 0 and that it fits in an int.  Then check that VAL OP BOUND is
     753              : // true.  If any condition is false, call one of the CODE runtime
     754              : // functions, which will panic.
     755              : 
     756              : void
     757       224475 : Expression::check_bounds(Gogo* gogo, Expression* val, Operator op,
     758              :                          Expression* bound,
     759              :                          Runtime::Function code,
     760              :                          Runtime::Function code_u,
     761              :                          Runtime::Function code_extend,
     762              :                          Runtime::Function code_extend_u,
     763              :                          Statement_inserter* inserter,
     764              :                          Location loc)
     765              : {
     766       224475 :   go_assert(val->is_multi_eval_safe());
     767       224475 :   go_assert(bound->is_multi_eval_safe());
     768              : 
     769       224475 :   Type* int_type = Type::lookup_integer_type("int");
     770       448950 :   int int_type_size = int_type->integer_type()->bits();
     771              : 
     772       224475 :   Type* val_type = val->type();
     773       224475 :   if (val_type->integer_type() == NULL)
     774              :     {
     775            0 :       go_assert(saw_errors());
     776              :       return;
     777              :     }
     778       448950 :   int val_type_size = val_type->integer_type()->bits();
     779       448950 :   bool val_is_unsigned = val_type->integer_type()->is_unsigned();
     780              : 
     781              :   // Check that VAL >= 0.
     782       224475 :   Expression* check = NULL;
     783       224475 :   if (!val_is_unsigned)
     784              :     {
     785       213394 :       Expression* zero = Expression::make_integer_ul(0, val_type, loc);
     786       213394 :       check = Expression::make_binary(OPERATOR_GE, val->copy(), zero, loc);
     787              :     }
     788              : 
     789              :   // If VAL's type is larger than int, check that VAL fits in an int.
     790       224475 :   if (val_type_size > int_type_size
     791       223780 :       || (val_type_size == int_type_size
     792       223780 :           && val_is_unsigned))
     793              :     {
     794         5511 :       mpz_t one;
     795         5511 :       mpz_init_set_ui(one, 1UL);
     796              : 
     797              :       // maxval = 2^(int_type_size - 1) - 1
     798         5511 :       mpz_t maxval;
     799         5511 :       mpz_init(maxval);
     800         5511 :       mpz_mul_2exp(maxval, one, int_type_size - 1);
     801         5511 :       mpz_sub_ui(maxval, maxval, 1);
     802         5511 :       Expression* max = Expression::make_integer_z(&maxval, val_type, loc);
     803         5511 :       mpz_clear(one);
     804         5511 :       mpz_clear(maxval);
     805              : 
     806         5511 :       Expression* cmp = Expression::make_binary(OPERATOR_LE, val->copy(),
     807              :                                                 max, loc);
     808         5511 :       if (check == NULL)
     809              :         check = cmp;
     810              :       else
     811          311 :         check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc);
     812              :     }
     813              : 
     814              :   // For the final check we can assume that VAL fits in an int.
     815       224475 :   Expression* ival;
     816       224475 :   if (val_type == int_type)
     817       188567 :     ival = val->copy();
     818              :   else
     819        35908 :     ival = Expression::make_cast(int_type, val->copy(), loc);
     820              : 
     821              :   // BOUND is assumed to fit in an int.  Either it comes from len or
     822              :   // cap, or it was checked by an earlier call.
     823       224475 :   Expression* ibound;
     824       224475 :   if (bound->type() == int_type)
     825       205360 :     ibound = bound->copy();
     826              :   else
     827        19115 :     ibound = Expression::make_cast(int_type, bound->copy(), loc);
     828              : 
     829       224475 :   Expression* cmp = Expression::make_binary(op, ival, ibound, loc);
     830       224475 :   if (check == NULL)
     831              :     check = cmp;
     832              :   else
     833       218594 :     check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc);
     834              : 
     835       224475 :   Runtime::Function c;
     836       224475 :   if (val_type_size > int_type_size)
     837              :     {
     838          695 :       if (val_is_unsigned)
     839              :         c = code_extend_u;
     840              :       else
     841          311 :         c = code_extend;
     842              :     }
     843              :   else
     844              :     {
     845       223780 :       if (val_is_unsigned)
     846              :         c = code_u;
     847              :       else
     848       213083 :         c = code;
     849              :     }
     850              : 
     851       224475 :   Expression* ignore = Expression::make_boolean(true, loc);
     852       224475 :   Expression* crash = Runtime::make_call(gogo, c, loc, 2,
     853              :                                          val->copy(), bound->copy());
     854       224475 :   Expression* cond = Expression::make_conditional(check, ignore, crash, loc);
     855       224475 :   Statement* s = Statement::make_statement(cond, true);
     856       224475 :   s->determine_types(gogo);
     857       224475 :   inserter->insert(s);
     858              : }
     859              : 
     860              : void
     861            0 : Expression::dump_expression(Ast_dump_context* ast_dump_context) const
     862              : {
     863            0 :   this->do_dump_expression(ast_dump_context);
     864            0 : }
     865              : 
     866              : // Error expressions.  This are used to avoid cascading errors.
     867              : 
     868              : class Error_expression : public Expression
     869              : {
     870              :  public:
     871         9856 :   Error_expression(Location location)
     872        19712 :     : Expression(EXPRESSION_ERROR, location)
     873              :   { }
     874              : 
     875              :  protected:
     876              :   bool
     877           62 :   do_is_constant() const
     878           62 :   { return true; }
     879              : 
     880              :   bool
     881           25 :   do_is_untyped(Type**) const
     882           25 :   { return false; }
     883              : 
     884              :   bool
     885           30 :   do_numeric_constant_value(Numeric_constant*)
     886           30 :   { return false; }
     887              : 
     888              :   bool
     889            6 :   do_discarding_value()
     890            6 :   { return true; }
     891              : 
     892              :   Type*
     893        12537 :   do_type()
     894        12537 :   { return Type::make_error_type(); }
     895              : 
     896              :   void
     897          160 :   do_determine_type(Gogo*, const Type_context*)
     898          160 :   { }
     899              : 
     900              :   Expression*
     901            0 :   do_copy()
     902            0 :   { return this; }
     903              : 
     904              :   bool
     905            9 :   do_is_addressable() const
     906            9 :   { return true; }
     907              : 
     908              :   Bexpression*
     909            0 :   do_get_backend(Translate_context* context)
     910            0 :   { return context->backend()->error_expression(); }
     911              : 
     912              :   void
     913              :   do_dump_expression(Ast_dump_context*) const;
     914              : };
     915              : 
     916              : // Dump the ast representation for an error expression to a dump context.
     917              : 
     918              : void
     919            0 : Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
     920              : {
     921            0 :   ast_dump_context->ostream() << "_Error_" ;
     922            0 : }
     923              : 
     924              : Expression*
     925         9856 : Expression::make_error(Location location)
     926              : {
     927         9856 :   return new Error_expression(location);
     928              : }
     929              : 
     930              : // An expression which is really a type.  This is used during parsing.
     931              : // It is an error if these survive after lowering.
     932              : 
     933              : class Type_expression : public Expression
     934              : {
     935              :  public:
     936       254305 :   Type_expression(Type* type, Location location)
     937       254305 :     : Expression(EXPRESSION_TYPE, location),
     938       508610 :       type_(type)
     939              :   { }
     940              : 
     941              :  protected:
     942              :   int
     943       143431 :   do_traverse(Traverse* traverse)
     944       143431 :   { return Type::traverse(this->type_, traverse); }
     945              : 
     946              :   Type*
     947       476268 :   do_type()
     948       476268 :   { return this->type_; }
     949              : 
     950              :   void
     951        21109 :   do_determine_type(Gogo*, const Type_context*)
     952        21109 :   { }
     953              : 
     954              :   void
     955              :   do_check_types(Gogo*);
     956              : 
     957              :   Expression*
     958            0 :   do_copy()
     959            0 :   { return this; }
     960              : 
     961              :   Bexpression*
     962              :   do_get_backend(Translate_context*);
     963              : 
     964              :   void do_dump_expression(Ast_dump_context*) const;
     965              : 
     966              :  private:
     967              :   // The type which we are representing as an expression.
     968              :   Type* type_;
     969              : };
     970              : 
     971              : void
     972        23066 : Type_expression::do_check_types(Gogo*)
     973              : {
     974        23066 :   if (this->type_->is_error())
     975              :     {
     976            2 :       go_assert(saw_errors());
     977            2 :       this->set_is_error();
     978              :     }
     979        23066 : }
     980              : 
     981              : Bexpression*
     982            2 : Type_expression::do_get_backend(Translate_context* context)
     983              : {
     984            2 :   if (!this->is_error_expression())
     985            2 :     this->report_error("invalid use of type");
     986            2 :   return context->backend()->error_expression();
     987              : }
     988              : 
     989              : void
     990            0 : Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
     991              : {
     992            0 :   ast_dump_context->dump_type(this->type_);
     993            0 : }
     994              : 
     995              : Expression*
     996       254305 : Expression::make_type(Type* type, Location location)
     997              : {
     998       254305 :   return new Type_expression(type, location);
     999              : }
    1000              : 
    1001              : // Class Var_expression.
    1002              : 
    1003              : // Lower a variable expression.  Here we just make sure that the
    1004              : // initialization expression of the variable has been lowered.  This
    1005              : // ensures that we will be able to determine the type of the variable
    1006              : // if necessary.
    1007              : 
    1008              : Expression*
    1009      6402656 : Var_expression::do_lower(Gogo* gogo, Named_object* function,
    1010              :                          Statement_inserter* inserter)
    1011              : {
    1012      6402656 :   if (this->variable_->is_variable())
    1013              :     {
    1014      5668157 :       Variable* var = this->variable_->var_value();
    1015              :       // This is either a local variable or a global variable.  A
    1016              :       // reference to a variable which is local to an enclosing
    1017              :       // function will be a reference to a field in a closure.
    1018      5668157 :       if (var->is_global())
    1019              :         {
    1020       446324 :           function = NULL;
    1021       446324 :           inserter = NULL;
    1022              :         }
    1023      5668157 :       var->lower_init_expression(gogo, function, inserter);
    1024              :     }
    1025      6402656 :   return this;
    1026              : }
    1027              : 
    1028              : // Return the type of a reference to a variable.
    1029              : 
    1030              : Type*
    1031     51500701 : Var_expression::do_type()
    1032              : {
    1033     51500701 :   if (this->variable_->is_variable())
    1034     45961541 :     return this->variable_->var_value()->type();
    1035      5539160 :   else if (this->variable_->is_result_variable())
    1036      5539160 :     return this->variable_->result_var_value()->type();
    1037              :   else
    1038            0 :     go_unreachable();
    1039              : }
    1040              : 
    1041              : // Determine the type of a reference to a variable.
    1042              : 
    1043              : void
    1044      6261234 : Var_expression::do_determine_type(Gogo* gogo, const Type_context*)
    1045              : {
    1046      6261234 :   if (this->variable_->is_variable())
    1047      5609315 :     this->variable_->var_value()->determine_type(gogo);
    1048      6261234 : }
    1049              : 
    1050              : // Something takes the address of this variable.  This means that we
    1051              : // may want to move the variable onto the heap.
    1052              : 
    1053              : void
    1054      1421692 : Var_expression::do_address_taken(bool escapes)
    1055              : {
    1056      1421692 :   if (!escapes)
    1057              :     {
    1058      1072633 :       if (this->variable_->is_variable())
    1059      1069616 :         this->variable_->var_value()->set_non_escaping_address_taken();
    1060         3017 :       else if (this->variable_->is_result_variable())
    1061         3017 :         this->variable_->result_var_value()->set_non_escaping_address_taken();
    1062              :       else
    1063            0 :         go_unreachable();
    1064              :     }
    1065              :   else
    1066              :     {
    1067       349059 :       if (this->variable_->is_variable())
    1068       348722 :         this->variable_->var_value()->set_address_taken();
    1069          337 :       else if (this->variable_->is_result_variable())
    1070          337 :         this->variable_->result_var_value()->set_address_taken();
    1071              :       else
    1072            0 :         go_unreachable();
    1073              :     }
    1074              : 
    1075      1421692 :   if (this->variable_->is_variable()
    1076      1421692 :       && this->variable_->var_value()->is_in_heap())
    1077              :     {
    1078      1167227 :       Node::make_node(this)->set_encoding(Node::ESCAPE_HEAP);
    1079      1167227 :       Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
    1080              :     }
    1081      1421692 : }
    1082              : 
    1083              : // Export a reference to a variable.
    1084              : 
    1085              : void
    1086        54719 : Var_expression::do_export(Export_function_body* efb) const
    1087              : {
    1088        54719 :   Named_object* no = this->variable_;
    1089        54719 :   if (no->is_result_variable() || !no->var_value()->is_global())
    1090        52210 :     efb->write_string(Gogo::unpack_hidden_name(no->name()));
    1091              :   else
    1092         2509 :     Expression::export_name(efb, no);
    1093        54719 : }
    1094              : 
    1095              : // Get the backend representation for a reference to a variable.
    1096              : 
    1097              : Bexpression*
    1098      4054421 : Var_expression::do_get_backend(Translate_context* context)
    1099              : {
    1100      4054421 :   Bvariable* bvar = this->variable_->get_backend_variable(context->gogo(),
    1101              :                                                           context->function());
    1102      4054421 :   bool is_in_heap;
    1103      4054421 :   Location loc = this->location();
    1104      4054421 :   Btype* btype;
    1105      4054421 :   Gogo* gogo = context->gogo();
    1106      4054421 :   if (this->variable_->is_variable())
    1107              :     {
    1108      3144125 :       is_in_heap = this->variable_->var_value()->is_in_heap();
    1109      3144125 :       btype = this->variable_->var_value()->type()->get_backend(gogo);
    1110              :     }
    1111       910296 :   else if (this->variable_->is_result_variable())
    1112              :     {
    1113       910296 :       is_in_heap = this->variable_->result_var_value()->is_in_heap();
    1114       910296 :       btype = this->variable_->result_var_value()->type()->get_backend(gogo);
    1115              :     }
    1116              :   else
    1117            0 :     go_unreachable();
    1118              : 
    1119      4054421 :   Bexpression* ret =
    1120      4054421 :       context->backend()->var_expression(bvar, loc);
    1121      4054421 :   if (is_in_heap)
    1122        66925 :     ret = context->backend()->indirect_expression(btype, ret, true, loc);
    1123      4054421 :   return ret;
    1124              : }
    1125              : 
    1126              : // Ast dump for variable expression.
    1127              : 
    1128              : void
    1129            0 : Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    1130              : {
    1131            0 :   ast_dump_context->ostream() << this->variable_->message_name() ;
    1132            0 : }
    1133              : 
    1134              : // Make a reference to a variable in an expression.
    1135              : 
    1136              : Expression*
    1137      3521311 : Expression::make_var_reference(Named_object* var, Location location)
    1138              : {
    1139      3521311 :   if (var->is_sink())
    1140        19221 :     return Expression::make_sink(location);
    1141      3502090 :   if (var->is_redefinition())
    1142            0 :     return Expression::make_error(location);
    1143              : 
    1144              :   // FIXME: Creating a new object for each reference to a variable is
    1145              :   // wasteful.
    1146      3502090 :   return new Var_expression(var, location);
    1147              : }
    1148              : 
    1149              : // Class Enclosed_var_expression.
    1150              : 
    1151              : int
    1152       822673 : Enclosed_var_expression::do_traverse(Traverse*)
    1153              : {
    1154       822673 :   return TRAVERSE_CONTINUE;
    1155              : }
    1156              : 
    1157              : // Lower the reference to the enclosed variable.
    1158              : 
    1159              : Expression*
    1160        92066 : Enclosed_var_expression::do_lower(Gogo* gogo, Named_object* function,
    1161              :                                   Statement_inserter* inserter)
    1162              : {
    1163        92066 :   gogo->lower_expression(function, inserter, &this->reference_);
    1164        92066 :   return this;
    1165              : }
    1166              : 
    1167              : // Flatten the reference to the enclosed variable.
    1168              : 
    1169              : Expression*
    1170        46835 : Enclosed_var_expression::do_flatten(Gogo* gogo, Named_object* function,
    1171              :                                     Statement_inserter* inserter)
    1172              : {
    1173        46835 :   gogo->flatten_expression(function, inserter, &this->reference_);
    1174        46835 :   return this;
    1175              : }
    1176              : 
    1177              : void
    1178        28424 : Enclosed_var_expression::do_address_taken(bool escapes)
    1179              : {
    1180        28424 :   if (!escapes)
    1181              :     {
    1182        23149 :       if (this->variable_->is_variable())
    1183        23080 :         this->variable_->var_value()->set_non_escaping_address_taken();
    1184           69 :       else if (this->variable_->is_result_variable())
    1185           69 :         this->variable_->result_var_value()->set_non_escaping_address_taken();
    1186              :       else
    1187            0 :         go_unreachable();
    1188              :     }
    1189              :   else
    1190              :     {
    1191         5275 :       if (this->variable_->is_variable())
    1192         5266 :         this->variable_->var_value()->set_address_taken();
    1193            9 :       else if (this->variable_->is_result_variable())
    1194            9 :         this->variable_->result_var_value()->set_address_taken();
    1195              :       else
    1196            0 :         go_unreachable();
    1197              :     }
    1198              : 
    1199        28424 :   if (this->variable_->is_variable()
    1200        28424 :       && this->variable_->var_value()->is_in_heap())
    1201        22115 :     Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
    1202        28424 : }
    1203              : 
    1204              : // Ast dump for enclosed variable expression.
    1205              : 
    1206              : void
    1207            0 : Enclosed_var_expression::do_dump_expression(Ast_dump_context* adc) const
    1208              : {
    1209            0 :   adc->ostream() << this->variable_->message_name();
    1210            0 : }
    1211              : 
    1212              : // Make a reference to a variable within an enclosing function.
    1213              : 
    1214              : Expression*
    1215        43132 : Expression::make_enclosing_var_reference(Expression* reference,
    1216              :                                          Named_object* var, Location location)
    1217              : {
    1218        43132 :   return new Enclosed_var_expression(reference, var, location);
    1219              : }
    1220              : 
    1221              : // Class Temporary_reference_expression.
    1222              : 
    1223              : // The type.
    1224              : 
    1225              : Type*
    1226     18795086 : Temporary_reference_expression::do_type()
    1227              : {
    1228     18795086 :   return this->statement_->type();
    1229              : }
    1230              : 
    1231              : // Called if something takes the address of this temporary variable.
    1232              : // We never have to move temporary variables to the heap, but we do
    1233              : // need to know that they must live in the stack rather than in a
    1234              : // register.
    1235              : 
    1236              : void
    1237        33962 : Temporary_reference_expression::do_address_taken(bool)
    1238              : {
    1239        33962 :   this->statement_->set_is_address_taken();
    1240        33962 : }
    1241              : 
    1242              : // Export a reference to a temporary.
    1243              : 
    1244              : void
    1245         6731 : Temporary_reference_expression::do_export(Export_function_body* efb) const
    1246              : {
    1247         6731 :   unsigned int idx = efb->temporary_index(this->statement_);
    1248         6731 :   char buf[50];
    1249         6731 :   snprintf(buf, sizeof buf, "$t%u", idx);
    1250         6731 :   efb->write_c_string(buf);
    1251         6731 : }
    1252              : 
    1253              : // Import a reference to a temporary.
    1254              : 
    1255              : Expression*
    1256         3923 : Temporary_reference_expression::do_import(Import_function_body* ifb,
    1257              :                                           Location loc)
    1258              : {
    1259         3923 :   std::string id = ifb->read_identifier();
    1260         3923 :   go_assert(id[0] == '$' && id[1] == 't');
    1261         3923 :   const char *p = id.c_str();
    1262         3923 :   char *end;
    1263         3923 :   long idx = strtol(p + 2, &end, 10);
    1264         3923 :   if (*end != '\0' || idx > 0x7fffffff)
    1265              :     {
    1266            0 :       if (!ifb->saw_error())
    1267            0 :         go_error_at(loc,
    1268              :                     ("invalid export data for %qs: "
    1269              :                      "invalid temporary reference index at %lu"),
    1270            0 :                     ifb->name().c_str(),
    1271            0 :                     static_cast<unsigned long>(ifb->off()));
    1272            0 :       ifb->set_saw_error();
    1273            0 :       return Expression::make_error(loc);
    1274              :     }
    1275              : 
    1276         3923 :   Temporary_statement* temp =
    1277         3923 :     ifb->temporary_statement(static_cast<unsigned int>(idx));
    1278         3923 :   if (temp == NULL)
    1279              :     {
    1280            0 :       if (!ifb->saw_error())
    1281            0 :         go_error_at(loc,
    1282              :                     ("invalid export data for %qs: "
    1283              :                      "undefined temporary reference index at %lu"),
    1284            0 :                     ifb->name().c_str(),
    1285            0 :                     static_cast<unsigned long>(ifb->off()));
    1286            0 :       ifb->set_saw_error();
    1287            0 :       return Expression::make_error(loc);
    1288              :     }
    1289              : 
    1290         3923 :   return Expression::make_temporary_reference(temp, loc);
    1291         3923 : }
    1292              : 
    1293              : // Get a backend expression referring to the variable.
    1294              : 
    1295              : Bexpression*
    1296      3793779 : Temporary_reference_expression::do_get_backend(Translate_context* context)
    1297              : {
    1298      3793779 :   Gogo* gogo = context->gogo();
    1299      3793779 :   Bvariable* bvar = this->statement_->get_backend_variable(context);
    1300      3793779 :   Bexpression* ret = gogo->backend()->var_expression(bvar, this->location());
    1301              : 
    1302              :   // The backend can't always represent the same set of recursive types
    1303              :   // that the Go frontend can.  In some cases this means that a
    1304              :   // temporary variable won't have the right backend type.  Correct
    1305              :   // that here by adding a type cast.  We need to use base() to push
    1306              :   // the circularity down one level.
    1307      3793779 :   Type* stype = this->statement_->type();
    1308      3793779 :   if (!this->is_lvalue_
    1309      3699405 :       && stype->points_to() != NULL
    1310      4264401 :       && stype->points_to()->is_void_type())
    1311              :     {
    1312        18132 :       Btype* btype = this->type()->base()->get_backend(gogo);
    1313        18132 :       ret = gogo->backend()->convert_expression(btype, ret, this->location());
    1314              :     }
    1315      3793779 :   return ret;
    1316              : }
    1317              : 
    1318              : // Ast dump for temporary reference.
    1319              : 
    1320              : void
    1321            0 : Temporary_reference_expression::do_dump_expression(
    1322              :                                 Ast_dump_context* ast_dump_context) const
    1323              : {
    1324            0 :   ast_dump_context->dump_temp_variable_name(this->statement_);
    1325            0 : }
    1326              : 
    1327              : // Make a reference to a temporary variable.
    1328              : 
    1329              : Temporary_reference_expression*
    1330      3860104 : Expression::make_temporary_reference(Temporary_statement* statement,
    1331              :                                      Location location)
    1332              : {
    1333      3860104 :   statement->add_use();
    1334      3860104 :   return new Temporary_reference_expression(statement, location);
    1335              : }
    1336              : 
    1337              : // Class Set_and_use_temporary_expression.
    1338              : 
    1339              : // Return the type.
    1340              : 
    1341              : Type*
    1342       326051 : Set_and_use_temporary_expression::do_type()
    1343              : {
    1344       326051 :   return this->statement_->type();
    1345              : }
    1346              : 
    1347              : // Determine the type of the expression.
    1348              : 
    1349              : void
    1350        20883 : Set_and_use_temporary_expression::do_determine_type(
    1351              :     Gogo* gogo,
    1352              :     const Type_context* context)
    1353              : {
    1354        20883 :   this->expr_->determine_type(gogo, context);
    1355        20883 : }
    1356              : 
    1357              : // Take the address.
    1358              : 
    1359              : void
    1360            0 : Set_and_use_temporary_expression::do_address_taken(bool)
    1361              : {
    1362            0 :   this->statement_->set_is_address_taken();
    1363            0 : }
    1364              : 
    1365              : // Return the backend representation.
    1366              : 
    1367              : Bexpression*
    1368        16126 : Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
    1369              : {
    1370        16126 :   Location loc = this->location();
    1371        16126 :   Gogo* gogo = context->gogo();
    1372        16126 :   Bvariable* bvar = this->statement_->get_backend_variable(context);
    1373        16126 :   Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, loc);
    1374              : 
    1375        16126 :   Named_object* fn = context->function();
    1376        16126 :   go_assert(fn != NULL);
    1377        16126 :   Bfunction* bfn = fn->func_value()->get_or_make_decl(gogo, fn);
    1378        16126 :   Bexpression* bexpr = this->expr_->get_backend(context);
    1379        16126 :   Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref,
    1380              :                                                           bexpr, loc);
    1381        16126 :   Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc);
    1382        16126 :   Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
    1383        16126 :   return ret;
    1384              : }
    1385              : 
    1386              : // Dump.
    1387              : 
    1388              : void
    1389            0 : Set_and_use_temporary_expression::do_dump_expression(
    1390              :     Ast_dump_context* ast_dump_context) const
    1391              : {
    1392            0 :   ast_dump_context->ostream() << '(';
    1393            0 :   ast_dump_context->dump_temp_variable_name(this->statement_);
    1394            0 :   ast_dump_context->ostream() << " = ";
    1395            0 :   this->expr_->dump_expression(ast_dump_context);
    1396            0 :   ast_dump_context->ostream() << ')';
    1397            0 : }
    1398              : 
    1399              : // Make a set-and-use temporary.
    1400              : 
    1401              : Set_and_use_temporary_expression*
    1402        19060 : Expression::make_set_and_use_temporary(Temporary_statement* statement,
    1403              :                                        Expression* expr, Location location)
    1404              : {
    1405        19060 :   return new Set_and_use_temporary_expression(statement, expr, location);
    1406              : }
    1407              : 
    1408              : // A sink expression--a use of the blank identifier _.
    1409              : 
    1410              : class Sink_expression : public Expression
    1411              : {
    1412              :  public:
    1413        27627 :   Sink_expression(Location location)
    1414        27627 :     : Expression(EXPRESSION_SINK, location),
    1415            0 :       type_(NULL), bvar_(NULL)
    1416              :   { }
    1417              : 
    1418              :  protected:
    1419              :   bool
    1420            0 :   do_discarding_value()
    1421            0 :   { return true; }
    1422              : 
    1423              :   Type*
    1424              :   do_type();
    1425              : 
    1426              :   void
    1427              :   do_determine_type(Gogo*, const Type_context*);
    1428              : 
    1429              :   Expression*
    1430            0 :   do_copy()
    1431            0 :   { return new Sink_expression(this->location()); }
    1432              : 
    1433              :   Bexpression*
    1434              :   do_get_backend(Translate_context*);
    1435              : 
    1436              :   void
    1437              :   do_dump_expression(Ast_dump_context*) const;
    1438              : 
    1439              :  private:
    1440              :   // The type of this sink variable.
    1441              :   Type* type_;
    1442              :   // The temporary variable we generate.
    1443              :   Bvariable* bvar_;
    1444              : };
    1445              : 
    1446              : // Return the type of a sink expression.
    1447              : 
    1448              : Type*
    1449       189204 : Sink_expression::do_type()
    1450              : {
    1451       189204 :   if (this->type_ == NULL)
    1452       189204 :     return Type::make_sink_type();
    1453              :   return this->type_;
    1454              : }
    1455              : 
    1456              : // Determine the type of a sink expression.
    1457              : 
    1458              : void
    1459        63873 : Sink_expression::do_determine_type(Gogo*, const Type_context* context)
    1460              : {
    1461        63873 :   if (context->type != NULL)
    1462            0 :     this->type_ = context->type;
    1463        63873 : }
    1464              : 
    1465              : // Return a temporary variable for a sink expression.  This will
    1466              : // presumably be a write-only variable which the middle-end will drop.
    1467              : 
    1468              : Bexpression*
    1469            0 : Sink_expression::do_get_backend(Translate_context* context)
    1470              : {
    1471            0 :   Location loc = this->location();
    1472            0 :   Gogo* gogo = context->gogo();
    1473            0 :   if (this->bvar_ == NULL)
    1474              :     {
    1475            0 :       if (this->type_ == NULL || this->type_->is_sink_type())
    1476              :         {
    1477            0 :           go_assert(saw_errors());
    1478            0 :           return gogo->backend()->error_expression();
    1479              :         }
    1480              : 
    1481            0 :       Named_object* fn = context->function();
    1482            0 :       go_assert(fn != NULL);
    1483            0 :       Bfunction* fn_ctx = fn->func_value()->get_or_make_decl(gogo, fn);
    1484            0 :       Btype* bt = this->type_->get_backend(context->gogo());
    1485            0 :       Bstatement* decl;
    1486            0 :       this->bvar_ =
    1487            0 :         gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL,
    1488              :                                             0, loc, &decl);
    1489            0 :       Bexpression* var_ref =
    1490            0 :           gogo->backend()->var_expression(this->bvar_, loc);
    1491            0 :       var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
    1492            0 :       return var_ref;
    1493              :     }
    1494            0 :   return gogo->backend()->var_expression(this->bvar_, loc);
    1495              : }
    1496              : 
    1497              : // Ast dump for sink expression.
    1498              : 
    1499              : void
    1500            0 : Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    1501              : {
    1502            0 :   ast_dump_context->ostream() << "_" ;
    1503            0 : }
    1504              : 
    1505              : // Make a sink expression.
    1506              : 
    1507              : Expression*
    1508        27627 : Expression::make_sink(Location location)
    1509              : {
    1510        27627 :   return new Sink_expression(location);
    1511              : }
    1512              : 
    1513              : // Class Func_expression.
    1514              : 
    1515              : // FIXME: Can a function expression appear in a constant expression?
    1516              : // The value is unchanging.  Initializing a constant to the address of
    1517              : // a function seems like it could work, though there might be little
    1518              : // point to it.
    1519              : 
    1520              : // Traversal.
    1521              : 
    1522              : int
    1523     14463672 : Func_expression::do_traverse(Traverse* traverse)
    1524              : {
    1525     14463672 :   return (this->closure_ == NULL
    1526     14463672 :           ? TRAVERSE_CONTINUE
    1527       232320 :           : Expression::traverse(&this->closure_, traverse));
    1528              : }
    1529              : 
    1530              : // Return the type of a function expression.
    1531              : 
    1532              : Type*
    1533     24389210 : Func_expression::do_type()
    1534              : {
    1535     24389210 :   if (this->function_->is_function())
    1536     11179566 :     return this->function_->func_value()->type();
    1537     13209644 :   else if (this->function_->is_function_declaration())
    1538     13209644 :     return this->function_->func_declaration_value()->type();
    1539              :   else
    1540            0 :     go_unreachable();
    1541              : }
    1542              : 
    1543              : // Get the backend representation for the code of a function expression.
    1544              : 
    1545              : Bexpression*
    1546      2137860 : Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc)
    1547              : {
    1548      2137860 :   Function_type* fntype;
    1549      2137860 :   if (no->is_function())
    1550       612754 :     fntype = no->func_value()->type();
    1551      1525106 :   else if (no->is_function_declaration())
    1552      1525106 :     fntype = no->func_declaration_value()->type();
    1553              :   else
    1554            0 :     go_unreachable();
    1555              : 
    1556              :   // Builtin functions are handled specially by Call_expression.  We
    1557              :   // can't take their address.
    1558      2137860 :   if (fntype->is_builtin())
    1559              :     {
    1560            0 :       go_error_at(loc,
    1561              :                   ("invalid use of special built-in function %qs; "
    1562              :                    "must be called"),
    1563            0 :                   no->message_name().c_str());
    1564            0 :       return gogo->backend()->error_expression();
    1565              :     }
    1566              : 
    1567      2137860 :   Bfunction* fndecl;
    1568      2137860 :   if (no->is_function())
    1569       612754 :     fndecl = no->func_value()->get_or_make_decl(gogo, no);
    1570      1525106 :   else if (no->is_function_declaration())
    1571      1525106 :     fndecl = no->func_declaration_value()->get_or_make_decl(gogo, no);
    1572              :   else
    1573              :     go_unreachable();
    1574              : 
    1575      2137860 :   return gogo->backend()->function_code_expression(fndecl, loc);
    1576              : }
    1577              : 
    1578              : // Get the backend representation for a function expression.  This is used when
    1579              : // we take the address of a function rather than simply calling it.  A func
    1580              : // value is represented as a pointer to a block of memory.  The first
    1581              : // word of that memory is a pointer to the function code.  The
    1582              : // remaining parts of that memory are the addresses of variables that
    1583              : // the function closes over.
    1584              : 
    1585              : Bexpression*
    1586       155520 : Func_expression::do_get_backend(Translate_context* context)
    1587              : {
    1588              :   // If there is no closure, just use the function descriptor.
    1589       155520 :   if (this->closure_ == NULL)
    1590              :     {
    1591       142718 :       Gogo* gogo = context->gogo();
    1592       142718 :       Named_object* no = this->function_;
    1593       142718 :       Expression* descriptor;
    1594       142718 :       if (no->is_function())
    1595        37923 :         descriptor = no->func_value()->descriptor(gogo, no);
    1596       104795 :       else if (no->is_function_declaration())
    1597              :         {
    1598       104795 :           if (no->func_declaration_value()->type()->is_builtin())
    1599              :             {
    1600            1 :               go_error_at(this->location(),
    1601              :                           ("invalid use of special built-in function %qs; "
    1602              :                            "must be called"),
    1603            1 :                           no->message_name().c_str());
    1604            1 :               return gogo->backend()->error_expression();
    1605              :             }
    1606       104794 :           descriptor = no->func_declaration_value()->descriptor(gogo, no);
    1607              :         }
    1608              :       else
    1609            0 :         go_unreachable();
    1610              : 
    1611       142717 :       Bexpression* bdesc = descriptor->get_backend(context);
    1612       142717 :       return gogo->backend()->address_expression(bdesc, this->location());
    1613              :     }
    1614              : 
    1615        12802 :   go_assert(this->function_->func_value()->enclosing() != NULL);
    1616              : 
    1617              :   // If there is a closure, then the closure is itself the function
    1618              :   // expression.  It is a pointer to a struct whose first field points
    1619              :   // to the function code and whose remaining fields are the addresses
    1620              :   // of the closed-over variables.
    1621        12802 :   Bexpression *bexpr = this->closure_->get_backend(context);
    1622              : 
    1623              :   // Introduce a backend type conversion, to account for any differences
    1624              :   // between the argument type (function descriptor, struct with a
    1625              :   // single field) and the closure (struct with multiple fields).
    1626        12802 :   Gogo* gogo = context->gogo();
    1627        12802 :   Btype *btype = this->type()->get_backend(gogo);
    1628        12802 :   return gogo->backend()->convert_expression(btype, bexpr, this->location());
    1629              : }
    1630              : 
    1631              : // The cost of inlining a function reference.
    1632              : 
    1633              : int
    1634       570556 : Func_expression::do_inlining_cost() const
    1635              : {
    1636              :   // FIXME: We don't inline references to nested functions.
    1637       570556 :   if (this->closure_ != NULL)
    1638              :     return 0x100000;
    1639       560412 :   if (this->function_->is_function()
    1640       560412 :       && this->function_->func_value()->enclosing() != NULL)
    1641         2780 :     return 0x100000;
    1642              : 
    1643              :   return 1;
    1644              : }
    1645              : 
    1646              : // Export a reference to a function.
    1647              : 
    1648              : void
    1649        10918 : Func_expression::do_export(Export_function_body* efb) const
    1650              : {
    1651        10918 :   Expression::export_name(efb, this->function_);
    1652        10918 : }
    1653              : 
    1654              : // Ast dump for function.
    1655              : 
    1656              : void
    1657            0 : Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    1658              : {
    1659            0 :   ast_dump_context->ostream() << this->function_->name();
    1660            0 :   if (this->closure_ != NULL)
    1661              :     {
    1662            0 :       ast_dump_context->ostream() << " {closure =  ";
    1663            0 :       this->closure_->dump_expression(ast_dump_context);
    1664            0 :       ast_dump_context->ostream() << "}";
    1665              :     }
    1666            0 : }
    1667              : 
    1668              : // Make a reference to a function in an expression.
    1669              : 
    1670              : Expression*
    1671      2156076 : Expression::make_func_reference(Named_object* function, Expression* closure,
    1672              :                                 Location location)
    1673              : {
    1674      2156076 :   Func_expression* fe = new Func_expression(function, closure, location);
    1675              : 
    1676              :   // Detect references to builtin functions and set the runtime code if
    1677              :   // appropriate.
    1678      2156076 :   if (function->is_function_declaration())
    1679      1798779 :     fe->set_runtime_code(Runtime::name_to_code(function->name()));
    1680      2156076 :   return fe;
    1681              : }
    1682              : 
    1683              : // Class Func_descriptor_expression.
    1684              : 
    1685              : // Constructor.
    1686              : 
    1687       259784 : Func_descriptor_expression::Func_descriptor_expression(Named_object* fn)
    1688              :   : Expression(EXPRESSION_FUNC_DESCRIPTOR, fn->location()),
    1689       259784 :     fn_(fn), dvar_(NULL)
    1690              : {
    1691       259784 :   go_assert(!fn->is_function() || !fn->func_value()->needs_closure());
    1692       259784 : }
    1693              : 
    1694              : // Traversal.
    1695              : 
    1696              : int
    1697            0 : Func_descriptor_expression::do_traverse(Traverse*)
    1698              : {
    1699            0 :   return TRAVERSE_CONTINUE;
    1700              : }
    1701              : 
    1702              : // All function descriptors have the same type.
    1703              : 
    1704              : Type* Func_descriptor_expression::descriptor_type;
    1705              : 
    1706              : void
    1707       408426 : Func_descriptor_expression::make_func_descriptor_type()
    1708              : {
    1709       408426 :   if (Func_descriptor_expression::descriptor_type != NULL)
    1710              :     return;
    1711         4646 :   Type* uintptr_type = Type::lookup_integer_type("uintptr");
    1712         4646 :   Type* struct_type = Type::make_builtin_struct_type(1, "fn", uintptr_type);
    1713         4646 :   Func_descriptor_expression::descriptor_type =
    1714         4646 :     Type::make_builtin_named_type("functionDescriptor", struct_type);
    1715              : }
    1716              : 
    1717              : Type*
    1718       403780 : Func_descriptor_expression::do_type()
    1719              : {
    1720       403780 :   Func_descriptor_expression::make_func_descriptor_type();
    1721       403780 :   return Func_descriptor_expression::descriptor_type;
    1722              : }
    1723              : 
    1724              : // The backend representation for a function descriptor.
    1725              : 
    1726              : Bexpression*
    1727       298003 : Func_descriptor_expression::do_get_backend(Translate_context* context)
    1728              : {
    1729       298003 :   Named_object* no = this->fn_;
    1730       298003 :   Location loc = no->location();
    1731       298003 :   if (this->dvar_ != NULL)
    1732        38228 :     return context->backend()->var_expression(this->dvar_, loc);
    1733              : 
    1734       259775 :   Gogo* gogo = context->gogo();
    1735       259775 :   Backend_name bname;
    1736       259775 :   gogo->function_descriptor_backend_name(no, &bname);
    1737       259775 :   bool is_descriptor = false;
    1738       259775 :   if (no->is_function_declaration()
    1739       105139 :       && !no->func_declaration_value()->asm_name().empty()
    1740       349886 :       && Linemap::is_predeclared_location(no->location()))
    1741              :     is_descriptor = true;
    1742              : 
    1743              :   // The runtime package implements some functions defined in the
    1744              :   // syscall package.  Let the syscall package define the descriptor
    1745              :   // in this case.
    1746       259775 :   if (gogo->compiling_runtime()
    1747        21484 :       && gogo->package_name() == "runtime"
    1748        14786 :       && no->is_function()
    1749         5496 :       && !no->func_value()->asm_name().empty()
    1750       263620 :       && no->func_value()->asm_name().compare(0, 8, "syscall.") == 0)
    1751              :     is_descriptor = true;
    1752              : 
    1753       259775 :   Btype* btype = this->type()->get_backend(gogo);
    1754              : 
    1755       259775 :   Bvariable* bvar;
    1756       259775 :   if (no->package() != NULL || is_descriptor)
    1757       115770 :     bvar =
    1758       115770 :       context->backend()->immutable_struct_reference(bname.name(),
    1759       231540 :                                                      bname.optional_asm_name(),
    1760              :                                                      btype, loc);
    1761              :   else
    1762              :     {
    1763       144005 :       Location bloc = Linemap::predeclared_location();
    1764              : 
    1765              :       // The runtime package has hash/equality functions that are
    1766              :       // referenced by type descriptors outside of the runtime, so the
    1767              :       // function descriptors must be visible even though they are not
    1768              :       // exported.
    1769       144005 :       bool is_exported_runtime = false;
    1770       144005 :       if (gogo->compiling_runtime()
    1771         8866 :           && gogo->package_name() == "runtime"
    1772       149465 :           && (no->name().find("hash") != std::string::npos
    1773         5355 :               || no->name().find("equal") != std::string::npos))
    1774              :         is_exported_runtime = true;
    1775              : 
    1776       144005 :       bool is_hidden = ((no->is_function()
    1777       143355 :                          && no->func_value()->enclosing() != NULL)
    1778       133240 :                         || (Gogo::is_hidden_name(no->name())
    1779         7957 :                             && !is_exported_runtime)
    1780       269491 :                         || Gogo::is_thunk(no));
    1781              : 
    1782       144005 :       if (no->is_function() && no->func_value()->is_referenced_by_inline())
    1783              :         is_hidden = false;
    1784              : 
    1785       142409 :       unsigned int flags = 0;
    1786       142409 :       if (is_hidden)
    1787       144005 :         flags |= Backend::variable_is_hidden;
    1788       144005 :       bvar = context->backend()->immutable_struct(bname.name(),
    1789       144005 :                                                   bname.optional_asm_name(),
    1790              :                                                   flags, btype, bloc);
    1791       144005 :       Expression_list* vals = new Expression_list();
    1792       144005 :       vals->push_back(Expression::make_func_code_reference(this->fn_, bloc));
    1793       144005 :       Expression* init =
    1794       144005 :         Expression::make_struct_composite_literal(this->type(), vals, bloc);
    1795       144005 :       Translate_context bcontext(gogo, NULL, NULL, NULL);
    1796       144005 :       bcontext.set_is_const();
    1797       144005 :       Bexpression* binit = init->get_backend(&bcontext);
    1798       144005 :       context->backend()->immutable_struct_set_init(bvar, bname.name(),
    1799              :                                                     flags, btype, bloc, binit);
    1800              :     }
    1801              : 
    1802       259775 :   this->dvar_ = bvar;
    1803       259775 :   return gogo->backend()->var_expression(bvar, loc);
    1804       259775 : }
    1805              : 
    1806              : // Print a function descriptor expression.
    1807              : 
    1808              : void
    1809            0 : Func_descriptor_expression::do_dump_expression(Ast_dump_context* context) const
    1810              : {
    1811            0 :   context->ostream() << "[descriptor " << this->fn_->name() << "]";
    1812            0 : }
    1813              : 
    1814              : // Make a function descriptor expression.
    1815              : 
    1816              : Func_descriptor_expression*
    1817       259784 : Expression::make_func_descriptor(Named_object* fn)
    1818              : {
    1819       259784 :   return new Func_descriptor_expression(fn);
    1820              : }
    1821              : 
    1822              : // Make the function descriptor type, so that it can be converted.
    1823              : 
    1824              : void
    1825         4646 : Expression::make_func_descriptor_type()
    1826              : {
    1827         4646 :   Func_descriptor_expression::make_func_descriptor_type();
    1828         4646 : }
    1829              : 
    1830              : // A reference to just the code of a function.
    1831              : 
    1832              : class Func_code_reference_expression : public Expression
    1833              : {
    1834              :  public:
    1835      2357830 :   Func_code_reference_expression(Named_object* function, Location location)
    1836      2357830 :     : Expression(EXPRESSION_FUNC_CODE_REFERENCE, location),
    1837      4715660 :       function_(function)
    1838              :   { }
    1839              : 
    1840              :  protected:
    1841              :   int
    1842       221665 :   do_traverse(Traverse*)
    1843       221665 :   { return TRAVERSE_CONTINUE; }
    1844              : 
    1845              :   bool
    1846       318868 :   do_is_static_initializer() const
    1847       318868 :   { return true; }
    1848              : 
    1849              :   Type*
    1850       457275 :   do_type()
    1851       457275 :   { return Type::make_pointer_type(Type::make_void_type()); }
    1852              : 
    1853              :   void
    1854       549002 :   do_determine_type(Gogo*, const Type_context*)
    1855       549002 :   { }
    1856              : 
    1857              :   Expression*
    1858            0 :   do_copy()
    1859              :   {
    1860            0 :     return Expression::make_func_code_reference(this->function_,
    1861            0 :                                                 this->location());
    1862              :   }
    1863              : 
    1864              :   Bexpression*
    1865              :   do_get_backend(Translate_context*);
    1866              : 
    1867              :   void
    1868            0 :   do_dump_expression(Ast_dump_context* context) const
    1869            0 :   { context->ostream() << "[raw " << this->function_->name() << "]" ; }
    1870              : 
    1871              :  private:
    1872              :   // The function.
    1873              :   Named_object* function_;
    1874              : };
    1875              : 
    1876              : // Get the backend representation for a reference to function code.
    1877              : 
    1878              : Bexpression*
    1879      2137860 : Func_code_reference_expression::do_get_backend(Translate_context* context)
    1880              : {
    1881      2137860 :   return Func_expression::get_code_pointer(context->gogo(), this->function_,
    1882      2137860 :                                            this->location());
    1883              : }
    1884              : 
    1885              : // Make a reference to the code of a function.
    1886              : 
    1887              : Expression*
    1888      2357830 : Expression::make_func_code_reference(Named_object* function, Location location)
    1889              : {
    1890      2357830 :   return new Func_code_reference_expression(function, location);
    1891              : }
    1892              : 
    1893              : // Class Unknown_expression.
    1894              : 
    1895              : // Return the name of an unknown expression.
    1896              : 
    1897              : const std::string&
    1898         5232 : Unknown_expression::name() const
    1899              : {
    1900         5232 :   return this->named_object_->name();
    1901              : }
    1902              : 
    1903              : // Set the iota value if this could be a reference to iota.
    1904              : 
    1905              : void
    1906        17225 : Unknown_expression::set_iota_value(int iota_value)
    1907              : {
    1908        17225 :   this->iota_value_ = iota_value;
    1909        17225 :   this->is_iota_ = true;
    1910        17225 : }
    1911              : 
    1912              : // Traversal.
    1913              : 
    1914              : int
    1915      2179207 : Unknown_expression::do_traverse(Traverse* traverse)
    1916              : {
    1917      2179207 :   if (this->lowered_ != NULL)
    1918              :     {
    1919      1131206 :       if (Expression::traverse(&this->lowered_, traverse) == TRAVERSE_EXIT)
    1920              :         return TRAVERSE_EXIT;
    1921              :     }
    1922              :   return TRAVERSE_CONTINUE;
    1923              : }
    1924              : 
    1925              : // Determine the type of a reference to an unknown name.  At this
    1926              : // point we have to figure out what the name refers to.
    1927              : 
    1928              : void
    1929       451116 : Unknown_expression::do_determine_type(Gogo* gogo, const Type_context* context)
    1930              : {
    1931       451116 :   if (this->is_error_expression())
    1932        11143 :     return;
    1933              : 
    1934       451116 :   if (this->lowered_ != NULL)
    1935              :     {
    1936        11097 :       this->lowered_->determine_type(gogo, context);
    1937        11097 :       return;
    1938              :     }
    1939              : 
    1940       440019 :   Location loc = this->location();
    1941              : 
    1942       440019 :   Named_object* no = this->named_object_;
    1943       440019 :   if (no->is_unknown())
    1944              :     {
    1945       439491 :       Named_object* real = no->unknown_value()->real_named_object();
    1946       439491 :       if (real == NULL)
    1947              :         {
    1948           46 :           if (!this->no_error_message_)
    1949           45 :             go_error_at(loc, "reference to undefined name %qs",
    1950           90 :                         no->message_name().c_str());
    1951           46 :           this->set_is_error();
    1952           46 :           return;
    1953              :         }
    1954       439445 :       no = real;
    1955       439445 :       this->named_object_ = real;
    1956              :     }
    1957              : 
    1958       439973 :   switch (no->classification())
    1959              :     {
    1960        91849 :     case Named_object::NAMED_OBJECT_TYPE:
    1961        91849 :       this->lowered_ = Expression::make_type(no->type_value(), loc);
    1962        91849 :       break;
    1963        70720 :     case Named_object::NAMED_OBJECT_FUNC:
    1964        70720 :     case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
    1965        70720 :       this->lowered_ = Expression::make_func_reference(no, NULL, loc);
    1966        70720 :       break;
    1967       256281 :     case Named_object::NAMED_OBJECT_CONST:
    1968       256281 :       this->lowered_ = Expression::make_const_reference(no, loc);
    1969       256281 :       this->lowered_->determine_type(gogo, context);
    1970       256281 :       if (this->is_iota_)
    1971           11 :         this->lowered_->const_expression()->set_iota_value(this->iota_value_);
    1972              :       break;
    1973        21123 :     case Named_object::NAMED_OBJECT_VAR:
    1974        21123 :       this->lowered_ = Expression::make_var_reference(no, loc);
    1975        21123 :       no->var_value()->set_is_used();
    1976        21123 :       this->lowered_->determine_type(gogo, context);
    1977        21123 :       break;
    1978            0 :     case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
    1979            0 :       if (!this->no_error_message_)
    1980            0 :         go_error_at(this->location(), "reference to undefined type %qs",
    1981            0 :                     no->message_name().c_str());
    1982            0 :       this->set_is_error();
    1983            0 :       break;
    1984            0 :     case Named_object::NAMED_OBJECT_PACKAGE:
    1985            0 :       if (!this->no_error_message_)
    1986            0 :         this->report_error(_("unexpected reference to package"));
    1987            0 :       this->set_is_error();
    1988            0 :       break;
    1989            0 :     default:
    1990            0 :       go_unreachable();
    1991              :     }
    1992              : }
    1993              : 
    1994              : Type*
    1995      1083816 : Unknown_expression::do_type()
    1996              : {
    1997      1083816 :   if (this->is_error_expression())
    1998           55 :     return Type::make_error_type();
    1999      1083761 :   go_assert(this->lowered_ != NULL);
    2000      1083761 :   return this->lowered_->type();
    2001              : }
    2002              : 
    2003              : bool
    2004       111569 : Unknown_expression::do_is_constant() const
    2005              : {
    2006       111569 :   if (this->is_error_expression())
    2007              :     return true;
    2008       111563 :   if (this->lowered_ != NULL)
    2009        17914 :     return this->lowered_->is_constant();
    2010              : 
    2011              :   // This can be called before do_determine_types by
    2012              :   // Binary_expression::do_determine_type, which needs to know which
    2013              :   // values are constant before it works out the appropriate
    2014              :   // Type_context to pass down.
    2015        93649 :   Named_object* no = this->named_object_;
    2016        93649 :   if (no->is_unknown())
    2017              :     {
    2018        93649 :       no = no->unknown_value()->real_named_object();
    2019        93649 :       if (no == NULL)
    2020              :         return true;
    2021              :     }
    2022        93644 :   return no->is_const();
    2023              : }
    2024              : 
    2025              : bool
    2026        94096 : Unknown_expression::do_is_untyped(Type** ptype) const
    2027              : {
    2028        94096 :   if (this->is_error_expression())
    2029              :     return false;
    2030        94096 :   if (this->lowered_ != NULL)
    2031            0 :     return this->lowered_->is_untyped(ptype);
    2032              : 
    2033        94096 :   Named_object* no = this->named_object_;
    2034        94096 :   if (no->is_unknown())
    2035              :     {
    2036        94096 :       no = no->unknown_value()->real_named_object();
    2037        94096 :       if (no == NULL)
    2038              :         return false;
    2039              :     }
    2040              : 
    2041        94091 :   if (!no->is_const())
    2042              :     return false;
    2043        92796 :   Type* t = no->const_value()->type();
    2044        92796 :   if (t != NULL)
    2045        87680 :     return Expression::is_untyped_type(t, ptype);
    2046         5116 :   return no->const_value()->expr()->is_untyped(ptype);
    2047              : }
    2048              : 
    2049              : bool
    2050        69210 : Unknown_expression::do_numeric_constant_value(Numeric_constant* nc)
    2051              : {
    2052        69210 :   if (this->is_error_expression())
    2053              :     return false;
    2054        69210 :   if (this->lowered_ != NULL)
    2055        69138 :     return this->lowered_->numeric_constant_value(nc);
    2056              : 
    2057              :   // This can be called before the determine_types pass.
    2058           72 :   Named_object* no = this->named_object_;
    2059           72 :   if (no->is_unknown())
    2060              :     {
    2061           72 :       no = no->unknown_value()->real_named_object();
    2062           72 :       if (no == NULL)
    2063              :         return false;
    2064              :     }
    2065           72 :   if (!no->is_const())
    2066              :     return false;
    2067           72 :   return no->const_value()->expr()->numeric_constant_value(nc);
    2068              : }
    2069              : 
    2070              : bool
    2071          259 : Unknown_expression::do_string_constant_value(std::string* val)
    2072              : {
    2073          259 :   if (this->is_error_expression())
    2074              :     return false;
    2075          259 :   go_assert(this->lowered_ != NULL);
    2076          259 :   return this->lowered_->string_constant_value(val);
    2077              : }
    2078              : 
    2079              : bool
    2080            0 : Unknown_expression::do_boolean_constant_value(bool* val)
    2081              : {
    2082            0 :   if (this->is_error_expression())
    2083              :     return false;
    2084            0 :   go_assert(this->lowered_ != NULL);
    2085            0 :   return this->lowered_->boolean_constant_value(val);
    2086              : }
    2087              : 
    2088              : bool
    2089        12895 : Unknown_expression::do_is_addressable() const
    2090              : {
    2091        12895 :   if (this->is_error_expression())
    2092              :     return true;
    2093        12893 :   go_assert(this->lowered_ != NULL);
    2094        12893 :   return this->lowered_->is_addressable();
    2095              : }
    2096              : 
    2097              : // Lower a reference to an unknown name.
    2098              : 
    2099              : Expression*
    2100       358115 : Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
    2101              : {
    2102       358115 :   if (this->is_error_expression())
    2103           29 :     return Expression::make_error(this->location());
    2104       358086 :   go_assert(this->lowered_ != NULL);
    2105              :   return this->lowered_;
    2106              : }
    2107              : 
    2108              : // Dump the ast representation for an unknown expression to a dump context.
    2109              : 
    2110              : void
    2111            0 : Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    2112              : {
    2113            0 :   if (this->lowered_ != NULL)
    2114            0 :     this->lowered_->dump_expression(ast_dump_context);
    2115              :   else
    2116            0 :     ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
    2117            0 :                                 << ")";
    2118            0 : }
    2119              : 
    2120              : // Make a reference to an unknown name.
    2121              : 
    2122              : Unknown_expression*
    2123       592258 : Expression::make_unknown_reference(Named_object* no, Location location)
    2124              : {
    2125       592258 :   return new Unknown_expression(no, location);
    2126              : }
    2127              : 
    2128              : // Start exporting a type conversion for a constant, if needed.  This
    2129              : // returns whether we need to export a closing parenthesis.
    2130              : 
    2131              : bool
    2132        65870 : Expression::export_constant_type(Export_function_body* efb, Type* type)
    2133              : {
    2134        65870 :   if (type == NULL
    2135        62463 :       || type->is_abstract()
    2136        96198 :       || type == efb->type_context())
    2137        52364 :     return false;
    2138        13506 :   efb->write_c_string("$convert(");
    2139        13506 :   efb->write_type(type);
    2140        13506 :   efb->write_c_string(", ");
    2141        13506 :   return true;
    2142              : }
    2143              : 
    2144              : // Finish a type conversion for a constant.
    2145              : 
    2146              : void
    2147        65870 : Expression::finish_export_constant_type(Export_function_body* efb, bool needed)
    2148              : {
    2149        65870 :   if (needed)
    2150        13506 :     efb->write_c_string(")");
    2151        65870 : }
    2152              : 
    2153              : // A boolean expression.
    2154              : 
    2155              : class Boolean_expression : public Expression
    2156              : {
    2157              :  public:
    2158       594735 :   Boolean_expression(bool val, Location location)
    2159       594735 :     : Expression(EXPRESSION_BOOLEAN, location),
    2160      1189470 :       val_(val), type_(NULL)
    2161              :   { }
    2162              : 
    2163              :   static Expression*
    2164              :   do_import(Import_expression*, Location);
    2165              : 
    2166              :  protected:
    2167              :   int
    2168              :   do_traverse(Traverse*);
    2169              : 
    2170              :   bool
    2171        24916 :   do_is_constant() const
    2172        24916 :   { return true; }
    2173              : 
    2174              :   bool
    2175              :   do_is_untyped(Type**) const;
    2176              : 
    2177              :   bool
    2178            0 :   do_is_zero_value() const
    2179            0 :   { return this->val_ == false; }
    2180              : 
    2181              :   bool
    2182         9479 :   do_boolean_constant_value(bool* val)
    2183              :   {
    2184         9479 :     *val = this->val_;
    2185         9479 :     return true;
    2186              :   }
    2187              : 
    2188              :   bool
    2189           11 :   do_is_static_initializer() const
    2190           11 :   { return true; }
    2191              : 
    2192              :   Type*
    2193              :   do_type();
    2194              : 
    2195              :   void
    2196              :   do_determine_type(Gogo*, const Type_context*);
    2197              : 
    2198              :   Expression*
    2199            0 :   do_copy()
    2200            0 :   { return this; }
    2201              : 
    2202              :   Bexpression*
    2203       652831 :   do_get_backend(Translate_context* context)
    2204       652831 :   { return context->backend()->boolean_constant_expression(this->val_); }
    2205              : 
    2206              :   int
    2207        47347 :   do_inlining_cost() const
    2208        47347 :   { return 1; }
    2209              : 
    2210              :   void
    2211              :   do_export(Export_function_body* efb) const;
    2212              : 
    2213              :   void
    2214            0 :   do_dump_expression(Ast_dump_context* ast_dump_context) const
    2215            0 :   { ast_dump_context->ostream() << (this->val_ ? "true" : "false"); }
    2216              : 
    2217              :  private:
    2218              :   // The constant.
    2219              :   bool val_;
    2220              :   // The type as determined by context.
    2221              :   Type* type_;
    2222              : };
    2223              : 
    2224              : // Traverse a boolean expression.  We just need to traverse the type
    2225              : // if there is one.
    2226              : 
    2227              : int
    2228      1399401 : Boolean_expression::do_traverse(Traverse* traverse)
    2229              : {
    2230      1399401 :   if (this->type_ != NULL)
    2231      1364439 :     return Type::traverse(this->type_, traverse);
    2232              :   return TRAVERSE_CONTINUE;
    2233              : }
    2234              : 
    2235              : bool
    2236        24131 : Boolean_expression::do_is_untyped(Type** ptype) const
    2237              : {
    2238        24131 :   if (this->type_ != NULL)
    2239           44 :     return Expression::is_untyped_type(this->type_, ptype);
    2240        24087 :   *ptype = Type::make_boolean_type();
    2241        24087 :   return true;
    2242              : }
    2243              : 
    2244              : // Get the type.
    2245              : 
    2246              : Type*
    2247      1545765 : Boolean_expression::do_type()
    2248              : {
    2249      1545765 :   if (this->type_ == NULL)
    2250        15257 :     this->type_ = Type::make_boolean_type();
    2251      1545765 :   return this->type_;
    2252              : }
    2253              : 
    2254              : // Set the type from the context.
    2255              : 
    2256              : void
    2257       656191 : Boolean_expression::do_determine_type(Gogo*, const Type_context* context)
    2258              : {
    2259       656191 :   if (this->type_ != NULL && !this->type_->is_abstract())
    2260              :     ;
    2261       566862 :   else if (context->type != NULL && context->type->is_boolean_type())
    2262       189034 :     this->type_ = context->type;
    2263       377828 :   else if (!context->may_be_abstract)
    2264       377185 :     this->type_ = Type::lookup_bool_type();
    2265       656191 : }
    2266              : 
    2267              : // Export a boolean constant.
    2268              : 
    2269              : void
    2270         3836 : Boolean_expression::do_export(Export_function_body* efb) const
    2271              : {
    2272         3836 :   bool exported_type = Expression::export_constant_type(efb, this->type_);
    2273         5839 :   efb->write_c_string(this->val_ ? "$true" : "$false");
    2274         3836 :   Expression::finish_export_constant_type(efb, exported_type);
    2275         3836 : }
    2276              : 
    2277              : // Import a boolean constant.
    2278              : 
    2279              : Expression*
    2280         2859 : Boolean_expression::do_import(Import_expression* imp, Location loc)
    2281              : {
    2282         2859 :   if (imp->version() >= EXPORT_FORMAT_V3)
    2283         2859 :     imp->require_c_string("$");
    2284         2859 :   if (imp->peek_char() == 't')
    2285              :     {
    2286         1370 :       imp->require_c_string("true");
    2287         1370 :       return Expression::make_boolean(true, loc);
    2288              :     }
    2289              :   else
    2290              :     {
    2291         1489 :       imp->require_c_string("false");
    2292         1489 :       return Expression::make_boolean(false, loc);
    2293              :     }
    2294              : }
    2295              : 
    2296              : // Make a boolean expression.
    2297              : 
    2298              : Expression*
    2299       594735 : Expression::make_boolean(bool val, Location location)
    2300              : {
    2301       594735 :   return new Boolean_expression(val, location);
    2302              : }
    2303              : 
    2304              : // Class String_expression.
    2305              : 
    2306              : // Traverse a string expression.  We just need to traverse the type
    2307              : // if there is one.
    2308              : 
    2309              : int
    2310      7998434 : String_expression::do_traverse(Traverse* traverse)
    2311              : {
    2312      7998434 :   if (this->type_ != NULL)
    2313      7103489 :     return Type::traverse(this->type_, traverse);
    2314              :   return TRAVERSE_CONTINUE;
    2315              : }
    2316              : 
    2317              : bool
    2318    102798683 : String_expression::do_is_untyped(Type** ptype) const
    2319              : {
    2320    102798683 :   if (this->type_ != NULL)
    2321         8255 :     return Expression::is_untyped_type(this->type_, ptype);
    2322    102790428 :   *ptype = Type::make_string_type();
    2323    102790428 :   return true;
    2324              : }
    2325              : 
    2326              : // Get the type.
    2327              : 
    2328              : Type*
    2329      5384288 : String_expression::do_type()
    2330              : {
    2331      5384288 :   if (this->type_ == NULL)
    2332        17815 :     this->type_ = Type::make_string_type();
    2333      5384288 :   return this->type_;
    2334              : }
    2335              : 
    2336              : // Set the type from the context.
    2337              : 
    2338              : void
    2339      2325620 : String_expression::do_determine_type(Gogo*, const Type_context* context)
    2340              : {
    2341      2325620 :   if (this->type_ != NULL && !this->type_->is_abstract())
    2342              :     ;
    2343      1587306 :   else if (context->type != NULL && context->type->is_string_type())
    2344      1540724 :     this->type_ = context->type;
    2345        46582 :   else if (!context->may_be_abstract)
    2346        28914 :     this->type_ = Type::lookup_string_type();
    2347      2325620 : }
    2348              : 
    2349              : // Build a string constant.
    2350              : 
    2351              : Bexpression*
    2352      1012121 : String_expression::do_get_backend(Translate_context* context)
    2353              : {
    2354      1012121 :   Gogo* gogo = context->gogo();
    2355      1012121 :   Btype* btype = Type::make_string_type()->get_backend(gogo);
    2356              : 
    2357      1012121 :   Location loc = this->location();
    2358      1012121 :   std::vector<Bexpression*> init(2);
    2359              : 
    2360      1012121 :   if (this->val_.size() == 0)
    2361        25731 :     init[0] = gogo->backend()->nil_pointer_expression();
    2362              :   else
    2363              :     {
    2364       986390 :       Bexpression* str_cst =
    2365       986390 :         gogo->backend()->string_constant_expression(this->val_);
    2366       986390 :       init[0] = gogo->backend()->address_expression(str_cst, loc);
    2367              :     }
    2368              : 
    2369      1012121 :   Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo);
    2370      1012121 :   mpz_t lenval;
    2371      1012121 :   mpz_init_set_ui(lenval, this->val_.length());
    2372      1012121 :   init[1] = gogo->backend()->integer_constant_expression(int_btype, lenval);
    2373      1012121 :   mpz_clear(lenval);
    2374              : 
    2375      1012121 :   return gogo->backend()->constructor_expression(btype, init, loc);
    2376      1012121 : }
    2377              : 
    2378              :  // Write string literal to string dump.
    2379              : 
    2380              : void
    2381         6474 : String_expression::export_string(String_dump* exp,
    2382              :                                  const String_expression* str)
    2383              : {
    2384         6474 :   std::string s;
    2385         6474 :   s.reserve(str->val_.length() * 4 + 2);
    2386         6474 :   s += '"';
    2387       175078 :   for (std::string::const_iterator p = str->val_.begin();
    2388       175078 :        p != str->val_.end();
    2389       168604 :        ++p)
    2390              :     {
    2391       168604 :       if (*p == '\\' || *p == '"')
    2392              :         {
    2393         6998 :           s += '\\';
    2394         6998 :           s += *p;
    2395              :         }
    2396       161606 :       else if (*p >= 0x20 && *p < 0x7f)
    2397       120717 :         s += *p;
    2398        40889 :       else if (*p == '\n')
    2399         1036 :         s += "\\n";
    2400        39853 :       else if (*p == '\t')
    2401          360 :         s += "\\t";
    2402              :       else
    2403              :         {
    2404        39493 :           s += "\\x";
    2405        39493 :           unsigned char c = *p;
    2406        39493 :           unsigned int dig = c >> 4;
    2407        39493 :           s += dig < 10 ? '0' + dig : 'A' + dig - 10;
    2408        39493 :           dig = c & 0xf;
    2409        39493 :           s += dig < 10 ? '0' + dig : 'A' + dig - 10;
    2410              :         }
    2411              :     }
    2412         6474 :   s += '"';
    2413         6474 :   exp->write_string(s);
    2414         6474 : }
    2415              : 
    2416              : // Export a string expression.
    2417              : 
    2418              : void
    2419         6474 : String_expression::do_export(Export_function_body* efb) const
    2420              : {
    2421         6474 :   bool exported_type = Expression::export_constant_type(efb, this->type_);
    2422         6474 :   String_expression::export_string(efb, this);
    2423         6474 :   Expression::finish_export_constant_type(efb, exported_type);
    2424         6474 : }
    2425              : 
    2426              : // Import a string expression.
    2427              : 
    2428              : Expression*
    2429        31862 : String_expression::do_import(Import_expression* imp, Location loc)
    2430              : {
    2431        31862 :   imp->require_c_string("\"");
    2432        31862 :   std::string val;
    2433       633891 :   while (true)
    2434              :     {
    2435       633891 :       int c = imp->get_char();
    2436       633891 :       if (c == '"' || c == -1)
    2437              :         break;
    2438       602029 :       if (c != '\\')
    2439       555673 :         val += static_cast<char>(c);
    2440              :       else
    2441              :         {
    2442        46356 :           c = imp->get_char();
    2443        46356 :           if (c == '\\' || c == '"')
    2444        19650 :             val += static_cast<char>(c);
    2445        26706 :           else if (c == 'n')
    2446         1074 :             val += '\n';
    2447        25632 :           else if (c == 't')
    2448          517 :             val += '\t';
    2449        25115 :           else if (c == 'x')
    2450              :             {
    2451        25115 :               c = imp->get_char();
    2452        25115 :               unsigned int vh = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
    2453        25115 :               c = imp->get_char();
    2454        25115 :               unsigned int vl = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
    2455        25115 :               char v = (vh << 4) | vl;
    2456        25115 :               val += v;
    2457              :             }
    2458              :           else
    2459              :             {
    2460            0 :               go_error_at(imp->location(), "bad string constant");
    2461            0 :               return Expression::make_error(loc);
    2462              :             }
    2463              :         }
    2464              :     }
    2465        31862 :   return Expression::make_string(val, loc);
    2466        31862 : }
    2467              : 
    2468              : // Ast dump for string expression.
    2469              : 
    2470              : void
    2471            0 : String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    2472              : {
    2473            0 :   String_expression::export_string(ast_dump_context, this);
    2474            0 : }
    2475              : 
    2476              : // Make a string expression with abstract string type (common case).
    2477              : 
    2478              : Expression*
    2479      1560200 : Expression::make_string(const std::string& val, Location location)
    2480              : {
    2481      1560200 :   return new String_expression(val, NULL, location);
    2482              : }
    2483              : 
    2484              : // Make a string expression with a specific string type.
    2485              : 
    2486              : Expression*
    2487        38286 : Expression::make_string_typed(const std::string& val, Type* type, Location location)
    2488              : {
    2489        38286 :   return new String_expression(val, type, location);
    2490              : }
    2491              : 
    2492              : // An expression that evaluates to some characteristic of a string.
    2493              : // This is used when indexing, bound-checking, or nil checking a string.
    2494              : 
    2495              : class String_info_expression : public Expression
    2496              : {
    2497              :  public:
    2498       441698 :   String_info_expression(Expression* string, String_info string_info,
    2499              :                         Location location)
    2500       441698 :     : Expression(EXPRESSION_STRING_INFO, location),
    2501       883396 :       string_(string), string_info_(string_info)
    2502              :   { }
    2503              : 
    2504              :  protected:
    2505              :   Type*
    2506              :   do_type();
    2507              : 
    2508              :   void
    2509       755952 :   do_determine_type(Gogo*, const Type_context*)
    2510       755952 :   { }
    2511              : 
    2512              :   Expression*
    2513       140063 :   do_copy()
    2514              :   {
    2515       140063 :     return new String_info_expression(this->string_->copy(), this->string_info_,
    2516       140063 :                                       this->location());
    2517              :   }
    2518              : 
    2519              :   Bexpression*
    2520              :   do_get_backend(Translate_context* context);
    2521              : 
    2522              :   void
    2523              :   do_dump_expression(Ast_dump_context*) const;
    2524              : 
    2525              :   void
    2526            0 :   do_issue_nil_check()
    2527            0 :   { this->string_->issue_nil_check(); }
    2528              : 
    2529              :  private:
    2530              :   // The string for which we are getting information.
    2531              :   Expression* string_;
    2532              :   // What information we want.
    2533              :   String_info string_info_;
    2534              : };
    2535              : 
    2536              : // Return the type of the string info.
    2537              : 
    2538              : Type*
    2539      1103159 : String_info_expression::do_type()
    2540              : {
    2541      1103159 :   switch (this->string_info_)
    2542              :     {
    2543       610412 :     case STRING_INFO_DATA:
    2544       610412 :       {
    2545       610412 :         Type* byte_type = Type::lookup_integer_type("uint8");
    2546       610412 :         return Type::make_pointer_type(byte_type);
    2547              :       }
    2548       492747 :     case STRING_INFO_LENGTH:
    2549       492747 :         return Type::lookup_integer_type("int");
    2550            0 :     default:
    2551            0 :       go_unreachable();
    2552              :     }
    2553              : }
    2554              : 
    2555              : // Return string information in GENERIC.
    2556              : 
    2557              : Bexpression*
    2558       443347 : String_info_expression::do_get_backend(Translate_context* context)
    2559              : {
    2560       443347 :   Gogo* gogo = context->gogo();
    2561              : 
    2562       443347 :   Bexpression* bstring = this->string_->get_backend(context);
    2563       443347 :   switch (this->string_info_)
    2564              :     {
    2565       443347 :     case STRING_INFO_DATA:
    2566       443347 :     case STRING_INFO_LENGTH:
    2567       443347 :       return gogo->backend()->struct_field_expression(bstring,
    2568              :                                                       this->string_info_,
    2569       443347 :                                                       this->location());
    2570            0 :       break;
    2571            0 :     default:
    2572            0 :       go_unreachable();
    2573              :     }
    2574              : }
    2575              : 
    2576              : // Dump ast representation for a type info expression.
    2577              : 
    2578              : void
    2579            0 : String_info_expression::do_dump_expression(
    2580              :     Ast_dump_context* ast_dump_context) const
    2581              : {
    2582            0 :   ast_dump_context->ostream() << "stringinfo(";
    2583            0 :   this->string_->dump_expression(ast_dump_context);
    2584            0 :   ast_dump_context->ostream() << ",";
    2585            0 :   ast_dump_context->ostream() <<
    2586            0 :       (this->string_info_ == STRING_INFO_DATA ? "data"
    2587            0 :     : this->string_info_ == STRING_INFO_LENGTH ? "length"
    2588            0 :     : "unknown");
    2589            0 :   ast_dump_context->ostream() << ")";
    2590            0 : }
    2591              : 
    2592              : // Make a string info expression.
    2593              : 
    2594              : Expression*
    2595       301635 : Expression::make_string_info(Expression* string, String_info string_info,
    2596              :                             Location location)
    2597              : {
    2598       301635 :   return new String_info_expression(string, string_info, location);
    2599              : }
    2600              : 
    2601              : // An expression that represents an string value: a struct with value pointer
    2602              : // and length fields.
    2603              : 
    2604              : class String_value_expression : public Expression
    2605              : {
    2606              :  public:
    2607         1689 :   String_value_expression(Expression* valptr, Expression* len, Location location)
    2608         1689 :       : Expression(EXPRESSION_STRING_VALUE, location),
    2609         3378 :         valptr_(valptr), len_(len)
    2610              :   { }
    2611              : 
    2612              :  protected:
    2613              :   int
    2614              :   do_traverse(Traverse*);
    2615              : 
    2616              :   Type*
    2617            0 :   do_type()
    2618            0 :   { return Type::make_string_type(); }
    2619              : 
    2620              :   void
    2621            0 :   do_determine_type(Gogo*, const Type_context*)
    2622            0 :   { go_unreachable(); }
    2623              : 
    2624              :   Expression*
    2625            0 :   do_copy()
    2626              :   {
    2627            0 :     return new String_value_expression(this->valptr_->copy(),
    2628            0 :                                        this->len_->copy(),
    2629            0 :                                        this->location());
    2630              :   }
    2631              : 
    2632              :   Bexpression*
    2633              :   do_get_backend(Translate_context* context);
    2634              : 
    2635              :   void
    2636              :   do_dump_expression(Ast_dump_context*) const;
    2637              : 
    2638              :  private:
    2639              :   // The value pointer.
    2640              :   Expression* valptr_;
    2641              :   // The length.
    2642              :   Expression* len_;
    2643              : };
    2644              : 
    2645              : int
    2646            0 : String_value_expression::do_traverse(Traverse* traverse)
    2647              : {
    2648            0 :   if (Expression::traverse(&this->valptr_, traverse) == TRAVERSE_EXIT
    2649            0 :       || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT)
    2650            0 :     return TRAVERSE_EXIT;
    2651              :   return TRAVERSE_CONTINUE;
    2652              : }
    2653              : 
    2654              : Bexpression*
    2655         1689 : String_value_expression::do_get_backend(Translate_context* context)
    2656              : {
    2657         1689 :   std::vector<Bexpression*> vals(2);
    2658         1689 :   vals[0] = this->valptr_->get_backend(context);
    2659         1689 :   vals[1] = this->len_->get_backend(context);
    2660              : 
    2661         1689 :   Gogo* gogo = context->gogo();
    2662         1689 :   Btype* btype = Type::make_string_type()->get_backend(gogo);
    2663         1689 :   return gogo->backend()->constructor_expression(btype, vals, this->location());
    2664         1689 : }
    2665              : 
    2666              : void
    2667            0 : String_value_expression::do_dump_expression(
    2668              :     Ast_dump_context* ast_dump_context) const
    2669              : {
    2670            0 :   ast_dump_context->ostream() << "stringvalue(";
    2671            0 :   ast_dump_context->ostream() << "value: ";
    2672            0 :   this->valptr_->dump_expression(ast_dump_context);
    2673            0 :   ast_dump_context->ostream() << ", length: ";
    2674            0 :   this->len_->dump_expression(ast_dump_context);
    2675            0 :   ast_dump_context->ostream() << ")";
    2676            0 : }
    2677              : 
    2678              : Expression*
    2679         1689 : Expression::make_string_value(Expression* valptr, Expression* len,
    2680              :                               Location location)
    2681              : {
    2682         1689 :   return new String_value_expression(valptr, len, location);
    2683              : }
    2684              : 
    2685              : // Make an integer expression.
    2686              : 
    2687              : class Integer_expression : public Expression
    2688              : {
    2689              :  public:
    2690      8465685 :   Integer_expression(const mpz_t* val, Type* type, bool is_character_constant,
    2691              :                      Location location)
    2692      8465685 :     : Expression(EXPRESSION_INTEGER, location),
    2693      8465685 :       type_(type), is_character_constant_(is_character_constant)
    2694      8465685 :   { mpz_init_set(this->val_, *val); }
    2695              : 
    2696              :   static Expression*
    2697              :   do_import(Import_expression*, Location);
    2698              : 
    2699              :   // Write VAL to string dump.
    2700              :   static void
    2701              :   export_integer(String_dump* exp, const mpz_t val);
    2702              : 
    2703              :   // Write VAL to dump context.
    2704              :   static void
    2705              :   dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val);
    2706              : 
    2707              :  protected:
    2708              :   int
    2709              :   do_traverse(Traverse*);
    2710              : 
    2711              :   bool
    2712      3482869 :   do_is_constant() const
    2713      3482869 :   { return true; }
    2714              : 
    2715              :   bool
    2716              :   do_is_untyped(Type**) const;
    2717              : 
    2718              :   bool
    2719          448 :   do_is_zero_value() const
    2720          448 :   { return mpz_sgn(this->val_) == 0; }
    2721              : 
    2722              :   bool
    2723      1539153 :   do_is_static_initializer() const
    2724      1539153 :   { return true; }
    2725              : 
    2726              :   bool
    2727              :   do_numeric_constant_value(Numeric_constant* nc);
    2728              : 
    2729              :   Type*
    2730              :   do_type();
    2731              : 
    2732              :   void
    2733              :   do_determine_type(Gogo*, const Type_context* context);
    2734              : 
    2735              :   void
    2736              :   do_check_types(Gogo*);
    2737              : 
    2738              :   Bexpression*
    2739              :   do_get_backend(Translate_context*);
    2740              : 
    2741              :   Expression*
    2742       478159 :   do_copy()
    2743              :   {
    2744       478159 :     if (this->is_character_constant_)
    2745          241 :       return Expression::make_character(&this->val_,
    2746          121 :                                         (this->type_ == NULL
    2747              :                                          ? NULL
    2748          120 :                                          : this->type_->copy_expressions()),
    2749          121 :                                         this->location());
    2750              :     else
    2751       941087 :       return Expression::make_integer_z(&this->val_,
    2752       478038 :                                         (this->type_ == NULL
    2753              :                                          ? NULL
    2754       463049 :                                          : this->type_->copy_expressions()),
    2755       478038 :                                         this->location());
    2756              :   }
    2757              : 
    2758              :   int
    2759      1686006 :   do_inlining_cost() const
    2760      1686006 :   { return 1; }
    2761              : 
    2762              :   void
    2763              :   do_export(Export_function_body*) const;
    2764              : 
    2765              :   void
    2766              :   do_dump_expression(Ast_dump_context*) const;
    2767              : 
    2768              :  private:
    2769              :   // The integer value.
    2770              :   mpz_t val_;
    2771              :   // The type so far.
    2772              :   Type* type_;
    2773              :   // Whether this is a character constant.
    2774              :   bool is_character_constant_;
    2775              : };
    2776              : 
    2777              : // Traverse an integer expression.  We just need to traverse the type
    2778              : // if there is one.
    2779              : 
    2780              : int
    2781     50913948 : Integer_expression::do_traverse(Traverse* traverse)
    2782              : {
    2783     50913948 :   if (this->type_ != NULL)
    2784     46071105 :     return Type::traverse(this->type_, traverse);
    2785              :   return TRAVERSE_CONTINUE;
    2786              : }
    2787              : 
    2788              : // Return a numeric constant for this expression.  We have to mark
    2789              : // this as a character when appropriate.
    2790              : 
    2791              : bool
    2792     26537412 : Integer_expression::do_numeric_constant_value(Numeric_constant* nc)
    2793              : {
    2794     26537412 :   if (this->is_character_constant_)
    2795        37209 :     nc->set_rune(this->type_, this->val_);
    2796              :   else
    2797     26500203 :     nc->set_int(this->type_, this->val_);
    2798     26537412 :   return true;
    2799              : }
    2800              : 
    2801              : bool
    2802      1505715 : Integer_expression::do_is_untyped(Type** ptype) const
    2803              : {
    2804      1505715 :   if (this->type_ != NULL)
    2805      1195888 :     return Expression::is_untyped_type(this->type_, ptype);
    2806       309827 :   if (this->is_character_constant_)
    2807        16451 :     *ptype = Type::make_abstract_character_type();
    2808              :   else
    2809       293376 :     *ptype = Type::make_abstract_integer_type();
    2810              :   return true;
    2811              : }
    2812              : 
    2813              : // Return the current type.  If we haven't set the type yet, we return
    2814              : // an abstract integer type.
    2815              : 
    2816              : Type*
    2817     20320332 : Integer_expression::do_type()
    2818              : {
    2819     20320332 :   if (this->type_ == NULL)
    2820              :     {
    2821       815511 :       if (this->is_character_constant_)
    2822         5997 :         this->type_ = Type::make_abstract_character_type();
    2823              :       else
    2824       809514 :         this->type_ = Type::make_abstract_integer_type();
    2825              :     }
    2826     20320332 :   return this->type_;
    2827              : }
    2828              : 
    2829              : // Set the type of the integer value.  Here we may switch from an
    2830              : // abstract type to a real type.
    2831              : 
    2832              : void
    2833      6712823 : Integer_expression::do_determine_type(Gogo*, const Type_context* context)
    2834              : {
    2835      6712823 :   if (this->type_ != NULL && !this->type_->is_abstract())
    2836              :     ;
    2837      2489431 :   else if (context->type != NULL && context->type->is_numeric_type())
    2838      1647597 :     this->type_ = context->type;
    2839       841834 :   else if (!context->may_be_abstract)
    2840              :     {
    2841        41910 :       if (this->is_character_constant_)
    2842          361 :         this->type_ = Type::lookup_integer_type("int32");
    2843              :       else
    2844        41549 :         this->type_ = Type::lookup_integer_type("int");
    2845              :     }
    2846      6712823 : }
    2847              : 
    2848              : // Check the type of an integer constant.
    2849              : 
    2850              : void
    2851      2467356 : Integer_expression::do_check_types(Gogo*)
    2852              : {
    2853      2467356 :   Type* type = this->type_;
    2854      2467356 :   if (type == NULL)
    2855            1 :     return;
    2856      2467355 :   Numeric_constant nc;
    2857      2467355 :   if (this->is_character_constant_)
    2858        54823 :     nc.set_rune(NULL, this->val_);
    2859              :   else
    2860      2412532 :     nc.set_int(NULL, this->val_);
    2861      2467355 :   if (!nc.set_type(type, true, this->location()))
    2862           28 :     this->set_is_error();
    2863      2467355 : }
    2864              : 
    2865              : // Get the backend representation for an integer constant.
    2866              : 
    2867              : Bexpression*
    2868      6027983 : Integer_expression::do_get_backend(Translate_context* context)
    2869              : {
    2870      6027983 :   if (this->is_error_expression()
    2871      6027983 :       || (this->type_ != NULL && this->type_->is_error_type()))
    2872              :     {
    2873            0 :       go_assert(saw_errors());
    2874            0 :       return context->gogo()->backend()->error_expression();
    2875              :     }
    2876              : 
    2877      6027983 :   Type* resolved_type = NULL;
    2878      6027983 :   if (this->type_ != NULL && !this->type_->is_abstract())
    2879      5982471 :     resolved_type = this->type_;
    2880        45512 :   else if (this->type_ != NULL && this->type_->float_type() != NULL)
    2881              :     {
    2882              :       // We are converting to an abstract floating point type.
    2883            0 :       resolved_type = Type::lookup_float_type("float64");
    2884              :     }
    2885        45512 :   else if (this->type_ != NULL && this->type_->complex_type() != NULL)
    2886              :     {
    2887              :       // We are converting to an abstract complex type.
    2888            0 :       resolved_type = Type::lookup_complex_type("complex128");
    2889              :     }
    2890              :   else
    2891              :     {
    2892              :       // If we still have an abstract type here, then this is being
    2893              :       // used in a constant expression which didn't get reduced for
    2894              :       // some reason.  Use a type which will fit the value.  We use <,
    2895              :       // not <=, because we need an extra bit for the sign bit.
    2896        45512 :       int bits = mpz_sizeinbase(this->val_, 2);
    2897        45512 :       Type* int_type = Type::lookup_integer_type("int");
    2898        91024 :       if (bits < int_type->integer_type()->bits())
    2899              :         resolved_type = int_type;
    2900            1 :       else if (bits < 64)
    2901            0 :         resolved_type = Type::lookup_integer_type("int64");
    2902              :       else
    2903              :         {
    2904            1 :           if (!saw_errors())
    2905            1 :             go_error_at(this->location(), "integer constant overflow");
    2906            1 :           return context->gogo()->backend()->error_expression();
    2907              :         }
    2908              :     }
    2909      6027982 :   Numeric_constant nc;
    2910      6027982 :   nc.set_int(resolved_type, this->val_);
    2911      6027982 :   return Expression::backend_numeric_constant_expression(context, &nc);
    2912      6027982 : }
    2913              : 
    2914              : // Write VAL to export data.
    2915              : 
    2916              : void
    2917        54986 : Integer_expression::export_integer(String_dump* exp, const mpz_t val)
    2918              : {
    2919        54986 :   char* s = mpz_get_str(NULL, 10, val);
    2920        54986 :   exp->write_c_string(s);
    2921        54986 :   free(s);
    2922        54986 : }
    2923              : 
    2924              : // Export an integer in a constant expression.
    2925              : 
    2926              : void
    2927        54986 : Integer_expression::do_export(Export_function_body* efb) const
    2928              : {
    2929        54986 :   bool exported_type = Expression::export_constant_type(efb, this->type_);
    2930              : 
    2931        54986 :   Integer_expression::export_integer(efb, this->val_);
    2932        54986 :   if (this->is_character_constant_)
    2933         1421 :     efb->write_c_string("'");
    2934              :   // A trailing space lets us reliably identify the end of the number.
    2935        54986 :   efb->write_c_string(" ");
    2936              : 
    2937        54986 :   Expression::finish_export_constant_type(efb, exported_type);
    2938        54986 : }
    2939              : 
    2940              : // Import an integer, floating point, or complex value.  This handles
    2941              : // all these types because they all start with digits.
    2942              : 
    2943              : Expression*
    2944       979371 : Integer_expression::do_import(Import_expression* imp, Location loc)
    2945              : {
    2946       979371 :   std::string num = imp->read_identifier();
    2947       979371 :   imp->require_c_string(" ");
    2948      1958742 :   if (!num.empty() && num[num.length() - 1] == 'i')
    2949              :     {
    2950            3 :       mpfr_t real;
    2951            3 :       size_t plus_pos = num.find('+', 1);
    2952            3 :       size_t minus_pos = num.find('-', 1);
    2953            3 :       size_t pos;
    2954            3 :       if (plus_pos == std::string::npos)
    2955              :         pos = minus_pos;
    2956            2 :       else if (minus_pos == std::string::npos)
    2957              :         pos = plus_pos;
    2958              :       else
    2959              :         {
    2960            0 :           go_error_at(imp->location(), "bad number in import data: %qs",
    2961              :                       num.c_str());
    2962            0 :           return Expression::make_error(loc);
    2963              :         }
    2964            3 :       if (pos == std::string::npos)
    2965            0 :         mpfr_init_set_ui(real, 0, MPFR_RNDN);
    2966              :       else
    2967              :         {
    2968            3 :           std::string real_str = num.substr(0, pos);
    2969            3 :           if (mpfr_init_set_str(real, real_str.c_str(), 10, MPFR_RNDN) != 0)
    2970              :             {
    2971            0 :               go_error_at(imp->location(), "bad number in import data: %qs",
    2972              :                           real_str.c_str());
    2973            0 :               return Expression::make_error(loc);
    2974              :             }
    2975            3 :         }
    2976              : 
    2977            3 :       std::string imag_str;
    2978            3 :       if (pos == std::string::npos)
    2979            0 :         imag_str = num;
    2980              :       else
    2981            3 :         imag_str = num.substr(pos);
    2982            3 :       imag_str = imag_str.substr(0, imag_str.size() - 1);
    2983            3 :       mpfr_t imag;
    2984            3 :       if (mpfr_init_set_str(imag, imag_str.c_str(), 10, MPFR_RNDN) != 0)
    2985              :         {
    2986            0 :           go_error_at(imp->location(), "bad number in import data: %qs",
    2987              :                       imag_str.c_str());
    2988            0 :           return Expression::make_error(loc);
    2989              :         }
    2990            3 :       mpc_t cval;
    2991            3 :       mpc_init2(cval, mpc_precision);
    2992            3 :       mpc_set_fr_fr(cval, real, imag, MPC_RNDNN);
    2993            3 :       mpfr_clear(real);
    2994            3 :       mpfr_clear(imag);
    2995            3 :       Expression* ret = Expression::make_complex(&cval, NULL, loc);
    2996            3 :       mpc_clear(cval);
    2997            3 :       return ret;
    2998            3 :     }
    2999       979368 :   else if (num.find('.') == std::string::npos
    3000       979368 :            && num.find('E') == std::string::npos)
    3001              :     {
    3002       975115 :       bool is_character_constant = (!num.empty()
    3003      1950230 :                                     && num[num.length() - 1] == '\'');
    3004         6646 :       if (is_character_constant)
    3005         6646 :         num = num.substr(0, num.length() - 1);
    3006       975115 :       mpz_t val;
    3007       975115 :       if (mpz_init_set_str(val, num.c_str(), 10) != 0)
    3008              :         {
    3009            0 :           go_error_at(imp->location(), "bad number in import data: %qs",
    3010              :                       num.c_str());
    3011            0 :           return Expression::make_error(loc);
    3012              :         }
    3013       975115 :       Expression* ret;
    3014       975115 :       if (is_character_constant)
    3015         6646 :         ret = Expression::make_character(&val, NULL, loc);
    3016              :       else
    3017       968469 :         ret = Expression::make_integer_z(&val, NULL, loc);
    3018       975115 :       mpz_clear(val);
    3019       975115 :       return ret;
    3020              :     }
    3021              :   else
    3022              :     {
    3023         4253 :       mpfr_t val;
    3024         4253 :       if (mpfr_init_set_str(val, num.c_str(), 10, MPFR_RNDN) != 0)
    3025              :         {
    3026            0 :           go_error_at(imp->location(), "bad number in import data: %qs",
    3027              :                       num.c_str());
    3028            0 :           return Expression::make_error(loc);
    3029              :         }
    3030         4253 :       Expression* ret = Expression::make_float(&val, NULL, loc);
    3031         4253 :       mpfr_clear(val);
    3032         4253 :       return ret;
    3033              :     }
    3034       979371 : }
    3035              : // Ast dump for integer expression.
    3036              : 
    3037              : void
    3038            0 : Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    3039              : {
    3040            0 :   if (this->is_character_constant_)
    3041            0 :     ast_dump_context->ostream() << '\'';
    3042            0 :   Integer_expression::export_integer(ast_dump_context, this->val_);
    3043            0 :   if (this->is_character_constant_)
    3044            0 :     ast_dump_context->ostream() << '\'';
    3045            0 : }
    3046              : 
    3047              : // Build a new integer value from a multi-precision integer.
    3048              : 
    3049              : Expression*
    3050      8405501 : Expression::make_integer_z(const mpz_t* val, Type* type, Location location)
    3051              : {
    3052      8405501 :   return new Integer_expression(val, type, false, location);
    3053              : }
    3054              : 
    3055              : // Build a new integer value from an unsigned long.
    3056              : 
    3057              : Expression*
    3058      4214610 : Expression::make_integer_ul(unsigned long val, Type *type, Location location)
    3059              : {
    3060      4214610 :   mpz_t zval;
    3061      4214610 :   mpz_init_set_ui(zval, val);
    3062      4214610 :   Expression* ret = Expression::make_integer_z(&zval, type, location);
    3063      4214610 :   mpz_clear(zval);
    3064      4214610 :   return ret;
    3065              : }
    3066              : 
    3067              : // Build a new integer value from a signed long.
    3068              : 
    3069              : Expression*
    3070        16515 : Expression::make_integer_sl(long val, Type *type, Location location)
    3071              : {
    3072        16515 :   mpz_t zval;
    3073        16515 :   mpz_init_set_si(zval, val);
    3074        16515 :   Expression* ret = Expression::make_integer_z(&zval, type, location);
    3075        16515 :   mpz_clear(zval);
    3076        16515 :   return ret;
    3077              : }
    3078              : 
    3079              : // Store an int64_t in an uninitialized mpz_t.
    3080              : 
    3081              : static void
    3082      1220049 : set_mpz_from_int64(mpz_t* zval, int64_t val)
    3083              : {
    3084      1220049 :   if (val >= 0)
    3085              :     {
    3086      1220049 :       unsigned long ul = static_cast<unsigned long>(val);
    3087      1220049 :       if (static_cast<int64_t>(ul) == val)
    3088              :         {
    3089      1220049 :           mpz_init_set_ui(*zval, ul);
    3090      1220049 :           return;
    3091              :         }
    3092              :     }
    3093            0 :   uint64_t uv;
    3094            0 :   if (val >= 0)
    3095              :     uv = static_cast<uint64_t>(val);
    3096              :   else
    3097            0 :     uv = static_cast<uint64_t>(- val);
    3098            0 :   unsigned long ul = uv & 0xffffffffUL;
    3099            0 :   mpz_init_set_ui(*zval, ul);
    3100            0 :   mpz_t hval;
    3101            0 :   mpz_init_set_ui(hval, static_cast<unsigned long>(uv >> 32));
    3102            0 :   mpz_mul_2exp(hval, hval, 32);
    3103            0 :   mpz_add(*zval, *zval, hval);
    3104            0 :   mpz_clear(hval);
    3105            0 :   if (val < 0)
    3106            0 :     mpz_neg(*zval, *zval);
    3107              : }
    3108              : 
    3109              : // Build a new integer value from an int64_t.
    3110              : 
    3111              : Expression*
    3112      1217923 : Expression::make_integer_int64(int64_t val, Type* type, Location location)
    3113              : {
    3114      1217923 :   mpz_t zval;
    3115      1217923 :   set_mpz_from_int64(&zval, val);
    3116      1217923 :   Expression* ret = Expression::make_integer_z(&zval, type, location);
    3117      1217923 :   mpz_clear(zval);
    3118      1217923 :   return ret;
    3119              : }
    3120              : 
    3121              : // Build a new character constant value.
    3122              : 
    3123              : Expression*
    3124        60184 : Expression::make_character(const mpz_t* val, Type* type, Location location)
    3125              : {
    3126        60184 :   return new Integer_expression(val, type, true, location);
    3127              : }
    3128              : 
    3129              : // Floats.
    3130              : 
    3131              : class Float_expression : public Expression
    3132              : {
    3133              :  public:
    3134        32243 :   Float_expression(const mpfr_t* val, Type* type, Location location)
    3135        32243 :     : Expression(EXPRESSION_FLOAT, location),
    3136        32243 :       type_(type)
    3137              :   {
    3138        32243 :     mpfr_init_set(this->val_, *val, MPFR_RNDN);
    3139        32243 :   }
    3140              : 
    3141              :   // Write VAL to export data.
    3142              :   static void
    3143              :   export_float(String_dump* exp, const mpfr_t val);
    3144              : 
    3145              :   // Write VAL to dump file.
    3146              :   static void
    3147              :   dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
    3148              : 
    3149              :  protected:
    3150              :   int
    3151              :   do_traverse(Traverse*);
    3152              : 
    3153              :   bool
    3154        17418 :   do_is_constant() const
    3155        17418 :   { return true; }
    3156              : 
    3157              :   bool
    3158              :   do_is_untyped(Type**) const;
    3159              : 
    3160              :   bool
    3161            4 :   do_is_zero_value() const
    3162              :   {
    3163            4 :     return mpfr_zero_p(this->val_) != 0
    3164            4 :            && mpfr_signbit(this->val_) == 0;
    3165              :   }
    3166              : 
    3167              :   bool
    3168        13963 :   do_is_static_initializer() const
    3169        13963 :   { return true; }
    3170              : 
    3171              :   bool
    3172        20066 :   do_numeric_constant_value(Numeric_constant* nc)
    3173              :   {
    3174        20066 :     nc->set_float(this->type_, this->val_);
    3175        20066 :     return true;
    3176              :   }
    3177              : 
    3178              :   Type*
    3179              :   do_type();
    3180              : 
    3181              :   void
    3182              :   do_determine_type(Gogo*, const Type_context*);
    3183              : 
    3184              :   void
    3185              :   do_check_types(Gogo*);
    3186              : 
    3187              :   Expression*
    3188           73 :   do_copy()
    3189          144 :   { return Expression::make_float(&this->val_,
    3190           73 :                                   (this->type_ == NULL
    3191              :                                    ? NULL
    3192           71 :                                    : this->type_->copy_expressions()),
    3193           73 :                                   this->location()); }
    3194              : 
    3195              :   Bexpression*
    3196              :   do_get_backend(Translate_context*);
    3197              : 
    3198              :   int
    3199         4765 :   do_inlining_cost() const
    3200         4765 :   { return 1; }
    3201              : 
    3202              :   void
    3203              :   do_export(Export_function_body*) const;
    3204              : 
    3205              :   void
    3206              :   do_dump_expression(Ast_dump_context*) const;
    3207              : 
    3208              :  private:
    3209              :   // The floating point value.
    3210              :   mpfr_t val_;
    3211              :   // The type so far.
    3212              :   Type* type_;
    3213              : };
    3214              : 
    3215              : // Traverse a float expression.  We just need to traverse the type if
    3216              : // there is one.
    3217              : 
    3218              : int
    3219       431792 : Float_expression::do_traverse(Traverse* traverse)
    3220              : {
    3221       431792 :   if (this->type_ != NULL)
    3222       385194 :     return Type::traverse(this->type_, traverse);
    3223              :   return TRAVERSE_CONTINUE;
    3224              : }
    3225              : 
    3226              : bool
    3227         7828 : Float_expression::do_is_untyped(Type** ptype) const
    3228              : {
    3229         7828 :   if (this->type_ != NULL)
    3230          130 :     return Expression::is_untyped_type(this->type_, ptype);
    3231         7698 :   *ptype = Type::make_abstract_float_type();
    3232         7698 :   return true;
    3233              : }
    3234              : 
    3235              : // Return the current type.  If we haven't set the type yet, we return
    3236              : // an abstract float type.
    3237              : 
    3238              : Type*
    3239       149905 : Float_expression::do_type()
    3240              : {
    3241       149905 :   if (this->type_ == NULL)
    3242         8272 :     this->type_ = Type::make_abstract_float_type();
    3243       149905 :   return this->type_;
    3244              : }
    3245              : 
    3246              : // Set the type of the float value.  Here we may switch from an
    3247              : // abstract type to a real type.
    3248              : 
    3249              : void
    3250        31815 : Float_expression::do_determine_type(Gogo*, const Type_context* context)
    3251              : {
    3252        31815 :   if (this->type_ != NULL && !this->type_->is_abstract())
    3253              :     ;
    3254        26734 :   else if (context->type != NULL
    3255        26734 :            && (context->type->integer_type() != NULL
    3256        33750 :                || context->type->float_type() != NULL
    3257        18531 :                || context->type->complex_type() != NULL))
    3258        17567 :     this->type_ = context->type;
    3259         9167 :   else if (!context->may_be_abstract)
    3260          895 :     this->type_ = Type::lookup_float_type("float64");
    3261        31815 : }
    3262              : 
    3263              : // Check the type of a float value.
    3264              : 
    3265              : void
    3266        26516 : Float_expression::do_check_types(Gogo*)
    3267              : {
    3268        26516 :   Type* type = this->type_;
    3269        26516 :   if (type == NULL)
    3270            1 :     return;
    3271        26515 :   Numeric_constant nc;
    3272        26515 :   nc.set_float(NULL, this->val_);
    3273        26515 :   if (!nc.set_type(this->type_, true, this->location()))
    3274           55 :     this->set_is_error();
    3275        26515 : }
    3276              : 
    3277              : // Get the backend representation for a float constant.
    3278              : 
    3279              : Bexpression*
    3280        20531 : Float_expression::do_get_backend(Translate_context* context)
    3281              : {
    3282        20531 :   if (this->is_error_expression()
    3283        20531 :       || (this->type_ != NULL && this->type_->is_error_type()))
    3284              :     {
    3285            0 :       go_assert(saw_errors());
    3286            0 :       return context->gogo()->backend()->error_expression();
    3287              :     }
    3288              : 
    3289        20531 :   Type* resolved_type;
    3290        20531 :   if (this->type_ != NULL && !this->type_->is_abstract())
    3291        20512 :     resolved_type = this->type_;
    3292           19 :   else if (this->type_ != NULL && this->type_->integer_type() != NULL)
    3293              :     {
    3294              :       // We have an abstract integer type.  We just hope for the best.
    3295            0 :       resolved_type = Type::lookup_integer_type("int");
    3296              :     }
    3297           19 :   else if (this->type_ != NULL && this->type_->complex_type() != NULL)
    3298              :     {
    3299              :       // We are converting to an abstract complex type.
    3300            0 :       resolved_type = Type::lookup_complex_type("complex128");
    3301              :     }
    3302              :   else
    3303              :     {
    3304              :       // If we still have an abstract type here, then this is being
    3305              :       // used in a constant expression which didn't get reduced.  We
    3306              :       // just use float64 and hope for the best.
    3307           19 :       resolved_type = Type::lookup_float_type("float64");
    3308              :     }
    3309              : 
    3310        20531 :   Numeric_constant nc;
    3311        20531 :   nc.set_float(resolved_type, this->val_);
    3312        20531 :   return Expression::backend_numeric_constant_expression(context, &nc);
    3313        20531 : }
    3314              : 
    3315              : // Write a floating point number to a string dump.
    3316              : 
    3317              : void
    3318          593 : Float_expression::export_float(String_dump *exp, const mpfr_t val)
    3319              : {
    3320          593 :   mpfr_exp_t exponent;
    3321          593 :   char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, MPFR_RNDN);
    3322          593 :   if (*s == '-')
    3323           53 :     exp->write_c_string("-");
    3324          593 :   exp->write_c_string("0.");
    3325          593 :   exp->write_c_string(*s == '-' ? s + 1 : s);
    3326          593 :   mpfr_free_str(s);
    3327          593 :   char buf[30];
    3328          593 :   snprintf(buf, sizeof buf, "E%ld", exponent);
    3329          593 :   exp->write_c_string(buf);
    3330          593 : }
    3331              : 
    3332              : // Export a floating point number in a constant expression.
    3333              : 
    3334              : void
    3335          549 : Float_expression::do_export(Export_function_body* efb) const
    3336              : {
    3337          549 :   bool exported_type = Expression::export_constant_type(efb, this->type_);
    3338              : 
    3339          549 :   Float_expression::export_float(efb, this->val_);
    3340              :   // A trailing space lets us reliably identify the end of the number.
    3341          549 :   efb->write_c_string(" ");
    3342              : 
    3343          549 :   Expression::finish_export_constant_type(efb, exported_type);
    3344          549 : }
    3345              : 
    3346              : // Dump a floating point number to the dump file.
    3347              : 
    3348              : void
    3349            0 : Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    3350              : {
    3351            0 :   Float_expression::export_float(ast_dump_context, this->val_);
    3352            0 : }
    3353              : 
    3354              : // Make a float expression.
    3355              : 
    3356              : Expression*
    3357        32243 : Expression::make_float(const mpfr_t* val, Type* type, Location location)
    3358              : {
    3359        32243 :   return new Float_expression(val, type, location);
    3360              : }
    3361              : 
    3362              : // Complex numbers.
    3363              : 
    3364              : class Complex_expression : public Expression
    3365              : {
    3366              :  public:
    3367         3600 :   Complex_expression(const mpc_t* val, Type* type, Location location)
    3368         3600 :     : Expression(EXPRESSION_COMPLEX, location),
    3369         3600 :       type_(type)
    3370              :   {
    3371         3600 :     mpc_init2(this->val_, mpc_precision);
    3372         3600 :     mpc_set(this->val_, *val, MPC_RNDNN);
    3373         3600 :   }
    3374              : 
    3375              :   // Write VAL to string dump.
    3376              :   static void
    3377              :   export_complex(String_dump* exp, const mpc_t val);
    3378              : 
    3379              :   // Write REAL/IMAG to dump context.
    3380              :   static void
    3381              :   dump_complex(Ast_dump_context* ast_dump_context, const mpc_t val);
    3382              : 
    3383              :  protected:
    3384              :   int
    3385              :   do_traverse(Traverse*);
    3386              : 
    3387              :   bool
    3388         1594 :   do_is_constant() const
    3389         1594 :   { return true; }
    3390              : 
    3391              :   bool
    3392              :   do_is_untyped(Type**) const;
    3393              : 
    3394              :   bool
    3395            4 :   do_is_zero_value() const
    3396              :   {
    3397            4 :     return mpfr_zero_p(mpc_realref(this->val_)) != 0
    3398            0 :            && mpfr_signbit(mpc_realref(this->val_)) == 0
    3399            0 :            && mpfr_zero_p(mpc_imagref(this->val_)) != 0
    3400            4 :            && mpfr_signbit(mpc_imagref(this->val_)) == 0;
    3401              :   }
    3402              : 
    3403              :   bool
    3404         1688 :   do_is_static_initializer() const
    3405         1688 :   { return true; }
    3406              : 
    3407              :   bool
    3408         1251 :   do_numeric_constant_value(Numeric_constant* nc)
    3409              :   {
    3410         1251 :     nc->set_complex(this->type_, this->val_);
    3411         1251 :     return true;
    3412              :   }
    3413              : 
    3414              :   Type*
    3415              :   do_type();
    3416              : 
    3417              :   void
    3418              :   do_determine_type(Gogo*, const Type_context*);
    3419              : 
    3420              :   void
    3421              :   do_check_types(Gogo*);
    3422              : 
    3423              :   Expression*
    3424           12 :   do_copy()
    3425              :   {
    3426           24 :     return Expression::make_complex(&this->val_,
    3427           12 :                                     (this->type_ == NULL
    3428              :                                      ? NULL
    3429           12 :                                      : this->type_->copy_expressions()),
    3430           12 :                                     this->location());
    3431              :   }
    3432              : 
    3433              :   Bexpression*
    3434              :   do_get_backend(Translate_context*);
    3435              : 
    3436              :   int
    3437          125 :   do_inlining_cost() const
    3438          125 :   { return 2; }
    3439              : 
    3440              :   void
    3441              :   do_export(Export_function_body*) const;
    3442              : 
    3443              :   void
    3444              :   do_dump_expression(Ast_dump_context*) const;
    3445              : 
    3446              :  private:
    3447              :   // The complex value.
    3448              :   mpc_t val_;
    3449              :   // The type if known.
    3450              :   Type* type_;
    3451              : };
    3452              : 
    3453              : // Traverse a complex expression.  We just need to traverse the type
    3454              : // if there is one.
    3455              : 
    3456              : int
    3457        43990 : Complex_expression::do_traverse(Traverse* traverse)
    3458              : {
    3459        43990 :   if (this->type_ != NULL)
    3460        42004 :     return Type::traverse(this->type_, traverse);
    3461              :   return TRAVERSE_CONTINUE;
    3462              : }
    3463              : 
    3464              : bool
    3465          945 : Complex_expression::do_is_untyped(Type** ptype) const
    3466              : {
    3467          945 :   if (this->type_ != NULL)
    3468           25 :     return Expression::is_untyped_type(this->type_, ptype);
    3469          920 :   *ptype = Type::make_abstract_complex_type();
    3470          920 :   return true;
    3471              : }
    3472              : 
    3473              : // Return the current type.  If we haven't set the type yet, we return
    3474              : // an abstract complex type.
    3475              : 
    3476              : Type*
    3477        18583 : Complex_expression::do_type()
    3478              : {
    3479        18583 :   if (this->type_ == NULL)
    3480           21 :     this->type_ = Type::make_abstract_complex_type();
    3481        18583 :   return this->type_;
    3482              : }
    3483              : 
    3484              : // Set the type of the complex value.  Here we may switch from an
    3485              : // abstract type to a real type.
    3486              : 
    3487              : void
    3488         5406 : Complex_expression::do_determine_type(Gogo*, const Type_context* context)
    3489              : {
    3490         5406 :   if (this->type_ != NULL && !this->type_->is_abstract())
    3491              :     ;
    3492         1837 :   else if (context->type != NULL && context->type->is_numeric_type())
    3493         1768 :     this->type_ = context->type;
    3494           69 :   else if (!context->may_be_abstract)
    3495           48 :     this->type_ = Type::lookup_complex_type("complex128");
    3496         5406 : }
    3497              : 
    3498              : // Check the type of a complex value.
    3499              : 
    3500              : void
    3501         1854 : Complex_expression::do_check_types(Gogo*)
    3502              : {
    3503         1854 :   Type* type = this->type_;
    3504         1854 :   if (type == NULL)
    3505            0 :     return;
    3506         1854 :   Numeric_constant nc;
    3507         1854 :   nc.set_complex(NULL, this->val_);
    3508         1854 :   if (!nc.set_type(this->type_, true, this->location()))
    3509            4 :     this->set_is_error();
    3510         1854 : }
    3511              : 
    3512              : // Get the backend representation for a complex constant.
    3513              : 
    3514              : Bexpression*
    3515         2529 : Complex_expression::do_get_backend(Translate_context* context)
    3516              : {
    3517         2529 :   if (this->is_error_expression()
    3518         2529 :       || (this->type_ != NULL && this->type_->is_error_type()))
    3519              :     {
    3520            0 :       go_assert(saw_errors());
    3521            0 :       return context->gogo()->backend()->error_expression();
    3522              :     }
    3523              : 
    3524         2529 :   Type* resolved_type;
    3525         2529 :   if (this->type_ != NULL && !this->type_->is_abstract())
    3526         2507 :     resolved_type = this->type_;
    3527           22 :   else if (this->type_ != NULL && this->type_->integer_type() != NULL)
    3528              :     {
    3529              :       // We are converting to an abstract integer type.
    3530            0 :       resolved_type = Type::lookup_integer_type("int");
    3531              :     }
    3532           22 :   else if (this->type_ != NULL && this->type_->float_type() != NULL)
    3533              :     {
    3534              :       // We are converting to an abstract float type.
    3535            0 :       resolved_type = Type::lookup_float_type("float64");
    3536              :     }
    3537              :   else
    3538              :     {
    3539              :       // If we still have an abstract type here, this is being
    3540              :       // used in a constant expression which didn't get reduced.  We
    3541              :       // just use complex128 and hope for the best.
    3542           22 :       resolved_type = Type::lookup_complex_type("complex128");
    3543              :     }
    3544              : 
    3545         2529 :   Numeric_constant nc;
    3546         2529 :   nc.set_complex(resolved_type, this->val_);
    3547         2529 :   return Expression::backend_numeric_constant_expression(context, &nc);
    3548         2529 : }
    3549              : 
    3550              : // Write REAL/IMAG to export data.
    3551              : 
    3552              : void
    3553           25 : Complex_expression::export_complex(String_dump* exp, const mpc_t val)
    3554              : {
    3555           25 :   if (!mpfr_zero_p(mpc_realref(val)))
    3556              :     {
    3557           19 :       Float_expression::export_float(exp, mpc_realref(val));
    3558           19 :       if (mpfr_sgn(mpc_imagref(val)) >= 0)
    3559           14 :         exp->write_c_string("+");
    3560              :     }
    3561           25 :   Float_expression::export_float(exp, mpc_imagref(val));
    3562           25 :   exp->write_c_string("i");
    3563           25 : }
    3564              : 
    3565              : // Export a complex number in a constant expression.
    3566              : 
    3567              : void
    3568           25 : Complex_expression::do_export(Export_function_body* efb) const
    3569              : {
    3570           25 :   bool exported_type = Expression::export_constant_type(efb, this->type_);
    3571              : 
    3572           25 :   Complex_expression::export_complex(efb, this->val_);
    3573              :   // A trailing space lets us reliably identify the end of the number.
    3574           25 :   efb->write_c_string(" ");
    3575              : 
    3576           25 :   Expression::finish_export_constant_type(efb, exported_type);
    3577           25 : }
    3578              : 
    3579              : // Dump a complex expression to the dump file.
    3580              : 
    3581              : void
    3582            0 : Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    3583              : {
    3584            0 :   Complex_expression::export_complex(ast_dump_context, this->val_);
    3585            0 : }
    3586              : 
    3587              : // Make a complex expression.
    3588              : 
    3589              : Expression*
    3590         3600 : Expression::make_complex(const mpc_t* val, Type* type, Location location)
    3591              : {
    3592         3600 :   return new Complex_expression(val, type, location);
    3593              : }
    3594              : 
    3595              : // Find a named object in an expression.
    3596              : 
    3597       416851 : class Find_named_object : public Traverse
    3598              : {
    3599              :  public:
    3600       416851 :   Find_named_object(Named_object* no)
    3601       416851 :     : Traverse(traverse_expressions),
    3602       416851 :       no_(no), found_(false)
    3603              :   { }
    3604              : 
    3605              :   // Whether we found the object.
    3606              :   bool
    3607       416851 :   found() const
    3608       416851 :   { return this->found_; }
    3609              : 
    3610              :  protected:
    3611              :   int
    3612              :   expression(Expression**);
    3613              : 
    3614              :  private:
    3615              :   // The object we are looking for.
    3616              :   Named_object* no_;
    3617              :   // Whether we found it.
    3618              :   bool found_;
    3619              : };
    3620              : 
    3621              : // Class Const_expression.
    3622              : 
    3623              : // Traversal.
    3624              : 
    3625              : int
    3626      7798338 : Const_expression::do_traverse(Traverse* traverse)
    3627              : {
    3628      7798338 :   if (this->type_ != NULL)
    3629      7453269 :     return Type::traverse(this->type_, traverse);
    3630              :   return TRAVERSE_CONTINUE;
    3631              : }
    3632              : 
    3633              : // Whether this is the zero value.
    3634              : 
    3635              : bool
    3636           32 : Const_expression::do_is_zero_value() const
    3637              : {
    3638           32 :   return this->constant_->const_value()->expr()->is_zero_value();
    3639              : }
    3640              : 
    3641              : // Lower a constant expression.  This is where we convert the
    3642              : // predeclared constant iota into an integer value.
    3643              : 
    3644              : Expression*
    3645      1204689 : Const_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*)
    3646              : {
    3647      1204689 :   Location loc = this->location();
    3648              : 
    3649      1204689 :   if (this->is_error_expression())
    3650          874 :     return Expression::make_error(loc);
    3651      1203815 :   if (this->constant_->const_value()->expr()->is_error_expression())
    3652          191 :     return Expression::make_error(loc);
    3653              : 
    3654      1203624 :   if (this->is_iota_)
    3655        10365 :     return Expression::make_integer_ul(this->iota_value_, NULL, loc);
    3656              : 
    3657              :   // Make sure that the constant itself has been lowered.
    3658      1193259 :   gogo->lower_constant(this->constant_);
    3659              : 
    3660      1193259 :   return this;
    3661              : }
    3662              : 
    3663              : // Return a numeric constant value.
    3664              : 
    3665              : bool
    3666       549250 : Const_expression::do_numeric_constant_value(Numeric_constant* nc)
    3667              : {
    3668       549250 :   if (this->seen_)
    3669              :     return false;
    3670              : 
    3671       549250 :   Type* ctype;
    3672       549250 :   if (this->type_ != NULL)
    3673              :     ctype = this->type_;
    3674              :   else
    3675          234 :     ctype = this->constant_->const_value()->type();
    3676              : 
    3677       549250 :   if (this->is_iota_)
    3678              :     {
    3679        54473 :       nc->set_unsigned_long(ctype,
    3680        54473 :                             static_cast<unsigned long>(this->iota_value_));
    3681        54473 :       return true;
    3682              :     }
    3683              : 
    3684       494777 :   Expression* e = this->constant_->const_value()->expr();
    3685              : 
    3686       494777 :   this->seen_ = true;
    3687              : 
    3688       494777 :   bool r = e->numeric_constant_value(nc);
    3689              : 
    3690       494777 :   this->seen_ = false;
    3691              : 
    3692       494777 :   if (r && ctype != NULL)
    3693              :     {
    3694       481498 :       if (!nc->set_type(ctype, false, this->location()))
    3695              :         return false;
    3696              :     }
    3697              : 
    3698              :   return r;
    3699              : }
    3700              : 
    3701              : bool
    3702        10533 : Const_expression::do_string_constant_value(std::string* val)
    3703              : {
    3704        10533 :   if (this->seen_)
    3705              :     return false;
    3706        10533 :   if (this->is_iota_)
    3707              :     return false;
    3708              : 
    3709        10533 :   Expression* e = this->constant_->const_value()->expr();
    3710              : 
    3711        10533 :   this->seen_ = true;
    3712        10533 :   bool ok = e->string_constant_value(val);
    3713        10533 :   this->seen_ = false;
    3714              : 
    3715        10533 :   return ok;
    3716              : }
    3717              : 
    3718              : bool
    3719         6822 : Const_expression::do_boolean_constant_value(bool* val)
    3720              : {
    3721         6822 :   if (this->seen_)
    3722              :     return false;
    3723         6822 :   if (this->is_iota_)
    3724              :     return false;
    3725              : 
    3726         6822 :   Expression* e = this->constant_->const_value()->expr();
    3727              : 
    3728         6822 :   this->seen_ = true;
    3729         6822 :   bool ok = e->boolean_constant_value(val);
    3730         6822 :   this->seen_ = false;
    3731              : 
    3732         6822 :   return ok;
    3733              : }
    3734              : 
    3735              : // Whether this is untyped.
    3736              : 
    3737              : bool
    3738        87888 : Const_expression::do_is_untyped(Type** ptype) const
    3739              : {
    3740        87888 :   if (this->type_ != NULL)
    3741        16888 :     return Expression::is_untyped_type(this->type_, ptype);
    3742              : 
    3743        71000 :   Named_constant* nc = this->constant_->const_value();
    3744        71000 :   if (nc->type() != NULL)
    3745        67984 :     return Expression::is_untyped_type(nc->type(), ptype);
    3746              : 
    3747         3016 :   return nc->expr()->is_untyped(ptype);
    3748              : }
    3749              : 
    3750              : // Return the type of the const reference.
    3751              : 
    3752              : Type*
    3753      3901938 : Const_expression::do_type()
    3754              : {
    3755      3901938 :   if (this->type_ == NULL)
    3756              :     {
    3757            0 :       go_assert(saw_errors());
    3758            0 :       return Type::make_error_type();
    3759              :     }
    3760              : 
    3761              :   return this->type_;
    3762              : }
    3763              : 
    3764              : // Set the type of the const reference.
    3765              : 
    3766              : void
    3767       645837 : Const_expression::do_determine_type(Gogo* gogo, const Type_context* context)
    3768              : {
    3769       645837 :   if (this->type_ != NULL)
    3770              :     return;
    3771              : 
    3772              :   // The type may depend on the type of other constants.  Avoid an
    3773              :   // endless loop.
    3774       427474 :   if (this->seen_)
    3775              :     {
    3776            0 :       if (!saw_errors())
    3777            0 :         go_error_at(this->location(), "constant refers to itself");
    3778            0 :       this->set_is_error();
    3779            0 :       this->type_ = Type::make_error_type();
    3780            0 :       return;
    3781              :     }
    3782              : 
    3783       427474 :   this->seen_ = true;
    3784              : 
    3785       427474 :   Named_constant* nc = this->constant_->const_value();
    3786       427474 :   nc->determine_type(gogo);
    3787              : 
    3788       427474 :   Type* ctype = nc->type();
    3789              : 
    3790       427474 :   this->seen_ = false;
    3791              : 
    3792       427474 :   if (ctype == NULL)
    3793              :     {
    3794            2 :       go_error_at(nc->expr()->location(), "constant refers to itself");
    3795            2 :       this->set_is_error();
    3796            2 :       this->type_ = Type::make_error_type();
    3797              :     }
    3798       427472 :   else if (!ctype->is_abstract())
    3799       224088 :     this->type_ = ctype;
    3800       203384 :   else if (context->type != NULL
    3801       149195 :            && context->type->is_numeric_type()
    3802       271564 :            && ctype->is_numeric_type())
    3803        68165 :     this->type_ = context->type;
    3804       135219 :   else if (context->type != NULL
    3805        81030 :            && context->type->is_string_type()
    3806       142757 :            && ctype->is_string_type())
    3807         7283 :     this->type_ = context->type;
    3808       127936 :   else if (context->type != NULL
    3809        73747 :            && context->type->is_boolean_type()
    3810       199582 :            && ctype->is_boolean_type())
    3811        71646 :     this->type_ = context->type;
    3812        56290 :   else if (!context->may_be_abstract)
    3813              :     {
    3814         9022 :       if (ctype->is_abstract())
    3815         9022 :         ctype = ctype->make_non_abstract_type();
    3816         9022 :       this->type_ = ctype;
    3817              :     }
    3818              :   else
    3819        47268 :     this->type_ = ctype;
    3820              : }
    3821              : 
    3822              : // Check for a loop in which the initializer of a constant refers to
    3823              : // the constant itself.
    3824              : 
    3825              : void
    3826       416851 : Const_expression::check_for_init_loop()
    3827              : {
    3828       416851 :   if (this->is_error_expression())
    3829            0 :     return;
    3830       416851 :   if (this->type_ != NULL && this->type_->is_error())
    3831              :     return;
    3832       416851 :   if (this->constant_->const_value()->expr()->is_error_expression())
    3833              :     {
    3834            0 :       this->set_is_error();
    3835            0 :       return;
    3836              :     }
    3837              : 
    3838       416851 :   if (this->seen_)
    3839              :     {
    3840            0 :       this->report_error(_("constant refers to itself"));
    3841            0 :       this->type_ = Type::make_error_type();
    3842            0 :       return;
    3843              :     }
    3844              : 
    3845       416851 :   Expression* init = this->constant_->const_value()->expr();
    3846       416851 :   Find_named_object find_named_object(this->constant_);
    3847              : 
    3848       416851 :   this->seen_ = true;
    3849       416851 :   Expression::traverse(&init, &find_named_object);
    3850       416851 :   this->seen_ = false;
    3851              : 
    3852       416851 :   if (find_named_object.found())
    3853              :     {
    3854            0 :       if (this->type_ == NULL || !this->type_->is_error())
    3855              :         {
    3856            0 :           this->report_error(_("constant refers to itself"));
    3857            0 :           this->type_ = Type::make_error_type();
    3858              :         }
    3859            0 :       return;
    3860              :     }
    3861       416851 : }
    3862              : 
    3863              : // Set the iota value if this is a reference to iota.
    3864              : 
    3865              : void
    3866        46842 : Const_expression::set_iota_value(int iota_value)
    3867              : {
    3868        46842 :   Named_constant* nc = this->constant_->const_value();
    3869        46842 :   if (nc->expr()->classification() == EXPRESSION_IOTA)
    3870              :     {
    3871        10363 :       this->is_iota_ = true;
    3872        10363 :       this->iota_value_ = iota_value;
    3873              :     }
    3874        46842 : }
    3875              : 
    3876              : // Check types of a const reference.
    3877              : 
    3878              : void
    3879       427219 : Const_expression::do_check_types(Gogo*)
    3880              : {
    3881       427219 :   if (this->is_error_expression())
    3882              :     return;
    3883       427219 :   if (this->type_ != NULL && this->type_->is_error())
    3884              :     return;
    3885       427217 :   if (this->constant_->const_value()->expr()->is_error_expression())
    3886              :     {
    3887            1 :       this->set_is_error();
    3888            1 :       return;
    3889              :     }
    3890              : 
    3891       427216 :   Expression* expr = this->constant_->const_value()->expr();
    3892       427216 :   if (expr->classification() == EXPRESSION_IOTA && !this->is_iota_)
    3893              :     {
    3894            4 :       go_error_at(this->location(),
    3895              :                   "iota is only defined in const declarations");
    3896              :       // Avoid knock-on errors.
    3897            4 :       this->is_iota_ = true;
    3898            4 :       this->iota_value_ = 0;
    3899              :     }
    3900              : 
    3901       427216 :   if (this->is_iota_ && this->type_->is_numeric_type())
    3902              :     {
    3903        10365 :       Numeric_constant nc;
    3904        10365 :       nc.set_unsigned_long(Type::make_abstract_integer_type(),
    3905        10365 :                            static_cast<unsigned long>(this->iota_value_));
    3906        10365 :       if (!nc.set_type(this->type_, true, this->location()))
    3907            0 :         this->set_is_error();
    3908        10365 :       return;
    3909        10365 :     }
    3910              : 
    3911       416851 :   this->check_for_init_loop();
    3912              : 
    3913              :   // Check that numeric constant fits in type.
    3914       416851 :   if (this->type_->is_numeric_type())
    3915              :     {
    3916       190624 :       Numeric_constant nc;
    3917       190624 :       if (expr->numeric_constant_value(&nc))
    3918              :         {
    3919       189898 :           if (!nc.set_type(this->type_, true, this->location()))
    3920          873 :             this->set_is_error();
    3921              :         }
    3922       190624 :     }
    3923              : }
    3924              : 
    3925              : // Return the backend representation for a const reference.
    3926              : 
    3927              : Bexpression*
    3928       259212 : Const_expression::do_get_backend(Translate_context* context)
    3929              : {
    3930       259212 :   if (this->is_error_expression()
    3931       259212 :       || (this->type_ != NULL && this->type_->is_error()))
    3932              :     {
    3933            0 :       go_assert(saw_errors());
    3934            0 :       return context->backend()->error_expression();
    3935              :     }
    3936              : 
    3937       259212 :   go_assert(!this->is_iota_);
    3938              : 
    3939              :   // If the type has been set for this expression, but the underlying
    3940              :   // object is an abstract int or float, we try to get the abstract
    3941              :   // value.  Otherwise we may lose something in the conversion.
    3942       259212 :   Expression* expr = this->constant_->const_value()->expr();
    3943       259212 :   if (this->type_ != NULL
    3944       235813 :       && this->type_->is_numeric_type()
    3945       403440 :       && (this->constant_->const_value()->type() == NULL
    3946       144228 :           || this->constant_->const_value()->type()->is_abstract()))
    3947              :     {
    3948        82314 :       Numeric_constant nc;
    3949        82314 :       if (expr->numeric_constant_value(&nc)
    3950        82314 :           && nc.set_type(this->type_, false, this->location()))
    3951              :         {
    3952        82314 :           Expression* e = nc.expression(this->location());
    3953        82314 :           return e->get_backend(context);
    3954              :         }
    3955        82314 :     }
    3956              : 
    3957       176898 :   if (this->type_ != NULL)
    3958       153499 :     expr = Expression::make_cast(this->type_, expr, this->location());
    3959       176898 :   return expr->get_backend(context);
    3960              : }
    3961              : 
    3962              : // When exporting a reference to a const as part of a const
    3963              : // expression, we export the value.  We ignore the fact that it has
    3964              : // a name.
    3965              : 
    3966              : void
    3967        30346 : Const_expression::do_export(Export_function_body* efb) const
    3968              : {
    3969        30346 :   this->constant_->const_value()->expr()->export_expression(efb);
    3970        30346 : }
    3971              : 
    3972              : // Dump ast representation for constant expression.
    3973              : 
    3974              : void
    3975            0 : Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    3976              : {
    3977            0 :   ast_dump_context->ostream() << this->constant_->name();
    3978            0 : }
    3979              : 
    3980              : // Make a reference to a constant in an expression.
    3981              : 
    3982              : Expression*
    3983       450984 : Expression::make_const_reference(Named_object* constant,
    3984              :                                  Location location)
    3985              : {
    3986       450984 :   return new Const_expression(constant, location);
    3987              : }
    3988              : 
    3989              : // Find a named object in an expression.
    3990              : 
    3991              : int
    3992       663121 : Find_named_object::expression(Expression** pexpr)
    3993              : {
    3994       663121 :   switch ((*pexpr)->classification())
    3995              :     {
    3996        75037 :     case Expression::EXPRESSION_CONST_REFERENCE:
    3997        75037 :       {
    3998        75037 :         Const_expression* ce = static_cast<Const_expression*>(*pexpr);
    3999        75037 :         if (ce->named_object() == this->no_)
    4000              :           break;
    4001              :         return TRAVERSE_CONTINUE;
    4002              :       }
    4003              : 
    4004          173 :     case Expression::EXPRESSION_VAR_REFERENCE:
    4005          173 :       if ((*pexpr)->var_expression()->named_object() == this->no_)
    4006              :         break;
    4007              :       return TRAVERSE_CONTINUE;
    4008         1414 :     case Expression::EXPRESSION_FUNC_REFERENCE:
    4009         1414 :       if ((*pexpr)->func_expression()->named_object() == this->no_)
    4010              :         break;
    4011              :       return TRAVERSE_CONTINUE;
    4012              :     case Expression::EXPRESSION_ERROR:
    4013              :       return TRAVERSE_EXIT;
    4014              :     default:
    4015              :       return TRAVERSE_CONTINUE;
    4016              :     }
    4017            0 :   this->found_ = true;
    4018            0 :   return TRAVERSE_EXIT;
    4019              : }
    4020              : 
    4021              : // The nil value.
    4022              : 
    4023              : class Nil_expression : public Expression
    4024              : {
    4025              :  public:
    4026      2349183 :   Nil_expression(Location location)
    4027      4698366 :     : Expression(EXPRESSION_NIL, location)
    4028              :   { }
    4029              : 
    4030              :   static Expression*
    4031              :   do_import(Import_expression*, Location);
    4032              : 
    4033              :  protected:
    4034              :   bool
    4035        59824 :   do_is_constant() const
    4036        59824 :   { return true; }
    4037              : 
    4038              :   bool
    4039              :   do_untyped_type(Type** ptype) const
    4040              :   {
    4041              :     *ptype = Type::make_nil_type();
    4042              :     return true;
    4043              :   }
    4044              : 
    4045              :   bool
    4046           18 :   do_is_zero_value() const
    4047           18 :   { return true; }
    4048              : 
    4049              :   bool
    4050       593355 :   do_is_static_initializer() const
    4051       593355 :   { return true; }
    4052              : 
    4053              :   Type*
    4054      2019129 :   do_type()
    4055      2019129 :   { return Type::make_nil_type(); }
    4056              : 
    4057              :   void
    4058      2948142 :   do_determine_type(Gogo*, const Type_context*)
    4059      2948142 :   { }
    4060              : 
    4061              :   Expression*
    4062            0 :   do_copy()
    4063            0 :   { return this; }
    4064              : 
    4065              :   Bexpression*
    4066      1202879 :   do_get_backend(Translate_context* context)
    4067      1202879 :   { return context->backend()->nil_pointer_expression(); }
    4068              : 
    4069              :   int
    4070        17529 :   do_inlining_cost() const
    4071        17529 :   { return 1; }
    4072              : 
    4073              :   void
    4074         1456 :   do_export(Export_function_body* efb) const
    4075         1456 :   { efb->write_c_string("$nil"); }
    4076              : 
    4077              :   void
    4078            0 :   do_dump_expression(Ast_dump_context* ast_dump_context) const
    4079            0 :   { ast_dump_context->ostream() << "nil"; }
    4080              : };
    4081              : 
    4082              : // Import a nil expression.
    4083              : 
    4084              : Expression*
    4085          621 : Nil_expression::do_import(Import_expression* imp, Location loc)
    4086              : {
    4087          621 :   if (imp->version() >= EXPORT_FORMAT_V3)
    4088          621 :     imp->require_c_string("$");
    4089          621 :   imp->require_c_string("nil");
    4090          621 :   return Expression::make_nil(loc);
    4091              : }
    4092              : 
    4093              : // Make a nil expression.
    4094              : 
    4095              : Expression*
    4096      2349183 : Expression::make_nil(Location location)
    4097              : {
    4098      2349183 :   return new Nil_expression(location);
    4099              : }
    4100              : 
    4101              : // The value of the predeclared constant iota.  This is little more
    4102              : // than a marker.  This will be lowered to an integer in
    4103              : // Const_expression::do_lower, which is where we know the value that
    4104              : // it should have.
    4105              : 
    4106              : class Iota_expression : public Parser_expression
    4107              : {
    4108              :  public:
    4109         4646 :   Iota_expression(Location location)
    4110         4646 :     : Parser_expression(EXPRESSION_IOTA, location)
    4111         4646 :   { }
    4112              : 
    4113              :  protected:
    4114              :   Type*
    4115            0 :   do_type()
    4116            0 :   { return Type::make_abstract_integer_type(); }
    4117              : 
    4118              :   void
    4119          471 :   do_determine_type(Gogo*, const Type_context*)
    4120          471 :   { }
    4121              : 
    4122              :   Expression*
    4123            0 :   do_lower(Gogo*, Named_object*, Statement_inserter*)
    4124            0 :   { go_unreachable(); }
    4125              : 
    4126              :   // There should only ever be one of these.
    4127              :   Expression*
    4128            0 :   do_copy()
    4129            0 :   { go_unreachable(); }
    4130              : 
    4131              :   void
    4132            0 :   do_dump_expression(Ast_dump_context* ast_dump_context) const
    4133            0 :   { ast_dump_context->ostream() << "iota"; }
    4134              : };
    4135              : 
    4136              : // Make an iota expression.  This is only called for one case: the
    4137              : // value of the predeclared constant iota.
    4138              : 
    4139              : Expression*
    4140         4646 : Expression::make_iota()
    4141              : {
    4142         6351 :   static Iota_expression iota_expression(Linemap::unknown_location());
    4143         4646 :   return &iota_expression;
    4144              : }
    4145              : 
    4146              : // Class Type_conversion_expression.
    4147              : 
    4148              : // Traversal.
    4149              : 
    4150              : int
    4151      6427874 : Type_conversion_expression::do_traverse(Traverse* traverse)
    4152              : {
    4153      6427874 :   if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
    4154      6427874 :       || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
    4155        75690 :     return TRAVERSE_EXIT;
    4156              :   return TRAVERSE_CONTINUE;
    4157              : }
    4158              : 
    4159              : // Return the type of the expression.
    4160              : 
    4161              : Type*
    4162      6939482 : Type_conversion_expression::do_type()
    4163              : {
    4164      6939482 :   if (this->is_error_expression() || this->expr_->is_error_expression())
    4165          259 :     return Type::make_error_type();
    4166      6939223 :   return this->type_;
    4167              : }
    4168              : 
    4169              : // Convert to a constant at lowering time.  Also lower conversions
    4170              : // from slice to pointer-to-array, as they can panic.
    4171              : 
    4172              : Expression*
    4173       464083 : Type_conversion_expression::do_lower(Gogo* gogo, Named_object*,
    4174              :                                      Statement_inserter* inserter)
    4175              : {
    4176       464083 :   Type* type = this->type_;
    4177       464083 :   Expression* val = this->expr_;
    4178       464083 :   Location location = this->location();
    4179              : 
    4180       464083 :   if (type->is_numeric_type())
    4181              :     {
    4182       293860 :       Numeric_constant nc;
    4183       293860 :       if (val->numeric_constant_value(&nc))
    4184              :         {
    4185        31348 :           if (!nc.set_type(type, true, location))
    4186           19 :             return Expression::make_error(location);
    4187        31329 :           return nc.expression(location);
    4188              :         }
    4189       293860 :     }
    4190              : 
    4191              :   // According to the language specification on string conversions
    4192              :   // (http://golang.org/ref/spec#Conversions_to_and_from_a_string_type):
    4193              :   // When converting an integer into a string, the string will be a UTF-8
    4194              :   // representation of the integer and integers "outside the range of valid
    4195              :   // Unicode code points are converted to '\uFFFD'."
    4196       432735 :   if (type->is_string_type())
    4197              :     {
    4198        27230 :       Numeric_constant nc;
    4199        27230 :       if (val->numeric_constant_value(&nc) && nc.is_int())
    4200              :         {
    4201              :           // An integer value doesn't fit in the Unicode code point range if it
    4202              :           // overflows the Go "int" type or is negative.
    4203          418 :           unsigned long ul;
    4204          418 :           if (!nc.set_type(Type::lookup_integer_type("int"), false, location)
    4205          418 :               || nc.to_unsigned_long(&ul) == Numeric_constant::NC_UL_NEGATIVE)
    4206            6 :             return Expression::make_string("\ufffd", location);
    4207              :         }
    4208        27230 :     }
    4209              : 
    4210       432729 :   if (type->is_slice_type())
    4211              :     {
    4212        25664 :       Type* element_type = type->array_type()->element_type()->forwarded();
    4213        24656 :       bool is_byte = (element_type->integer_type() != NULL
    4214        11824 :                       && element_type->integer_type()->is_byte());
    4215        24656 :       bool is_rune = (element_type->integer_type() != NULL
    4216        11824 :                       && element_type->integer_type()->is_rune());
    4217        12628 :       if (is_byte || is_rune)
    4218              :         {
    4219         9918 :           std::string s;
    4220         9918 :           if (val->string_constant_value(&s))
    4221              :             {
    4222         4887 :               Expression_list* vals = new Expression_list();
    4223         4887 :               if (is_byte)
    4224              :                 {
    4225         4831 :                   for (std::string::const_iterator p = s.begin();
    4226       164092 :                        p != s.end();
    4227       159261 :                        p++)
    4228              :                     {
    4229       159261 :                       unsigned char c = static_cast<unsigned char>(*p);
    4230       159261 :                       vals->push_back(Expression::make_integer_ul(c,
    4231              :                                                                   element_type,
    4232              :                                                                   location));
    4233              :                     }
    4234              :                 }
    4235              :               else
    4236              :                 {
    4237           56 :                   const char *p = s.data();
    4238           56 :                   const char *pend = s.data() + s.length();
    4239          609 :                   while (p < pend)
    4240              :                     {
    4241          553 :                       unsigned int c;
    4242          553 :                       int adv = Lex::fetch_char(p, &c);
    4243          553 :                       if (adv == 0)
    4244              :                         {
    4245            4 :                           go_warning_at(this->location(), 0,
    4246              :                                      "invalid UTF-8 encoding");
    4247            4 :                           adv = 1;
    4248              :                         }
    4249          553 :                       p += adv;
    4250          553 :                       vals->push_back(Expression::make_integer_ul(c,
    4251              :                                                                   element_type,
    4252              :                                                                   location));
    4253              :                     }
    4254              :                 }
    4255              : 
    4256         4887 :               return Expression::make_slice_composite_literal(type, vals,
    4257              :                                                               location);
    4258              :             }
    4259         9918 :         }
    4260              :     }
    4261              : 
    4262       427842 :   if (type->points_to() != NULL
    4263       121169 :       && type->points_to()->array_type() != NULL
    4264         3503 :       && !type->points_to()->is_slice_type()
    4265         1545 :       && val->type()->is_slice_type()
    4266       427934 :       && Type::are_identical(type->points_to()->array_type()->element_type(),
    4267           92 :                              val->type()->array_type()->element_type(),
    4268              :                              0, NULL))
    4269              :     {
    4270           46 :       Temporary_statement* val_temp = NULL;
    4271           46 :       if (!val->is_multi_eval_safe())
    4272              :         {
    4273           25 :           val_temp = Statement::make_temporary(val->type(), NULL, location);
    4274           25 :           inserter->insert(val_temp);
    4275           25 :           val = Expression::make_set_and_use_temporary(val_temp, val,
    4276              :                                                        location);
    4277              :         }
    4278              : 
    4279           46 :       Type* int_type = Type::lookup_integer_type("int");
    4280           46 :       Temporary_statement* vallen_temp =
    4281           46 :         Statement::make_temporary(int_type, NULL, location);
    4282           46 :       inserter->insert(vallen_temp);
    4283              : 
    4284           92 :       Expression* arrlen = type->points_to()->array_type()->length();
    4285           46 :       Expression* vallen =
    4286           46 :         Expression::make_slice_info(val, Expression::SLICE_INFO_LENGTH,
    4287              :                                     location);
    4288           46 :       vallen = Expression::make_set_and_use_temporary(vallen_temp, vallen,
    4289              :                                                       location);
    4290           46 :       Expression* cond = Expression::make_binary(OPERATOR_GT, arrlen, vallen,
    4291              :                                                  location);
    4292              : 
    4293           46 :       vallen = Expression::make_temporary_reference(vallen_temp, location);
    4294           46 :       Expression* panic = Runtime::make_call(gogo,
    4295              :                                              Runtime::PANIC_SLICE_CONVERT,
    4296              :                                              location, 2, arrlen, vallen);
    4297              : 
    4298           46 :       Expression* nil = Expression::make_nil(location);
    4299           46 :       Expression* check = Expression::make_conditional(cond, panic, nil,
    4300              :                                                        location);
    4301              : 
    4302           46 :       if (val_temp == NULL)
    4303           21 :         val = val->copy();
    4304              :       else
    4305           25 :         val = Expression::make_temporary_reference(val_temp, location);
    4306           46 :       Expression* ptr =
    4307           46 :         Expression::make_slice_info(val, Expression::SLICE_INFO_VALUE_POINTER,
    4308              :                                     location);
    4309           46 :       ptr = Expression::make_unsafe_cast(type, ptr, location);
    4310              : 
    4311           46 :       Expression* ret = Expression::make_compound(check, ptr, location);
    4312           46 :       ret->determine_type_no_context(gogo);
    4313           46 :       return ret;
    4314              :     }
    4315              : 
    4316       427796 :   return this;
    4317              : }
    4318              : 
    4319              : // Flatten a type conversion by using a temporary variable for the slice
    4320              : // in slice to string conversions.
    4321              : 
    4322              : Expression*
    4323       846814 : Type_conversion_expression::do_flatten(Gogo*, Named_object*,
    4324              :                                        Statement_inserter* inserter)
    4325              : {
    4326       846814 :   if (this->type()->is_error_type() || this->expr_->is_error_expression())
    4327              :     {
    4328          723 :       go_assert(saw_errors());
    4329          723 :       return Expression::make_error(this->location());
    4330              :     }
    4331              : 
    4332       846091 :   if (((this->type()->is_string_type()
    4333        22867 :         && this->expr_->type()->is_slice_type())
    4334       840340 :        || this->expr_->type()->interface_type() != NULL)
    4335       883084 :       && !this->expr_->is_multi_eval_safe())
    4336              :     {
    4337         7268 :       Temporary_statement* temp =
    4338         7268 :           Statement::make_temporary(NULL, this->expr_, this->location());
    4339         7268 :       inserter->insert(temp);
    4340         7268 :       this->expr_ = Expression::make_temporary_reference(temp, this->location());
    4341              :     }
    4342              : 
    4343              :   // For interface conversion and string to/from slice conversions,
    4344              :   // decide if we can allocate on stack.
    4345      1438394 :   if (this->type()->interface_type() != NULL
    4346       592303 :       || this->type()->is_string_type()
    4347       569436 :       || this->expr_->type()->is_string_type())
    4348              :     {
    4349       278526 :       Node* n = Node::make_node(this);
    4350       278526 :       if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
    4351        10302 :         this->no_escape_ = true;
    4352              :     }
    4353       846091 :   return this;
    4354              : }
    4355              : 
    4356              : // Return whether a type conversion is a constant.
    4357              : 
    4358              : bool
    4359       380572 : Type_conversion_expression::do_is_constant() const
    4360              : {
    4361       380572 :   if (!this->expr_->is_constant())
    4362              :     return false;
    4363              : 
    4364              :   // A conversion to a type that may not be used as a constant is not
    4365              :   // a constant.  For example, []byte(nil).
    4366        63191 :   Type* type = this->type_;
    4367        85345 :   if (type->integer_type() == NULL
    4368        21995 :       && type->float_type() == NULL
    4369        21982 :       && type->complex_type() == NULL
    4370        21982 :       && !type->is_boolean_type()
    4371        21885 :       && !type->is_string_type())
    4372              :     return false;
    4373              : 
    4374              :   return true;
    4375              : }
    4376              : 
    4377              : // Return whether a type conversion is a zero value.
    4378              : 
    4379              : bool
    4380          183 : Type_conversion_expression::do_is_zero_value() const
    4381              : {
    4382          183 :   if (!this->expr_->is_zero_value())
    4383              :     return false;
    4384              : 
    4385              :   // Some type conversion from zero value is still not zero value.
    4386              :   // For example, []byte("") or interface{}(0).
    4387              :   // Conservatively, only report true if the RHS is nil.
    4388            0 :   Type* type = this->type_;
    4389            0 :   if (type->integer_type() == NULL
    4390            0 :       && type->float_type() == NULL
    4391            0 :       && type->complex_type() == NULL
    4392            0 :       && !type->is_boolean_type()
    4393            0 :       && !type->is_string_type())
    4394            0 :     return this->expr_->is_nil_expression();
    4395              : 
    4396              :   return true;
    4397              : }
    4398              : 
    4399              : // Return whether a type conversion can be used in a constant
    4400              : // initializer.
    4401              : 
    4402              : bool
    4403        47536 : Type_conversion_expression::do_is_static_initializer() const
    4404              : {
    4405        47536 :   Type* type = this->type_;
    4406        47536 :   Type* expr_type = this->expr_->type();
    4407              : 
    4408        91784 :   if (type->interface_type() != NULL
    4409        47536 :       || expr_type->interface_type() != NULL)
    4410         3288 :     return false;
    4411              : 
    4412        44248 :   if (!this->expr_->is_static_initializer())
    4413              :     return false;
    4414              : 
    4415        34847 :   if (Type::are_identical(type, expr_type,
    4416              :                           Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
    4417              :                           NULL))
    4418              :     return true;
    4419              : 
    4420        22312 :   if (type->is_string_type() && expr_type->is_string_type())
    4421              :     return true;
    4422              : 
    4423        22241 :   if ((type->is_numeric_type()
    4424        22212 :        || type->is_boolean_type()
    4425        22212 :        || type->points_to() != NULL)
    4426        44371 :       && (expr_type->is_numeric_type()
    4427        22094 :           || expr_type->is_boolean_type()
    4428        22094 :           || expr_type->points_to() != NULL))
    4429        22117 :     return true;
    4430              : 
    4431              :   return false;
    4432              : }
    4433              : 
    4434              : // Return the constant numeric value if there is one.
    4435              : 
    4436              : bool
    4437       105449 : Type_conversion_expression::do_numeric_constant_value(
    4438              :     Numeric_constant* nc)
    4439              : {
    4440       105449 :   if (!this->type_->is_numeric_type())
    4441              :     return false;
    4442        96627 :   if (!this->expr_->numeric_constant_value(nc))
    4443              :     return false;
    4444        10669 :   return nc->set_type(this->type_, false, this->location());
    4445              : }
    4446              : 
    4447              : // Return the constant string value if there is one.
    4448              : 
    4449              : bool
    4450         7974 : Type_conversion_expression::do_string_constant_value(std::string* val)
    4451              : {
    4452         7974 :   if (this->type_->is_string_type() && this->expr_->type()->is_string_type())
    4453          126 :     return this->expr_->string_constant_value(val);
    4454              : 
    4455         7848 :   if (this->type_->is_string_type()
    4456         7848 :       && this->expr_->type()->integer_type() != NULL)
    4457              :     {
    4458          207 :       Numeric_constant nc;
    4459          207 :       if (this->expr_->numeric_constant_value(&nc))
    4460              :         {
    4461          122 :           unsigned long ival;
    4462          122 :           if (nc.to_unsigned_long(&ival) == Numeric_constant::NC_UL_VALID)
    4463              :             {
    4464          122 :               unsigned int cval = static_cast<unsigned int>(ival);
    4465          122 :               if (static_cast<unsigned long>(cval) != ival)
    4466              :                 {
    4467            1 :                   go_warning_at(this->location(), 0,
    4468              :                                 "unicode code point 0x%lx out of range",
    4469              :                                 ival);
    4470            1 :                   cval = 0xfffd; // Unicode "replacement character."
    4471              :                 }
    4472          122 :               val->clear();
    4473          122 :               Lex::append_char(cval, true, val, this->location());
    4474          122 :               return true;
    4475              :             }
    4476              :         }
    4477          207 :     }
    4478              : 
    4479              :   // FIXME: Could handle conversion from const []int here.
    4480              : 
    4481              :   return false;
    4482              : }
    4483              : 
    4484              : // Return the constant boolean value if there is one.
    4485              : 
    4486              : bool
    4487         6048 : Type_conversion_expression::do_boolean_constant_value(bool* val)
    4488              : {
    4489         6048 :   if (!this->type_->is_boolean_type())
    4490              :     return false;
    4491           12 :   return this->expr_->boolean_constant_value(val);
    4492              : }
    4493              : 
    4494              : // Determine the resulting type of the conversion.
    4495              : 
    4496              : void
    4497      2505712 : Type_conversion_expression::do_determine_type(Gogo* gogo, const Type_context*)
    4498              : {
    4499      2505712 :   Type_context subcontext(this->type_, false);
    4500      2505712 :   this->expr_->determine_type(gogo, &subcontext);
    4501      2505712 : }
    4502              : 
    4503              : // Check that types are convertible.
    4504              : 
    4505              : void
    4506       126355 : Type_conversion_expression::do_check_types(Gogo*)
    4507              : {
    4508       126355 :   Type* type = this->type_;
    4509       126355 :   Type* expr_type = this->expr_->type();
    4510       126355 :   std::string reason;
    4511              : 
    4512       126355 :   if (type->is_error() || expr_type->is_error())
    4513              :     {
    4514            2 :       this->set_is_error();
    4515            2 :       return;
    4516              :     }
    4517              : 
    4518       126353 :   if (this->may_convert_function_types_
    4519            0 :       && type->function_type() != NULL
    4520       252611 :       && expr_type->function_type() != NULL)
    4521              :     return;
    4522              : 
    4523       126353 :   if (Type::are_convertible(type, expr_type, &reason))
    4524              :     return;
    4525              : 
    4526              :   // We can convert all numeric types if the value is a constant.
    4527          102 :   if (type->is_numeric_type()
    4528           17 :       && expr_type->is_numeric_type()
    4529          107 :       && this->expr_->is_constant())
    4530              :     return;
    4531              : 
    4532           97 :   go_error_at(this->location(), "%s", reason.c_str());
    4533           97 :   this->set_is_error();
    4534       126355 : }
    4535              : 
    4536              : // Copy.
    4537              : 
    4538              : Expression*
    4539         5949 : Type_conversion_expression::do_copy()
    4540              : {
    4541        11898 :   Expression* ret = new Type_conversion_expression(this->type_->copy_expressions(),
    4542         5949 :                                                    this->expr_->copy(),
    4543         5949 :                                                    this->location());
    4544         5949 :   ret->conversion_expression()->set_no_copy(this->no_copy_);
    4545         5949 :   return ret;
    4546              : }
    4547              : 
    4548              : // Get the backend representation for a type conversion.
    4549              : 
    4550              : Bexpression*
    4551      2943669 : Type_conversion_expression::do_get_backend(Translate_context* context)
    4552              : {
    4553      2943669 :   Type* type = this->type_;
    4554      2943669 :   Type* expr_type = this->expr_->type();
    4555      2943669 :   Type_context tcontext(type, false);
    4556              : 
    4557      2943669 :   Gogo* gogo = context->gogo();
    4558      2943669 :   Btype* btype = type->get_backend(gogo);
    4559      2943669 :   Location loc = this->location();
    4560              : 
    4561      2943669 :   if (Type::are_identical(type, expr_type,
    4562              :                           Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
    4563              :                           NULL))
    4564              :     {
    4565      1104847 :       Bexpression* bexpr = this->expr_->get_backend(context);
    4566      1104847 :       return gogo->backend()->convert_expression(btype, bexpr, loc);
    4567              :     }
    4568      2066046 :   else if (type->interface_type() != NULL
    4569      1838822 :            && expr_type->interface_type() == NULL)
    4570              :     {
    4571       201200 :       Expression* conversion =
    4572       402400 :           Expression::convert_type_to_interface(type, this->expr_,
    4573       201200 :                                                 this->no_escape_, loc);
    4574       201200 :       conversion->determine_type(gogo, &tcontext);
    4575       201200 :       return conversion->get_backend(context);
    4576              :     }
    4577      3249220 :   else if (type->interface_type() != NULL
    4578      1637622 :            || expr_type->interface_type() != NULL)
    4579              :     {
    4580        26024 :       Expression* conversion =
    4581        26024 :           Expression::convert_for_assignment(gogo, type, this->expr_,
    4582              :                                              loc);
    4583        26024 :       conversion->determine_type(gogo, &tcontext);
    4584        26024 :       return conversion->get_backend(context);
    4585              :     }
    4586      1611598 :   else if (type->is_string_type()
    4587      1611598 :            && expr_type->integer_type() != NULL)
    4588              :     {
    4589          648 :       mpz_t intval;
    4590          648 :       Numeric_constant nc;
    4591          648 :       if (this->expr_->numeric_constant_value(&nc)
    4592          648 :           && nc.to_int(&intval))
    4593              :         {
    4594          380 :           std::string s;
    4595          380 :           unsigned int x;
    4596          380 :           if (mpz_fits_uint_p(intval))
    4597          381 :             x = mpz_get_ui(intval);
    4598              :           else
    4599              :             {
    4600            1 :               char* ms = mpz_get_str(NULL, 16, intval);
    4601            1 :               go_warning_at(loc, 0,
    4602              :                             "unicode code point 0x%s out of range in string",
    4603              :                             ms);
    4604            1 :               free(ms);
    4605            1 :               x = 0xfffd;
    4606              :             }
    4607          380 :           Lex::append_char(x, true, &s, loc);
    4608          380 :           mpz_clear(intval);
    4609          380 :           Expression* se = Expression::make_string(s, loc);
    4610          380 :           se->determine_type(gogo, &tcontext);
    4611          380 :           return se->get_backend(context);
    4612          380 :         }
    4613              : 
    4614          268 :       Expression* buf;
    4615          268 :       if (this->no_escape_)
    4616              :         {
    4617          200 :           Type* byte_type = Type::lookup_integer_type("uint8");
    4618          200 :           Expression* buflen =
    4619          200 :             Expression::make_integer_ul(4, NULL, loc);
    4620          200 :           Type* array_type = Type::make_array_type(byte_type, buflen);
    4621          200 :           buf = Expression::make_allocation(array_type, loc);
    4622          200 :           buf->allocation_expression()->set_allocate_on_stack();
    4623          200 :           buf->allocation_expression()->set_no_zero();
    4624              :         }
    4625              :       else
    4626           68 :         buf = Expression::make_nil(loc);
    4627          268 :       Expression* i2s_expr =
    4628          268 :         Runtime::make_call(gogo, Runtime::INTSTRING, loc, 2, buf, this->expr_);
    4629          268 :       Expression* ret = Expression::make_cast(type, i2s_expr, loc);
    4630          268 :       Type_context tcontext(type, false);
    4631          268 :       ret->determine_type(gogo, &tcontext);
    4632          268 :       return ret->get_backend(context);
    4633          648 :     }
    4634      1610950 :   else if (type->is_string_type() && expr_type->is_slice_type())
    4635              :     {
    4636         5289 :       Array_type* a = expr_type->array_type();
    4637         5289 :       Type* e = a->element_type()->forwarded();
    4638         5289 :       go_assert(e->integer_type() != NULL);
    4639         5289 :       go_assert(this->expr_->is_multi_eval_safe());
    4640              : 
    4641         5289 :       Expression* buf;
    4642         5289 :       if (this->no_escape_ && !this->no_copy_)
    4643              :         {
    4644          408 :           Type* byte_type = Type::lookup_integer_type("uint8");
    4645          408 :           Expression* buflen =
    4646          408 :             Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
    4647          408 :           Type* array_type = Type::make_array_type(byte_type, buflen);
    4648          408 :           buf = Expression::make_allocation(array_type, loc);
    4649          408 :           buf->allocation_expression()->set_allocate_on_stack();
    4650          408 :           buf->allocation_expression()->set_no_zero();
    4651              :         }
    4652              :       else
    4653         4881 :         buf = Expression::make_nil(loc);
    4654              : 
    4655        10578 :       if (e->integer_type()->is_byte())
    4656              :         {
    4657         5155 :           Expression* ptr =
    4658         5155 :             Expression::make_slice_info(this->expr_, SLICE_INFO_VALUE_POINTER,
    4659              :                                         loc);
    4660         5155 :           Expression* len =
    4661         5155 :             Expression::make_slice_info(this->expr_, SLICE_INFO_LENGTH, loc);
    4662         5155 :           if (this->no_copy_)
    4663              :             {
    4664         1689 :               if (gogo->debug_optimization())
    4665            6 :                 go_debug(loc, "no copy string([]byte)");
    4666         1689 :               Expression* str = Expression::make_string_value(ptr, len, loc);
    4667         1689 :               return str->get_backend(context);
    4668              :             }
    4669         3466 :           Expression* ret = Runtime::make_call(gogo, Runtime::SLICEBYTETOSTRING,
    4670              :                                                loc, 3, buf, ptr, len);
    4671         3466 :           Type_context tcontext(type, false);
    4672         3466 :           ret->determine_type(gogo, &tcontext);
    4673         3466 :           return ret->get_backend(context);
    4674              :         }
    4675              :       else
    4676              :         {
    4677          268 :           go_assert(e->integer_type()->is_rune());
    4678          134 :           Expression* ret = Runtime::make_call(gogo, Runtime::SLICERUNETOSTRING,
    4679              :                                                loc, 2, buf, this->expr_);
    4680          134 :           Type_context tcontext(type, false);
    4681          134 :           ret->determine_type(gogo, &tcontext);
    4682          134 :           return ret->get_backend(context);
    4683              :         }
    4684              :     }
    4685      1609294 :   else if (type->is_slice_type() && expr_type->is_string_type())
    4686              :     {
    4687         3128 :       Type* e = type->array_type()->element_type()->forwarded();
    4688         1564 :       go_assert(e->integer_type() != NULL);
    4689              : 
    4690         1564 :       Runtime::Function code;
    4691         3128 :       if (e->integer_type()->is_byte())
    4692              :         code = Runtime::STRINGTOSLICEBYTE;
    4693              :       else
    4694              :         {
    4695           90 :           go_assert(e->integer_type()->is_rune());
    4696              :           code = Runtime::STRINGTOSLICERUNE;
    4697              :         }
    4698              : 
    4699         1564 :       Expression* buf;
    4700         1564 :       if (this->no_escape_)
    4701              :         {
    4702          524 :           Expression* buflen =
    4703          524 :             Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
    4704          524 :           Type* array_type = Type::make_array_type(e, buflen);
    4705          524 :           buf = Expression::make_allocation(array_type, loc);
    4706          524 :           buf->allocation_expression()->set_allocate_on_stack();
    4707          524 :           buf->allocation_expression()->set_no_zero();
    4708              :         }
    4709              :       else
    4710         1040 :         buf = Expression::make_nil(loc);
    4711         1564 :       Expression* s2a = Runtime::make_call(gogo, code, loc, 2, buf,
    4712              :                                            this->expr_);
    4713         1564 :       Expression* ret = Expression::make_unsafe_cast(type, s2a, loc);
    4714         1564 :       Type_context tcontext(type, false);
    4715         1564 :       ret->determine_type(gogo, &tcontext);
    4716         1564 :       return ret->get_backend(context);
    4717              :     }
    4718      1604097 :   else if (type->is_numeric_type())
    4719              :     {
    4720       412225 :       go_assert(Type::are_convertible(type, expr_type, NULL));
    4721       412225 :       Bexpression* bexpr = this->expr_->get_backend(context);
    4722       412225 :       return gogo->backend()->convert_expression(btype, bexpr, loc);
    4723              :     }
    4724      1191872 :   else if ((type->is_unsafe_pointer_type()
    4725       770030 :             && (expr_type->points_to() != NULL
    4726      1406304 :                 || expr_type->integer_type()))
    4727       436895 :            || (expr_type->is_unsafe_pointer_type()
    4728       214432 :                && type->points_to() != NULL)
    4729      1414335 :            || (this->may_convert_function_types_
    4730            0 :                && type->function_type() != NULL
    4731       969409 :                && expr_type->function_type() != NULL))
    4732              :     {
    4733       969409 :       Bexpression* bexpr = this->expr_->get_backend(context);
    4734       969409 :       return gogo->backend()->convert_expression(btype, bexpr, loc);
    4735              :     }
    4736              :   else
    4737              :     {
    4738       222463 :       Expression* conversion =
    4739       222463 :           Expression::convert_for_assignment(gogo, type, this->expr_, loc);
    4740       222463 :       conversion->determine_type(gogo, &tcontext);
    4741       222463 :       return conversion->get_backend(context);
    4742              :     }
    4743              : }
    4744              : 
    4745              : // Cost of inlining a type conversion.
    4746              : 
    4747              : int
    4748       289413 : Type_conversion_expression::do_inlining_cost() const
    4749              : {
    4750       289413 :   Type* type = this->type_;
    4751       289413 :   Type* expr_type = this->expr_->type();
    4752       491515 :   if (type->interface_type() != NULL || expr_type->interface_type() != NULL)
    4753        87311 :     return 10;
    4754       298377 :   else if (type->is_string_type() && expr_type->integer_type() != NULL)
    4755              :     return 10;
    4756       201934 :   else if (type->is_string_type() && expr_type->is_slice_type())
    4757              :     return 10;
    4758       199427 :   else if (type->is_slice_type() && expr_type->is_string_type())
    4759              :     return 10;
    4760              :   else
    4761       193138 :     return 1;
    4762              : }
    4763              : 
    4764              : // Output a type conversion in a constant expression.
    4765              : 
    4766              : void
    4767        10254 : Type_conversion_expression::do_export(Export_function_body* efb) const
    4768              : {
    4769        10254 :   efb->write_c_string("$convert(");
    4770        10254 :   efb->write_type(this->type_);
    4771        10254 :   efb->write_c_string(", ");
    4772              : 
    4773        10254 :   Type* old_context = efb->type_context();
    4774        10254 :   efb->set_type_context(this->type_);
    4775              : 
    4776        10254 :   this->expr_->export_expression(efb);
    4777              : 
    4778        10254 :   efb->set_type_context(old_context);
    4779              : 
    4780        10254 :   efb->write_c_string(")");
    4781        10254 : }
    4782              : 
    4783              : // Import a type conversion or a struct construction.
    4784              : 
    4785              : Expression*
    4786        18058 : Type_conversion_expression::do_import(Import_expression* imp, Location loc)
    4787              : {
    4788        18058 :   imp->require_c_string("$convert(");
    4789        18058 :   Type* type = imp->read_type();
    4790        18058 :   imp->require_c_string(", ");
    4791        18058 :   Expression* val = Expression::import_expression(imp, loc);
    4792        18058 :   imp->require_c_string(")");
    4793        18058 :   return Expression::make_cast(type, val, loc);
    4794              : }
    4795              : 
    4796              : // Dump ast representation for a type conversion expression.
    4797              : 
    4798              : void
    4799            0 : Type_conversion_expression::do_dump_expression(
    4800              :     Ast_dump_context* ast_dump_context) const
    4801              : {
    4802            0 :   ast_dump_context->dump_type(this->type_);
    4803            0 :   ast_dump_context->ostream() << "(";
    4804            0 :   ast_dump_context->dump_expression(this->expr_);
    4805            0 :   ast_dump_context->ostream() << ") ";
    4806            0 : }
    4807              : 
    4808              : // Make a type cast expression.
    4809              : 
    4810              : Expression*
    4811      3012628 : Expression::make_cast(Type* type, Expression* val, Location location)
    4812              : {
    4813      3012628 :   if (type->is_error_type() || val->is_error_expression())
    4814          512 :     return Expression::make_error(location);
    4815      3012116 :   return new Type_conversion_expression(type, val, location);
    4816              : }
    4817              : 
    4818              : // Class Unsafe_type_conversion_expression.
    4819              : 
    4820              : // Traversal.
    4821              : 
    4822              : int
    4823      1435754 : Unsafe_type_conversion_expression::do_traverse(Traverse* traverse)
    4824              : {
    4825      1435754 :   if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
    4826      1435754 :       || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
    4827        70884 :     return TRAVERSE_EXIT;
    4828              :   return TRAVERSE_CONTINUE;
    4829              : }
    4830              : 
    4831              : // Return whether an unsafe type conversion can be used as a constant
    4832              : // initializer.
    4833              : 
    4834              : bool
    4835          184 : Unsafe_type_conversion_expression::do_is_static_initializer() const
    4836              : {
    4837          184 :   Type* type = this->type_;
    4838          184 :   Type* expr_type = this->expr_->type();
    4839              : 
    4840          368 :   if (type->interface_type() != NULL
    4841          184 :       || expr_type->interface_type() != NULL)
    4842            0 :     return false;
    4843              : 
    4844          184 :   if (!this->expr_->is_static_initializer())
    4845              :     return false;
    4846              : 
    4847            0 :   if (Type::are_convertible(type, expr_type, NULL))
    4848              :     return true;
    4849              : 
    4850            0 :   if (type->is_string_type() && expr_type->is_string_type())
    4851              :     return true;
    4852              : 
    4853            0 :   if ((type->is_numeric_type()
    4854            0 :        || type->is_boolean_type()
    4855            0 :        || type->points_to() != NULL)
    4856            0 :       && (expr_type->is_numeric_type()
    4857            0 :           || expr_type->is_boolean_type()
    4858            0 :           || expr_type->points_to() != NULL))
    4859            0 :     return true;
    4860              : 
    4861              :   return false;
    4862              : }
    4863              : 
    4864              : // Copy.
    4865              : 
    4866              : Expression*
    4867            0 : Unsafe_type_conversion_expression::do_copy()
    4868              : {
    4869            0 :   return new Unsafe_type_conversion_expression(this->type_->copy_expressions(),
    4870            0 :                                                this->expr_->copy(),
    4871            0 :                                                this->location());
    4872              : }
    4873              : 
    4874              : // Convert to backend representation.
    4875              : 
    4876              : Bexpression*
    4877       741101 : Unsafe_type_conversion_expression::do_get_backend(Translate_context* context)
    4878              : {
    4879              :   // We are only called for a limited number of cases.
    4880              : 
    4881       741101 :   Type* t = this->type_;
    4882       741101 :   Type* et = this->expr_->type();
    4883              : 
    4884       741101 :   if (t->is_error_type()
    4885       741101 :       || this->expr_->is_error_expression()
    4886      1482202 :       || et->is_error_type())
    4887              :     {
    4888            0 :       go_assert(saw_errors());
    4889            0 :       return context->backend()->error_expression();
    4890              :     }
    4891              : 
    4892       741101 :   if (t->array_type() != NULL)
    4893        58490 :     go_assert(et->array_type() != NULL
    4894              :               && t->is_slice_type() == et->is_slice_type());
    4895       711856 :   else if (t->struct_type() != NULL)
    4896              :     {
    4897           36 :       if (t->named_type() != NULL
    4898           30 :           && et->named_type() != NULL
    4899           58 :           && !Type::are_convertible(t, et, NULL))
    4900              :         {
    4901            0 :           go_assert(saw_errors());
    4902            0 :           return context->backend()->error_expression();
    4903              :         }
    4904              : 
    4905           72 :       go_assert(et->struct_type() != NULL
    4906              :                 && Type::are_convertible(t, et, NULL));
    4907              :     }
    4908       711820 :   else if (t->map_type() != NULL)
    4909        21419 :     go_assert(et->map_type() != NULL || et->points_to() != NULL);
    4910       690799 :   else if (t->channel_type() != NULL)
    4911         9220 :     go_assert(et->channel_type() != NULL || et->points_to() != NULL);
    4912       681692 :   else if (t->points_to() != NULL)
    4913       615272 :     go_assert(et->points_to() != NULL
    4914              :               || et->channel_type() != NULL
    4915              :               || et->map_type() != NULL
    4916              :               || et->function_type() != NULL
    4917              :               || et->integer_type() != NULL
    4918              :               || et->is_nil_type());
    4919       114544 :   else if (t->function_type() != NULL)
    4920         1343 :     go_assert(et->points_to() != NULL);
    4921       113201 :   else if (et->is_unsafe_pointer_type())
    4922        44766 :     go_assert(t->points_to() != NULL
    4923              :               || (t->integer_type() != NULL
    4924              :                   && t->integer_type() == Type::lookup_integer_type("uintptr")->real_type()));
    4925        98279 :   else if (t->interface_type() != NULL)
    4926              :     {
    4927        79976 :       bool empty_iface = t->interface_type()->is_empty();
    4928       119964 :       go_assert(et->interface_type() != NULL
    4929              :                 && et->interface_type()->is_empty() == empty_iface);
    4930              :     }
    4931        58291 :   else if (t->integer_type() != NULL)
    4932       866509 :     go_assert(et->is_boolean_type()
    4933              :               || et->integer_type() != NULL
    4934              :               || et->function_type() != NULL
    4935              :               || et->points_to() != NULL
    4936              :               || et->map_type() != NULL
    4937              :               || et->channel_type() != NULL
    4938              :               || et->is_nil_type());
    4939              :   else
    4940            0 :     go_unreachable();
    4941              : 
    4942       741101 :   Gogo* gogo = context->gogo();
    4943       741101 :   Btype* btype = t->get_backend(gogo);
    4944       741101 :   Bexpression* bexpr = this->expr_->get_backend(context);
    4945       741101 :   Location loc = this->location();
    4946       741101 :   return gogo->backend()->convert_expression(btype, bexpr, loc);
    4947              : }
    4948              : 
    4949              : // Dump ast representation for an unsafe type conversion expression.
    4950              : 
    4951              : void
    4952            0 : Unsafe_type_conversion_expression::do_dump_expression(
    4953              :     Ast_dump_context* ast_dump_context) const
    4954              : {
    4955            0 :   ast_dump_context->dump_type(this->type_);
    4956            0 :   ast_dump_context->ostream() << "(";
    4957            0 :   ast_dump_context->dump_expression(this->expr_);
    4958            0 :   ast_dump_context->ostream() << ") ";
    4959            0 : }
    4960              : 
    4961              : // Make an unsafe type conversion expression.
    4962              : 
    4963              : Expression*
    4964       780304 : Expression::make_unsafe_cast(Type* type, Expression* expr,
    4965              :                              Location location)
    4966              : {
    4967       780304 :   return new Unsafe_type_conversion_expression(type, expr, location);
    4968              : }
    4969              : 
    4970              : // Class Unary_expression.
    4971              : 
    4972              : // Call the address_taken method of the operand if needed.  This is
    4973              : // called after escape analysis but before inserting write barriers.
    4974              : 
    4975              : void
    4976       826646 : Unary_expression::check_operand_address_taken(Gogo*)
    4977              : {
    4978       826646 :   if (this->op_ != OPERATOR_AND)
    4979              :     return;
    4980              : 
    4981              :   // If this->escapes_ is false at this point, then it was set to
    4982              :   // false by an explicit call to set_does_not_escape, and the value
    4983              :   // does not escape.  If this->escapes_ is true, we may be able to
    4984              :   // set it to false based on the escape analysis pass.
    4985       205342 :   if (this->escapes_)
    4986              :     {
    4987       176931 :       Node* n = Node::make_node(this);
    4988       176931 :       if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
    4989       129243 :         this->escapes_ = false;
    4990              :     }
    4991              : 
    4992       205342 :   this->expr_->address_taken(this->escapes_);
    4993              : }
    4994              : 
    4995              : // If we are taking the address of a composite literal, and the
    4996              : // contents are not constant, then we want to make a heap expression
    4997              : // instead.
    4998              : 
    4999              : Expression*
    5000      1637015 : Unary_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*)
    5001              : {
    5002      1637015 :   Location loc = this->location();
    5003              : 
    5004      1637015 :   if (this->is_error_expression())
    5005            7 :     return Expression::make_error(loc);
    5006              : 
    5007      1637008 :   Operator op = this->op_;
    5008      1637008 :   Expression* expr = this->expr_;
    5009              : 
    5010      1637008 :   if (expr->is_error_expression())
    5011            2 :     return Expression::make_error(loc);
    5012              : 
    5013      1637006 :   if (op == OPERATOR_MULT && expr->is_type_expression())
    5014              :     {
    5015          163 :       Expression* ret =
    5016          163 :         Expression::make_type(Type::make_pointer_type(expr->type()), loc);
    5017          163 :       ret->determine_type_no_context(gogo);
    5018          163 :       return ret;
    5019              :     }
    5020              : 
    5021              :   // *&x simplifies to x.  *(*T)(unsafe.Pointer)(&x) does not require
    5022              :   // moving x to the heap.  FIXME: Is it worth doing a real escape
    5023              :   // analysis here?  This case is found in math/unsafe.go and is
    5024              :   // therefore worth special casing.
    5025      1636843 :   if (op == OPERATOR_MULT)
    5026              :     {
    5027              :       Expression* e = expr;
    5028      1187271 :       while (e->classification() == EXPRESSION_CONVERSION)
    5029              :         {
    5030        20844 :           Type_conversion_expression* te
    5031              :             = static_cast<Type_conversion_expression*>(e);
    5032        20844 :           e = te->expr();
    5033              :         }
    5034              : 
    5035      1166427 :       if (e->classification() == EXPRESSION_UNARY)
    5036              :         {
    5037         2957 :           Unary_expression* ue = static_cast<Unary_expression*>(e);
    5038         2957 :           if (ue->op_ == OPERATOR_AND)
    5039              :             {
    5040         1069 :               if (e == expr)
    5041              :                 {
    5042              :                   // *&x == x.
    5043           24 :                   if (!ue->expr_->is_addressable() && !ue->create_temp_)
    5044              :                     {
    5045            0 :                       go_error_at(ue->location(),
    5046              :                                   "invalid operand for unary %<&%>");
    5047            0 :                       this->set_is_error();
    5048              :                     }
    5049           24 :                   return ue->expr_;
    5050              :                 }
    5051         1045 :               ue->set_does_not_escape();
    5052              :             }
    5053              :         }
    5054              :     }
    5055              : 
    5056              :   // Check for an invalid pointer dereference.  We need to do this
    5057              :   // here because Unary_expression::do_type will return an error type
    5058              :   // in this case.  That can cause code to appear erroneous, and
    5059              :   // therefore disappear at lowering time, without any error message.
    5060      1166403 :   if (op == OPERATOR_MULT && expr->type()->points_to() == NULL)
    5061              :     {
    5062            0 :       this->report_error(_("expected pointer"));
    5063            0 :       return Expression::make_error(this->location());
    5064              :     }
    5065              : 
    5066      1636819 :   if (op == OPERATOR_PLUS || op == OPERATOR_MINUS || op == OPERATOR_XOR)
    5067              :     {
    5068        87866 :       Numeric_constant nc;
    5069        87866 :       if (expr->numeric_constant_value(&nc))
    5070              :         {
    5071        64140 :           Numeric_constant result;
    5072        64140 :           bool issued_error;
    5073        64140 :           if (Unary_expression::eval_constant(this->type_, op, &nc, loc,
    5074              :                                               &result, &issued_error))
    5075              :             {
    5076        64140 :               Expression* ret = result.expression(loc);
    5077        64140 :               Type_context subcontext(this->type_, this->type_->is_abstract());
    5078        64140 :               ret->determine_type(gogo, &subcontext);
    5079        64140 :               ret->check_types(gogo);
    5080        64140 :               return ret;
    5081              :             }
    5082            0 :           else if (issued_error)
    5083            0 :             return Expression::make_error(this->location());
    5084        64140 :         }
    5085        87866 :     }
    5086              : 
    5087      1572679 :   return this;
    5088              : }
    5089              : 
    5090              : // Flatten expression if a nil check must be performed and create temporary
    5091              : // variables if necessary.
    5092              : 
    5093              : Expression*
    5094      1372791 : Unary_expression::do_flatten(Gogo* gogo, Named_object*,
    5095              :                              Statement_inserter* inserter)
    5096              : {
    5097      1372791 :   if (this->is_error_expression()
    5098      1372791 :       || this->expr_->is_error_expression()
    5099      2745582 :       || this->expr_->type()->is_error_type())
    5100              :     {
    5101            0 :       go_assert(saw_errors());
    5102            0 :       return Expression::make_error(this->location());
    5103              :     }
    5104              : 
    5105      1372791 :   Location location = this->location();
    5106      1372791 :   if (this->op_ == OPERATOR_MULT
    5107      1372791 :       && !this->expr_->is_multi_eval_safe())
    5108              :     {
    5109       176462 :       go_assert(this->expr_->type()->points_to() != NULL);
    5110       176462 :       switch (this->requires_nil_check(gogo))
    5111              :         {
    5112            0 :           case NIL_CHECK_ERROR_ENCOUNTERED:
    5113            0 :             {
    5114            0 :               go_assert(saw_errors());
    5115            0 :               return Expression::make_error(this->location());
    5116              :             }
    5117              :           case NIL_CHECK_NOT_NEEDED:
    5118              :             break;
    5119         4142 :           case NIL_CHECK_NEEDED:
    5120         4142 :             this->create_temp_ = true;
    5121         4142 :             break;
    5122            0 :           case NIL_CHECK_DEFAULT:
    5123            0 :             go_unreachable();
    5124              :         }
    5125              :     }
    5126              : 
    5127      1372791 :   if (this->create_temp_ && !this->expr_->is_multi_eval_safe())
    5128              :     {
    5129        12729 :       Temporary_statement* temp =
    5130        12729 :           Statement::make_temporary(NULL, this->expr_, location);
    5131        12729 :       inserter->insert(temp);
    5132        12729 :       this->expr_ = Expression::make_temporary_reference(temp, location);
    5133              :     }
    5134              : 
    5135      1372791 :   return this;
    5136              : }
    5137              : 
    5138              : // Return whether a unary expression is a constant.
    5139              : 
    5140              : bool
    5141       334011 : Unary_expression::do_is_constant() const
    5142              : {
    5143       334011 :   if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND)
    5144              :     {
    5145              :       // These are not constant by Go language rules.
    5146              :       return false;
    5147              :     }
    5148              :   else
    5149        39276 :     return this->expr_->is_constant();
    5150              : }
    5151              : 
    5152              : bool
    5153       234004 : Unary_expression::do_is_untyped(Type** ptype) const
    5154              : {
    5155       234004 :   if (this->type_ != NULL)
    5156          144 :     return Expression::is_untyped_type(this->type_, ptype);
    5157              : 
    5158       233860 :   if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND)
    5159              :     return false;
    5160        28276 :   return this->expr_->is_untyped(ptype);
    5161              : }
    5162              : 
    5163              : // Return whether a unary expression can be used as a constant
    5164              : // initializer.
    5165              : 
    5166              : bool
    5167      1022986 : Unary_expression::do_is_static_initializer() const
    5168              : {
    5169      1022986 :   if (this->op_ == OPERATOR_MULT)
    5170              :     return false;
    5171      1022971 :   else if (this->op_ == OPERATOR_AND)
    5172      1022965 :     return Unary_expression::base_is_static_initializer(this->expr_);
    5173              :   else
    5174            6 :     return this->expr_->is_static_initializer();
    5175              : }
    5176              : 
    5177              : // Return whether the address of EXPR can be used as a static
    5178              : // initializer.
    5179              : 
    5180              : bool
    5181      1023017 : Unary_expression::base_is_static_initializer(Expression* expr)
    5182              : {
    5183              :   // The address of a field reference can be a static initializer if
    5184              :   // the base can be a static initializer.
    5185      1023837 :   Field_reference_expression* fre = expr->field_reference_expression();
    5186      1023837 :   if (fre != NULL)
    5187          820 :     return Unary_expression::base_is_static_initializer(fre->expr());
    5188              : 
    5189              :   // The address of an index expression can be a static initializer if
    5190              :   // the base can be a static initializer and the index is constant.
    5191      1023017 :   Array_index_expression* aind = expr->array_index_expression();
    5192      1023017 :   if (aind != NULL)
    5193           52 :     return (aind->end() == NULL
    5194           52 :             && aind->start()->is_constant()
    5195          104 :             && Unary_expression::base_is_static_initializer(aind->array()));
    5196              : 
    5197              :   // The address of a global variable can be a static initializer.
    5198      1022965 :   Var_expression* ve = expr->var_expression();
    5199      1022965 :   if (ve != NULL)
    5200              :     {
    5201        20906 :       Named_object* no = ve->named_object();
    5202        20906 :       return no->is_variable() && no->var_value()->is_global();
    5203              :     }
    5204              : 
    5205              :   // The address of a composite literal can be used as a static
    5206              :   // initializer if the composite literal is itself usable as a
    5207              :   // static initializer.
    5208      1002059 :   if (expr->is_composite_literal() && expr->is_static_initializer())
    5209              :     return true;
    5210              : 
    5211              :   // The address of a string constant can be used as a static
    5212              :   // initializer.  This can not be written in Go itself but this is
    5213              :   // used when building a type descriptor.
    5214      1022640 :   if (expr->string_expression() != NULL)
    5215              :     return true;
    5216              : 
    5217              :   return false;
    5218              : }
    5219              : 
    5220              : // Return whether this dereference expression requires an explicit nil
    5221              : // check. If we are dereferencing the pointer to a large struct
    5222              : // (greater than the specified size threshold), we need to check for
    5223              : // nil. We don't bother to check for small structs because we expect
    5224              : // the system to crash on a nil pointer dereference. However, if we
    5225              : // know the address of this expression is being taken, we must always
    5226              : // check for nil.
    5227              : Unary_expression::Nil_check_classification
    5228      1277339 : Unary_expression::requires_nil_check(Gogo* gogo)
    5229              : {
    5230      1277339 :   go_assert(this->op_ == OPERATOR_MULT);
    5231      1277339 :   go_assert(this->expr_->type()->points_to() != NULL);
    5232              : 
    5233      1277339 :   if (this->issue_nil_check_ == NIL_CHECK_NEEDED)
    5234              :     return NIL_CHECK_NEEDED;
    5235      1208709 :   else if (this->issue_nil_check_ == NIL_CHECK_NOT_NEEDED)
    5236              :     return NIL_CHECK_NOT_NEEDED;
    5237              : 
    5238       560928 :   Type* ptype = this->expr_->type()->points_to();
    5239       560928 :   int64_t type_size = -1;
    5240       560928 :   if (!ptype->is_void_type())
    5241              :     {
    5242       560928 :       bool ok = ptype->backend_type_size(gogo, &type_size);
    5243       560928 :       if (!ok)
    5244              :         return NIL_CHECK_ERROR_ENCOUNTERED;
    5245              :     }
    5246              : 
    5247       560928 :   int64_t size_cutoff = gogo->nil_check_size_threshold();
    5248       560928 :   if (size_cutoff == -1 || (type_size != -1 && type_size >= size_cutoff))
    5249        15662 :     this->issue_nil_check_ = NIL_CHECK_NEEDED;
    5250              :   else
    5251       545266 :     this->issue_nil_check_ = NIL_CHECK_NOT_NEEDED;
    5252       560928 :   return this->issue_nil_check_;
    5253              : }
    5254              : 
    5255              : // Apply unary opcode OP to UNC, setting NC.  Return true if this
    5256              : // could be done, false if not.  On overflow, issues an error and sets
    5257              : // *ISSUED_ERROR.
    5258              : 
    5259              : bool
    5260        81587 : Unary_expression::eval_constant(Type* type, Operator op,
    5261              :                                 const Numeric_constant* unc,
    5262              :                                 Location location, Numeric_constant* nc,
    5263              :                                 bool* issued_error)
    5264              : {
    5265        81587 :   *issued_error = false;
    5266        81587 :   switch (op)
    5267              :     {
    5268         1029 :     case OPERATOR_PLUS:
    5269         1029 :       *nc = *unc;
    5270         1029 :       return true;
    5271              : 
    5272        71496 :     case OPERATOR_MINUS:
    5273        71496 :       if (unc->is_int() || unc->is_rune())
    5274              :         break;
    5275         4061 :       else if (unc->is_float())
    5276              :         {
    5277         4051 :           mpfr_t uval;
    5278         4051 :           unc->get_float(&uval);
    5279         4051 :           mpfr_t val;
    5280         4051 :           mpfr_init(val);
    5281         4051 :           mpfr_neg(val, uval, MPFR_RNDN);
    5282         4051 :           Type* utype = unc->type();
    5283         4051 :           if (type != NULL
    5284         4051 :               && type->is_abstract()
    5285         6024 :               && type->is_numeric_type())
    5286              :             utype = type;
    5287         4051 :           nc->set_float(utype, val);
    5288         4051 :           mpfr_clear(uval);
    5289         4051 :           mpfr_clear(val);
    5290         4051 :           return true;
    5291              :         }
    5292           10 :       else if (unc->is_complex())
    5293              :         {
    5294           10 :           mpc_t uval;
    5295           10 :           unc->get_complex(&uval);
    5296           10 :           mpc_t val;
    5297           10 :           mpc_init2(val, mpc_precision);
    5298           10 :           mpc_neg(val, uval, MPC_RNDNN);
    5299           10 :           Type* utype = unc->type();
    5300           10 :           if (type != NULL
    5301           10 :               && type->is_abstract()
    5302           16 :               && type->is_numeric_type())
    5303              :             utype = type;
    5304           10 :           nc->set_complex(utype, val);
    5305           10 :           mpc_clear(uval);
    5306           10 :           mpc_clear(val);
    5307           10 :           return true;
    5308              :         }
    5309              :       else
    5310            0 :         go_unreachable();
    5311              : 
    5312              :     case OPERATOR_XOR:
    5313              :       break;
    5314              : 
    5315              :     case OPERATOR_NOT:
    5316              :     case OPERATOR_AND:
    5317              :     case OPERATOR_MULT:
    5318              :       return false;
    5319              : 
    5320            0 :     default:
    5321            0 :       go_unreachable();
    5322              :     }
    5323              : 
    5324        76497 :   if (!unc->is_int() && !unc->is_rune())
    5325              :     return false;
    5326              : 
    5327        76497 :   mpz_t uval;
    5328        76497 :   if (unc->is_rune())
    5329            0 :     unc->get_rune(&uval);
    5330              :   else
    5331        76497 :     unc->get_int(&uval);
    5332        76497 :   mpz_t val;
    5333        76497 :   mpz_init(val);
    5334              : 
    5335        76497 :   switch (op)
    5336              :     {
    5337        67435 :     case OPERATOR_MINUS:
    5338        67435 :       mpz_neg(val, uval);
    5339        67435 :       break;
    5340              : 
    5341              :     case OPERATOR_NOT:
    5342              :       mpz_set_ui(val, mpz_cmp_si(uval, 0) == 0 ? 1 : 0);
    5343              :       break;
    5344              : 
    5345         9062 :     case OPERATOR_XOR:
    5346         9062 :       {
    5347         9062 :         Type* utype = unc->type();
    5348        18124 :         if (utype->integer_type() == NULL
    5349         9062 :             || utype->integer_type()->is_abstract())
    5350          124 :           mpz_com(val, uval);
    5351              :         else
    5352              :           {
    5353              :             // The number of HOST_WIDE_INTs that it takes to represent
    5354              :             // UVAL.
    5355         8938 :             size_t count = ((mpz_sizeinbase(uval, 2)
    5356              :                              + HOST_BITS_PER_WIDE_INT
    5357         8938 :                              - 1)
    5358              :                             / HOST_BITS_PER_WIDE_INT);
    5359              : 
    5360         8938 :             unsigned HOST_WIDE_INT* phwi = new unsigned HOST_WIDE_INT[count];
    5361         8938 :             memset(phwi, 0, count * sizeof(HOST_WIDE_INT));
    5362              : 
    5363        17876 :             size_t obits = utype->integer_type()->bits();
    5364              : 
    5365        17876 :             if (!utype->integer_type()->is_unsigned() && mpz_sgn(uval) < 0)
    5366              :               {
    5367            0 :                 mpz_t adj;
    5368            0 :                 mpz_init_set_ui(adj, 1);
    5369            0 :                 mpz_mul_2exp(adj, adj, obits);
    5370            0 :                 mpz_add(uval, uval, adj);
    5371            0 :                 mpz_clear(adj);
    5372              :               }
    5373              : 
    5374         8938 :             size_t ecount;
    5375         8938 :             mpz_export(phwi, &ecount, -1, sizeof(HOST_WIDE_INT), 0, 0, uval);
    5376         8938 :             go_assert(ecount <= count);
    5377              : 
    5378              :             // Trim down to the number of words required by the type.
    5379         8938 :             size_t ocount = ((obits + HOST_BITS_PER_WIDE_INT - 1)
    5380              :                              / HOST_BITS_PER_WIDE_INT);
    5381         8938 :             go_assert(ocount <= count);
    5382              : 
    5383        17876 :             for (size_t i = 0; i < ocount; ++i)
    5384         8938 :               phwi[i] = ~phwi[i];
    5385              : 
    5386         8938 :             size_t clearbits = ocount * HOST_BITS_PER_WIDE_INT - obits;
    5387         8938 :             if (clearbits != 0)
    5388         4176 :               phwi[ocount - 1] &= (((unsigned HOST_WIDE_INT) (HOST_WIDE_INT) -1)
    5389         4176 :                                    >> clearbits);
    5390              : 
    5391         8938 :             mpz_import(val, ocount, -1, sizeof(HOST_WIDE_INT), 0, 0, phwi);
    5392              : 
    5393        17876 :             if (!utype->integer_type()->is_unsigned()
    5394         8938 :                 && mpz_tstbit(val, obits - 1))
    5395              :               {
    5396            7 :                 mpz_t adj;
    5397            7 :                 mpz_init_set_ui(adj, 1);
    5398            7 :                 mpz_mul_2exp(adj, adj, obits);
    5399            7 :                 mpz_sub(val, val, adj);
    5400            7 :                 mpz_clear(adj);
    5401              :               }
    5402              : 
    5403         8938 :             delete[] phwi;
    5404              :           }
    5405              :       }
    5406              :       break;
    5407              : 
    5408            0 :     default:
    5409            0 :       go_unreachable();
    5410              :     }
    5411              : 
    5412        76497 :   if (unc->is_rune())
    5413            0 :     nc->set_rune(NULL, val);
    5414              :   else
    5415        76497 :     nc->set_int(NULL, val);
    5416              : 
    5417        76497 :   mpz_clear(uval);
    5418        76497 :   mpz_clear(val);
    5419              : 
    5420        76497 :   if (!nc->set_type(unc->type(), true, location))
    5421              :     {
    5422            0 :       *issued_error = true;
    5423            0 :       return false;
    5424              :     }
    5425              :   return true;
    5426              : }
    5427              : 
    5428              : // Return the integral constant value of a unary expression, if it has one.
    5429              : 
    5430              : bool
    5431        38877 : Unary_expression::do_numeric_constant_value(Numeric_constant* nc)
    5432              : {
    5433        38877 :   if (this->is_error_expression())
    5434              :     return false;
    5435              : 
    5436        38877 :   Numeric_constant unc;
    5437        38877 :   if (!this->expr_->numeric_constant_value(&unc))
    5438              :     return false;
    5439        17447 :   bool issued_error;
    5440        17447 :   bool r = Unary_expression::eval_constant(this->type_, this->op_, &unc,
    5441              :                                            this->location(), nc,
    5442              :                                            &issued_error);
    5443        17447 :   if (issued_error)
    5444            0 :     this->set_is_error();
    5445              :   return r;
    5446        38877 : }
    5447              : 
    5448              : // Return the boolean constant value of a unary expression, if it has one.
    5449              : 
    5450              : bool
    5451        57888 : Unary_expression::do_boolean_constant_value(bool* val)
    5452              : {
    5453        57888 :   if (this->op_ == OPERATOR_NOT
    5454        57888 :       && this->expr_->boolean_constant_value(val))
    5455              :     {
    5456          295 :       *val = !*val;
    5457          295 :       return true;
    5458              :     }
    5459              :   return false;
    5460              : }
    5461              : 
    5462              : // Return the type of a unary expression.
    5463              : 
    5464              : Type*
    5465     20088562 : Unary_expression::do_type()
    5466              : {
    5467     20088562 :   if (this->type_ == NULL)
    5468              :     {
    5469     19590261 :       switch (this->op_)
    5470              :         {
    5471      3929967 :         case OPERATOR_AND:
    5472      3929967 :           return Type::make_pointer_type(this->expr_->type());
    5473              : 
    5474     15660294 :         case OPERATOR_MULT:
    5475     15660294 :           {
    5476     15660294 :             if (this->expr_->is_type_expression())
    5477        10468 :               return Type::make_pointer_type(this->expr_->type());
    5478              : 
    5479     15649826 :             Type* subtype = this->expr_->type();
    5480     15649826 :             Type* points_to = subtype->points_to();
    5481     15649826 :             if (points_to == NULL)
    5482              :               {
    5483            1 :                 this->report_error(_("expected pointer"));
    5484            1 :                 this->type_ = Type::make_error_type();
    5485            1 :                 return this->type_;
    5486              :               }
    5487              :             return points_to;
    5488              :           }
    5489              : 
    5490            0 :         default:
    5491            0 :           go_assert(saw_errors());
    5492            0 :           return Type::make_error_type();
    5493              :         }
    5494              :     }
    5495              : 
    5496              :   return this->type_;
    5497              : }
    5498              : 
    5499              : // Determine abstract types for a unary expression.
    5500              : 
    5501              : void
    5502      4815751 : Unary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
    5503              : {
    5504      4815751 :   switch (this->op_)
    5505              :     {
    5506       187668 :     case OPERATOR_PLUS:
    5507       187668 :     case OPERATOR_MINUS:
    5508       187668 :     case OPERATOR_NOT:
    5509       187668 :     case OPERATOR_XOR:
    5510       187668 :       {
    5511       187668 :         if (this->type_ != NULL)
    5512        20904 :           return;
    5513              : 
    5514       166764 :         Type* dummy;
    5515       166764 :         Type_context subcontext(*context);
    5516       166764 :         if (this->expr_->is_untyped(&dummy) && this->expr_->is_constant())
    5517              :           {
    5518              :             // We evaluate an untyped operator as untyped.  Then we
    5519              :             // convert it to the desired type.  Otherwise we may, for
    5520              :             // example, give a useless error for one more than the
    5521              :             // most positive integer when it is the operand of a unary
    5522              :             // minus.
    5523        62919 :             subcontext.type = NULL;
    5524        62919 :             subcontext.may_be_abstract = true;
    5525              :           }
    5526       166764 :         this->expr_->determine_type(gogo, &subcontext);
    5527              : 
    5528       166764 :         this->type_ = this->expr_->type();
    5529              : 
    5530              :         // If this is an untyped expression in a typed context, use
    5531              :         // the context type.  If this doesn't work we'll report an
    5532              :         // error later.
    5533       166764 :         if (this->type_->is_abstract()
    5534        63184 :             && !context->may_be_abstract
    5535       220765 :             && context->type != NULL)
    5536              :           {
    5537        53524 :             if (context->type->interface_type() == NULL)
    5538        53296 :               this->type_ = context->type;
    5539              :             else
    5540          228 :               this->type_ = this->type_->make_non_abstract_type();
    5541              :           }
    5542              :       }
    5543       166764 :       break;
    5544              : 
    5545      2929077 :     case OPERATOR_AND:
    5546              :       // Taking the address of something.
    5547      2929077 :       {
    5548      2929077 :         Type* subtype = (context->type == NULL
    5549      2929077 :                          ? NULL
    5550      2629573 :                          : context->type->points_to());
    5551      2929077 :         Type_context subcontext(subtype, false);
    5552      2929077 :         this->expr_->determine_type(gogo, &subcontext);
    5553              :       }
    5554      2929077 :       break;
    5555              : 
    5556      1699006 :     case OPERATOR_MULT:
    5557      1699006 :       {
    5558      1699006 :         if (this->expr_->is_type_expression())
    5559              :           {
    5560         4891 :             this->expr_->determine_type_no_context(gogo);
    5561         4891 :             return;
    5562              :           }
    5563              : 
    5564              :         // Indirecting through a pointer.
    5565      1694115 :         Type* subtype = (context->type == NULL
    5566      1694115 :                          ? NULL
    5567        53160 :                          : Type::make_pointer_type(context->type));
    5568      1694115 :         Type_context subcontext(subtype, false);
    5569      1694115 :         this->expr_->determine_type(gogo, &subcontext);
    5570              :       }
    5571      1694115 :       break;
    5572              : 
    5573            0 :     default:
    5574            0 :       go_unreachable();
    5575              :     }
    5576              : }
    5577              : 
    5578              : // Check types for a unary expression.
    5579              : 
    5580              : void
    5581       322830 : Unary_expression::do_check_types(Gogo*)
    5582              : {
    5583       322830 :   if (this->is_error_expression())
    5584              :     return;
    5585              : 
    5586       322828 :   Type* type = this->expr_->type();
    5587       322828 :   if (type->is_error())
    5588              :     {
    5589            0 :       this->set_is_error();
    5590            0 :       return;
    5591              :     }
    5592              : 
    5593       322828 :   switch (this->op_)
    5594              :     {
    5595        68635 :     case OPERATOR_PLUS:
    5596        68635 :     case OPERATOR_MINUS:
    5597        76490 :       if (type->integer_type() == NULL
    5598          103 :           && type->float_type() == NULL
    5599       322832 :           && type->complex_type() == NULL)
    5600            2 :         this->report_error(_("expected numeric type"));
    5601              :       break;
    5602              : 
    5603        32185 :     case OPERATOR_NOT:
    5604        32185 :       if (!type->is_boolean_type())
    5605            0 :         this->report_error(_("expected boolean type"));
    5606              :       break;
    5607              : 
    5608         2582 :     case OPERATOR_XOR:
    5609         2582 :       if (type->integer_type() == NULL)
    5610            2 :         this->report_error(_("expected integer"));
    5611              :       break;
    5612              : 
    5613       181054 :     case OPERATOR_AND:
    5614       181054 :       if (!this->expr_->is_addressable())
    5615              :         {
    5616         4826 :           if (!this->create_temp_)
    5617              :             {
    5618            1 :               go_error_at(this->location(), "invalid operand for unary %<&%>");
    5619            1 :               this->set_is_error();
    5620              :             }
    5621              :         }
    5622              :       else
    5623       176228 :         this->expr_->issue_nil_check();
    5624              :       break;
    5625              : 
    5626        38372 :     case OPERATOR_MULT:
    5627        38372 :       if (this->expr_->is_type_expression())
    5628              :         break;
    5629              : 
    5630              :       // Catching an invalid indirection of unsafe.Pointer here avoid
    5631              :       // having to deal with TYPE_VOID in other places.
    5632        38209 :       if (this->expr_->type()->is_unsafe_pointer_type())
    5633              :         {
    5634            1 :           go_error_at(this->location(),
    5635              :                       "invalid indirect of %<unsafe.Pointer%>");
    5636            1 :           this->set_is_error();
    5637            1 :           return;
    5638              :         }
    5639              : 
    5640              :       // Indirecting through a pointer.
    5641        38208 :       if (type->points_to() == NULL)
    5642            0 :         this->report_error(_("expected pointer"));
    5643        38208 :       if (type->points_to()->is_error())
    5644            1 :         this->set_is_error();
    5645              :       break;
    5646              : 
    5647            0 :     default:
    5648            0 :       go_unreachable();
    5649              :     }
    5650              : }
    5651              : 
    5652              : // Get the backend representation for a unary expression.
    5653              : 
    5654              : Bexpression*
    5655      3040376 : Unary_expression::do_get_backend(Translate_context* context)
    5656              : {
    5657      3040376 :   Gogo* gogo = context->gogo();
    5658      3040376 :   Location loc = this->location();
    5659              : 
    5660              :   // Taking the address of a set-and-use-temporary expression requires
    5661              :   // setting the temporary and then taking the address.
    5662      3040376 :   if (this->op_ == OPERATOR_AND)
    5663              :     {
    5664      1831097 :       Set_and_use_temporary_expression* sut =
    5665      1831097 :         this->expr_->set_and_use_temporary_expression();
    5666          619 :       if (sut != NULL)
    5667              :         {
    5668          619 :           Temporary_statement* temp = sut->temporary();
    5669          619 :           Bvariable* bvar = temp->get_backend_variable(context);
    5670          619 :           Bexpression* bvar_expr =
    5671          619 :               gogo->backend()->var_expression(bvar, loc);
    5672          619 :           Bexpression* bval = sut->expression()->get_backend(context);
    5673              : 
    5674          619 :           Named_object* fn = context->function();
    5675          619 :           go_assert(fn != NULL);
    5676          619 :           Bfunction* bfn =
    5677          619 :               fn->func_value()->get_or_make_decl(gogo, fn);
    5678          619 :           Bstatement* bassign =
    5679          619 :               gogo->backend()->assignment_statement(bfn, bvar_expr, bval, loc);
    5680          619 :           Bexpression* bvar_addr =
    5681          619 :               gogo->backend()->address_expression(bvar_expr, loc);
    5682          619 :           return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
    5683              :         }
    5684              :     }
    5685              : 
    5686      3039757 :   Bexpression* ret;
    5687      3039757 :   Bexpression* bexpr = this->expr_->get_backend(context);
    5688      3039757 :   Btype* btype = (this->type_ == NULL
    5689      3039757 :                   ? this->expr_->type()->get_backend(gogo)
    5690       102250 :                   : this->type_->get_backend(gogo));
    5691      3039757 :   switch (this->op_)
    5692              :     {
    5693          116 :     case OPERATOR_PLUS:
    5694          116 :       ret = gogo->backend()->convert_expression(btype, bexpr, loc);
    5695          116 :       break;
    5696              : 
    5697        10894 :     case OPERATOR_MINUS:
    5698        10894 :       ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
    5699        10894 :       ret = gogo->backend()->convert_expression(btype, ret, loc);
    5700        10894 :       break;
    5701              : 
    5702        97392 :     case OPERATOR_NOT:
    5703        97392 :     case OPERATOR_XOR:
    5704        97392 :       ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
    5705        97392 :       ret = gogo->backend()->convert_expression(btype, ret, loc);
    5706        97392 :       break;
    5707              : 
    5708      1830478 :     case OPERATOR_AND:
    5709      1830478 :       if (!this->create_temp_)
    5710              :         {
    5711              :           // We should not see a non-constant constructor here; cases
    5712              :           // where we would see one should have been moved onto the
    5713              :           // heap at parse time.  Taking the address of a nonconstant
    5714              :           // constructor will not do what the programmer expects.
    5715              : 
    5716      1795139 :           go_assert(!this->expr_->is_composite_literal()
    5717              :                     || this->expr_->is_static_initializer());
    5718      1795139 :           if (this->expr_->classification() == EXPRESSION_UNARY)
    5719              :             {
    5720         3790 :               Unary_expression* ue =
    5721              :                 static_cast<Unary_expression*>(this->expr_);
    5722         3790 :               go_assert(ue->op() != OPERATOR_AND);
    5723              :             }
    5724              :         }
    5725              : 
    5726      1830478 :       if (this->is_gc_root_ || this->is_slice_init_)
    5727              :         {
    5728       289255 :           std::string var_name;
    5729       289255 :           bool copy_to_heap = false;
    5730       289255 :           if (this->is_gc_root_)
    5731              :             {
    5732              :               // Build a decl for a GC root variable.  GC roots are mutable, so
    5733              :               // they cannot be represented as an immutable_struct in the
    5734              :               // backend.
    5735         2111 :               var_name = gogo->gc_root_name();
    5736              :             }
    5737              :           else
    5738              :             {
    5739              :               // Build a decl for a slice value initializer.  An immutable slice
    5740              :               // value initializer may have to be copied to the heap if it
    5741              :               // contains pointers in a non-constant context.
    5742       287144 :               var_name = gogo->initializer_name();
    5743              : 
    5744       287144 :               Array_type* at = this->expr_->type()->array_type();
    5745            0 :               go_assert(at != NULL);
    5746              : 
    5747              :               // If we are not copying the value to the heap, we will only
    5748              :               // initialize the value once, so we can use this directly
    5749              :               // rather than copying it.  In that case we can't make it
    5750              :               // read-only, because the program is permitted to change it.
    5751       287144 :               copy_to_heap = (context->function() != NULL
    5752       287144 :                               || context->is_const());
    5753              :             }
    5754         2111 :           unsigned int flags = (Backend::variable_is_hidden
    5755              :                                 | Backend::variable_address_is_taken);
    5756         2111 :           if (copy_to_heap)
    5757              :             flags |= Backend::variable_is_constant;
    5758       289255 :           Bvariable* implicit =
    5759       289255 :             gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
    5760       289255 :           gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
    5761              :                                                       flags, bexpr);
    5762       289255 :           bexpr = gogo->backend()->var_expression(implicit, loc);
    5763              : 
    5764              :           // If we are not copying a slice initializer to the heap,
    5765              :           // then it can be changed by the program, so if it can
    5766              :           // contain pointers we must register it as a GC root.
    5767       289255 :           if (this->is_slice_init_
    5768       287144 :               && !copy_to_heap
    5769       298118 :               && this->expr_->type()->has_pointer())
    5770              :             {
    5771         2660 :               Bexpression* root =
    5772         2660 :                   gogo->backend()->var_expression(implicit, loc);
    5773         2660 :               root = gogo->backend()->address_expression(root, loc);
    5774         2660 :               Type* type = Type::make_pointer_type(this->expr_->type());
    5775         2660 :               gogo->add_gc_root(Expression::make_backend(root, type, loc));
    5776              :             }
    5777       289255 :         }
    5778      1541223 :       else if ((this->expr_->is_composite_literal()
    5779      1485772 :                 || this->expr_->string_expression() != NULL)
    5780      2193134 :                && this->expr_->is_static_initializer())
    5781              :         {
    5782       707362 :           std::string var_name(gogo->initializer_name());
    5783       707362 :           unsigned int flags = (Backend::variable_is_hidden
    5784              :                                 | Backend::variable_address_is_taken);
    5785       707362 :           Bvariable* decl =
    5786       707362 :             gogo->backend()->immutable_struct(var_name, "", flags, btype, loc);
    5787       707362 :           gogo->backend()->immutable_struct_set_init(decl, var_name, flags,
    5788              :                                                      btype, loc, bexpr);
    5789       707362 :           bexpr = gogo->backend()->var_expression(decl, loc);
    5790       707362 :         }
    5791       833861 :       else if (this->expr_->is_constant())
    5792              :         {
    5793        14716 :           std::string var_name(gogo->initializer_name());
    5794        14716 :           unsigned int flags = (Backend::variable_is_hidden
    5795              :                                 | Backend::variable_is_constant
    5796              :                                 | Backend::variable_address_is_taken);
    5797        14716 :           Bvariable* decl =
    5798        14716 :             gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
    5799        14716 :           gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
    5800              :                                                       flags, bexpr);
    5801        14716 :           bexpr = gogo->backend()->var_expression(decl, loc);
    5802        14716 :         }
    5803              : 
    5804      1830478 :       go_assert(!this->create_temp_ || this->expr_->is_multi_eval_safe());
    5805      1830478 :       ret = gogo->backend()->address_expression(bexpr, loc);
    5806      1830478 :       break;
    5807              : 
    5808      1100877 :     case OPERATOR_MULT:
    5809      1100877 :       {
    5810      1100877 :         go_assert(this->expr_->type()->points_to() != NULL);
    5811              : 
    5812      1100877 :         Type* ptype = this->expr_->type()->points_to();
    5813      1100877 :         Btype* pbtype = ptype->get_backend(gogo);
    5814      1100877 :         switch (this->requires_nil_check(gogo))
    5815              :           {
    5816              :             case NIL_CHECK_NOT_NEEDED:
    5817              :               break;
    5818            0 :             case NIL_CHECK_ERROR_ENCOUNTERED:
    5819            0 :               {
    5820            0 :                 go_assert(saw_errors());
    5821            0 :                 return gogo->backend()->error_expression();
    5822              :               }
    5823        80150 :             case NIL_CHECK_NEEDED:
    5824        80150 :               {
    5825        80150 :                 go_assert(this->expr_->is_multi_eval_safe());
    5826              : 
    5827              :                 // If we're nil-checking the result of a set-and-use-temporary
    5828              :                 // expression, then pick out the target temp and use that
    5829              :                 // for the final result of the conditional.
    5830        80150 :                 Bexpression* tbexpr = bexpr;
    5831        80150 :                 Bexpression* ubexpr = bexpr;
    5832        80150 :                 Set_and_use_temporary_expression* sut =
    5833        80150 :                     this->expr_->set_and_use_temporary_expression();
    5834            0 :                 if (sut != NULL) {
    5835            0 :                   Temporary_statement* temp = sut->temporary();
    5836            0 :                   Bvariable* bvar = temp->get_backend_variable(context);
    5837            0 :                   ubexpr = gogo->backend()->var_expression(bvar, loc);
    5838              :                 }
    5839        80150 :                 Bexpression* nil =
    5840        80150 :                     Expression::make_nil(loc)->get_backend(context);
    5841        80150 :                 Bexpression* compare =
    5842        80150 :                     gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr,
    5843              :                                                        nil, loc);
    5844        80150 :                 Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM,
    5845              :                                                        loc, 0);
    5846        80150 :                 crash->determine_type_no_context(gogo);
    5847        80150 :                 Bexpression* bcrash = crash->get_backend(context);
    5848        80150 :                 Bfunction* bfn = context->function()->func_value()->get_decl();
    5849        80150 :                 bexpr = gogo->backend()->conditional_expression(bfn, btype,
    5850              :                                                                 compare,
    5851              :                                                                 bcrash, ubexpr,
    5852              :                                                                 loc);
    5853        80150 :                 break;
    5854              :               }
    5855            0 :             case NIL_CHECK_DEFAULT:
    5856            0 :               go_unreachable();
    5857              :           }
    5858      1100877 :         ret = gogo->backend()->indirect_expression(pbtype, bexpr, false, loc);
    5859              :       }
    5860      1100877 :       break;
    5861              : 
    5862            0 :     default:
    5863            0 :       go_unreachable();
    5864              :     }
    5865              : 
    5866              :   return ret;
    5867              : }
    5868              : 
    5869              : // Export a unary expression.
    5870              : 
    5871              : void
    5872         3143 : Unary_expression::do_export(Export_function_body* efb) const
    5873              : {
    5874         3143 :   switch (this->op_)
    5875              :     {
    5876            0 :     case OPERATOR_PLUS:
    5877            0 :       efb->write_c_string("+");
    5878            0 :       break;
    5879          112 :     case OPERATOR_MINUS:
    5880          112 :       efb->write_c_string("-");
    5881          112 :       break;
    5882          304 :     case OPERATOR_NOT:
    5883          304 :       efb->write_c_string("!");
    5884          304 :       break;
    5885           44 :     case OPERATOR_XOR:
    5886           44 :       efb->write_c_string("^");
    5887           44 :       break;
    5888         1003 :     case OPERATOR_AND:
    5889         1003 :       efb->write_c_string("&");
    5890         1003 :       break;
    5891         1680 :     case OPERATOR_MULT:
    5892         1680 :       efb->write_c_string("*");
    5893         1680 :       break;
    5894            0 :     default:
    5895            0 :       go_unreachable();
    5896              :     }
    5897         3143 :   this->expr_->export_expression(efb);
    5898         3143 : }
    5899              : 
    5900              : // Import a unary expression.
    5901              : 
    5902              : Expression*
    5903         9449 : Unary_expression::do_import(Import_expression* imp, Location loc)
    5904              : {
    5905         9449 :   Operator op;
    5906         9449 :   switch (imp->get_char())
    5907              :     {
    5908              :     case '+':
    5909              :       op = OPERATOR_PLUS;
    5910              :       break;
    5911         7704 :     case '-':
    5912         7704 :       op = OPERATOR_MINUS;
    5913         7704 :       break;
    5914          537 :     case '!':
    5915          537 :       op = OPERATOR_NOT;
    5916          537 :       break;
    5917           74 :     case '^':
    5918           74 :       op = OPERATOR_XOR;
    5919           74 :       break;
    5920          640 :     case '&':
    5921          640 :       op = OPERATOR_AND;
    5922          640 :       break;
    5923          494 :     case '*':
    5924          494 :       op = OPERATOR_MULT;
    5925          494 :       break;
    5926            0 :     default:
    5927            0 :       go_unreachable();
    5928              :     }
    5929         9449 :   if (imp->version() < EXPORT_FORMAT_V3)
    5930            0 :     imp->require_c_string(" ");
    5931         9449 :   Expression* expr = Expression::import_expression(imp, loc);
    5932         9449 :   return Expression::make_unary(op, expr, loc);
    5933              : }
    5934              : 
    5935              : // Dump ast representation of an unary expression.
    5936              : 
    5937              : void
    5938            0 : Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    5939              : {
    5940            0 :   ast_dump_context->dump_operator(this->op_);
    5941            0 :   ast_dump_context->ostream() << "(";
    5942            0 :   ast_dump_context->dump_expression(this->expr_);
    5943            0 :   ast_dump_context->ostream() << ") ";
    5944            0 : }
    5945              : 
    5946              : // Make a unary expression.
    5947              : 
    5948              : Expression*
    5949      3785625 : Expression::make_unary(Operator op, Expression* expr, Location location)
    5950              : {
    5951      3785625 :   return new Unary_expression(op, expr, location);
    5952              : }
    5953              : 
    5954              : Expression*
    5955       998873 : Expression::make_dereference(Expression* ptr,
    5956              :                              Nil_check_classification docheck,
    5957              :                              Location location)
    5958              : {
    5959       998873 :   Expression* deref = Expression::make_unary(OPERATOR_MULT, ptr, location);
    5960       998873 :   if (docheck == NIL_CHECK_NEEDED)
    5961        13135 :     deref->unary_expression()->set_requires_nil_check(true);
    5962       985738 :   else if (docheck == NIL_CHECK_NOT_NEEDED)
    5963       434317 :     deref->unary_expression()->set_requires_nil_check(false);
    5964       998873 :   return deref;
    5965              : }
    5966              : 
    5967              : // If this is an indirection through a pointer, return the expression
    5968              : // being pointed through.  Otherwise return this.
    5969              : 
    5970              : Expression*
    5971         9703 : Expression::deref()
    5972              : {
    5973         9703 :   if (this->classification_ == EXPRESSION_UNARY)
    5974              :     {
    5975         4510 :       Unary_expression* ue = static_cast<Unary_expression*>(this);
    5976         4510 :       if (ue->op() == OPERATOR_MULT)
    5977         4510 :         return ue->operand();
    5978              :     }
    5979              :   return this;
    5980              : }
    5981              : 
    5982              : // Class Binary_expression.
    5983              : 
    5984              : // Traversal.
    5985              : 
    5986              : int
    5987     13844198 : Binary_expression::do_traverse(Traverse* traverse)
    5988              : {
    5989     13844198 :   int t = Expression::traverse(&this->left_, traverse);
    5990     13844198 :   if (t == TRAVERSE_EXIT)
    5991              :     return TRAVERSE_EXIT;
    5992     13462706 :   return Expression::traverse(&this->right_, traverse);
    5993              : }
    5994              : 
    5995              : // Return whether a binary expression is untyped.
    5996              : 
    5997              : bool
    5998    103762724 : Binary_expression::do_is_untyped(Type** ptype) const
    5999              : {
    6000    103762724 :   if (this->type_ != NULL)
    6001        13270 :     return Expression::is_untyped_type(this->type_, ptype);
    6002              : 
    6003    103749454 :   switch (this->op_)
    6004              :     {
    6005       670841 :     case OPERATOR_EQEQ:
    6006       670841 :     case OPERATOR_NOTEQ:
    6007       670841 :     case OPERATOR_LT:
    6008       670841 :     case OPERATOR_LE:
    6009       670841 :     case OPERATOR_GT:
    6010       670841 :     case OPERATOR_GE:
    6011              :       // Comparisons are untyped by default.
    6012       670841 :       *ptype = Type::make_boolean_type();
    6013       670841 :       return true;
    6014              : 
    6015       205429 :     case OPERATOR_LSHIFT:
    6016       205429 :     case OPERATOR_RSHIFT:
    6017              :       // A shift operation is untyped if the left hand expression is
    6018              :       // untyped.  The right hand expression is irrelevant.
    6019       205429 :       return this->left_->is_untyped(ptype);
    6020              : 
    6021    102873184 :     default:
    6022    102873184 :       break;
    6023              :     }
    6024              : 
    6025    102873184 :   Type* tleft;
    6026    102873184 :   Type* tright;
    6027    102873184 :   if (!this->left_->is_untyped(&tleft)
    6028    102873184 :       || !this->right_->is_untyped(&tright))
    6029       114848 :     return false;
    6030              : 
    6031              :   // If both sides are numeric, pick a type based on the kind.
    6032    102758336 :   enum kind { INT, RUNE, FLOAT, COMPLEX };
    6033    102758336 :   enum kind kleft, kright;
    6034              : 
    6035    102758336 :   if (tleft->integer_type() != NULL)
    6036        35030 :     kleft = tleft->integer_type()->is_rune() ? RUNE : INT;
    6037    102740821 :   else if (tleft->float_type() != NULL)
    6038              :     kleft = FLOAT;
    6039    102758337 :   else if (tleft->complex_type() != NULL)
    6040              :     kleft = COMPLEX;
    6041              :   else
    6042              :     {
    6043              :       // Not numeric.  If the types are different, we will report an
    6044              :       // error later.
    6045    102740473 :       *ptype = tleft;
    6046    102740473 :       return true;
    6047              :     }
    6048              : 
    6049        17863 :   if (tright->integer_type() != NULL)
    6050        34622 :     kright = tright->integer_type()->is_rune() ? RUNE : INT;
    6051          552 :   else if (tright->float_type() != NULL)
    6052              :     kright = FLOAT;
    6053        17925 :   else if (tright->complex_type() != NULL)
    6054              :     kright = COMPLEX;
    6055              :   else
    6056              :     {
    6057              :       // Types are different.  We will report an error later.
    6058            0 :       *ptype = tleft;
    6059            0 :       return true;
    6060              :     }
    6061              : 
    6062        17863 :   if (kleft > kright)
    6063          303 :     *ptype = tleft;
    6064              :   else
    6065        17560 :     *ptype = tright;
    6066              : 
    6067              :   return true;
    6068              : }
    6069              : 
    6070              : // Return whether this expression may be used as a static initializer.
    6071              : 
    6072              : bool
    6073       473455 : Binary_expression::do_is_static_initializer() const
    6074              : {
    6075       473455 :   if (!this->left_->is_static_initializer()
    6076       473455 :       || !this->right_->is_static_initializer())
    6077          351 :     return false;
    6078              : 
    6079              :   // Addresses can be static initializers, but we can't implement
    6080              :   // arbitray binary expressions of them.
    6081       473104 :   Unary_expression* lu = this->left_->unary_expression();
    6082       473104 :   Unary_expression* ru = this->right_->unary_expression();
    6083       473104 :   if (lu != NULL && lu->op() == OPERATOR_AND)
    6084              :     {
    6085            0 :       if (ru != NULL && ru->op() == OPERATOR_AND)
    6086            0 :         return this->op_ == OPERATOR_MINUS;
    6087              :       else
    6088            0 :         return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
    6089              :     }
    6090       473104 :   else if (ru != NULL && ru->op() == OPERATOR_AND)
    6091            0 :     return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
    6092              : 
    6093              :   // Other cases should resolve in the backend.
    6094              :   return true;
    6095              : }
    6096              : 
    6097              : // Return the type to use for a binary operation on operands of
    6098              : // LEFT_TYPE and RIGHT_TYPE.  These are the types of constants and as
    6099              : // such may be NULL or abstract.
    6100              : 
    6101              : bool
    6102      1303987 : Binary_expression::operation_type(Operator op, Type* left_type,
    6103              :                                   Type* right_type, Type** result_type)
    6104              : {
    6105      1303987 :   if (left_type != right_type
    6106       185638 :       && !left_type->is_abstract()
    6107        81373 :       && !right_type->is_abstract()
    6108        81090 :       && left_type->base() != right_type->base()
    6109              :       && op != OPERATOR_LSHIFT
    6110      1310631 :       && op != OPERATOR_RSHIFT)
    6111              :     {
    6112              :       // May be a type error--let it be diagnosed elsewhere.
    6113              :       return false;
    6114              :     }
    6115              : 
    6116      1303976 :   if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
    6117              :     {
    6118       110800 :       if (left_type->integer_type() != NULL)
    6119       110791 :         *result_type = left_type;
    6120              :       else
    6121            9 :         *result_type = Type::make_abstract_integer_type();
    6122              :     }
    6123      1193176 :   else if (!left_type->is_abstract() && left_type->named_type() != NULL)
    6124       912031 :     *result_type = left_type;
    6125       281145 :   else if (!right_type->is_abstract() && right_type->named_type() != NULL)
    6126          306 :     *result_type = right_type;
    6127       280839 :   else if (!left_type->is_abstract())
    6128            0 :     *result_type = left_type;
    6129       280839 :   else if (!right_type->is_abstract())
    6130            0 :     *result_type = right_type;
    6131       280839 :   else if (left_type->complex_type() != NULL)
    6132         1431 :     *result_type = left_type;
    6133       279408 :   else if (right_type->complex_type() != NULL)
    6134          400 :     *result_type = right_type;
    6135       279008 :   else if (left_type->float_type() != NULL)
    6136         2613 :     *result_type = left_type;
    6137       276395 :   else if (right_type->float_type() != NULL)
    6138          148 :     *result_type = right_type;
    6139       463386 :   else if (left_type->integer_type() != NULL
    6140       187139 :            && left_type->integer_type()->is_rune())
    6141         2104 :     *result_type = left_type;
    6142       459178 :   else if (right_type->integer_type() != NULL
    6143       185035 :            && right_type->integer_type()->is_rune())
    6144           65 :     *result_type = right_type;
    6145              :   else
    6146       274078 :     *result_type = left_type;
    6147              : 
    6148              :   return true;
    6149              : }
    6150              : 
    6151              : // Convert an integer comparison code and an operator to a boolean
    6152              : // value.
    6153              : 
    6154              : bool
    6155         2996 : Binary_expression::cmp_to_bool(Operator op, int cmp)
    6156              : {
    6157         2996 :   switch (op)
    6158              :     {
    6159         2268 :     case OPERATOR_EQEQ:
    6160         2268 :       return cmp == 0;
    6161          696 :       break;
    6162          696 :     case OPERATOR_NOTEQ:
    6163          696 :       return cmp != 0;
    6164           14 :       break;
    6165           14 :     case OPERATOR_LT:
    6166           14 :       return cmp < 0;
    6167            0 :       break;
    6168            0 :     case OPERATOR_LE:
    6169            0 :       return cmp <= 0;
    6170            8 :     case OPERATOR_GT:
    6171            8 :       return cmp > 0;
    6172           10 :     case OPERATOR_GE:
    6173           10 :       return cmp >= 0;
    6174            0 :     default:
    6175            0 :       go_unreachable();
    6176              :     }
    6177              : }
    6178              : 
    6179              : // Compare constants according to OP.
    6180              : 
    6181              : bool
    6182          936 : Binary_expression::compare_constant(Operator op, Numeric_constant* left_nc,
    6183              :                                     Numeric_constant* right_nc,
    6184              :                                     Location location, bool* result)
    6185              : {
    6186          936 :   Type* left_type = left_nc->type();
    6187          936 :   Type* right_type = right_nc->type();
    6188              : 
    6189          936 :   Type* type;
    6190          936 :   if (!Binary_expression::operation_type(op, left_type, right_type, &type))
    6191              :     return false;
    6192              : 
    6193              :   // When comparing an untyped operand to a typed operand, we are
    6194              :   // effectively coercing the untyped operand to the other operand's
    6195              :   // type, so make sure that is valid.
    6196          936 :   if (!left_nc->set_type(type, true, location)
    6197          936 :       || !right_nc->set_type(type, true, location))
    6198            0 :     return false;
    6199              : 
    6200          936 :   bool ret;
    6201          936 :   int cmp;
    6202          936 :   if (type->complex_type() != NULL)
    6203              :     {
    6204            7 :       if (op != OPERATOR_EQEQ && op != OPERATOR_NOTEQ)
    6205              :         return false;
    6206            7 :       ret = Binary_expression::compare_complex(left_nc, right_nc, &cmp);
    6207              :     }
    6208          929 :   else if (type->float_type() != NULL)
    6209           28 :     ret = Binary_expression::compare_float(left_nc, right_nc, &cmp);
    6210              :   else
    6211          901 :     ret = Binary_expression::compare_integer(left_nc, right_nc, &cmp);
    6212              : 
    6213          936 :   if (ret)
    6214          936 :     *result = Binary_expression::cmp_to_bool(op, cmp);
    6215              : 
    6216              :   return ret;
    6217              : }
    6218              : 
    6219              : // Compare integer constants.
    6220              : 
    6221              : bool
    6222          901 : Binary_expression::compare_integer(const Numeric_constant* left_nc,
    6223              :                                    const Numeric_constant* right_nc,
    6224              :                                    int* cmp)
    6225              : {
    6226          901 :   mpz_t left_val;
    6227          901 :   if (!left_nc->to_int(&left_val))
    6228              :     return false;
    6229          901 :   mpz_t right_val;
    6230          901 :   if (!right_nc->to_int(&right_val))
    6231              :     {
    6232            0 :       mpz_clear(left_val);
    6233            0 :       return false;
    6234              :     }
    6235              : 
    6236          901 :   *cmp = mpz_cmp(left_val, right_val);
    6237              : 
    6238          901 :   mpz_clear(left_val);
    6239          901 :   mpz_clear(right_val);
    6240              : 
    6241          901 :   return true;
    6242              : }
    6243              : 
    6244              : // Compare floating point constants.
    6245              : 
    6246              : bool
    6247           28 : Binary_expression::compare_float(const Numeric_constant* left_nc,
    6248              :                                  const Numeric_constant* right_nc,
    6249              :                                  int* cmp)
    6250              : {
    6251           28 :   mpfr_t left_val;
    6252           28 :   if (!left_nc->to_float(&left_val))
    6253              :     return false;
    6254           28 :   mpfr_t right_val;
    6255           28 :   if (!right_nc->to_float(&right_val))
    6256              :     {
    6257            0 :       mpfr_clear(left_val);
    6258            0 :       return false;
    6259              :     }
    6260              : 
    6261              :   // We already coerced both operands to the same type.  If that type
    6262              :   // is not an abstract type, we need to round the values accordingly.
    6263           28 :   Type* type = left_nc->type();
    6264           28 :   if (!type->is_abstract() && type->float_type() != NULL)
    6265              :     {
    6266           30 :       int bits = type->float_type()->bits();
    6267           15 :       mpfr_prec_round(left_val, bits, MPFR_RNDN);
    6268           15 :       mpfr_prec_round(right_val, bits, MPFR_RNDN);
    6269              :     }
    6270              : 
    6271           28 :   *cmp = mpfr_cmp(left_val, right_val);
    6272              : 
    6273           28 :   mpfr_clear(left_val);
    6274           28 :   mpfr_clear(right_val);
    6275              : 
    6276           28 :   return true;
    6277              : }
    6278              : 
    6279              : // Compare complex constants.  Complex numbers may only be compared
    6280              : // for equality.
    6281              : 
    6282              : bool
    6283            7 : Binary_expression::compare_complex(const Numeric_constant* left_nc,
    6284              :                                    const Numeric_constant* right_nc,
    6285              :                                    int* cmp)
    6286              : {
    6287            7 :   mpc_t left_val;
    6288            7 :   if (!left_nc->to_complex(&left_val))
    6289              :     return false;
    6290            7 :   mpc_t right_val;
    6291            7 :   if (!right_nc->to_complex(&right_val))
    6292              :     {
    6293            0 :       mpc_clear(left_val);
    6294            0 :       return false;
    6295              :     }
    6296              : 
    6297              :   // We already coerced both operands to the same type.  If that type
    6298              :   // is not an abstract type, we need to round the values accordingly.
    6299            7 :   Type* type = left_nc->type();
    6300            7 :   if (!type->is_abstract() && type->complex_type() != NULL)
    6301              :     {
    6302            4 :       int bits = type->complex_type()->bits();
    6303            2 :       mpfr_prec_round(mpc_realref(left_val), bits / 2, MPFR_RNDN);
    6304            2 :       mpfr_prec_round(mpc_imagref(left_val), bits / 2, MPFR_RNDN);
    6305            2 :       mpfr_prec_round(mpc_realref(right_val), bits / 2, MPFR_RNDN);
    6306            2 :       mpfr_prec_round(mpc_imagref(right_val), bits / 2, MPFR_RNDN);
    6307              :     }
    6308              : 
    6309            7 :   *cmp = mpc_cmp(left_val, right_val) != 0;
    6310              : 
    6311            7 :   mpc_clear(left_val);
    6312            7 :   mpc_clear(right_val);
    6313              : 
    6314            7 :   return true;
    6315              : }
    6316              : 
    6317              : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC.  Return
    6318              : // true if this could be done, false if not.  Issue errors at LOCATION
    6319              : // as appropriate, and sets *ISSUED_ERROR if it did.
    6320              : 
    6321              : bool
    6322       293931 : Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
    6323              :                                  Numeric_constant* right_nc,
    6324              :                                  Location location, Numeric_constant* nc,
    6325              :                                  bool* issued_error)
    6326              : {
    6327       293931 :   *issued_error = false;
    6328       293931 :   switch (op)
    6329              :     {
    6330              :     case OPERATOR_OROR:
    6331              :     case OPERATOR_ANDAND:
    6332              :     case OPERATOR_EQEQ:
    6333              :     case OPERATOR_NOTEQ:
    6334              :     case OPERATOR_LT:
    6335              :     case OPERATOR_LE:
    6336              :     case OPERATOR_GT:
    6337              :     case OPERATOR_GE:
    6338              :       // These return boolean values, not numeric.
    6339              :       return false;
    6340       293931 :     default:
    6341       293931 :       break;
    6342              :     }
    6343              : 
    6344       293931 :   Type* left_type = left_nc->type();
    6345       293931 :   Type* right_type = right_nc->type();
    6346              : 
    6347       293931 :   Type* type;
    6348       293931 :   if (!Binary_expression::operation_type(op, left_type, right_type, &type))
    6349              :     return false;
    6350              : 
    6351       293931 :   bool is_shift = op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT;
    6352              : 
    6353              :   // When combining an untyped operand with a typed operand, we are
    6354              :   // effectively coercing the untyped operand to the other operand's
    6355              :   // type, so make sure that is valid.
    6356       293931 :   if (!left_nc->set_type(type, true, location))
    6357              :     return false;
    6358       293931 :   if (!is_shift && !right_nc->set_type(type, true, location))
    6359              :     return false;
    6360       293931 :   if (is_shift
    6361       293931 :       && right_type->integer_type() == NULL
    6362       293931 :       && !right_type->is_abstract())
    6363              :     return false;
    6364              : 
    6365       293931 :   bool r;
    6366       293931 :   if (type->complex_type() != NULL)
    6367         1017 :     r = Binary_expression::eval_complex(op, left_nc, right_nc, location, nc,
    6368              :                                         issued_error);
    6369       292914 :   else if (type->float_type() != NULL)
    6370         1832 :     r = Binary_expression::eval_float(op, left_nc, right_nc, location, nc,
    6371              :                                       issued_error);
    6372              :   else
    6373       291082 :     r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc,
    6374              :                                         issued_error);
    6375              : 
    6376       293931 :   if (r)
    6377              :     {
    6378       293931 :       r = nc->set_type(type, true, location);
    6379       293931 :       if (!r)
    6380           12 :         *issued_error = true;
    6381              :     }
    6382              : 
    6383              :   return r;
    6384              : }
    6385              : 
    6386              : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
    6387              : // integer operations.  Return true if this could be done, false if
    6388              : // not.
    6389              : 
    6390              : bool
    6391       291082 : Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
    6392              :                                 const Numeric_constant* right_nc,
    6393              :                                 Location location, Numeric_constant* nc,
    6394              :                                 bool* issued_error)
    6395              : {
    6396       291082 :   mpz_t left_val;
    6397       291082 :   if (!left_nc->to_int(&left_val))
    6398              :     return false;
    6399       291082 :   mpz_t right_val;
    6400       291082 :   if (!right_nc->to_int(&right_val))
    6401              :     {
    6402            0 :       mpz_clear(left_val);
    6403            0 :       return false;
    6404              :     }
    6405              : 
    6406       291082 :   mpz_t val;
    6407       291082 :   mpz_init(val);
    6408              : 
    6409       291082 :   switch (op)
    6410              :     {
    6411        37520 :     case OPERATOR_PLUS:
    6412        37520 :       mpz_add(val, left_val, right_val);
    6413        37520 :       if (mpz_sizeinbase(val, 2) > 0x100000)
    6414              :         {
    6415            0 :           go_error_at(location, "constant addition overflow");
    6416            0 :           nc->set_invalid();
    6417            0 :           mpz_set_ui(val, 1);
    6418            0 :           *issued_error = true;
    6419              :         }
    6420              :       break;
    6421        27168 :     case OPERATOR_MINUS:
    6422        27168 :       mpz_sub(val, left_val, right_val);
    6423        27168 :       if (mpz_sizeinbase(val, 2) > 0x100000)
    6424              :         {
    6425            0 :           go_error_at(location, "constant subtraction overflow");
    6426            0 :           nc->set_invalid();
    6427            0 :           mpz_set_ui(val, 1);
    6428            0 :           *issued_error = true;
    6429              :         }
    6430              :       break;
    6431         6898 :     case OPERATOR_OR:
    6432         6898 :       mpz_ior(val, left_val, right_val);
    6433         6898 :       break;
    6434           22 :     case OPERATOR_XOR:
    6435           22 :       mpz_xor(val, left_val, right_val);
    6436           22 :       break;
    6437        95431 :     case OPERATOR_MULT:
    6438        95431 :       mpz_mul(val, left_val, right_val);
    6439        95431 :       if (mpz_sizeinbase(val, 2) > 0x100000)
    6440              :         {
    6441            1 :           go_error_at(location, "constant multiplication overflow");
    6442            1 :           nc->set_invalid();
    6443            1 :           mpz_set_ui(val, 1);
    6444            1 :           *issued_error = true;
    6445              :         }
    6446              :       break;
    6447        12095 :     case OPERATOR_DIV:
    6448        12095 :       if (mpz_sgn(right_val) != 0)
    6449        12095 :         mpz_tdiv_q(val, left_val, right_val);
    6450              :       else
    6451              :         {
    6452            0 :           go_error_at(location, "division by zero");
    6453            0 :           nc->set_invalid();
    6454            0 :           mpz_set_ui(val, 0);
    6455            0 :           *issued_error = true;
    6456              :         }
    6457              :       break;
    6458          118 :     case OPERATOR_MOD:
    6459          118 :       if (mpz_sgn(right_val) != 0)
    6460          118 :         mpz_tdiv_r(val, left_val, right_val);
    6461              :       else
    6462              :         {
    6463            0 :           go_error_at(location, "division by zero");
    6464            0 :           nc->set_invalid();
    6465            0 :           mpz_set_ui(val, 0);
    6466            0 :           *issued_error = true;
    6467              :         }
    6468              :       break;
    6469       103231 :     case OPERATOR_LSHIFT:
    6470       103231 :       {
    6471       103231 :         unsigned long shift = mpz_get_ui(right_val);
    6472       103231 :         if (mpz_cmp_ui(right_val, shift) == 0 && shift <= 0x100000)
    6473       103231 :           mpz_mul_2exp(val, left_val, shift);
    6474              :         else
    6475              :           {
    6476            0 :             go_error_at(location, "shift count overflow");
    6477            0 :             nc->set_invalid();
    6478            0 :             mpz_set_ui(val, 1);
    6479            0 :             *issued_error = true;
    6480              :           }
    6481              :         break;
    6482              :       }
    6483              :       break;
    6484         7569 :     case OPERATOR_RSHIFT:
    6485         7569 :       {
    6486         7569 :         unsigned long shift = mpz_get_ui(right_val);
    6487         7569 :         if (mpz_cmp_ui(right_val, shift) != 0)
    6488              :           {
    6489            0 :             go_error_at(location, "shift count overflow");
    6490            0 :             nc->set_invalid();
    6491            0 :             mpz_set_ui(val, 1);
    6492            0 :             *issued_error = true;
    6493              :           }
    6494              :         else
    6495              :           {
    6496         7569 :             if (mpz_cmp_ui(left_val, 0) >= 0)
    6497         7557 :               mpz_tdiv_q_2exp(val, left_val, shift);
    6498              :             else
    6499           12 :               mpz_fdiv_q_2exp(val, left_val, shift);
    6500              :           }
    6501              :         break;
    6502              :       }
    6503              :       break;
    6504          964 :     case OPERATOR_AND:
    6505          964 :       mpz_and(val, left_val, right_val);
    6506          964 :       break;
    6507           66 :     case OPERATOR_BITCLEAR:
    6508           66 :       {
    6509           66 :         mpz_t tval;
    6510           66 :         mpz_init(tval);
    6511           66 :         mpz_com(tval, right_val);
    6512           66 :         mpz_and(val, left_val, tval);
    6513           66 :         mpz_clear(tval);
    6514              :       }
    6515           66 :       break;
    6516            0 :     default:
    6517            0 :       go_unreachable();
    6518              :     }
    6519              : 
    6520       291082 :   mpz_clear(left_val);
    6521       291082 :   mpz_clear(right_val);
    6522              : 
    6523       291082 :   if (left_nc->is_rune()
    6524       291082 :       || (op != OPERATOR_LSHIFT
    6525       289428 :           && op != OPERATOR_RSHIFT
    6526       178630 :           && right_nc->is_rune()))
    6527         1703 :     nc->set_rune(NULL, val);
    6528              :   else
    6529       289379 :     nc->set_int(NULL, val);
    6530              : 
    6531       291082 :   mpz_clear(val);
    6532              : 
    6533       291082 :   return true;
    6534              : }
    6535              : 
    6536              : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
    6537              : // floating point operations.  Return true if this could be done,
    6538              : // false if not.
    6539              : 
    6540              : bool
    6541         1832 : Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
    6542              :                               const Numeric_constant* right_nc,
    6543              :                               Location location, Numeric_constant* nc,
    6544              :                               bool* issued_error)
    6545              : {
    6546         1832 :   mpfr_t left_val;
    6547         1832 :   if (!left_nc->to_float(&left_val))
    6548              :     return false;
    6549         1832 :   mpfr_t right_val;
    6550         1832 :   if (!right_nc->to_float(&right_val))
    6551              :     {
    6552            0 :       mpfr_clear(left_val);
    6553            0 :       return false;
    6554              :     }
    6555              : 
    6556         1832 :   mpfr_t val;
    6557         1832 :   mpfr_init(val);
    6558              : 
    6559         1832 :   bool ret = true;
    6560         1832 :   switch (op)
    6561              :     {
    6562          261 :     case OPERATOR_PLUS:
    6563          261 :       mpfr_add(val, left_val, right_val, MPFR_RNDN);
    6564          261 :       break;
    6565          179 :     case OPERATOR_MINUS:
    6566          179 :       mpfr_sub(val, left_val, right_val, MPFR_RNDN);
    6567          179 :       break;
    6568            0 :     case OPERATOR_OR:
    6569            0 :     case OPERATOR_XOR:
    6570            0 :     case OPERATOR_AND:
    6571            0 :     case OPERATOR_BITCLEAR:
    6572            0 :     case OPERATOR_MOD:
    6573            0 :     case OPERATOR_LSHIFT:
    6574            0 :     case OPERATOR_RSHIFT:
    6575            0 :       mpfr_set_ui(val, 0, MPFR_RNDN);
    6576            0 :       ret = false;
    6577            0 :       break;
    6578          480 :     case OPERATOR_MULT:
    6579          480 :       mpfr_mul(val, left_val, right_val, MPFR_RNDN);
    6580          480 :       break;
    6581          912 :     case OPERATOR_DIV:
    6582          912 :       if (!mpfr_zero_p(right_val))
    6583          911 :         mpfr_div(val, left_val, right_val, MPFR_RNDN);
    6584              :       else
    6585              :         {
    6586            1 :           go_error_at(location, "division by zero");
    6587            1 :           nc->set_invalid();
    6588            1 :           mpfr_set_ui(val, 0, MPFR_RNDN);
    6589            1 :           *issued_error = true;
    6590              :         }
    6591              :       break;
    6592            0 :     default:
    6593            0 :       go_unreachable();
    6594              :     }
    6595              : 
    6596         1832 :   mpfr_clear(left_val);
    6597         1832 :   mpfr_clear(right_val);
    6598              : 
    6599         1832 :   nc->set_float(NULL, val);
    6600         1832 :   mpfr_clear(val);
    6601              : 
    6602         1832 :   return ret;
    6603              : }
    6604              : 
    6605              : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
    6606              : // complex operations.  Return true if this could be done, false if
    6607              : // not.
    6608              : 
    6609              : bool
    6610         1017 : Binary_expression::eval_complex(Operator op, const Numeric_constant* left_nc,
    6611              :                                 const Numeric_constant* right_nc,
    6612              :                                 Location location, Numeric_constant* nc,
    6613              :                                 bool* issued_error)
    6614              : {
    6615         1017 :   mpc_t left_val;
    6616         1017 :   if (!left_nc->to_complex(&left_val))
    6617              :     return false;
    6618         1017 :   mpc_t right_val;
    6619         1017 :   if (!right_nc->to_complex(&right_val))
    6620              :     {
    6621            0 :       mpc_clear(left_val);
    6622            0 :       return false;
    6623              :     }
    6624              : 
    6625         1017 :   mpc_t val;
    6626         1017 :   mpc_init2(val, mpc_precision);
    6627              : 
    6628         1017 :   bool ret = true;
    6629         1017 :   switch (op)
    6630              :     {
    6631          702 :     case OPERATOR_PLUS:
    6632          702 :       mpc_add(val, left_val, right_val, MPC_RNDNN);
    6633          702 :       break;
    6634          266 :     case OPERATOR_MINUS:
    6635          266 :       mpc_sub(val, left_val, right_val, MPC_RNDNN);
    6636          266 :       break;
    6637            0 :     case OPERATOR_OR:
    6638            0 :     case OPERATOR_XOR:
    6639            0 :     case OPERATOR_AND:
    6640            0 :     case OPERATOR_BITCLEAR:
    6641            0 :     case OPERATOR_MOD:
    6642            0 :     case OPERATOR_LSHIFT:
    6643            0 :     case OPERATOR_RSHIFT:
    6644            0 :       mpc_set_ui(val, 0, MPC_RNDNN);
    6645            0 :       ret = false;
    6646            0 :       break;
    6647           13 :     case OPERATOR_MULT:
    6648           13 :       mpc_mul(val, left_val, right_val, MPC_RNDNN);
    6649           13 :       break;
    6650           36 :     case OPERATOR_DIV:
    6651           36 :       if (mpc_cmp_si(right_val, 0) == 0)
    6652              :         {
    6653            5 :           go_error_at(location, "division by zero");
    6654            5 :           nc->set_invalid();
    6655            5 :           mpc_set_ui(val, 0, MPC_RNDNN);
    6656            5 :           *issued_error = true;
    6657            5 :           break;
    6658              :         }
    6659           31 :       mpc_div(val, left_val, right_val, MPC_RNDNN);
    6660           31 :       break;
    6661            0 :     default:
    6662            0 :       go_unreachable();
    6663              :     }
    6664              : 
    6665         1017 :   mpc_clear(left_val);
    6666         1017 :   mpc_clear(right_val);
    6667              : 
    6668         1017 :   nc->set_complex(NULL, val);
    6669         1017 :   mpc_clear(val);
    6670              : 
    6671         1017 :   return ret;
    6672              : }
    6673              : 
    6674              : // Lower a binary expression.  We have to evaluate constant
    6675              : // expressions now, in order to implement Go's unlimited precision
    6676              : // constants.
    6677              : 
    6678              : Expression*
    6679      1496442 : Binary_expression::do_lower(Gogo* gogo, Named_object*,
    6680              :                             Statement_inserter* inserter)
    6681              : {
    6682      1496442 :   Location location = this->location();
    6683              : 
    6684      1496442 :   if (this->is_error_expression())
    6685          360 :     return Expression::make_error(location);
    6686              : 
    6687      1496082 :   Operator op = this->op_;
    6688      1496082 :   Expression* left = this->left_;
    6689      1496082 :   Expression* right = this->right_;
    6690              : 
    6691      1496082 :   if (left->is_error_expression() || right->is_error_expression())
    6692          186 :     return Expression::make_error(location);
    6693              : 
    6694      1495896 :   const bool is_comparison = (op == OPERATOR_EQEQ
    6695              :                               || op == OPERATOR_NOTEQ
    6696              :                               || op == OPERATOR_LT
    6697              :                               || op == OPERATOR_LE
    6698              :                               || op == OPERATOR_GT
    6699      1495896 :                               || op == OPERATOR_GE);
    6700              : 
    6701              :   // Numeric constant expressions.
    6702      1495896 :   {
    6703      1495896 :     Numeric_constant left_nc;
    6704      1495896 :     Numeric_constant right_nc;
    6705      1495896 :     if (left->numeric_constant_value(&left_nc)
    6706      1573131 :         && right->numeric_constant_value(&right_nc))
    6707              :       {
    6708        42654 :         Expression* ret;
    6709        42654 :         if (is_comparison)
    6710              :           {
    6711          936 :             bool result;
    6712          936 :             if (!Binary_expression::compare_constant(op, &left_nc,
    6713              :                                                      &right_nc, location,
    6714              :                                                      &result))
    6715            0 :               return this;
    6716          936 :             ret = Expression::make_boolean(result, location);
    6717              :           }
    6718              :         else
    6719              :           {
    6720        41718 :             Numeric_constant nc;
    6721        41718 :             bool issued_error;
    6722        41718 :             if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
    6723              :                                                   location, &nc,
    6724              :                                                   &issued_error))
    6725              :               {
    6726           12 :                 if (issued_error)
    6727           12 :                   return Expression::make_error(location);
    6728            0 :                 return this;
    6729              :               }
    6730        41706 :             ret = nc.expression(location);
    6731        41718 :           }
    6732              : 
    6733        42642 :         Type_context subcontext(this->type_, this->type_->is_abstract());
    6734        42642 :         ret->determine_type(gogo, &subcontext);
    6735        42642 :         ret->check_types(gogo);
    6736        42642 :         return ret;
    6737              :       }
    6738      1495896 :   }
    6739              : 
    6740              :   // String constant expressions.
    6741              :   //
    6742              :   // Avoid constant folding here if the left and right types are incompatible
    6743              :   // (leave the operation intact so that the type checker can complain about it
    6744              :   // later on). If concatenating an abstract string with a named string type,
    6745              :   // result type needs to be of the named type (see issue 31412).
    6746      1453242 :   if (left->type()->is_string_type()
    6747       131954 :       && right->type()->is_string_type()
    6748      1585188 :       && (left->type()->named_type() == NULL
    6749        93524 :           || right->type()->named_type() == NULL
    6750        93524 :           || left->type()->named_type() == right->type()->named_type()))
    6751              :     {
    6752       131946 :       std::string left_string;
    6753       131946 :       std::string right_string;
    6754       131946 :       if (left->string_constant_value(&left_string)
    6755       178147 :           && right->string_constant_value(&right_string))
    6756              :         {
    6757        40346 :           Expression* ret = NULL;
    6758        40346 :           if (op == OPERATOR_PLUS)
    6759              :             {
    6760        38286 :               delete left;
    6761        38286 :               delete right;
    6762        38286 :               ret = Expression::make_string_typed(left_string + right_string,
    6763              :                                                   this->type_, location);
    6764              :             }
    6765         2060 :           else if (is_comparison)
    6766              :             {
    6767         2060 :               int cmp = left_string.compare(right_string);
    6768         2060 :               bool r = Binary_expression::cmp_to_bool(op, cmp);
    6769         2060 :               delete left;
    6770         2060 :               delete right;
    6771         2060 :               ret = Expression::make_boolean(r, location);
    6772              :             }
    6773              : 
    6774        40346 :           if (ret != NULL)
    6775              :             {
    6776        40346 :               Type_context subcontext(this->type_, this->type_->is_abstract());
    6777        40346 :               ret->determine_type(gogo, &subcontext);
    6778        40346 :               ret->check_types(gogo);
    6779        40346 :               return ret;
    6780              :             }
    6781              :         }
    6782       131946 :     }
    6783              : 
    6784              :   // Lower struct, array, and some interface comparisons.
    6785      1412896 :   if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
    6786              :     {
    6787       493638 :       if (left->type()->struct_type() != NULL
    6788         8053 :           && right->type()->struct_type() != NULL)
    6789         8038 :         return this->lower_struct_comparison(gogo, inserter);
    6790       491926 :       else if (left->type()->array_type() != NULL
    6791        14379 :                && !left->type()->is_slice_type()
    6792        17804 :                && right->type()->array_type() != NULL
    6793         8895 :                && !right->type()->is_slice_type())
    6794         8895 :         return this->lower_array_comparison(gogo, inserter);
    6795       557939 :       else if ((left->type()->interface_type() != NULL
    6796       479082 :                 && right->type()->interface_type() == NULL)
    6797       769160 :                || (left->type()->interface_type() == NULL
    6798       379365 :                    && right->type()->interface_type() != NULL))
    6799        79140 :         return this->lower_interface_value_comparison(gogo, inserter);
    6800              :     }
    6801              : 
    6802              :   // Lower string concatenation to String_concat_expression, so that
    6803              :   // we can group sequences of string additions.
    6804      1316823 :   if (this->left_->type()->is_string_type() && this->op_ == OPERATOR_PLUS)
    6805              :     {
    6806        16280 :       Expression_list* exprs;
    6807        16280 :       String_concat_expression* left_sce =
    6808        16280 :         this->left_->string_concat_expression();
    6809        16280 :       if (left_sce != NULL)
    6810         5359 :         exprs = left_sce->exprs();
    6811              :       else
    6812              :         {
    6813        10921 :           exprs = new Expression_list();
    6814        10921 :           exprs->push_back(this->left_);
    6815              :         }
    6816              : 
    6817        16280 :       String_concat_expression* right_sce =
    6818        16280 :         this->right_->string_concat_expression();
    6819        16280 :       if (right_sce != NULL)
    6820          401 :         exprs->append(right_sce->exprs());
    6821              :       else
    6822        15879 :         exprs->push_back(this->right_);
    6823              : 
    6824        16280 :       return Expression::make_string_concat(exprs);
    6825              :     }
    6826              : 
    6827      1300543 :   return this;
    6828              : }
    6829              : 
    6830              : // Lower a struct comparison.
    6831              : 
    6832              : Expression*
    6833         8038 : Binary_expression::lower_struct_comparison(Gogo* gogo,
    6834              :                                            Statement_inserter* inserter)
    6835              : {
    6836         8038 :   Struct_type* st = this->left_->type()->struct_type();
    6837         8038 :   Struct_type* st2 = this->right_->type()->struct_type();
    6838         8038 :   if (st2 == NULL)
    6839            0 :     return this;
    6840         8038 :   if (st != st2
    6841         8038 :       && !Type::are_identical(st, st2,
    6842              :                               Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
    6843              :                               NULL))
    6844            0 :     return this;
    6845         8038 :   if (!Type::are_compatible_for_comparison(true, this->left_->type(),
    6846         8038 :                                            this->right_->type(), NULL))
    6847            0 :     return this;
    6848              : 
    6849              :   // See if we can compare using memcmp.  As a heuristic, we use
    6850              :   // memcmp rather than field references and comparisons if there are
    6851              :   // more than two fields.
    6852         8038 :   if (st->compare_is_identity(gogo) && st->total_field_count() > 2)
    6853          549 :     return this->lower_compare_to_memcmp(gogo, inserter);
    6854              : 
    6855         7489 :   Location loc = this->location();
    6856              : 
    6857         7489 :   Expression* left = this->left_;
    6858         7489 :   Temporary_statement* left_temp = NULL;
    6859         7489 :   if (left->var_expression() == NULL
    6860         7489 :       && left->temporary_reference_expression() == NULL)
    6861              :     {
    6862         7170 :       left_temp = Statement::make_temporary(left->type(), NULL, loc);
    6863         7170 :       inserter->insert(left_temp);
    6864         7170 :       left = Expression::make_set_and_use_temporary(left_temp, left, loc);
    6865              :     }
    6866              : 
    6867         7489 :   Expression* right = this->right_;
    6868         7489 :   Temporary_statement* right_temp = NULL;
    6869         7489 :   if (right->var_expression() == NULL
    6870         7489 :       && right->temporary_reference_expression() == NULL)
    6871              :     {
    6872         7304 :       right_temp = Statement::make_temporary(right->type(), NULL, loc);
    6873         7304 :       inserter->insert(right_temp);
    6874         7304 :       right = Expression::make_set_and_use_temporary(right_temp, right, loc);
    6875              :     }
    6876              : 
    6877         7489 :   Expression* ret = Expression::make_boolean(true, loc);
    6878         7489 :   const Struct_field_list* fields = st->fields();
    6879         7489 :   unsigned int field_index = 0;
    6880         7489 :   for (Struct_field_list::const_iterator pf = fields->begin();
    6881        25275 :        pf != fields->end();
    6882        17786 :        ++pf, ++field_index)
    6883              :     {
    6884        17786 :       if (Gogo::is_sink_name(pf->field_name()))
    6885          128 :         continue;
    6886              : 
    6887        17658 :       if (field_index > 0)
    6888              :         {
    6889        10486 :           if (left_temp == NULL)
    6890          554 :             left = left->copy();
    6891              :           else
    6892         9932 :             left = Expression::make_temporary_reference(left_temp, loc);
    6893        10486 :           if (right_temp == NULL)
    6894          365 :             right = right->copy();
    6895              :           else
    6896        10121 :             right = Expression::make_temporary_reference(right_temp, loc);
    6897              :         }
    6898        17658 :       Expression* f1 = Expression::make_field_reference(left, field_index,
    6899              :                                                         loc);
    6900        17658 :       Expression* f2 = Expression::make_field_reference(right, field_index,
    6901              :                                                         loc);
    6902        17658 :       Expression* cond = Expression::make_binary(OPERATOR_EQEQ, f1, f2, loc);
    6903        17658 :       ret = Expression::make_binary(OPERATOR_ANDAND, ret, cond, loc);
    6904              :     }
    6905              : 
    6906         7489 :   if (this->op_ == OPERATOR_NOTEQ)
    6907         6403 :     ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
    6908              : 
    6909         7489 :   ret->determine_type_no_context(gogo);
    6910              : 
    6911         7489 :   return ret;
    6912              : }
    6913              : 
    6914              : // Lower an array comparison.
    6915              : 
    6916              : Expression*
    6917         8895 : Binary_expression::lower_array_comparison(Gogo* gogo,
    6918              :                                           Statement_inserter* inserter)
    6919              : {
    6920         8895 :   Array_type* at = this->left_->type()->array_type();
    6921         8895 :   Array_type* at2 = this->right_->type()->array_type();
    6922         8895 :   if (at2 == NULL)
    6923            0 :     return this;
    6924         8895 :   if (at != at2
    6925         8895 :       && !Type::are_identical(at, at2,
    6926              :                               Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
    6927              :                               NULL))
    6928            0 :     return this;
    6929         8895 :   if (!Type::are_compatible_for_comparison(true, this->left_->type(),
    6930         8895 :                                            this->right_->type(), NULL))
    6931            0 :     return this;
    6932              : 
    6933              :   // Call memcmp directly if possible.  This may let the middle-end
    6934              :   // optimize the call.
    6935         8895 :   if (at->compare_is_identity(gogo))
    6936         7934 :     return this->lower_compare_to_memcmp(gogo, inserter);
    6937              : 
    6938              :   // Call the array comparison function.
    6939          961 :   Named_object* equal_fn =
    6940          961 :     at->equal_function(gogo, this->left_->type()->named_type(), NULL);
    6941              : 
    6942          961 :   Location loc = this->location();
    6943              : 
    6944          961 :   Expression* func = Expression::make_func_reference(equal_fn, NULL, loc);
    6945              : 
    6946          961 :   Expression_list* args = new Expression_list();
    6947          961 :   args->push_back(this->operand_address(inserter, this->left_));
    6948          961 :   args->push_back(this->operand_address(inserter, this->right_));
    6949              : 
    6950          961 :   Call_expression* ce = Expression::make_call(func, args, false, loc);
    6951              : 
    6952              :   // Record that this is a call to a generated equality function.  We
    6953              :   // need to do this because a comparison returns an abstract boolean
    6954              :   // type, but the function necessarily returns "bool".  The
    6955              :   // difference shows up in code like
    6956              :   //     type mybool bool
    6957              :   //     var b mybool = [10]string{} == [10]string{}
    6958              :   // The comparison function returns "bool", but since a comparison
    6959              :   // has an abstract boolean type we need an implicit conversion to
    6960              :   // "mybool".  The implicit conversion is inserted in
    6961              :   // Call_expression::do_flatten.
    6962          961 :   ce->set_is_equal_function();
    6963              : 
    6964          961 :   Expression* ret = ce;
    6965          961 :   if (this->op_ == OPERATOR_NOTEQ)
    6966          485 :     ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
    6967              : 
    6968          961 :   ret->determine_type_no_context(gogo);
    6969              : 
    6970          961 :   return ret;
    6971              : }
    6972              : 
    6973              : // Lower an interface to value comparison.
    6974              : 
    6975              : Expression*
    6976        79140 : Binary_expression::lower_interface_value_comparison(Gogo*,
    6977              :                                                     Statement_inserter* inserter)
    6978              : {
    6979        79140 :   Type* left_type = this->left_->type();
    6980        79140 :   Type* right_type = this->right_->type();
    6981        79140 :   Interface_type* ift;
    6982        79140 :   if (left_type->interface_type() != NULL)
    6983              :     {
    6984        78857 :       ift = left_type->interface_type();
    6985        78857 :       if (!ift->implements_interface(right_type, NULL))
    6986        74700 :         return this;
    6987              :     }
    6988              :   else
    6989              :     {
    6990          283 :       ift = right_type->interface_type();
    6991          283 :       if (!ift->implements_interface(left_type, NULL))
    6992            0 :         return this;
    6993              :     }
    6994         4440 :   if (!Type::are_compatible_for_comparison(true, left_type, right_type, NULL))
    6995            0 :     return this;
    6996              : 
    6997         4440 :   Location loc = this->location();
    6998              : 
    6999         4440 :   if (left_type->interface_type() == NULL
    7000          283 :       && left_type->points_to() == NULL
    7001           89 :       && !this->left_->is_addressable())
    7002              :     {
    7003            4 :       Temporary_statement* temp =
    7004            4 :           Statement::make_temporary(left_type, NULL, loc);
    7005            4 :       inserter->insert(temp);
    7006            4 :       this->left_ =
    7007            4 :           Expression::make_set_and_use_temporary(temp, this->left_, loc);
    7008              :     }
    7009              : 
    7010         4440 :   if (right_type->interface_type() == NULL
    7011         4157 :       && right_type->points_to() == NULL
    7012         3326 :       && !this->right_->is_addressable())
    7013              :     {
    7014         2317 :       Temporary_statement* temp =
    7015         2317 :           Statement::make_temporary(right_type, NULL, loc);
    7016         2317 :       inserter->insert(temp);
    7017         2317 :       this->right_ =
    7018         2317 :           Expression::make_set_and_use_temporary(temp, this->right_, loc);
    7019              :     }
    7020              : 
    7021         4440 :   return this;
    7022              : }
    7023              : 
    7024              : // Lower a struct or array comparison to a call to memcmp.
    7025              : 
    7026              : Expression*
    7027         8483 : Binary_expression::lower_compare_to_memcmp(Gogo* gogo,
    7028              :                                            Statement_inserter* inserter)
    7029              : {
    7030         8483 :   Location loc = this->location();
    7031              : 
    7032         8483 :   Expression* a1 = this->operand_address(inserter, this->left_);
    7033         8483 :   Expression* a2 = this->operand_address(inserter, this->right_);
    7034         8483 :   Expression* len = Expression::make_type_info(this->left_->type(),
    7035              :                                                TYPE_INFO_SIZE);
    7036              : 
    7037         8483 :   Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP, loc, 3,
    7038              :                                         a1, a2, len);
    7039         8483 :   Type* int32_type = Type::lookup_integer_type("int32");
    7040         8483 :   Expression* zero = Expression::make_integer_ul(0, int32_type, loc);
    7041         8483 :   Expression* ret = Expression::make_binary(this->op_, call, zero, loc);
    7042         8483 :   Type_context context(this->type_, this->type_->is_abstract());
    7043         8483 :   ret->determine_type(gogo, &context);
    7044         8483 :   return ret;
    7045              : }
    7046              : 
    7047              : Expression*
    7048       868869 : Binary_expression::do_flatten(Gogo* gogo, Named_object*,
    7049              :                               Statement_inserter* inserter)
    7050              : {
    7051       868869 :   Location loc = this->location();
    7052       868869 :   if (this->left_->type()->is_error_type()
    7053       868869 :       || this->right_->type()->is_error_type()
    7054       868869 :       || this->left_->is_error_expression()
    7055      1737738 :       || this->right_->is_error_expression())
    7056              :     {
    7057            0 :       go_assert(saw_errors());
    7058            0 :       return Expression::make_error(loc);
    7059              :     }
    7060              : 
    7061       868869 :   Temporary_statement* temp;
    7062              : 
    7063       868869 :   Type* left_type = this->left_->type();
    7064       868869 :   bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
    7065       868869 :                       || this->op_ == OPERATOR_RSHIFT);
    7066       868869 :   bool is_idiv_op = ((this->op_ == OPERATOR_DIV &&
    7067      1730164 :                       left_type->integer_type() != NULL)
    7068       870470 :                      || this->op_ == OPERATOR_MOD);
    7069       868869 :   bool is_string_op = (left_type->is_string_type()
    7070      1737738 :                        && this->right_->type()->is_string_type());
    7071              : 
    7072        46743 :   if (is_string_op)
    7073              :     {
    7074              :       // Mark string([]byte) operands to reuse the backing store.
    7075              :       // String comparison does not keep the reference, so it is safe.
    7076        46743 :       Type_conversion_expression* lce =
    7077        46743 :         this->left_->conversion_expression();
    7078         1100 :       if (lce != NULL && lce->expr()->type()->is_slice_type())
    7079         1080 :         lce->set_no_copy(true);
    7080        46743 :       Type_conversion_expression* rce =
    7081        46743 :         this->right_->conversion_expression();
    7082          885 :       if (rce != NULL && rce->expr()->type()->is_slice_type())
    7083          395 :         rce->set_no_copy(true);
    7084              :     }
    7085              : 
    7086       868869 :   if (is_shift_op
    7087       843131 :       || (is_idiv_op
    7088        11890 :           && (gogo->check_divide_by_zero() || gogo->check_divide_overflow()))
    7089      1700110 :       || is_string_op)
    7090              :     {
    7091        84371 :       if (!this->left_->is_multi_eval_safe())
    7092              :         {
    7093        38136 :           temp = Statement::make_temporary(NULL, this->left_, loc);
    7094        38136 :           inserter->insert(temp);
    7095        38136 :           this->left_ = Expression::make_temporary_reference(temp, loc);
    7096              :         }
    7097        84371 :       if (!this->right_->is_multi_eval_safe())
    7098              :         {
    7099        43290 :           temp =
    7100        43290 :               Statement::make_temporary(NULL, this->right_, loc);
    7101        43290 :           this->right_ = Expression::make_temporary_reference(temp, loc);
    7102        43290 :           inserter->insert(temp);
    7103              :         }
    7104              :     }
    7105       868869 :   return this;
    7106              : }
    7107              : 
    7108              : 
    7109              : // Return the address of EXPR, cast to unsafe.Pointer.
    7110              : 
    7111              : Expression*
    7112        18888 : Binary_expression::operand_address(Statement_inserter* inserter,
    7113              :                                    Expression* expr)
    7114              : {
    7115        18888 :   Location loc = this->location();
    7116              : 
    7117        18888 :   if (!expr->is_addressable())
    7118              :     {
    7119         2194 :       Temporary_statement* temp = Statement::make_temporary(expr->type(), NULL,
    7120              :                                                             loc);
    7121         2194 :       inserter->insert(temp);
    7122         2194 :       expr = Expression::make_set_and_use_temporary(temp, expr, loc);
    7123              :     }
    7124        18888 :   expr = Expression::make_unary(OPERATOR_AND, expr, loc);
    7125        18888 :   static_cast<Unary_expression*>(expr)->set_does_not_escape();
    7126        18888 :   Type* void_type = Type::make_void_type();
    7127        18888 :   Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
    7128        18888 :   return Expression::make_cast(unsafe_pointer_type, expr, loc);
    7129              : }
    7130              : 
    7131              : // Return the numeric constant value, if it has one.
    7132              : 
    7133              : bool
    7134       731469 : Binary_expression::do_numeric_constant_value(Numeric_constant* nc)
    7135              : {
    7136       731469 :   if (this->is_error_expression())
    7137              :     return false;
    7138              : 
    7139       731272 :   Numeric_constant left_nc;
    7140       731272 :   if (!this->left_->numeric_constant_value(&left_nc))
    7141              :     return false;
    7142       276414 :   Numeric_constant right_nc;
    7143       276414 :   if (!this->right_->numeric_constant_value(&right_nc))
    7144              :     return false;
    7145       252213 :   bool issued_error;
    7146       252213 :   bool r = Binary_expression::eval_constant(this->op_, &left_nc, &right_nc,
    7147              :                                             this->location(), nc,
    7148              :                                             &issued_error);
    7149       252213 :   if (issued_error)
    7150            1 :     this->set_is_error();
    7151              :   return r;
    7152       731272 : }
    7153              : 
    7154              : // Return the boolean constant value, if it has one.
    7155              : 
    7156              : bool
    7157      1103404 : Binary_expression::do_boolean_constant_value(bool* val)
    7158              : {
    7159      1103404 :   if (this->is_error_expression())
    7160              :     return false;
    7161              : 
    7162      1103404 :   bool is_comparison = false;
    7163      1103404 :   switch (this->op_)
    7164              :     {
    7165       672060 :     case OPERATOR_EQEQ:
    7166       672060 :     case OPERATOR_NOTEQ:
    7167       672060 :     case OPERATOR_LT:
    7168       672060 :     case OPERATOR_LE:
    7169       672060 :     case OPERATOR_GT:
    7170       672060 :     case OPERATOR_GE:
    7171       672060 :       is_comparison = true;
    7172       672060 :       break;
    7173              :     case OPERATOR_ANDAND:
    7174              :     case OPERATOR_OROR:
    7175              :       break;
    7176              :     default:
    7177              :       return false;
    7178              :     }
    7179              : 
    7180      1675802 :   Numeric_constant left_nc, right_nc;
    7181       837901 :   if (is_comparison
    7182       672060 :       && this->left_->numeric_constant_value(&left_nc)
    7183       846499 :       && this->right_->numeric_constant_value(&right_nc))
    7184            0 :     return Binary_expression::compare_constant(this->op_, &left_nc,
    7185              :                                                &right_nc,
    7186              :                                                this->location(),
    7187            0 :                                                val);
    7188              : 
    7189      1675802 :   std::string left_str, right_str;
    7190       837901 :   if (is_comparison
    7191       672060 :       && this->left_->string_constant_value(&left_str)
    7192       837965 :       && this->right_->string_constant_value(&right_str))
    7193              :     {
    7194            0 :       *val = Binary_expression::cmp_to_bool(this->op_,
    7195              :                                             left_str.compare(right_str));
    7196            0 :       return true;
    7197              :     }
    7198              : 
    7199       837901 :   bool left_bval;
    7200       837901 :   if (this->left_->boolean_constant_value(&left_bval))
    7201              :     {
    7202         5727 :       if (this->op_ == OPERATOR_ANDAND && !left_bval)
    7203              :         {
    7204         1789 :           *val = false;
    7205         2797 :           return true;
    7206              :         }
    7207         3938 :       else if (this->op_ == OPERATOR_OROR && left_bval)
    7208              :         {
    7209          167 :           *val = true;
    7210          167 :           return true;
    7211              :         }
    7212              : 
    7213         3771 :       bool right_bval;
    7214         3771 :       if (this->right_->boolean_constant_value(&right_bval))
    7215              :         {
    7216          841 :           switch (this->op_)
    7217              :             {
    7218            2 :             case OPERATOR_EQEQ:
    7219            2 :               *val = (left_bval == right_bval);
    7220            2 :               return true;
    7221            0 :             case OPERATOR_NOTEQ:
    7222            0 :               *val = (left_bval != right_bval);
    7223            0 :               return true;
    7224          839 :             case OPERATOR_ANDAND:
    7225          839 :             case OPERATOR_OROR:
    7226          839 :               *val = right_bval;
    7227          839 :               return true;
    7228            0 :             default:
    7229            0 :               go_unreachable();
    7230              :             }
    7231              :         }
    7232              :     }
    7233              : 
    7234              :   return false;
    7235              : }
    7236              : 
    7237              : // Note that the value is being discarded.
    7238              : 
    7239              : bool
    7240            2 : Binary_expression::do_discarding_value()
    7241              : {
    7242            2 :   if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
    7243            0 :     return this->right_->discarding_value();
    7244              :   else
    7245              :     {
    7246            2 :       this->unused_value_error();
    7247            2 :       return false;
    7248              :     }
    7249              : }
    7250              : 
    7251              : // Get type.
    7252              : 
    7253              : Type*
    7254      7253083 : Binary_expression::do_type()
    7255              : {
    7256      7253083 :   if (this->type_ == NULL)
    7257              :     {
    7258          157 :       go_assert(saw_errors());
    7259          157 :       return Type::make_error_type();
    7260              :     }
    7261              : 
    7262              :   return this->type_;
    7263              : }
    7264              : 
    7265              : // Set type for a binary expression.
    7266              : 
    7267              : void
    7268      2880813 : Binary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
    7269              : {
    7270      2880813 :   if (this->type_ != NULL)
    7271       539095 :     return;
    7272              : 
    7273              :   // For a shift operation, the type of the binary expression is the
    7274              :   // type of the left operand.  If the left operand is a constant,
    7275              :   // then it gets its type from the context.
    7276      2341836 :   bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
    7277      2341836 :                       || this->op_ == OPERATOR_RSHIFT);
    7278              : 
    7279              :   // For a comparison operation, the type of the binary expression is
    7280              :   // a boolean type.
    7281      2341836 :   bool is_comparison = (this->op_ == OPERATOR_EQEQ
    7282              :                         || this->op_ == OPERATOR_NOTEQ
    7283              :                         || this->op_ == OPERATOR_LT
    7284              :                         || this->op_ == OPERATOR_LE
    7285              :                         || this->op_ == OPERATOR_GT
    7286      2341836 :                         || this->op_ == OPERATOR_GE);
    7287              : 
    7288              :   // For constant expressions, the context of the result is not useful in
    7289              :   // determining the types of the operands.  It is only legal to use abstract
    7290              :   // boolean, numeric, and string constants as operands where it is legal to
    7291              :   // use non-abstract boolean, numeric, and string constants, respectively.
    7292              :   // Any issues with the operation will be resolved in the check_types pass.
    7293      2341836 :   bool left_is_constant = this->left_->is_constant();
    7294      2341836 :   bool right_is_constant = this->right_->is_constant();
    7295      2341836 :   bool is_constant_expr = left_is_constant && right_is_constant;
    7296              : 
    7297      2341836 :   Type_context subcontext(*context);
    7298      2341836 :   if (is_comparison)
    7299      1291780 :     subcontext.type = NULL;
    7300              : 
    7301      2341836 :   Type* tleft;
    7302      2341836 :   bool left_is_untyped = this->left_->is_untyped(&tleft);
    7303      2341836 :   if (!left_is_untyped)
    7304              :     {
    7305      1955194 :       this->left_->determine_type(gogo, &subcontext);
    7306      1955194 :       tleft = this->left_->type();
    7307              :     }
    7308              : 
    7309      2341836 :   Type* tright;
    7310      2341836 :   bool right_is_untyped = this->right_->is_untyped(&tright);
    7311      2341836 :   if (!right_is_untyped)
    7312              :     {
    7313              :       // For a shift operation, the right operand should always be an
    7314              :       // integer.
    7315      1768703 :       if (is_shift_op)
    7316              :         {
    7317       192174 :           subcontext.type = Type::lookup_integer_type("uint");
    7318       192174 :           subcontext.may_be_abstract = false;
    7319              :         }
    7320              : 
    7321      1768703 :       this->right_->determine_type(gogo, &subcontext);
    7322      1768703 :       tright = this->right_->type();
    7323              :     }
    7324              : 
    7325              :   // For each operand we have the real type or, if the operand is a
    7326              :   // untyped, a guess at the type.  Use this to determine the types of
    7327              :   // untyped operands.
    7328              : 
    7329      2341836 :   subcontext = *context;
    7330      2341836 :   if (left_is_untyped && (right_is_untyped || is_shift_op) && is_constant_expr)
    7331              :     {
    7332              :       // We evaluate the operands of an untyped expression as untyped
    7333              :       // values.  Then we convert to the desired type.  Otherwise we
    7334              :       // may, for example, mishandle a floating-point constant
    7335              :       // division as an integer division.
    7336       123559 :       subcontext.type = NULL;
    7337       123559 :       subcontext.may_be_abstract = true;
    7338              :     }
    7339      2218277 :   else if (is_comparison)
    7340              :     {
    7341              :       // In a comparison, the context does not determine the types of
    7342              :       // the operands.
    7343      1290807 :       subcontext.type = NULL;
    7344              :     }
    7345              : 
    7346              :   // Set the context for the left hand operand.
    7347              : 
    7348      2341836 :   if (is_shift_op)
    7349              :     {
    7350              :       // The right hand operand of a shift plays no role in
    7351              :       // determining the type of the left hand operand.
    7352       222363 :       if (subcontext.type == NULL
    7353        17187 :           && right_is_constant
    7354        16137 :           && context->may_be_abstract)
    7355         5785 :         subcontext.type = Type::make_abstract_integer_type();
    7356              :     }
    7357      2119473 :   else if (!tleft->is_abstract())
    7358      1745704 :     subcontext.type = tleft;
    7359       373769 :   else if (!tright->is_abstract())
    7360        30915 :     subcontext.type = tright;
    7361       342854 :   else if (subcontext.type == NULL)
    7362              :     {
    7363       324651 :       if ((tleft->integer_type() != NULL && tright->integer_type() != NULL)
    7364      2625422 :           || (tleft->float_type() != NULL && tright->float_type() != NULL)
    7365      2623905 :           || (tleft->complex_type() != NULL && tright->complex_type() != NULL)
    7366       282017 :           || (tleft->is_boolean_type() && tright->is_boolean_type()))
    7367              :         {
    7368              :           // Both sides have an abstract integer, abstract float,
    7369              :           // abstract complex, or abstract boolean type.  Just let
    7370              :           // CONTEXT determine whether they may remain abstract or not.
    7371              :         }
    7372        40093 :       else if (tleft->complex_type() != NULL)
    7373            8 :         subcontext.type = tleft;
    7374        40085 :       else if (tright->complex_type() != NULL)
    7375          818 :         subcontext.type = tright;
    7376        39267 :       else if (tleft->float_type() != NULL)
    7377          478 :         subcontext.type = tleft;
    7378        38789 :       else if (tright->float_type() != NULL)
    7379          360 :         subcontext.type = tright;
    7380              :       else
    7381        38429 :         subcontext.type = tleft;
    7382              :     }
    7383              : 
    7384      2341836 :   if (left_is_untyped)
    7385              :     {
    7386       386642 :       this->left_->determine_type(gogo, &subcontext);
    7387       386642 :       tleft = this->left_->type();
    7388              :     }
    7389              : 
    7390      2341836 :   if (is_shift_op)
    7391              :     {
    7392              :       // We may have inherited an unusable type for the shift operand.
    7393              :       // Give a useful error if that happened.
    7394       222363 :       if (left_is_untyped
    7395       222363 :           && !is_constant_expr
    7396         1497 :           && subcontext.type != NULL
    7397         1402 :           && !subcontext.may_be_abstract
    7398         1402 :           && subcontext.type->interface_type() == NULL
    7399       223753 :           && subcontext.type->integer_type() == NULL
    7400          123 :           && !tleft->is_error()
    7401       222486 :           && !tright->is_error())
    7402          123 :         this->report_error(("invalid context-determined non-integer type "
    7403              :                             "for left operand of shift"));
    7404              : 
    7405              :       // The context for the right hand operand is the same as for the
    7406              :       // left hand operand, except for a shift operator.
    7407       222363 :       subcontext.type = Type::lookup_integer_type("uint");
    7408       222363 :       subcontext.may_be_abstract = false;
    7409              :     }
    7410              : 
    7411      2341836 :   if (right_is_untyped)
    7412              :     {
    7413       573133 :       this->right_->determine_type(gogo, &subcontext);
    7414       573133 :       tright = this->right_->type();
    7415              :     }
    7416              : 
    7417      2341836 :   if (this->left_->is_error_expression()
    7418      2341747 :       || tleft->is_error()
    7419      2341746 :       || this->right_->is_error_expression()
    7420      4683565 :       || tright->is_error())
    7421              :     {
    7422          107 :       this->set_is_error();
    7423          107 :       return;
    7424              :     }
    7425              : 
    7426      2341729 :   if (is_comparison)
    7427              :     {
    7428      1291729 :       if (context->type != NULL && context->type->is_boolean_type())
    7429       543376 :         this->type_ = context->type;
    7430       748353 :       else if (!context->may_be_abstract)
    7431       646396 :         this->type_ = Type::lookup_bool_type();
    7432              :       else
    7433       101957 :         this->type_ = Type::make_boolean_type();
    7434              :     }
    7435              :   else
    7436              :     {
    7437      1050000 :       if (is_shift_op)
    7438              :         {
    7439              :           // Shifts only work with integers, so force an abstract
    7440              :           // floating-point type (such as 1.0 << 1) into an integer.
    7441       222356 :           if (tleft->is_abstract()
    7442        11454 :               && tleft->integer_type() == NULL
    7443       222444 :               && context->type == NULL)
    7444              :             {
    7445            2 :               this->type_ = Type::make_abstract_integer_type();
    7446            2 :               if (!context->may_be_abstract)
    7447            2 :                 this->type_ = this->type_->make_non_abstract_type();
    7448              :             }
    7449              :           else
    7450       222354 :             this->type_ = tleft;
    7451              :         }
    7452              :       else
    7453              :         {
    7454       827644 :           if (!Binary_expression::operation_type(this->op_, tleft, tright,
    7455              :                                                  &this->type_))
    7456              :             {
    7457           11 :               this->report_error("incompatible types in binary expression");
    7458           11 :               this->type_ = Type::make_error_type();
    7459           11 :               return;
    7460              :             }
    7461              :         }
    7462              : 
    7463              :       // If this is an untyped expression in a typed context, use the
    7464              :       // context type.  If this doesn't work we'll report an error
    7465              :       // later.
    7466      1049989 :       if (this->type_->is_abstract()
    7467       122662 :           && !context->may_be_abstract
    7468      1121918 :           && context->type != NULL)
    7469              :         {
    7470        21121 :           if (context->type->interface_type() == NULL
    7471        20884 :               && ((this->type_->is_numeric_type()
    7472        19294 :                    && context->type->is_numeric_type())
    7473         1602 :                   || (this->type_->is_string_type()
    7474         1253 :                       && context->type->is_string_type())
    7475          381 :                   || (this->type_->is_boolean_type()
    7476          337 :                       && context->type->is_boolean_type())))
    7477        20840 :             this->type_ = context->type;
    7478      2341999 :           else if (context->type->interface_type() != NULL)
    7479          237 :             this->type_ = this->type_->make_non_abstract_type();
    7480              :         }
    7481              :     }
    7482              : }
    7483              : 
    7484              : // Report an error if the binary operator OP does not support TYPE.
    7485              : // OTYPE is the type of the other operand.  Return whether the
    7486              : // operation is OK.  This should not be used for shift.
    7487              : 
    7488              : bool
    7489       869128 : Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
    7490              :                                        Location location)
    7491              : {
    7492       869128 :   switch (op)
    7493              :     {
    7494        64063 :     case OPERATOR_OROR:
    7495        64063 :     case OPERATOR_ANDAND:
    7496        64063 :       if (!type->is_boolean_type()
    7497       128126 :           || !otype->is_boolean_type())
    7498              :         {
    7499            0 :           go_error_at(location, "expected boolean type");
    7500            0 :           return false;
    7501              :         }
    7502              :       break;
    7503              : 
    7504       417882 :     case OPERATOR_EQEQ:
    7505       417882 :     case OPERATOR_NOTEQ:
    7506       417882 :       {
    7507       417882 :         std::string reason;
    7508       417882 :         if (!Type::are_compatible_for_comparison(true, type, otype, &reason))
    7509              :           {
    7510           32 :             go_error_at(location, "%s", reason.c_str());
    7511           32 :             return false;
    7512              :           }
    7513           32 :       }
    7514       417850 :       break;
    7515              : 
    7516       152884 :     case OPERATOR_LT:
    7517       152884 :     case OPERATOR_LE:
    7518       152884 :     case OPERATOR_GT:
    7519       152884 :     case OPERATOR_GE:
    7520       152884 :       {
    7521       152884 :         std::string reason;
    7522       152884 :         if (!Type::are_compatible_for_comparison(false, type, otype, &reason))
    7523              :           {
    7524           20 :             go_error_at(location, "%s", reason.c_str());
    7525           20 :             return false;
    7526              :           }
    7527           20 :       }
    7528       152864 :       break;
    7529              : 
    7530       118413 :     case OPERATOR_PLUS:
    7531       118413 :     case OPERATOR_PLUSEQ:
    7532       173006 :       if ((!type->is_numeric_type() && !type->is_string_type())
    7533       291419 :           || (!otype->is_numeric_type() && !otype->is_string_type()))
    7534              :         {
    7535            0 :           go_error_at(location,
    7536              :                    "expected integer, floating, complex, or string type");
    7537            0 :           return false;
    7538              :         }
    7539              :       break;
    7540              : 
    7541        76621 :     case OPERATOR_MINUS:
    7542        76621 :     case OPERATOR_MINUSEQ:
    7543        76621 :     case OPERATOR_MULT:
    7544        76621 :     case OPERATOR_MULTEQ:
    7545        76621 :     case OPERATOR_DIV:
    7546        76621 :     case OPERATOR_DIVEQ:
    7547       153241 :       if (!type->is_numeric_type() || !otype->is_numeric_type())
    7548              :         {
    7549            1 :           go_error_at(location, "expected integer, floating, or complex type");
    7550            1 :           return false;
    7551              :         }
    7552              :       break;
    7553              : 
    7554        39265 :     case OPERATOR_MOD:
    7555        39265 :     case OPERATOR_MODEQ:
    7556        39265 :     case OPERATOR_OR:
    7557        39265 :     case OPERATOR_OREQ:
    7558        39265 :     case OPERATOR_AND:
    7559        39265 :     case OPERATOR_ANDEQ:
    7560        39265 :     case OPERATOR_XOR:
    7561        39265 :     case OPERATOR_XOREQ:
    7562        39265 :     case OPERATOR_BITCLEAR:
    7563        39265 :     case OPERATOR_BITCLEAREQ:
    7564        78518 :       if (type->integer_type() == NULL || otype->integer_type() == NULL)
    7565              :         {
    7566           12 :           go_error_at(location, "expected integer type");
    7567           12 :           return false;
    7568              :         }
    7569              :       break;
    7570              : 
    7571            0 :     default:
    7572            0 :       go_unreachable();
    7573              :     }
    7574              : 
    7575              :   return true;
    7576              : }
    7577              : 
    7578              : // Check types.
    7579              : 
    7580              : void
    7581       594868 : Binary_expression::do_check_types(Gogo*)
    7582              : {
    7583       594868 :   if (this->classification() == EXPRESSION_ERROR)
    7584              :     return;
    7585              : 
    7586       594636 :   Type* left_type = this->left_->type();
    7587       594636 :   Type* right_type = this->right_->type();
    7588       594636 :   if (left_type->is_error() || right_type->is_error())
    7589              :     {
    7590            1 :       this->set_is_error();
    7591            1 :       return;
    7592              :     }
    7593              : 
    7594       594635 :   if (this->op_ == OPERATOR_EQEQ
    7595              :       || this->op_ == OPERATOR_NOTEQ
    7596              :       || this->op_ == OPERATOR_LT
    7597              :       || this->op_ == OPERATOR_LE
    7598              :       || this->op_ == OPERATOR_GT
    7599       594635 :       || this->op_ == OPERATOR_GE)
    7600              :     {
    7601       285441 :       if (left_type->is_nil_type() && right_type->is_nil_type())
    7602              :         {
    7603            2 :           this->report_error(_("invalid comparison of nil with nil"));
    7604            2 :           return;
    7605              :         }
    7606       285439 :       if (!Type::are_assignable(left_type, right_type, NULL)
    7607       285439 :           && !Type::are_assignable(right_type, left_type, NULL))
    7608              :         {
    7609           32 :           this->report_error(_("incompatible types in binary expression"));
    7610           32 :           return;
    7611              :         }
    7612       285407 :       if (!Binary_expression::check_operator_type(this->op_, left_type,
    7613              :                                                   right_type,
    7614              :                                                   this->location())
    7615       285407 :           || !Binary_expression::check_operator_type(this->op_, right_type,
    7616              :                                                      left_type,
    7617              :                                                      this->location()))
    7618              :         {
    7619           52 :           this->set_is_error();
    7620           52 :           return;
    7621              :         }
    7622              :     }
    7623       309194 :   else if (this->op_ != OPERATOR_LSHIFT && this->op_ != OPERATOR_RSHIFT)
    7624              :     {
    7625       274770 :       if (!Type::are_compatible_for_binop(left_type, right_type))
    7626              :         {
    7627           16 :           this->report_error(_("incompatible types in binary expression"));
    7628           16 :           return;
    7629              :         }
    7630       274754 :       if (!Binary_expression::check_operator_type(this->op_, left_type,
    7631              :                                                   right_type,
    7632              :                                                   this->location()))
    7633              :         {
    7634           12 :           this->set_is_error();
    7635           12 :           return;
    7636              :         }
    7637       274742 :       if (this->op_ == OPERATOR_DIV || this->op_ == OPERATOR_MOD)
    7638              :         {
    7639              :           // Division by a zero integer constant is an error.
    7640        15069 :           Numeric_constant rconst;
    7641        15069 :           unsigned long rval;
    7642        15069 :           if (left_type->integer_type() != NULL
    7643        12915 :               && this->right_->numeric_constant_value(&rconst)
    7644         9862 :               && rconst.to_unsigned_long(&rval) == Numeric_constant::NC_UL_VALID
    7645         9673 :               && rval == 0)
    7646              :             {
    7647            2 :               this->report_error(_("integer division by zero"));
    7648            2 :               return;
    7649              :             }
    7650        15069 :         }
    7651              :     }
    7652              :   else
    7653              :     {
    7654        34424 :       if (left_type->integer_type() == NULL
    7655           41 :           && !left_type->is_abstract()
    7656           32 :           && !this->is_constant())
    7657           32 :         this->report_error(_("shift of non-integer operand"));
    7658              : 
    7659        34424 :       if (right_type->is_string_type())
    7660            0 :         this->report_error(_("shift count not integer"));
    7661        34424 :       else if (!right_type->is_abstract()
    7662        34424 :                && right_type->integer_type() == NULL)
    7663            0 :         this->report_error(_("shift count not integer"));
    7664              :       else
    7665              :         {
    7666        34424 :           Numeric_constant nc;
    7667        34424 :           if (this->right_->numeric_constant_value(&nc))
    7668              :             {
    7669        30682 :               mpz_t val;
    7670        30682 :               if (!nc.to_int(&val))
    7671            0 :                 this->report_error(_("shift count not integer"));
    7672              :               else
    7673              :                 {
    7674        30682 :                   if (mpz_sgn(val) < 0)
    7675              :                     {
    7676            1 :                       this->report_error(_("negative shift count"));
    7677            1 :                       Location rloc = this->right_->location();
    7678            1 :                       this->right_ = Expression::make_integer_ul(0, right_type,
    7679              :                                                                  rloc);
    7680              :                     }
    7681        30682 :                   mpz_clear(val);
    7682              :                 }
    7683              :             }
    7684        34424 :         }
    7685              :     }
    7686              : }
    7687              : 
    7688              : // Get the backend representation for a binary expression.
    7689              : 
    7690              : Bexpression*
    7691      1996101 : Binary_expression::do_get_backend(Translate_context* context)
    7692              : {
    7693      1996101 :   Gogo* gogo = context->gogo();
    7694      1996101 :   Location loc = this->location();
    7695      1996101 :   Type* left_type = this->left_->type();
    7696      1996101 :   Type* right_type = this->right_->type();
    7697              : 
    7698      1996101 :   bool use_left_type = true;
    7699      1996101 :   bool is_shift_op = false;
    7700      1996101 :   bool is_idiv_op = false;
    7701      1996101 :   switch (this->op_)
    7702              :     {
    7703      1266990 :     case OPERATOR_EQEQ:
    7704      1266990 :     case OPERATOR_NOTEQ:
    7705      1266990 :     case OPERATOR_LT:
    7706      1266990 :     case OPERATOR_LE:
    7707      1266990 :     case OPERATOR_GT:
    7708      1266990 :     case OPERATOR_GE:
    7709      1266990 :       return Expression::comparison(context, this->type_, this->op_,
    7710      1266990 :                                     this->left_, this->right_, loc);
    7711              : 
    7712              :     case OPERATOR_OROR:
    7713              :     case OPERATOR_ANDAND:
    7714       729111 :       use_left_type = false;
    7715              :       break;
    7716              :     case OPERATOR_PLUS:
    7717              :     case OPERATOR_MINUS:
    7718              :     case OPERATOR_OR:
    7719              :     case OPERATOR_XOR:
    7720              :     case OPERATOR_MULT:
    7721              :       break;
    7722         8928 :     case OPERATOR_DIV:
    7723       745409 :       if (left_type->float_type() != NULL || left_type->complex_type() != NULL)
    7724              :         break;
    7725              :       // Fall through.
    7726              :     case OPERATOR_MOD:
    7727              :       is_idiv_op = true;
    7728              :       break;
    7729       143543 :     case OPERATOR_LSHIFT:
    7730       143543 :     case OPERATOR_RSHIFT:
    7731       143543 :       is_shift_op = true;
    7732       143543 :       break;
    7733         2018 :     case OPERATOR_BITCLEAR:
    7734         2018 :       this->right_ = Expression::make_unary(OPERATOR_XOR, this->right_, loc);
    7735              :     case OPERATOR_AND:
    7736              :       break;
    7737            0 :     default:
    7738            0 :       go_unreachable();
    7739              :     }
    7740              : 
    7741              :   // The only binary operation for string is +, and that should have
    7742              :   // been converted to a String_concat_expression in do_lower.
    7743       729111 :   go_assert(!left_type->is_string_type());
    7744              : 
    7745       729111 :   Bexpression* left = this->left_->get_backend(context);
    7746       729111 :   Bexpression* right = this->right_->get_backend(context);
    7747              : 
    7748       729111 :   Type* type = use_left_type ? left_type : right_type;
    7749       729111 :   Btype* btype = type->get_backend(gogo);
    7750              : 
    7751       729111 :   Bexpression* ret =
    7752       729111 :       gogo->backend()->binary_expression(this->op_, left, right, loc);
    7753       729111 :   ret = gogo->backend()->convert_expression(btype, ret, loc);
    7754              : 
    7755              :   // Initialize overflow constants.
    7756       729111 :   Bexpression* overflow;
    7757       729111 :   mpz_t zero;
    7758       729111 :   mpz_init_set_ui(zero, 0UL);
    7759       729111 :   mpz_t one;
    7760       729111 :   mpz_init_set_ui(one, 1UL);
    7761       729111 :   mpz_t neg_one;
    7762       729111 :   mpz_init_set_si(neg_one, -1);
    7763              : 
    7764       729111 :   Btype* left_btype = left_type->get_backend(gogo);
    7765       729111 :   Btype* right_btype = right_type->get_backend(gogo);
    7766              : 
    7767              :   // In Go, a shift larger than the size of the type is well-defined.
    7768              :   // This is not true in C, so we need to insert a conditional.
    7769              :   // We also need to check for a negative shift count.
    7770       729111 :   if (is_shift_op)
    7771              :     {
    7772       143543 :       go_assert(left_type->integer_type() != NULL);
    7773       143543 :       go_assert(right_type->integer_type() != NULL);
    7774              : 
    7775       287086 :       int bits = left_type->integer_type()->bits();
    7776              : 
    7777       143543 :       Numeric_constant nc;
    7778       143543 :       unsigned long ul;
    7779       143543 :       if (!this->right_->numeric_constant_value(&nc)
    7780       139593 :           || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID
    7781       283136 :           || ul >= static_cast<unsigned long>(bits))
    7782              :         {
    7783         4368 :           mpz_t bitsval;
    7784         4368 :           mpz_init_set_ui(bitsval, bits);
    7785         4368 :           Bexpression* bits_expr =
    7786         4368 :             gogo->backend()->integer_constant_expression(right_btype, bitsval);
    7787         4368 :           Bexpression* compare =
    7788         4368 :             gogo->backend()->binary_expression(OPERATOR_LT,
    7789              :                                                right, bits_expr, loc);
    7790              : 
    7791         4368 :           Bexpression* zero_expr =
    7792         4368 :             gogo->backend()->integer_constant_expression(left_btype, zero);
    7793         4368 :           overflow = zero_expr;
    7794         4368 :           Bfunction* bfn = context->function()->func_value()->get_decl();
    7795         4368 :           if (this->op_ == OPERATOR_RSHIFT
    7796         5848 :               && !left_type->integer_type()->is_unsigned())
    7797              :             {
    7798          344 :               Bexpression* neg_expr =
    7799          344 :                 gogo->backend()->binary_expression(OPERATOR_LT, left,
    7800              :                                                    zero_expr, loc);
    7801          344 :               Bexpression* neg_one_expr =
    7802          344 :                 gogo->backend()->integer_constant_expression(left_btype,
    7803              :                                                              neg_one);
    7804          344 :               overflow = gogo->backend()->conditional_expression(bfn,
    7805              :                                                                  btype,
    7806              :                                                                  neg_expr,
    7807              :                                                                  neg_one_expr,
    7808              :                                                                  zero_expr,
    7809              :                                                                  loc);
    7810              :             }
    7811         4368 :           ret = gogo->backend()->conditional_expression(bfn, btype, compare,
    7812              :                                                         ret, overflow, loc);
    7813         4368 :           mpz_clear(bitsval);
    7814              :         }
    7815              : 
    7816       287086 :       if (!right_type->integer_type()->is_unsigned()
    7817       143543 :           && (!this->right_->numeric_constant_value(&nc)
    7818          425 :               || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID))
    7819              :         {
    7820          133 :           Bexpression* zero_expr =
    7821          133 :             gogo->backend()->integer_constant_expression(right_btype, zero);
    7822          133 :           Bexpression* compare =
    7823          133 :             gogo->backend()->binary_expression(OPERATOR_LT, right, zero_expr,
    7824              :                                                loc);
    7825          133 :           Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_SHIFT,
    7826              :                                                  loc, 0);
    7827          133 :           crash->determine_type_no_context(gogo);
    7828          133 :           Bexpression* bcrash = crash->get_backend(context);
    7829          133 :           Bfunction* bfn = context->function()->func_value()->get_decl();
    7830          133 :           ret = gogo->backend()->conditional_expression(bfn, btype, compare,
    7831              :                                                         bcrash, ret, loc);
    7832              :         }
    7833       143543 :     }
    7834              : 
    7835              :   // Add checks for division by zero and division overflow as needed.
    7836       729111 :   if (is_idiv_op)
    7837              :     {
    7838        11583 :       if (gogo->check_divide_by_zero())
    7839              :         {
    7840              :           // right == 0
    7841        11583 :           Bexpression* zero_expr =
    7842        11583 :               gogo->backend()->integer_constant_expression(right_btype, zero);
    7843        11583 :           Bexpression* check =
    7844        11583 :               gogo->backend()->binary_expression(OPERATOR_EQEQ,
    7845              :                                                  right, zero_expr, loc);
    7846              : 
    7847        11583 :           Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_DIVIDE,
    7848              :                                                  loc, 0);
    7849        11583 :           crash->determine_type_no_context(gogo);
    7850        11583 :           Bexpression* bcrash = crash->get_backend(context);
    7851              : 
    7852              :           // right == 0 ? (panicdivide(), 0) : ret
    7853        11583 :           Bfunction* bfn = context->function()->func_value()->get_decl();
    7854        11583 :           ret = gogo->backend()->conditional_expression(bfn, btype,
    7855              :                                                         check, bcrash,
    7856              :                                                         ret, loc);
    7857              :         }
    7858              : 
    7859        11583 :       if (gogo->check_divide_overflow())
    7860              :         {
    7861              :           // right == -1
    7862              :           // FIXME: It would be nice to say that this test is expected
    7863              :           // to return false.
    7864              : 
    7865        11583 :           Bexpression* neg_one_expr =
    7866        11583 :               gogo->backend()->integer_constant_expression(right_btype, neg_one);
    7867        11583 :           Bexpression* check =
    7868        11583 :               gogo->backend()->binary_expression(OPERATOR_EQEQ,
    7869              :                                                  right, neg_one_expr, loc);
    7870              : 
    7871        11583 :           Bexpression* zero_expr =
    7872        11583 :               gogo->backend()->integer_constant_expression(btype, zero);
    7873        11583 :           Bexpression* one_expr =
    7874        11583 :               gogo->backend()->integer_constant_expression(btype, one);
    7875        11583 :           Bfunction* bfn = context->function()->func_value()->get_decl();
    7876              : 
    7877        23166 :           if (type->integer_type()->is_unsigned())
    7878              :             {
    7879              :               // An unsigned -1 is the largest possible number, so
    7880              :               // dividing is always 1 or 0.
    7881              : 
    7882         5288 :               Bexpression* cmp =
    7883         5288 :                   gogo->backend()->binary_expression(OPERATOR_EQEQ,
    7884              :                                                      left, right, loc);
    7885         5288 :               if (this->op_ == OPERATOR_DIV)
    7886         3207 :                 overflow =
    7887         3207 :                     gogo->backend()->conditional_expression(bfn, btype, cmp,
    7888              :                                                             one_expr, zero_expr,
    7889              :                                                             loc);
    7890              :               else
    7891         2081 :                 overflow =
    7892         2081 :                     gogo->backend()->conditional_expression(bfn, btype, cmp,
    7893              :                                                             zero_expr, left,
    7894              :                                                             loc);
    7895              :             }
    7896              :           else
    7897              :             {
    7898              :               // Computing left / -1 is the same as computing - left,
    7899              :               // which does not overflow since Go sets -fwrapv.
    7900         6295 :               if (this->op_ == OPERATOR_DIV)
    7901              :                 {
    7902         4134 :                   Expression* negate_expr =
    7903         4134 :                       Expression::make_unary(OPERATOR_MINUS, this->left_, loc);
    7904         4134 :                   overflow = negate_expr->get_backend(context);
    7905              :                 }
    7906              :               else
    7907              :                 overflow = zero_expr;
    7908              :             }
    7909        11583 :           overflow = gogo->backend()->convert_expression(btype, overflow, loc);
    7910              : 
    7911              :           // right == -1 ? - left : ret
    7912        11583 :           ret = gogo->backend()->conditional_expression(bfn, btype,
    7913              :                                                         check, overflow,
    7914              :                                                         ret, loc);
    7915              :         }
    7916              :     }
    7917              : 
    7918       729111 :   mpz_clear(zero);
    7919       729111 :   mpz_clear(one);
    7920       729111 :   mpz_clear(neg_one);
    7921       729111 :   return ret;
    7922              : }
    7923              : 
    7924              : // Export a binary expression.
    7925              : 
    7926              : void
    7927        16026 : Binary_expression::do_export(Export_function_body* efb) const
    7928              : {
    7929        16026 :   efb->write_c_string("(");
    7930        16026 :   this->left_->export_expression(efb);
    7931        16026 :   switch (this->op_)
    7932              :     {
    7933          607 :     case OPERATOR_OROR:
    7934          607 :       efb->write_c_string(" || ");
    7935          607 :       break;
    7936         1193 :     case OPERATOR_ANDAND:
    7937         1193 :       efb->write_c_string(" && ");
    7938         1193 :       break;
    7939         2323 :     case OPERATOR_EQEQ:
    7940         2323 :       efb->write_c_string(" == ");
    7941         2323 :       break;
    7942          872 :     case OPERATOR_NOTEQ:
    7943          872 :       efb->write_c_string(" != ");
    7944          872 :       break;
    7945         1526 :     case OPERATOR_LT:
    7946         1526 :       efb->write_c_string(" < ");
    7947         1526 :       break;
    7948          785 :     case OPERATOR_LE:
    7949          785 :       efb->write_c_string(" <= ");
    7950          785 :       break;
    7951          355 :     case OPERATOR_GT:
    7952          355 :       efb->write_c_string(" > ");
    7953          355 :       break;
    7954         1052 :     case OPERATOR_GE:
    7955         1052 :       efb->write_c_string(" >= ");
    7956         1052 :       break;
    7957         1746 :     case OPERATOR_PLUS:
    7958         1746 :       efb->write_c_string(" + ");
    7959         1746 :       break;
    7960         1185 :     case OPERATOR_MINUS:
    7961         1185 :       efb->write_c_string(" - ");
    7962         1185 :       break;
    7963          430 :     case OPERATOR_OR:
    7964          430 :       efb->write_c_string(" | ");
    7965          430 :       break;
    7966          163 :     case OPERATOR_XOR:
    7967          163 :       efb->write_c_string(" ^ ");
    7968          163 :       break;
    7969          534 :     case OPERATOR_MULT:
    7970          534 :       efb->write_c_string(" * ");
    7971          534 :       break;
    7972          430 :     case OPERATOR_DIV:
    7973          430 :       efb->write_c_string(" / ");
    7974          430 :       break;
    7975          187 :     case OPERATOR_MOD:
    7976          187 :       efb->write_c_string(" % ");
    7977          187 :       break;
    7978          386 :     case OPERATOR_LSHIFT:
    7979          386 :       efb->write_c_string(" << ");
    7980          386 :       break;
    7981         1125 :     case OPERATOR_RSHIFT:
    7982         1125 :       efb->write_c_string(" >> ");
    7983         1125 :       break;
    7984         1046 :     case OPERATOR_AND:
    7985         1046 :       efb->write_c_string(" & ");
    7986         1046 :       break;
    7987           81 :     case OPERATOR_BITCLEAR:
    7988           81 :       efb->write_c_string(" &^ ");
    7989           81 :       break;
    7990            0 :     default:
    7991            0 :       go_unreachable();
    7992              :     }
    7993        16026 :   this->right_->export_expression(efb);
    7994        16026 :   efb->write_c_string(")");
    7995        16026 : }
    7996              : 
    7997              : // Import a binary expression.
    7998              : 
    7999              : Expression*
    8000        22026 : Binary_expression::do_import(Import_expression* imp, Location loc)
    8001              : {
    8002        22026 :   imp->require_c_string("(");
    8003              : 
    8004        22026 :   Expression* left = Expression::import_expression(imp, loc);
    8005              : 
    8006        22026 :   Operator op;
    8007        22026 :   if (imp->match_c_string(" || "))
    8008              :     {
    8009          652 :       op = OPERATOR_OROR;
    8010          652 :       imp->advance(4);
    8011              :     }
    8012        21374 :   else if (imp->match_c_string(" && "))
    8013              :     {
    8014         1823 :       op = OPERATOR_ANDAND;
    8015         1823 :       imp->advance(4);
    8016              :     }
    8017        19551 :   else if (imp->match_c_string(" == "))
    8018              :     {
    8019         3241 :       op = OPERATOR_EQEQ;
    8020         3241 :       imp->advance(4);
    8021              :     }
    8022        16310 :   else if (imp->match_c_string(" != "))
    8023              :     {
    8024          843 :       op = OPERATOR_NOTEQ;
    8025          843 :       imp->advance(4);
    8026              :     }
    8027        15467 :   else if (imp->match_c_string(" < "))
    8028              :     {
    8029         1154 :       op = OPERATOR_LT;
    8030         1154 :       imp->advance(3);
    8031              :     }
    8032        14313 :   else if (imp->match_c_string(" <= "))
    8033              :     {
    8034          988 :       op = OPERATOR_LE;
    8035          988 :       imp->advance(4);
    8036              :     }
    8037        13325 :   else if (imp->match_c_string(" > "))
    8038              :     {
    8039          226 :       op = OPERATOR_GT;
    8040          226 :       imp->advance(3);
    8041              :     }
    8042        13099 :   else if (imp->match_c_string(" >= "))
    8043              :     {
    8044         2482 :       op = OPERATOR_GE;
    8045         2482 :       imp->advance(4);
    8046              :     }
    8047        10617 :   else if (imp->match_c_string(" + "))
    8048              :     {
    8049         1789 :       op = OPERATOR_PLUS;
    8050         1789 :       imp->advance(3);
    8051              :     }
    8052         8828 :   else if (imp->match_c_string(" - "))
    8053              :     {
    8054         1554 :       op = OPERATOR_MINUS;
    8055         1554 :       imp->advance(3);
    8056              :     }
    8057         7274 :   else if (imp->match_c_string(" | "))
    8058              :     {
    8059          347 :       op = OPERATOR_OR;
    8060          347 :       imp->advance(3);
    8061              :     }
    8062         6927 :   else if (imp->match_c_string(" ^ "))
    8063              :     {
    8064          152 :       op = OPERATOR_XOR;
    8065          152 :       imp->advance(3);
    8066              :     }
    8067         6775 :   else if (imp->match_c_string(" * "))
    8068              :     {
    8069          573 :       op = OPERATOR_MULT;
    8070          573 :       imp->advance(3);
    8071              :     }
    8072         6202 :   else if (imp->match_c_string(" / "))
    8073              :     {
    8074          223 :       op = OPERATOR_DIV;
    8075          223 :       imp->advance(3);
    8076              :     }
    8077         5979 :   else if (imp->match_c_string(" % "))
    8078              :     {
    8079           40 :       op = OPERATOR_MOD;
    8080           40 :       imp->advance(3);
    8081              :     }
    8082         5939 :   else if (imp->match_c_string(" << "))
    8083              :     {
    8084          120 :       op = OPERATOR_LSHIFT;
    8085          120 :       imp->advance(4);
    8086              :     }
    8087         5819 :   else if (imp->match_c_string(" >> "))
    8088              :     {
    8089          941 :       op = OPERATOR_RSHIFT;
    8090          941 :       imp->advance(4);
    8091              :     }
    8092         4878 :   else if (imp->match_c_string(" & "))
    8093              :     {
    8094          940 :       op = OPERATOR_AND;
    8095          940 :       imp->advance(3);
    8096              :     }
    8097         3938 :   else if (imp->match_c_string(" &^ "))
    8098              :     {
    8099           74 :       op = OPERATOR_BITCLEAR;
    8100           74 :       imp->advance(4);
    8101              :     }
    8102         3864 :   else if (imp->match_c_string(")"))
    8103              :     {
    8104              :       // Not a binary operator after all.
    8105         3864 :       imp->advance(1);
    8106         3864 :       return left;
    8107              :     }
    8108              :   else
    8109              :     {
    8110            0 :       go_error_at(imp->location(), "unrecognized binary operator");
    8111            0 :       return Expression::make_error(loc);
    8112              :     }
    8113              : 
    8114        18162 :   Expression* right = Expression::import_expression(imp, loc);
    8115              : 
    8116        18162 :   imp->require_c_string(")");
    8117              : 
    8118        18162 :   return Expression::make_binary(op, left, right, loc);
    8119              : }
    8120              : 
    8121              : // Dump ast representation of a binary expression.
    8122              : 
    8123              : void
    8124            0 : Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
    8125              : {
    8126            0 :   ast_dump_context->ostream() << "(";
    8127            0 :   ast_dump_context->dump_expression(this->left_);
    8128            0 :   ast_dump_context->ostream() << " ";
    8129            0 :   ast_dump_context->dump_operator(this->op_);
    8130            0 :   ast_dump_context->ostream() << " ";
    8131            0 :   ast_dump_context->dump_expression(this->right_);
    8132            0 :   ast_dump_context->ostream() << ") ";
    8133            0 : }
    8134              : 
    8135              : // Make a binary expression.
    8136              : 
    8137              : Expression*
    8138      2341942 : Expression::make_binary(Operator op, Expression* left, Expression* right,
    8139              :                         Location location)
    8140              : {
    8141      2341942 :   return new Binary_expression(op, left, right, location);
    8142              : }
    8143              : 
    8144              : // Implement a comparison.
    8145              : 
    8146              : Bexpression*
    8147      1266990 : Expression::comparison(Translate_context* context, Type* result_type,
    8148              :                        Operator op, Expression* left, Expression* right,
    8149              :                        Location location)
    8150              : {
    8151      1266990 :   Gogo* gogo = context->gogo();
    8152      1266990 :   Type* left_type = left->type();
    8153      1266990 :   Type* right_type = right->type();
    8154              : 
    8155      1266990 :   Expression* zexpr = Expression::make_integer_ul(0, NULL, location);
    8156              : 
    8157      1266990 :   if (left_type->is_string_type() && right_type->is_string_type())
    8158              :     {
    8159        45351 :       go_assert(left->is_multi_eval_safe());
    8160        45351 :       go_assert(right->is_multi_eval_safe());
    8161              : 
    8162        45351 :       if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
    8163              :         {
    8164              :           // (l.len == r.len
    8165              :           //  ? (l.ptr == r.ptr ? true : memcmp(l.ptr, r.ptr, r.len) == 0)
    8166              :           //  : false)
    8167        44859 :           Expression* llen = Expression::make_string_info(left,
    8168              :                                                           STRING_INFO_LENGTH,
    8169              :                                                           location);
    8170        44859 :           Expression* rlen = Expression::make_string_info(right,
    8171              :                                                           STRING_INFO_LENGTH,
    8172              :                                                           location);
    8173        44859 :           Expression* leneq = Expression::make_binary(OPERATOR_EQEQ, llen, rlen,
    8174              :                                                       location);
    8175        44859 :           Expression* lptr = Expression::make_string_info(left->copy(),
    8176              :                                                           STRING_INFO_DATA,
    8177              :                                                           location);
    8178        44859 :           Expression* rptr = Expression::make_string_info(right->copy(),
    8179              :                                                           STRING_INFO_DATA,
    8180              :                                                           location);
    8181        44859 :           Expression* ptreq = Expression::make_binary(OPERATOR_EQEQ, lptr, rptr,
    8182              :                                                       location);
    8183        44859 :           Expression* btrue = Expression::make_boolean(true, location);
    8184        44859 :           Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP,
    8185              :                                                 location, 3,
    8186              :                                                 lptr->copy(), rptr->copy(),
    8187              :                                                 rlen->copy());
    8188        44859 :           Type* int32_type = Type::lookup_integer_type("int32");
    8189        44859 :           Expression* zero = Expression::make_integer_ul(0, int32_type, location);
    8190        44859 :           Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, call, zero,
    8191              :                                                     location);
    8192        44859 :           Expression* cond = Expression::make_conditional(ptreq, btrue, cmp,
    8193              :                                                           location);
    8194        44859 :           Expression* bfalse = Expression::make_boolean(false, location);
    8195        44859 :           left = Expression::make_conditional(leneq, cond, bfalse, location);
    8196        44859 :           right = Expression::make_boolean(true, location);
    8197              :         }
    8198              :       else
    8199              :         {
    8200          492 :           left = Runtime::make_call(gogo, Runtime::CMPSTRING, location, 2,
    8201              :                                     left, right);
    8202          492 :           right = zexpr;
    8203              :         }
    8204              :     }
    8205      1221639 :   else if ((left_type->interface_type() != NULL
    8206        60274 :             && right_type->interface_type() == NULL
    8207        52571 :             && !right_type->is_nil_type())
    8208      1220095 :            || (left_type->interface_type() == NULL
    8209      1161365 :                && !left_type->is_nil_type()
    8210      1161361 :                && right_type->interface_type() != NULL))
    8211              :     {
    8212              :       // Comparing an interface value to a non-interface value.
    8213         3236 :       if (left_type->interface_type() == NULL)
    8214              :         {
    8215              :           std::swap(left_type, right_type);
    8216              :           std::swap(left, right);
    8217              :         }
    8218              : 
    8219              :       // The right operand is not an interface.  We need to take its
    8220              :       // address if it is not a direct interface type.
    8221         1692 :       Expression* pointer_arg = NULL;
    8222         1692 :       if (right_type->is_direct_iface_type())
    8223          565 :         pointer_arg = Expression::unpack_direct_iface(right, location);
    8224              :       else
    8225              :         {
    8226         1127 :           go_assert(right->is_addressable());
    8227         1127 :           pointer_arg = Expression::make_unary(OPERATOR_AND, right,
    8228              :                                                location);
    8229              :         }
    8230              : 
    8231         1692 :       Expression* descriptor =
    8232         1692 :           Expression::make_type_descriptor(right_type, location);
    8233         2990 :       left = Runtime::make_call(gogo,
    8234         3384 :                                 (left_type->interface_type()->is_empty()
    8235              :                                  ? Runtime::EFACEVALEQ
    8236              :                                  : Runtime::IFACEVALEQ),
    8237              :                                 location, 3, left, descriptor,
    8238              :                                 pointer_arg);
    8239         1692 :       go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
    8240         1692 :       right = Expression::make_boolean(true, location);
    8241              :     }
    8242      1219947 :   else if (left_type->interface_type() != NULL
    8243        58730 :            && right_type->interface_type() != NULL)
    8244              :     {
    8245         7703 :       Runtime::Function compare_function;
    8246        15406 :       if (left_type->interface_type()->is_empty()
    8247         8573 :           && right_type->interface_type()->is_empty())
    8248              :         compare_function = Runtime::EFACEEQ;
    8249        13766 :       else if (!left_type->interface_type()->is_empty()
    8250        13716 :                && !right_type->interface_type()->is_empty())
    8251              :         compare_function = Runtime::IFACEEQ;
    8252              :       else
    8253              :         {
    8254          104 :           if (left_type->interface_type()->is_empty())
    8255              :             {
    8256           50 :               std::swap(left_type, right_type);
    8257           50 :               std::swap(left, right);
    8258              :             }
    8259          104 :           go_assert(!left_type->interface_type()->is_empty());
    8260          104 :           go_assert(right_type->interface_type()->is_empty());
    8261              :           compare_function = Runtime::IFACEEFACEEQ;
    8262              :         }
    8263              : 
    8264         7703 :       left = Runtime::make_call(gogo, compare_function, location, 2,
    8265              :                                 left, right);
    8266         7703 :       go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
    8267         7703 :       right = Expression::make_boolean(true, location);
    8268              :     }
    8269              : 
    8270      1266990 :   if (left_type->is_nil_type()
    8271      1266990 :       && (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ))
    8272              :     {
    8273              :       std::swap(left_type, right_type);
    8274              :       std::swap(left, right);
    8275              :     }
    8276              : 
    8277      1266990 :   if (right_type->is_nil_type())
    8278              :     {
    8279       124823 :       right = Expression::make_nil(location);
    8280       124823 :       if (left_type->array_type() != NULL
    8281         6666 :           && left_type->array_type()->length() == NULL)
    8282              :         {
    8283         3333 :           Array_type* at = left_type->array_type();
    8284         3333 :           left = at->get_value_pointer(context->gogo(), left);
    8285              :         }
    8286       121490 :       else if (left_type->interface_type() != NULL)
    8287              :         {
    8288              :           // An interface is nil if the first field is nil.
    8289        51028 :           left = Expression::make_field_reference(left, 0, location);
    8290              :         }
    8291              :     }
    8292              : 
    8293      1266990 :   left->determine_type_no_context(gogo);
    8294      1266990 :   right->determine_type_no_context(gogo);
    8295              : 
    8296      1266990 :   Bexpression* left_bexpr = left->get_backend(context);
    8297      1266990 :   Bexpression* right_bexpr = right->get_backend(context);
    8298              : 
    8299      1266990 :   Bexpression* ret = gogo->backend()->binary_expression(op, left_bexpr,
    8300              :                                                         right_bexpr, location);
    8301      1266990 :   if (result_type != NULL)
    8302      1266885 :     ret = gogo->backend()->convert_expression(result_type->get_backend(gogo),
    8303              :                                               ret, location);
    8304      1266990 :   return ret;
    8305              : }
    8306              : 
    8307              : // Class String_concat_expression.
    8308              : 
    8309              : bool
    8310         1461 : String_concat_expression::do_is_constant() const
    8311              : {
    8312         2295 :   for (Expression_list::const_iterator pe = this->exprs_->begin();
    8313         2295 :        pe != this->exprs_->end();
    8314          834 :        ++pe)
    8315              :     {
    8316         2295 :       if (!(*pe)->is_constant())
    8317         1461 :         return false;
    8318              :     }
    8319              :   return true;
    8320              : }
    8321              : 
    8322              : bool
    8323          403 : String_concat_expression::do_is_untyped(Type** ptype) const
    8324              : {
    8325          403 :   for (Expression_list::iterator pe = this->exprs_->begin();
    8326          403 :        pe != this->exprs_->end();
    8327            0 :        ++pe)
    8328              :     {
    8329          403 :       if (!(*pe)->is_untyped(ptype))
    8330          403 :         return false;
    8331              :     }
    8332              : 
    8333            0 :   *ptype = Type::make_string_type();
    8334            0 :   return true;
    8335              : }
    8336              : 
    8337              : bool
    8338            6 : String_concat_expression::do_is_zero_value() const
    8339              : {
    8340            6 :   for (Expression_list::const_iterator pe = this->exprs_->begin();
    8341            6 :        pe != this->exprs_->end();
    8342            0 :        ++pe)
    8343              :     {
    8344            6 :       if (!(*pe)->is_zero_value())
    8345            6 :         return false;
    8346              :     }
    8347              :   return true;
    8348              : }
    8349              : 
    8350              : bool
    8351           39 : String_concat_expression::do_is_static_initializer() const
    8352              : {
    8353           52 :   for (Expression_list::const_iterator pe = this->exprs_->begin();
    8354           52 :        pe != this->exprs_->end();
    8355           13 :        ++pe)
    8356              :     {
    8357           52 :       if (!(*pe)->is_static_initializer())
    8358           39 :         return false;
    8359              :     }
    8360              :   return true;
    8361              : }
    8362              : 
    8363              : Type*
    8364       109310 : String_concat_expression::do_type()
    8365              : {
    8366       109310 :   Type* t = this->exprs_->front()->type();
    8367       109310 :   Expression_list::iterator pe = this->exprs_->begin();
    8368       109310 :   ++pe;
    8369       290786 :   for (; pe != this->exprs_->end(); ++pe)
    8370              :     {
    8371       181476 :       Type* t1;
    8372       181476 :       if (!Binary_expression::operation_type(OPERATOR_PLUS, t,
    8373       181476 :                                              (*pe)->type(),
    8374              :                                              &t1))
    8375            0 :         return Type::make_error_type();
    8376       181476 :       t = t1;
    8377              :     }
    8378              :   return t;
    8379              : }
    8380              : 
    8381              : void
    8382         3795 : String_concat_expression::do_determine_type(Gogo* gogo,
    8383              :                                             const Type_context* context)
    8384              : {
    8385         3795 :   Type_context subcontext(*context);
    8386         3795 :   for (Expression_list::iterator pe = this->exprs_->begin();
    8387         3795 :        pe != this->exprs_->end();
    8388            0 :        ++pe)
    8389              :     {
    8390         3795 :       Type* t = (*pe)->type();
    8391         3795 :       if (!t->is_abstract())
    8392              :         {
    8393         3795 :           subcontext.type = t;
    8394         3795 :           break;
    8395              :         }
    8396              :     }
    8397         3795 :   if (subcontext.type == NULL)
    8398            0 :     subcontext.type = this->exprs_->front()->type();
    8399        14101 :   for (Expression_list::iterator pe = this->exprs_->begin();
    8400        14101 :        pe != this->exprs_->end();
    8401        10306 :        ++pe)
    8402        10306 :     (*pe)->determine_type(gogo, &subcontext);
    8403         3795 : }
    8404              : 
    8405              : void
    8406           21 : String_concat_expression::do_check_types(Gogo*)
    8407              : {
    8408           21 :   if (this->is_error_expression())
    8409              :     return;
    8410           21 :   Type* t = this->exprs_->front()->type();
    8411           21 :   if (t->is_error())
    8412              :     {
    8413            0 :       this->set_is_error();
    8414            0 :       return;
    8415              :     }
    8416           21 :   Expression_list::iterator pe = this->exprs_->begin();
    8417           21 :   ++pe;
    8418           48 :   for (; pe != this->exprs_->end(); ++pe)
    8419              :     {
    8420           27 :       Type* t1 = (*pe)->type();
    8421           27 :       if (!Type::are_compatible_for_binop(t, t1))
    8422              :         {
    8423            0 :           this->report_error("incompatible types in binary expression");
    8424            0 :           return;
    8425              :         }
    8426           27 :       if (!Binary_expression::check_operator_type(OPERATOR_PLUS, t, t1,
    8427              :                                                   this->location()))
    8428              :         {
    8429            0 :           this->set_is_error();
    8430            0 :           return;
    8431              :         }
    8432              :     }
    8433              : }
    8434              : 
    8435              : Expression*
    8436        10472 : String_concat_expression::do_flatten(Gogo* gogo, Named_object*,
    8437              :                                      Statement_inserter* inserter)
    8438              : {
    8439        10472 :   if (this->is_error_expression())
    8440            0 :     return this;
    8441        10472 :   Location loc = this->location();
    8442        10472 :   Type* type = this->type();
    8443              : 
    8444              :   // Mark string([]byte) operands to reuse the backing store.
    8445              :   // runtime.concatstrings does not keep the reference.
    8446              :   //
    8447              :   // Note: in the gc runtime, if all but one inputs are empty,
    8448              :   // concatstrings returns the only nonempty input without copy.
    8449              :   // So it is not safe to reuse the backing store if it is a
    8450              :   // string([]byte) conversion. So the gc compiler does the
    8451              :   // no-copy optimization only when there is at least one
    8452              :   // constant nonempty input. Currently the gccgo runtime
    8453              :   // doesn't do this, so we don't do the check.
    8454        10472 :   for (Expression_list::iterator p = this->exprs_->begin();
    8455        37161 :        p != this->exprs_->end();
    8456        26689 :        ++p)
    8457              :     {
    8458        27106 :       Type_conversion_expression* tce = (*p)->conversion_expression();
    8459          417 :       if (tce != NULL)
    8460          417 :         tce->set_no_copy(true);
    8461              :     }
    8462              : 
    8463        10472 :   Expression* buf = NULL;
    8464        10472 :   Node* n = Node::make_node(this);
    8465        10472 :   if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
    8466              :     {
    8467         1205 :       size_t size = 0;
    8468         1205 :       for (Expression_list::iterator p = this->exprs_->begin();
    8469         4128 :            p != this->exprs_->end();
    8470         2923 :            ++p)
    8471              :         {
    8472         2923 :           std::string s;
    8473         2923 :           if ((*p)->string_constant_value(&s))
    8474         1342 :             size += s.length();
    8475         2923 :         }
    8476              :       // Make a buffer on stack if the result does not escape.
    8477              :       // But don't do this if we know it won't fit.
    8478         1205 :       if (size < (size_t)tmp_string_buf_size)
    8479              :         {
    8480         1129 :           Type* byte_type = Type::lookup_integer_type("uint8");
    8481         1129 :           Expression* buflen =
    8482         1129 :             Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
    8483         1129 :           Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
    8484         1129 :           Type* array_type = Type::make_array_type(byte_type, buflen);
    8485         1129 :           buf = Expression::make_allocation(array_type, loc);
    8486         1129 :           buf->allocation_expression()->set_allocate_on_stack();
    8487         1129 :           buf->allocation_expression()->set_no_zero();
    8488              :         }
    8489              :     }
    8490         1129 :   if (buf == NULL)
    8491         9343 :     buf = Expression::make_nil(loc);
    8492        10472 :   go_assert(this->exprs_->size() > 1);
    8493        10472 :   Expression* len =
    8494        10472 :     Expression::make_integer_ul(this->exprs_->size(), NULL, loc);
    8495        10472 :   Array_type* array_type = Type::make_array_type(type, len);
    8496        10472 :   array_type->set_is_array_incomparable();
    8497        10472 :   Expression* array =
    8498        10472 :     Expression::make_array_composite_literal(array_type, this->exprs_,
    8499              :                                              loc);
    8500        10472 :   Temporary_statement* ts =
    8501        10472 :     Statement::make_temporary(array_type, array, loc);
    8502        10472 :   ts->determine_types(gogo);
    8503        10472 :   inserter->insert(ts);
    8504        10472 :   Expression* ref = Expression::make_temporary_reference(ts, loc);
    8505        10472 :   ref = Expression::make_unary(OPERATOR_AND, ref, loc);
    8506        10472 :   Expression* call =
    8507        10472 :     Runtime::make_call(gogo, Runtime::CONCATSTRINGS, loc, 3, buf,
    8508              :                        ref, len->copy());
    8509        10472 :   Expression* ret = Expression::make_cast(type, call, loc);
    8510        10472 :   Type_context context(type, false);
    8511        10472 :   ret->determine_type(gogo, &context);
    8512        10472 :   return ret;
    8513              : }
    8514              : 
    8515              : void
    8516            0 : String_concat_expression::do_dump_expression(
    8517              :     Ast_dump_context* ast_dump_context) const
    8518              : {
    8519            0 :   ast_dump_context->ostream() << "concat(";
    8520            0 :   ast_dump_context->dump_expression_list(this->exprs_, false);
    8521            0 :   ast_dump_context->ostream() << ")";
    8522            0 : }
    8523              : 
    8524              : Expression*
    8525        16280 : Expression::make_string_concat(Expression_list* exprs)
    8526              : {
    8527        16280 :   return new String_concat_expression(exprs);
    8528              : }
    8529              : 
    8530              : // Class Bound_method_expression.
    8531              : 
    8532              : // Traversal.
    8533              : 
    8534              : int
    8535       401478 : Bound_method_expression::do_traverse(Traverse* traverse)
    8536              : {
    8537       401478 :   return Expression::traverse(&this->expr_, traverse);
    8538              : }
    8539              : 
    8540              : // Return the type of a bound method expression.  The type of this
    8541              : // object is simply the type of the method with no receiver.
    8542              : 
    8543              : Type*
    8544      2418516 : Bound_method_expression::do_type()
    8545              : {
    8546      2418516 :   Named_object* fn = this->method_->named_object();
    8547      2418516 :   Function_type* fntype;
    8548      2418516 :   if (fn->is_function())
    8549      1356007 :     fntype = fn->func_value()->type();
    8550      1062509 :   else if (fn->is_function_declaration())
    8551      1062509 :     fntype = fn->func_declaration_value()->type();
    8552              :   else
    8553            0 :     return Type::make_error_type();
    8554      2418516 :   return fntype->copy_without_receiver();
    8555              : }
    8556              : 
    8557              : // Determine the types of a method expression.
    8558              : 
    8559              : void
    8560       264971 : Bound_method_expression::do_determine_type(Gogo* gogo, const Type_context*)
    8561              : {
    8562       264971 :   Named_object* fn = this->method_->named_object();
    8563       264971 :   Function_type* fntype;
    8564       264971 :   if (fn->is_function())
    8565       137245 :     fntype = fn->func_value()->type();
    8566       127726 :   else if (fn->is_function_declaration())
    8567       127726 :     fntype = fn->func_declaration_value()->type();
    8568              :   else
    8569              :     fntype = NULL;
    8570       264971 :   if (fntype == NULL || !fntype->is_method())
    8571            0 :     this->expr_->determine_type_no_context(gogo);
    8572              :   else
    8573              :     {
    8574       264971 :       Type_context subcontext(fntype->receiver()->type(), false);
    8575       264971 :       this->expr_->determine_type(gogo, &subcontext);
    8576              :     }
    8577       264971 : }
    8578              : 
    8579              : // Check the types of a method expression.
    8580              : 
    8581              : void
    8582        23671 : Bound_method_expression::do_check_types(Gogo*)
    8583              : {
    8584        23671 :   Named_object* fn = this->function();
    8585        23671 :   if (!fn->is_function() && !fn->is_function_declaration())
    8586              :     {
    8587            0 :       this->report_error(_("object is not a method"));
    8588            0 :       return;
    8589              :     }
    8590              : 
    8591        23671 :   Function_type* fntype;
    8592        23671 :   if (fn->is_function())
    8593        10989 :     fntype = fn->func_value()->type();
    8594        12682 :   else if (fn->is_function_declaration())
    8595        12682 :     fntype = fn->func_declaration_value()->type();
    8596              :   else
    8597              :     go_unreachable();
    8598        23671 :   Type* rtype = fntype->receiver()->type()->deref();
    8599        23671 :   Type* etype = (this->expr_type_ != NULL
    8600        23671 :                  ? this->expr_type_
    8601        23671 :                  : this->expr_->type());
    8602        23671 :   etype = etype->deref();
    8603        23671 :   if (!Type::are_identical(rtype, etype, Type::COMPARE_TAGS, NULL))
    8604            0 :     this->report_error(_("method type does not match object type"));
    8605              : }
    8606              : 
    8607              : // If a bound method expression is not simply called, then it is
    8608              : // represented as a closure.  The closure will hold a single variable,
    8609              : // the receiver to pass to the method.  The function will be a simple
    8610              : // thunk that pulls that value from the closure and calls the method
    8611              : // with the remaining arguments.
    8612              : //
    8613              : // Because method values are not common, we don't build all thunks for
    8614              : // every methods, but instead only build them as we need them.  In
    8615              : // particular, we even build them on demand for methods defined in
    8616              : // other packages.
    8617              : 
    8618              : Bound_method_expression::Method_value_thunks
    8619              :   Bound_method_expression::method_value_thunks;
    8620              : 
    8621              : // Find or create the thunk for FN.
    8622              : 
    8623              : Named_object*
    8624          934 : Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
    8625              :                                       Named_object* fn)
    8626              : {
    8627          934 :   std::pair<Named_object*, Named_object*> val(fn, NULL);
    8628          934 :   std::pair<Method_value_thunks::iterator, bool> ins =
    8629          934 :     Bound_method_expression::method_value_thunks.insert(val);
    8630          934 :   if (!ins.second)
    8631              :     {
    8632              :       // We have seen this method before.
    8633          287 :       go_assert(ins.first->second != NULL);
    8634              :       return ins.first->second;
    8635              :     }
    8636              : 
    8637          647 :   Location loc = fn->location();
    8638              : 
    8639          647 :   Function_type* orig_fntype;
    8640          647 :   if (fn->is_function())
    8641          541 :     orig_fntype = fn->func_value()->type();
    8642          106 :   else if (fn->is_function_declaration())
    8643          106 :     orig_fntype = fn->func_declaration_value()->type();
    8644              :   else
    8645              :     orig_fntype = NULL;
    8646              : 
    8647          647 :   if (orig_fntype == NULL || !orig_fntype->is_method())
    8648              :     {
    8649            0 :       ins.first->second =
    8650            0 :         Named_object::make_erroneous_name(gogo->thunk_name());
    8651            0 :       return ins.first->second;
    8652              :     }
    8653              : 
    8654          647 :   Struct_field_list* sfl = new Struct_field_list();
    8655              :   // The type here is wrong--it should be the C function type.  But it
    8656              :   // doesn't really matter.
    8657          647 :   Type* vt = Type::make_pointer_type(Type::make_void_type());
    8658         1294 :   sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
    8659         1294 :   sfl->push_back(Struct_field(Typed_identifier("val",
    8660              :                                                orig_fntype->receiver()->type(),
    8661         1294 :                                                loc)));
    8662          647 :   Struct_type* st = Type::make_struct_type(sfl, loc);
    8663          647 :   st->set_is_struct_incomparable();
    8664          647 :   Type* closure_type = Type::make_pointer_type(st);
    8665              : 
    8666          647 :   Function_type* new_fntype = orig_fntype->copy_with_names();
    8667              : 
    8668          647 :   std::string thunk_name = gogo->thunk_name();
    8669          647 :   Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
    8670              :                                               false, loc);
    8671              : 
    8672          647 :   Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
    8673          647 :   cvar->set_is_used();
    8674          647 :   cvar->set_is_closure();
    8675          647 :   Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
    8676              :                                                  NULL, cvar);
    8677          647 :   new_no->func_value()->set_closure_var(cp);
    8678              : 
    8679          647 :   gogo->start_block(loc);
    8680              : 
    8681              :   // Field 0 of the closure is the function code pointer, field 1 is
    8682              :   // the value on which to invoke the method.
    8683          647 :   Expression* arg = Expression::make_var_reference(cp, loc);
    8684          647 :   arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
    8685          647 :   arg = Expression::make_field_reference(arg, 1, loc);
    8686              : 
    8687          647 :   Expression* bme = Expression::make_bound_method(arg, method, fn, loc);
    8688              : 
    8689          647 :   const Typed_identifier_list* orig_params = orig_fntype->parameters();
    8690          647 :   Expression_list* args;
    8691          647 :   if (orig_params == NULL || orig_params->empty())
    8692              :     args = NULL;
    8693              :   else
    8694              :     {
    8695          386 :       const Typed_identifier_list* new_params = new_fntype->parameters();
    8696          386 :       args = new Expression_list();
    8697          386 :       for (Typed_identifier_list::const_iterator p = new_params->begin();
    8698         1135 :            p != new_params->end();
    8699          749 :            ++p)
    8700              :         {
    8701          749 :           Named_object* p_no = gogo->lookup(p->name(), NULL);
    8702          749 :           go_assert(p_no != NULL
    8703              :                     && p_no->is_variable()
    8704              :                     && p_no->var_value()->is_parameter());
    8705          749 :           args->push_back(Expression::make_var_reference(p_no, loc));
    8706              :         }
    8707              :     }
    8708              : 
    8709          647 :   Call_expression* call = Expression::make_call(bme, args,
    8710          647 :                                                 orig_fntype->is_varargs(),
    8711              :                                                 loc);
    8712          647 :   call->set_varargs_are_lowered();
    8713              : 
    8714          647 :   Statement* s = Statement::make_return_from_call(new_no, call, loc);
    8715          647 :   s->determine_types(gogo);
    8716          647 :   gogo->add_statement(s);
    8717          647 :   Block* b = gogo->finish_block(loc);
    8718          647 :   gogo->add_block(b, loc);
    8719              : 
    8720              :   // This is called after lowering.
    8721          647 :   gogo->lower_block(new_no, b);
    8722              : 
    8723          647 :   gogo->finish_function(loc);
    8724              : 
    8725          647 :   ins.first->second = new_no;
    8726          647 :   return new_no;
    8727          647 : }
    8728              : 
    8729              : // Look up a thunk for FN.
    8730              : 
    8731              : Named_object*
    8732          934 : Bound_method_expression::lookup_thunk(Named_object* fn)
    8733              : {
    8734          934 :   Method_value_thunks::const_iterator p =
    8735          934 :     Bound_method_expression::method_value_thunks.find(fn);
    8736          934 :   if (p == Bound_method_expression::method_value_thunks.end())
    8737              :     return NULL;
    8738          934 :   return p->second;
    8739              : }
    8740              : 
    8741              : // Return an expression to check *REF for nil while dereferencing
    8742              : // according to FIELD_INDEXES.  Update *REF to build up the field
    8743              : // reference.  This is a static function so that we don't have to
    8744              : // worry about declaring Field_indexes in expressions.h.
    8745              : 
    8746              : static Expression*
    8747           31 : bme_check_nil(const Method::Field_indexes* field_indexes, Location loc,
    8748              :               Expression** ref)
    8749              : {
    8750           31 :   if (field_indexes == NULL)
    8751           14 :     return Expression::make_boolean(false, loc);
    8752           17 :   Expression* cond = bme_check_nil(field_indexes->next, loc, ref);
    8753           34 :   Struct_type* stype = (*ref)->type()->deref()->struct_type();
    8754           17 :   go_assert(stype != NULL
    8755              :             && field_indexes->field_index < stype->field_count());
    8756           17 :   if ((*ref)->type()->struct_type() == NULL)
    8757              :     {
    8758           10 :       go_assert((*ref)->type()->points_to() != NULL);
    8759           10 :       Expression* n = Expression::make_binary(OPERATOR_EQEQ, *ref,
    8760              :                                               Expression::make_nil(loc),
    8761              :                                               loc);
    8762           10 :       cond = Expression::make_binary(OPERATOR_OROR, cond, n, loc);
    8763           10 :       *ref = Expression::make_dereference(*ref, Expression::NIL_CHECK_DEFAULT,
    8764              :                                           loc);
    8765           20 :       go_assert((*ref)->type()->struct_type() == stype);
    8766              :     }
    8767           17 :   *ref = Expression::make_field_reference(*ref, field_indexes->field_index,
    8768              :                                           loc);
    8769           17 :   return cond;
    8770              : }
    8771              : 
    8772              : // Flatten a method value into a struct with nil checks.  We can't do
    8773              : // this in the lowering phase, because if the method value is called
    8774              : // directly we don't need a thunk.  That case will have been handled
    8775              : // by Call_expression::do_lower, so if we get here then we do need a
    8776              : // thunk.
    8777              : 
    8778              : Expression*
    8779          934 : Bound_method_expression::do_flatten(Gogo* gogo, Named_object*,
    8780              :                                     Statement_inserter* inserter)
    8781              : {
    8782          934 :   Location loc = this->location();
    8783              : 
    8784          934 :   Named_object* thunk = Bound_method_expression::lookup_thunk(this->function_);
    8785              : 
    8786              :   // The thunk should have been created during the
    8787              :   // create_function_descriptors pass.
    8788          934 :   if (thunk == NULL || thunk->is_erroneous())
    8789              :     {
    8790            0 :       go_assert(saw_errors());
    8791            0 :       return Expression::make_error(loc);
    8792              :     }
    8793              : 
    8794              :   // Force the expression into a variable.  This is only necessary if
    8795              :   // we are going to do nil checks below, but it's easy enough to
    8796              :   // always do it.
    8797          934 :   Expression* expr = this->expr_;
    8798          934 :   if (!expr->is_multi_eval_safe())
    8799              :     {
    8800          292 :       Temporary_statement* etemp = Statement::make_temporary(NULL, expr, loc);
    8801          292 :       inserter->insert(etemp);
    8802          292 :       expr = Expression::make_temporary_reference(etemp, loc);
    8803              :     }
    8804              : 
    8805              :   // If the method expects a value, and we have a pointer, we need to
    8806              :   // dereference the pointer.
    8807              : 
    8808          934 :   Named_object* fn = this->method_->named_object();
    8809          934 :   Function_type *fntype;
    8810          934 :   if (fn->is_function())
    8811          814 :     fntype = fn->func_value()->type();
    8812          120 :   else if (fn->is_function_declaration())
    8813          120 :     fntype = fn->func_declaration_value()->type();
    8814              :   else
    8815            0 :     go_unreachable();
    8816              : 
    8817          934 :   Expression* val = expr;
    8818          934 :   if (fntype->receiver()->type()->points_to() == NULL
    8819         1135 :       && val->type()->points_to() != NULL)
    8820           25 :     val = Expression::make_dereference(val, NIL_CHECK_DEFAULT, loc);
    8821              : 
    8822              :   // Note that we are ignoring this->expr_type_ here.  The thunk will
    8823              :   // expect a closure whose second field has type this->expr_type_ (if
    8824              :   // that is not NULL).  We are going to pass it a closure whose
    8825              :   // second field has type this->expr_->type().  Since
    8826              :   // this->expr_type_ is only not-NULL for pointer types, we can get
    8827              :   // away with this.
    8828              : 
    8829          934 :   Struct_field_list* fields = new Struct_field_list();
    8830         1868 :   fields->push_back(Struct_field(Typed_identifier("fn",
    8831          934 :                                                   thunk->func_value()->type(),
    8832          934 :                                                   loc)));
    8833         1868 :   fields->push_back(Struct_field(Typed_identifier("val", val->type(), loc)));
    8834          934 :   Struct_type* st = Type::make_struct_type(fields, loc);
    8835          934 :   st->set_is_struct_incomparable();
    8836              : 
    8837          934 :   Expression_list* vals = new Expression_list();
    8838          934 :   vals->push_back(Expression::make_func_code_reference(thunk, loc));
    8839          934 :   vals->push_back(val);
    8840              : 
    8841          934 :   Expression* ret = Expression::make_struct_composite_literal(st, vals, loc);
    8842          934 :   ret = Expression::make_heap_expression(ret, loc);
    8843              : 
    8844          934 :   Node* node = Node::make_node(this);
    8845          934 :   if ((node->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
    8846          417 :     ret->heap_expression()->set_allocate_on_stack();
    8847          517 :   else if (gogo->compiling_runtime()
    8848            0 :            && gogo->package_name() == "runtime"
    8849          517 :            && !saw_errors())
    8850            0 :     go_error_at(loc, "%s escapes to heap, not allowed in runtime",
    8851            0 :                 node->ast_format(gogo).c_str());
    8852              : 
    8853              :   // If necessary, check whether the expression or any embedded
    8854              :   // pointers are nil.
    8855              : 
    8856          934 :   Expression* nil_check = NULL;
    8857          934 :   if (this->method_->field_indexes() != NULL)
    8858              :     {
    8859           14 :       Expression* ref = expr;
    8860           14 :       nil_check = bme_check_nil(this->method_->field_indexes(), loc, &ref);
    8861           14 :       expr = ref;
    8862              :     }
    8863              : 
    8864         1135 :   if (this->method_->is_value_method() && expr->type()->points_to() != NULL)
    8865              :     {
    8866           27 :       Expression* n = Expression::make_binary(OPERATOR_EQEQ, expr,
    8867              :                                               Expression::make_nil(loc),
    8868              :                                               loc);
    8869           27 :       if (nil_check == NULL)
    8870              :         nil_check = n;
    8871              :       else
    8872            6 :         nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc);
    8873              :     }
    8874              : 
    8875          934 :   if (nil_check != NULL)
    8876              :     {
    8877           35 :       Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
    8878              :       // Fix the type of the conditional expression by pretending to
    8879              :       // evaluate to RET either way through the conditional.
    8880           35 :       crash->determine_type_no_context(gogo);
    8881           35 :       crash = Expression::make_compound(crash, ret, loc);
    8882           35 :       ret = Expression::make_conditional(nil_check, crash, ret, loc);
    8883              :     }
    8884              : 
    8885              :   // RET is a pointer to a struct, but we want a function type.
    8886          934 :   ret = Expression::make_unsafe_cast(this->type(), ret, loc);
    8887              : 
    8888          934 :   ret->determine_type_no_context(gogo);
    8889              : 
    8890          934 :   return ret;
    8891              : }
    8892              : 
    8893              : // Dump ast representation of a bound method expression.
    8894              : 
    8895              : void
    8896            0 : Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
    8897              :     const
    8898              : {
    8899            0 :   if (this->expr_type_ != NULL)
    8900            0 :     ast_dump_context->ostream() << "(";
    8901            0 :   ast_dump_context->dump_expression(this->expr_);
    8902            0 :   if (this->expr_type_ != NULL)
    8903              :     {
    8904            0 :       ast_dump_context->ostream() << ":";
    8905            0 :       ast_dump_context->dump_type(this->expr_type_);
    8906            0 :       ast_dump_context->ostream() << ")";
    8907              :     }
    8908              : 
    8909            0 :   ast_dump_context->ostream() << "." << this->function_->name();
    8910            0 : }
    8911              : 
    8912              : // Make a method expression.
    8913              : 
    8914              : Bound_method_expression*
    8915       264730 : Expression::make_bound_method(Expression* expr, const Method* method,
    8916              :                               Named_object* function, Location location)
    8917              : {
    8918       264730 :   return new Bound_method_expression(expr, method, function, location);
    8919              : }
    8920              : 
    8921              : // A general selector.  This is a Parser_expression for LEFT.NAME.  It
    8922              : // is lowered after we know the type of the left hand side.
    8923              : 
    8924              : class Selector_expression : public Parser_expression
    8925              : {
    8926              :  public:
    8927       700127 :   Selector_expression(Expression* left, const std::string& name,
    8928              :                       Location location)
    8929       700127 :     : Parser_expression(EXPRESSION_SELECTOR, location),
    8930       700127 :       left_(left), name_(name), resolved_(NULL)
    8931       700127 :   { }
    8932              : 
    8933              :   // Return the resolved selector.  This will typically be a
    8934              :   // Field_reference_expression or a Bound_method_expression or an
    8935              :   // Interface_field_reference_expression.
    8936              :   Expression*
    8937         1156 :   resolved()
    8938         1156 :   { return this->resolved_; }
    8939              : 
    8940              :  protected:
    8941              :   int
    8942      3601519 :   do_traverse(Traverse* traverse)
    8943      3601519 :   { return Expression::traverse(&this->left_, traverse); }
    8944              : 
    8945              :   Type*
    8946              :   do_type();
    8947              : 
    8948              :   void
    8949              :   do_determine_type(Gogo*, const Type_context*);
    8950              : 
    8951              :   bool
    8952              :   do_is_addressable() const;
    8953              : 
    8954              :   void
    8955              :   do_issue_nil_check();
    8956              : 
    8957              :   Expression*
    8958              :   do_lower(Gogo*, Named_object*, Statement_inserter*);
    8959              : 
    8960              :   Expression*
    8961            0 :   do_copy()
    8962              :   {
    8963            0 :     return new Selector_expression(this->left_->copy(), this->name_,
    8964            0 :                                    this->location());
    8965              :   }
    8966              : 
    8967              :   void
    8968              :   do_dump_expression(Ast_dump_context* ast_dump_context) const;
    8969              : 
    8970              :  private:
    8971              :   Expression*
    8972              :   lower_method_expression(Gogo*);
    8973              : 
    8974              :   // The expression on the left hand side.
    8975              :   Expression* left_;
    8976              :   // The name on the right hand side.
    8977              :   std::string name_;
    8978              :   // The resolved expression.
    8979              :   Expression* resolved_;
    8980              : };
    8981              : 
    8982              : void
    8983       807096 : Selector_expression::do_determine_type(Gogo* gogo, const Type_context* context)
    8984              : {
    8985       807096 :   if (this->is_error_expression() || this->resolved_ != NULL)
    8986              :     return;
    8987       700125 :   Expression* left = this->left_;
    8988       700125 :   left->determine_type_no_context(gogo);
    8989       700125 :   if (left->is_error_expression())
    8990            7 :     this->set_is_error();
    8991              :   else
    8992              :     {
    8993       700118 :       if (left->is_type_expression())
    8994          602 :         this->resolved_ = this->lower_method_expression(gogo);
    8995              :       else
    8996       699516 :         this->resolved_ = Type::bind_field_or_method(gogo, left->type(), left,
    8997       699516 :                                                      this->name_,
    8998              :                                                      this->location());
    8999       700118 :       this->resolved_->determine_type(gogo, context);
    9000              :     }
    9001              : }
    9002              : 
    9003              : Type*
    9004      2874842 : Selector_expression::do_type()
    9005              : {
    9006      2874842 :   if (this->is_error_expression())
    9007           12 :     return Type::make_error_type();
    9008      2874830 :   go_assert(this->resolved_ != NULL);
    9009      2874830 :   return this->resolved_->type();
    9010              : }
    9011              : 
    9012              : bool
    9013       141725 : Selector_expression::do_is_addressable() const
    9014              : {
    9015       141725 :   if (this->is_error_expression())
    9016              :     return true;
    9017       141724 :   go_assert(this->resolved_ != NULL);
    9018       141724 :   return this->resolved_->is_addressable();
    9019              : }
    9020              : 
    9021              : void
    9022        16436 : Selector_expression::do_issue_nil_check()
    9023              : {
    9024        16436 :   if (this->is_error_expression())
    9025              :     return;
    9026        16436 :   go_assert(this->resolved_ != NULL);
    9027        16436 :   this->resolved_->issue_nil_check();
    9028              : }
    9029              : 
    9030              : // Lower a selector expression to the resolved value.
    9031              : 
    9032              : Expression*
    9033       771980 : Selector_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
    9034              : {
    9035       771980 :   if (this->is_error_expression() || this->resolved_ == NULL)
    9036            5 :     return Expression::make_error(this->location());
    9037              :   return this->resolved_;
    9038              : }
    9039              : 
    9040              : // Lower a method expression T.M or (*T).M.  We turn this into a
    9041              : // function literal.
    9042              : 
    9043              : Expression*
    9044          602 : Selector_expression::lower_method_expression(Gogo* gogo)
    9045              : {
    9046          602 :   Location location = this->location();
    9047          602 :   Type* left_type = this->left_->type();
    9048          602 :   Type* type = left_type;
    9049          602 :   const std::string& name(this->name_);
    9050              : 
    9051          602 :   bool is_pointer;
    9052          602 :   if (type->points_to() == NULL)
    9053              :     is_pointer = false;
    9054              :   else
    9055              :     {
    9056          407 :       is_pointer = true;
    9057          407 :       type = type->points_to();
    9058              :     }
    9059              : 
    9060          602 :   Named_type* nt = type->named_type();
    9061          602 :   Struct_type* st = type->struct_type();
    9062          602 :   bool is_ambiguous = false;
    9063          602 :   Method* method = NULL;
    9064          602 :   if (nt != NULL)
    9065          599 :     method = nt->method_function(name, &is_ambiguous);
    9066            3 :   else if (st != NULL)
    9067            1 :     method = st->method_function(name, &is_ambiguous);
    9068          602 :   const Typed_identifier* imethod = NULL;
    9069          602 :   if (method == NULL && !is_pointer)
    9070              :     {
    9071           28 :       Interface_type* it = type->interface_type();
    9072           28 :       if (it != NULL)
    9073           28 :         imethod = it->find_method(name);
    9074              :     }
    9075              : 
    9076          602 :   if ((method == NULL && imethod == NULL)
    9077          602 :       || (left_type->named_type() != NULL && left_type->points_to() != NULL))
    9078              :     {
    9079            3 :       if (nt != NULL)
    9080              :         {
    9081            2 :           if (!is_ambiguous)
    9082            2 :             go_error_at(location, "type %<%s%s%> has no method %qs",
    9083              :                         is_pointer ? "*" : "",
    9084            4 :                         nt->message_name().c_str(),
    9085            4 :                         Gogo::message_name(name).c_str());
    9086              :           else
    9087            0 :             go_error_at(location, "method %<%s%s%> is ambiguous in type %qs",
    9088            0 :                         Gogo::message_name(name).c_str(),
    9089              :                         is_pointer ? "*" : "",
    9090            0 :                         nt->message_name().c_str());
    9091              :         }
    9092              :       else
    9093              :         {
    9094            1 :           if (!is_ambiguous)
    9095            1 :             go_error_at(location, "type has no method %qs",
    9096            2 :                         Gogo::message_name(name).c_str());
    9097              :           else
    9098            0 :             go_error_at(location, "method %qs is ambiguous",
    9099            0 :                         Gogo::message_name(name).c_str());
    9100              :         }
    9101            3 :       return Expression::make_error(location);
    9102              :     }
    9103              : 
    9104          599 :   if (method != NULL && !is_pointer && !method->is_value_method())
    9105              :     {
    9106            1 :       go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
    9107            2 :                   nt->message_name().c_str(),
    9108            1 :                   Gogo::message_name(name).c_str());
    9109            1 :       return Expression::make_error(location);
    9110              :     }
    9111              : 
    9112              :   // Build a new function type in which the receiver becomes the first
    9113              :   // argument.
    9114          598 :   Function_type* method_type;
    9115          598 :   if (method != NULL)
    9116              :     {
    9117          570 :       method_type = method->type();
    9118          570 :       go_assert(method_type->is_method());
    9119              :     }
    9120              :   else
    9121              :     {
    9122           28 :       method_type = imethod->type()->function_type();
    9123           28 :       go_assert(method_type != NULL && !method_type->is_method());
    9124              :     }
    9125              : 
    9126          598 :   const char* const receiver_name = "$this";
    9127          598 :   Typed_identifier_list* parameters = new Typed_identifier_list();
    9128         1196 :   parameters->push_back(Typed_identifier(receiver_name, this->left_->type(),
    9129         1196 :                                          location));
    9130              : 
    9131          598 :   const Typed_identifier_list* method_parameters = method_type->parameters();
    9132          598 :   if (method_parameters != NULL)
    9133              :     {
    9134          272 :       int i = 0;
    9135          272 :       for (Typed_identifier_list::const_iterator p = method_parameters->begin();
    9136          730 :            p != method_parameters->end();
    9137          458 :            ++p, ++i)
    9138              :         {
    9139          458 :           if (!p->name().empty() && !Gogo::is_sink_name(p->name()))
    9140          439 :             parameters->push_back(*p);
    9141              :           else
    9142              :             {
    9143           19 :               char buf[20];
    9144           19 :               snprintf(buf, sizeof buf, "$param%d", i);
    9145           38 :               parameters->push_back(Typed_identifier(buf, p->type(),
    9146           38 :                                                      p->location()));
    9147              :             }
    9148              :         }
    9149              :     }
    9150              : 
    9151          598 :   const Typed_identifier_list* method_results = method_type->results();
    9152          598 :   Typed_identifier_list* results;
    9153          598 :   if (method_results == NULL)
    9154              :     results = NULL;
    9155              :   else
    9156              :     {
    9157          477 :       results = new Typed_identifier_list();
    9158          477 :       for (Typed_identifier_list::const_iterator p = method_results->begin();
    9159         1004 :            p != method_results->end();
    9160          527 :            ++p)
    9161          527 :         results->push_back(*p);
    9162              :     }
    9163              : 
    9164          598 :   Function_type* fntype = Type::make_function_type(NULL, parameters, results,
    9165              :                                                    location);
    9166          598 :   if (method_type->is_varargs())
    9167            3 :     fntype->set_is_varargs();
    9168              : 
    9169              :   // We generate methods which always takes a pointer to the receiver
    9170              :   // as their first argument.  If this is for a pointer type, we can
    9171              :   // simply reuse the existing function.  We use an internal hack to
    9172              :   // get the right type.
    9173              :   // FIXME: This optimization is disabled because it doesn't yet work
    9174              :   // with function descriptors when the method expression is not
    9175              :   // directly called.
    9176          598 :   if (method != NULL && is_pointer && false)
    9177              :     {
    9178              :       Named_object* mno = (method->needs_stub_method()
    9179              :                            ? method->stub_object()
    9180              :                            : method->named_object());
    9181              :       Expression* f = Expression::make_func_reference(mno, NULL, location);
    9182              :       f = Expression::make_cast(fntype, f, location);
    9183              :       Type_conversion_expression* tce =
    9184              :         static_cast<Type_conversion_expression*>(f);
    9185              :       tce->set_may_convert_function_types();
    9186              :       return f;
    9187              :     }
    9188              : 
    9189          598 :   Named_object* no = gogo->start_function(gogo->thunk_name(), fntype, false,
    9190              :                                           location);
    9191              : 
    9192          598 :   Named_object* vno = gogo->lookup(receiver_name, NULL);
    9193          598 :   go_assert(vno != NULL);
    9194          598 :   Expression* ve = Expression::make_var_reference(vno, location);
    9195          598 :   Expression* bm;
    9196          598 :   if (method != NULL)
    9197          570 :     bm = Type::bind_field_or_method(gogo, type, ve, name, location);
    9198              :   else
    9199           28 :     bm = Expression::make_interface_field_reference(ve, name, location);
    9200              : 
    9201              :   // Even though we found the method above, if it has an error type we
    9202              :   // may see an error here.
    9203          598 :   if (bm->is_error_expression())
    9204              :     {
    9205            0 :       gogo->finish_function(location);
    9206            0 :       return bm;
    9207              :     }
    9208              : 
    9209          598 :   Expression_list* args;
    9210          598 :   if (parameters->size() <= 1)
    9211              :     args = NULL;
    9212              :   else
    9213              :     {
    9214          272 :       args = new Expression_list();
    9215          272 :       Typed_identifier_list::const_iterator p = parameters->begin();
    9216          272 :       ++p;
    9217          730 :       for (; p != parameters->end(); ++p)
    9218              :         {
    9219          458 :           vno = gogo->lookup(p->name(), NULL);
    9220          458 :           go_assert(vno != NULL);
    9221          458 :           args->push_back(Expression::make_var_reference(vno, location));
    9222              :         }
    9223              :     }
    9224              : 
    9225          598 :   gogo->start_block(location);
    9226              : 
    9227          598 :   Call_expression* call = Expression::make_call(bm, args,
    9228          598 :                                                 method_type->is_varargs(),
    9229              :                                                 location);
    9230              : 
    9231          598 :   Statement* s = Statement::make_return_from_call(no, call, location);
    9232          598 :   s->determine_types(gogo);
    9233          598 :   gogo->add_statement(s);
    9234              : 
    9235          598 :   Block* b = gogo->finish_block(location);
    9236              : 
    9237          598 :   gogo->add_block(b, location);
    9238              : 
    9239          598 :   gogo->finish_function(location);
    9240              : 
    9241          598 :   return Expression::make_func_reference(no, NULL, location);
    9242              : }
    9243              : 
    9244              : // Dump the ast for a selector expression.
    9245              : 
    9246              : void
    9247            0 : Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
    9248              :     const
    9249              : {
    9250            0 :   ast_dump_context->dump_expression(this->left_);
    9251            0 :   ast_dump_context->ostream() << ".";
    9252            0 :   ast_dump_context->ostream() << this->name_;
    9253            0 : }
    9254              : 
    9255              : // Make a selector expression.
    9256              : 
    9257              : Expression*
    9258       700127 : Expression::make_selector(Expression* left, const std::string& name,
    9259              :                           Location location)
    9260              : {
    9261       700127 :   return new Selector_expression(left, name, location);
    9262              : }
    9263              : 
    9264              : // Class Builtin_call_expression.  This is used for a call to a
    9265              : // builtin function.
    9266              : 
    9267       240766 : Builtin_call_expression::Builtin_call_expression(Gogo* gogo,
    9268              :                                                  Expression* fn,
    9269              :                                                  Expression_list* args,
    9270              :                                                  bool is_varargs,
    9271       240766 :                                                  Location location)
    9272              :   : Call_expression(fn, args, is_varargs, location),
    9273       240766 :     gogo_(gogo), code_(BUILTIN_INVALID), seen_(false),
    9274       240766 :     recover_arg_is_set_(false)
    9275              : {
    9276       240766 :   const Named_object* no;
    9277       240766 :   if (fn->is_error_expression())
    9278              :     {
    9279              :       this->code_ = BUILTIN_INVALID;
    9280              :       return;
    9281              :     }
    9282       240766 :   else if (fn->func_expression() != NULL)
    9283       240766 :     no = fn->func_expression()->named_object();
    9284            0 :   else if (fn->unknown_expression() != NULL)
    9285            0 :     no = fn->unknown_expression()->named_object();
    9286              :   else
    9287            0 :     go_unreachable();
    9288              : 
    9289       240766 :   const std::string& name(no->name());
    9290       240766 :   if (name == "append")
    9291        15751 :     this->code_ = BUILTIN_APPEND;
    9292       225015 :   else if (name == "cap")
    9293        16623 :     this->code_ = BUILTIN_CAP;
    9294       208392 :   else if (name == "close")
    9295         1094 :     this->code_ = BUILTIN_CLOSE;
    9296       207298 :   else if (name == "complex")
    9297        13722 :     this->code_ = BUILTIN_COMPLEX;
    9298       193576 :   else if (name == "copy")
    9299         4493 :     this->code_ = BUILTIN_COPY;
    9300       189083 :   else if (name == "delete")
    9301          943 :     this->code_ = BUILTIN_DELETE;
    9302       188140 :   else if (name == "imag")
    9303          555 :     this->code_ = BUILTIN_IMAG;
    9304       187585 :   else if (name == "len")
    9305       116380 :     this->code_ = BUILTIN_LEN;
    9306        71205 :   else if (name == "make")
    9307        15137 :     this->code_ = BUILTIN_MAKE;
    9308        56068 :   else if (name == "new")
    9309        21304 :     this->code_ = BUILTIN_NEW;
    9310        34764 :   else if (name == "panic")
    9311        15153 :     this->code_ = BUILTIN_PANIC;
    9312        19611 :   else if (name == "print")
    9313         2727 :     this->code_ = BUILTIN_PRINT;
    9314        16884 :   else if (name == "println")
    9315        13459 :     this->code_ = BUILTIN_PRINTLN;
    9316         3425 :   else if (name == "real")
    9317          493 :     this->code_ = BUILTIN_REAL;
    9318         2932 :   else if (name == "recover")
    9319          857 :     this->code_ = BUILTIN_RECOVER;
    9320         2075 :   else if (name == "Add")
    9321            9 :     this->code_ = BUILTIN_ADD;
    9322         2066 :   else if (name == "Alignof")
    9323           17 :     this->code_ = BUILTIN_ALIGNOF;
    9324         2049 :   else if (name == "Offsetof")
    9325         1161 :     this->code_ = BUILTIN_OFFSETOF;
    9326          888 :   else if (name == "Sizeof")
    9327          879 :     this->code_ = BUILTIN_SIZEOF;
    9328            9 :   else if (name == "Slice")
    9329            9 :     this->code_ = BUILTIN_SLICE;
    9330              :   else
    9331            0 :     go_unreachable();
    9332              : }
    9333              : 
    9334              : // Return whether this is a call to recover.  This is a virtual
    9335              : // function called from the parent class.
    9336              : 
    9337              : bool
    9338         1580 : Builtin_call_expression::do_is_recover_call() const
    9339              : {
    9340         1580 :   if (this->classification() == EXPRESSION_ERROR)
    9341              :     return false;
    9342         1580 :   return this->code_ == BUILTIN_RECOVER;
    9343              : }
    9344              : 
    9345              : // Set the argument for a call to recover.
    9346              : 
    9347              : void
    9348          857 : Builtin_call_expression::do_set_recover_arg(Expression* arg)
    9349              : {
    9350          857 :   const Expression_list* args = this->args();
    9351          857 :   go_assert(args == NULL || args->empty());
    9352          857 :   Expression_list* new_args = new Expression_list();
    9353          857 :   new_args->push_back(arg);
    9354          857 :   this->set_args(new_args);
    9355          857 :   this->recover_arg_is_set_ = true;
    9356          857 : }
    9357              : 
    9358              : // Lower a builtin call expression.  This turns new and make into
    9359              : // specific expressions.  We also convert to a constant if we can.
    9360              : 
    9361              : Expression*
    9362       449703 : Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
    9363              :                                   Statement_inserter* inserter)
    9364              : {
    9365       449703 :   if (this->is_error_expression())
    9366          995 :     return this;
    9367              : 
    9368       448708 :   Location loc = this->location();
    9369              : 
    9370       448708 :   if (this->code_ == BUILTIN_OFFSETOF)
    9371              :     {
    9372         1154 :       Expression* arg = this->one_arg();
    9373         1154 :       Field_reference_expression* farg = arg->field_reference_expression();
    9374         2097 :       while (farg != NULL)
    9375              :         {
    9376         2097 :           if (!farg->implicit())
    9377              :             break;
    9378              :           // When the selector refers to an embedded field,
    9379              :           // it must not be reached through pointer indirections.
    9380         1841 :           if (farg->expr()->deref() != farg->expr())
    9381              :             {
    9382          898 :               this->report_error(_("argument of Offsetof implies "
    9383              :                                    "indirection of an embedded field"));
    9384          898 :               return this;
    9385              :             }
    9386              :           // Go up until we reach the original base.
    9387         3040 :           farg = farg->expr()->field_reference_expression();
    9388              :         }
    9389              :     }
    9390              : 
    9391       447810 :   if (this->is_constant())
    9392              :     {
    9393        15726 :       Numeric_constant nc;
    9394        15726 :       if (this->numeric_constant_value(&nc))
    9395              :         {
    9396        15726 :           Expression* ret = nc.expression(loc);
    9397        15726 :           Type_context subcontext;
    9398        15726 :           if (this->type() != NULL)
    9399         1526 :             subcontext = Type_context(this->type(),
    9400         1526 :                                       this->type()->is_abstract());
    9401        15726 :           ret->determine_type(gogo, &subcontext);
    9402        15726 :           return ret;
    9403              :         }
    9404        15726 :     }
    9405              : 
    9406       432084 :   switch (this->code_)
    9407              :     {
    9408              :     default:
    9409              :       break;
    9410              : 
    9411        23184 :     case BUILTIN_NEW:
    9412        23184 :       return Expression::make_allocation(this->one_arg()->type(), loc);
    9413              : 
    9414        15099 :     case BUILTIN_MAKE:
    9415        15099 :       return this->lower_make(gogo, inserter);
    9416              : 
    9417          874 :     case BUILTIN_RECOVER:
    9418          874 :       if (function != NULL)
    9419          874 :         function->func_value()->set_calls_recover();
    9420              :       else
    9421              :         {
    9422              :           // Calling recover outside of a function always returns the
    9423              :           // nil empty interface.
    9424            0 :           Type* eface = Type::make_empty_interface_type(loc);
    9425            0 :           return Expression::make_cast(eface, Expression::make_nil(loc), loc);
    9426              :         }
    9427          874 :       break;
    9428              : 
    9429         1559 :     case BUILTIN_DELETE:
    9430         1559 :       {
    9431         1559 :         const Expression_list* args = this->args();
    9432         1559 :         Type* key_type =
    9433         3118 :           args->front()->type()->map_type()->key_type();
    9434         1559 :         Expression_list::iterator pa = this->args()->begin();
    9435         1559 :         pa++;
    9436         1559 :         Type* arg_type = (*pa)->type();
    9437         1559 :         if (!Type::are_identical(key_type, arg_type, 0, NULL))
    9438           16 :           *pa = Expression::make_cast(key_type, *pa, loc);
    9439              :       }
    9440              :       break;
    9441              : 
    9442        17885 :     case BUILTIN_PRINT:
    9443        17885 :     case BUILTIN_PRINTLN:
    9444              :       // Force all the arguments into temporary variables, so that we
    9445              :       // don't try to evaluate something while holding the print lock.
    9446        17885 :       if (this->args() == NULL)
    9447              :         break;
    9448        61881 :       for (Expression_list::iterator pa = this->args()->begin();
    9449        61881 :            pa != this->args()->end();
    9450        44065 :            ++pa)
    9451              :         {
    9452        44065 :           if (!(*pa)->is_multi_eval_safe())
    9453              :             {
    9454        27576 :               Temporary_statement* temp =
    9455        27576 :                 Statement::make_temporary(NULL, *pa, loc);
    9456        27576 :               inserter->insert(temp);
    9457        27576 :               *pa = Expression::make_temporary_reference(temp, loc);
    9458              :             }
    9459              :         }
    9460              :       break;
    9461              :     }
    9462              : 
    9463              :   return this;
    9464              : }
    9465              : 
    9466              : // Flatten a builtin call expression.  This turns the arguments of some
    9467              : // builtin calls into temporary expressions.  Also expand copy and append
    9468              : // to runtime calls.
    9469              : 
    9470              : Expression*
    9471       210171 : Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
    9472              :                                     Statement_inserter* inserter)
    9473              : {
    9474       210171 :   if (this->is_error_expression())
    9475              :     {
    9476          978 :       go_assert(saw_errors());
    9477          978 :       return this;
    9478              :     }
    9479              : 
    9480       209193 :   Location loc = this->location();
    9481              : 
    9482       209193 :   switch (this->code_)
    9483              :     {
    9484              :     default:
    9485              :       break;
    9486              : 
    9487         2654 :     case BUILTIN_APPEND:
    9488         2654 :       return this->flatten_append(gogo, function, inserter, NULL, NULL);
    9489              : 
    9490         4478 :     case BUILTIN_COPY:
    9491         4478 :       {
    9492         4478 :         Type* at = this->args()->front()->type();
    9493        13434 :         for (Expression_list::iterator pa = this->args()->begin();
    9494        13434 :              pa != this->args()->end();
    9495         8956 :              ++pa)
    9496              :           {
    9497         8956 :             if ((*pa)->is_error_expression())
    9498              :               {
    9499            0 :                 go_assert(saw_errors());
    9500            0 :                 return Expression::make_error(loc);
    9501              :               }
    9502         8956 :             if ((*pa)->is_nil_expression())
    9503              :               {
    9504            0 :                 Expression* nil = Expression::make_nil(loc);
    9505            0 :                 Expression* zero = Expression::make_integer_ul(0, NULL, loc);
    9506            0 :                 *pa = Expression::make_slice_value(at, nil, zero, zero, loc);
    9507              :               }
    9508         8956 :             if (!(*pa)->is_multi_eval_safe())
    9509              :               {
    9510         5001 :                 Temporary_statement* temp =
    9511         5001 :                   Statement::make_temporary(NULL, *pa, loc);
    9512         5001 :                 inserter->insert(temp);
    9513         5001 :                 *pa = Expression::make_temporary_reference(temp, loc);
    9514              :               }
    9515              :           }
    9516              : 
    9517              :         // Lower to runtime call.
    9518         4478 :         const Expression_list* args = this->args();
    9519         4478 :         go_assert(args != NULL && args->size() == 2);
    9520         4478 :         Expression* arg1 = args->front();
    9521         4478 :         Expression* arg2 = args->back();
    9522         4478 :         go_assert(arg1->is_multi_eval_safe());
    9523         4478 :         go_assert(arg2->is_multi_eval_safe());
    9524         4478 :         bool arg2_is_string = arg2->type()->is_string_type();
    9525              : 
    9526         4478 :         Expression* ret;
    9527         8956 :         Type* et = at->array_type()->element_type();
    9528         4478 :         if (et->has_pointer())
    9529              :           {
    9530         1649 :             Expression* td = Expression::make_type_descriptor(et, loc);
    9531         1649 :             Expression* pd =
    9532         1649 :               Expression::make_slice_info(arg1, SLICE_INFO_VALUE_POINTER, loc);
    9533         1649 :             Expression* ld =
    9534         1649 :               Expression::make_slice_info(arg1, SLICE_INFO_LENGTH, loc);
    9535         1649 :             Expression* ps =
    9536         1649 :               Expression::make_slice_info(arg2, SLICE_INFO_VALUE_POINTER, loc);
    9537         1649 :             Expression* ls =
    9538         1649 :               Expression::make_slice_info(arg2, SLICE_INFO_LENGTH, loc);
    9539         1649 :             ret = Runtime::make_call(gogo, Runtime::TYPEDSLICECOPY, loc,
    9540              :                                      5, td, pd, ld, ps, ls);
    9541              :           }
    9542              :         else
    9543              :           {
    9544         2829 :             Type* int_type = Type::lookup_integer_type("int");
    9545         2829 :             Type* uintptr_type = Type::lookup_integer_type("uintptr");
    9546              : 
    9547              :             // l1 = len(arg1)
    9548         2829 :             Named_object* lenfn = gogo->lookup_global("len");
    9549         2829 :             Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
    9550         2829 :             Expression_list* len_args = new Expression_list();
    9551         2829 :             len_args->push_back(arg1->copy());
    9552         2829 :             Expression* len1 = Expression::make_call(lenref, len_args, false, loc);
    9553         2829 :             gogo->lower_expression(function, inserter, &len1);
    9554         2829 :             gogo->flatten_expression(function, inserter, &len1);
    9555         2829 :             Temporary_statement* l1tmp = Statement::make_temporary(int_type, len1, loc);
    9556         2829 :             l1tmp->determine_types(gogo);
    9557         2829 :             inserter->insert(l1tmp);
    9558              : 
    9559              :             // l2 = len(arg2)
    9560         2829 :             len_args = new Expression_list();
    9561         2829 :             len_args->push_back(arg2->copy());
    9562         2829 :             Expression* len2 = Expression::make_call(lenref, len_args, false, loc);
    9563         2829 :             gogo->lower_expression(function, inserter, &len2);
    9564         2829 :             gogo->flatten_expression(function, inserter, &len2);
    9565         2829 :             Temporary_statement* l2tmp = Statement::make_temporary(int_type, len2, loc);
    9566         2829 :             l2tmp->determine_types(gogo);
    9567         2829 :             inserter->insert(l2tmp);
    9568              : 
    9569              :             // n = (l1 < l2 ? l1 : l2)
    9570         2829 :             Expression* l1ref = Expression::make_temporary_reference(l1tmp, loc);
    9571         2829 :             Expression* l2ref = Expression::make_temporary_reference(l2tmp, loc);
    9572         2829 :             Expression* cond = Expression::make_binary(OPERATOR_LT, l1ref, l2ref, loc);
    9573         2829 :             Expression* n = Expression::make_conditional(cond,
    9574              :                                                          l1ref->copy(),
    9575              :                                                          l2ref->copy(),
    9576              :                                                          loc);
    9577         2829 :             Temporary_statement* ntmp = Statement::make_temporary(NULL, n, loc);
    9578         2829 :             ntmp->determine_types(gogo);
    9579         2829 :             inserter->insert(ntmp);
    9580              : 
    9581              :             // sz = n * sizeof(elem_type)
    9582         2829 :             Expression* nref = Expression::make_temporary_reference(ntmp, loc);
    9583         2829 :             nref = Expression::make_cast(uintptr_type, nref, loc);
    9584         2829 :             Expression* sz = Expression::make_type_info(et, TYPE_INFO_SIZE);
    9585         2829 :             sz = Expression::make_binary(OPERATOR_MULT, sz, nref, loc);
    9586              : 
    9587              :             // memmove(arg1.ptr, arg2.ptr, sz)
    9588         2829 :             Expression* p1 = Expression::make_slice_info(arg1,
    9589              :                                                          SLICE_INFO_VALUE_POINTER,
    9590              :                                                          loc);
    9591         2829 :             Expression* p2 = (arg2_is_string
    9592         2829 :                               ? Expression::make_string_info(arg2,
    9593              :                                                              STRING_INFO_DATA,
    9594              :                                                              loc)
    9595         2452 :                               : Expression::make_slice_info(arg2,
    9596              :                                                             SLICE_INFO_VALUE_POINTER,
    9597              :                                                             loc));
    9598         2829 :             Expression* call = Runtime::make_call(gogo,
    9599              :                                                   Runtime::BUILTIN_MEMMOVE,
    9600              :                                                   loc, 3,
    9601              :                                                   p1, p2, sz);
    9602              : 
    9603              :             // n is the return value of copy
    9604         2829 :             nref = Expression::make_temporary_reference(ntmp, loc);
    9605         2829 :             ret = Expression::make_compound(call, nref, loc);
    9606              :           }
    9607         4478 :         ret->determine_type_no_context(gogo);
    9608         4478 :         return ret;
    9609              :       }
    9610        15370 :       break;
    9611              : 
    9612        15370 :     case BUILTIN_PANIC:
    9613        15370 :       for (Expression_list::iterator pa = this->args()->begin();
    9614        30740 :            pa != this->args()->end();
    9615        15370 :            ++pa)
    9616              :         {
    9617        15370 :           if (!(*pa)->is_multi_eval_safe()
    9618        30138 :               && (*pa)->type()->interface_type() != NULL)
    9619              :             {
    9620        14768 :               Temporary_statement* temp =
    9621        14768 :                 Statement::make_temporary(NULL, *pa, loc);
    9622        14768 :               inserter->insert(temp);
    9623        14768 :               *pa = Expression::make_temporary_reference(temp, loc);
    9624              :             }
    9625              :         }
    9626              :       break;
    9627              : 
    9628       154386 :     case BUILTIN_LEN:
    9629       154386 :     case BUILTIN_CAP:
    9630       154386 :       {
    9631       154386 :         Expression_list::iterator pa = this->args()->begin();
    9632       154386 :         if (!(*pa)->is_multi_eval_safe()
    9633       154386 :             && ((*pa)->type()->map_type() != NULL
    9634        15197 :                 || (*pa)->type()->channel_type() != NULL))
    9635              :           {
    9636          692 :             Temporary_statement* temp =
    9637          692 :               Statement::make_temporary(NULL, *pa, loc);
    9638          692 :             inserter->insert(temp);
    9639          692 :             *pa = Expression::make_temporary_reference(temp, loc);
    9640              :           }
    9641              :       }
    9642              :       break;
    9643              : 
    9644          867 :     case BUILTIN_DELETE:
    9645          867 :       {
    9646              :         // Lower to a runtime function call.
    9647          867 :         const Expression_list* args = this->args();
    9648              : 
    9649              :         // Since this function returns no value it must appear in
    9650              :         // a statement by itself, so we don't have to worry about
    9651              :         // order of evaluation of values around it.  Evaluate the
    9652              :         // map first to get order of evaluation right.
    9653          867 :         Map_type* mt = args->front()->type()->map_type();
    9654          867 :         Temporary_statement* map_temp =
    9655          867 :           Statement::make_temporary(mt, args->front(), loc);
    9656          867 :         inserter->insert(map_temp);
    9657              : 
    9658          867 :         Temporary_statement* key_temp =
    9659          867 :           Statement::make_temporary(mt->key_type(), args->back(), loc);
    9660          867 :         inserter->insert(key_temp);
    9661              : 
    9662          867 :         Expression* e1 = Expression::make_type_descriptor(mt, loc);
    9663          867 :         Expression* e2 = Expression::make_temporary_reference(map_temp,
    9664              :                                                               loc);
    9665          867 :         Expression* e3 = Expression::make_temporary_reference(key_temp,
    9666              :                                                               loc);
    9667              : 
    9668          867 :         Runtime::Function code;
    9669          867 :         switch (mt->algorithm(gogo))
    9670              :           {
    9671          139 :             case Map_type::MAP_ALG_FAST32:
    9672          139 :             case Map_type::MAP_ALG_FAST32PTR:
    9673          139 :               {
    9674          139 :                 code = Runtime::MAPDELETE_FAST32;
    9675          139 :                 Type* uint32_type = Type::lookup_integer_type("uint32");
    9676          139 :                 Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
    9677          139 :                 e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
    9678          139 :                 e3 = Expression::make_unsafe_cast(uint32_ptr_type, e3,
    9679              :                                                   loc);
    9680          139 :                 e3 = Expression::make_dereference(e3,
    9681              :                                                   Expression::NIL_CHECK_NOT_NEEDED,
    9682              :                                                   loc);
    9683          139 :                 break;
    9684              :               }
    9685          211 :             case Map_type::MAP_ALG_FAST64:
    9686          211 :             case Map_type::MAP_ALG_FAST64PTR:
    9687          211 :               {
    9688          211 :                 code = Runtime::MAPDELETE_FAST64;
    9689          211 :                 Type* uint64_type = Type::lookup_integer_type("uint64");
    9690          211 :                 Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
    9691          211 :                 e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
    9692          211 :                 e3 = Expression::make_unsafe_cast(uint64_ptr_type, e3,
    9693              :                                                   loc);
    9694          211 :                 e3 = Expression::make_dereference(e3,
    9695              :                                                   Expression::NIL_CHECK_NOT_NEEDED,
    9696              :                                                   loc);
    9697          211 :                 break;
    9698              :               }
    9699              :             case Map_type::MAP_ALG_FASTSTR:
    9700              :               code = Runtime::MAPDELETE_FASTSTR;
    9701              :               break;
    9702          177 :             default:
    9703          177 :               code = Runtime::MAPDELETE;
    9704              : 
    9705              :               // If the call to delete is deferred, and is in a loop,
    9706              :               // then the loop will only have a single instance of the
    9707              :               // temporary variable.  Passing the address of the
    9708              :               // temporary variable here means that the deferred call
    9709              :               // will see the last value in the loop, not the current
    9710              :               // value.  So for this unusual case copy the value into
    9711              :               // the heap.
    9712          177 :               if (!this->is_deferred())
    9713          144 :                 e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
    9714              :               else
    9715              :                 {
    9716           33 :                   Expression* a = Expression::make_allocation(mt->key_type(),
    9717              :                                                               loc);
    9718           33 :                   Temporary_statement* atemp =
    9719           33 :                     Statement::make_temporary(NULL, a, loc);
    9720           33 :                   atemp->determine_types(gogo);
    9721           33 :                   inserter->insert(atemp);
    9722              : 
    9723           33 :                   a = Expression::make_temporary_reference(atemp, loc);
    9724           33 :                   a = Expression::make_dereference(a, NIL_CHECK_NOT_NEEDED, loc);
    9725           33 :                   Statement* s = Statement::make_assignment(a, e3, loc);
    9726           33 :                   s->determine_types(gogo);
    9727           33 :                   inserter->insert(s);
    9728              : 
    9729           33 :                   e3 = Expression::make_temporary_reference(atemp, loc);
    9730              :                 }
    9731              :           }
    9732              : 
    9733          867 :         Expression* ret = Runtime::make_call(gogo, code, loc, 3, e1, e2, e3);
    9734          867 :         ret->determine_type_no_context(gogo);
    9735          867 :         return ret;
    9736              :       }
    9737              : 
    9738            2 :     case BUILTIN_ADD:
    9739            2 :       {
    9740            2 :         Expression* ptr = this->args()->front();
    9741            2 :         Type* uintptr_type = Type::lookup_integer_type("uintptr");
    9742            2 :         ptr = Expression::make_cast(uintptr_type, ptr, loc);
    9743            2 :         Expression* len = this->args()->back();
    9744            2 :         len = Expression::make_cast(uintptr_type, len, loc);
    9745            2 :         Expression* add = Expression::make_binary(OPERATOR_PLUS, ptr, len,
    9746              :                                                   loc);
    9747            2 :         Expression* ret = Expression::make_cast(this->args()->front()->type(),
    9748              :                                                 add, loc);
    9749            2 :         ret->determine_type_no_context(gogo);
    9750            2 :         return ret;
    9751              :       }
    9752              : 
    9753            9 :     case BUILTIN_SLICE:
    9754            9 :       {
    9755            9 :         Expression* ptr = this->args()->front();
    9756            9 :         Temporary_statement* ptr_temp = NULL;
    9757            9 :         if (!ptr->is_multi_eval_safe())
    9758              :           {
    9759            8 :             ptr_temp = Statement::make_temporary(NULL, ptr, loc);
    9760            8 :             inserter->insert(ptr_temp);
    9761            8 :             ptr = Expression::make_temporary_reference(ptr_temp, loc);
    9762              :           }
    9763              : 
    9764            9 :         Expression* len = this->args()->back();
    9765            9 :         Temporary_statement* len_temp = NULL;
    9766            9 :         if (!len->is_multi_eval_safe())
    9767              :           {
    9768            2 :             len_temp = Statement::make_temporary(NULL, len, loc);
    9769            2 :             inserter->insert(len_temp);
    9770            2 :             len = Expression::make_temporary_reference(len_temp, loc);
    9771              :           }
    9772              : 
    9773            9 :         bool fits_in_int;
    9774            9 :         Numeric_constant nc;
    9775            9 :         if (this->args()->back()->numeric_constant_value(&nc))
    9776              :           {
    9777              :             // We gave an error for constants that don't fit in int in
    9778              :             // check_types.
    9779              :             fits_in_int = true;
    9780              :           }
    9781              :         else
    9782              :           {
    9783            2 :             Integer_type* itype = this->args()->back()->type()->integer_type();
    9784            0 :             go_assert(itype != NULL);
    9785            2 :             int ebits = itype->bits();
    9786            2 :             int intbits =
    9787            4 :               Type::lookup_integer_type("int")->integer_type()->bits();
    9788              : 
    9789              :             // We can treat ebits == intbits as small even for an
    9790              :             // unsigned integer type, because we will convert the
    9791              :             // value to int and then reject it in the runtime if it is
    9792              :             // negative.
    9793              : 
    9794            2 :             fits_in_int = ebits <= intbits;
    9795              :           }
    9796              : 
    9797           11 :         Runtime::Function code = (fits_in_int
    9798            2 :                                   ? Runtime::UNSAFESLICE
    9799              :                                   : Runtime::UNSAFESLICE64);
    9800            9 :         Expression* td =
    9801            9 :           Expression::make_type_descriptor(ptr->type()->points_to(), loc);
    9802            9 :         Expression* check = Runtime::make_call(gogo, code, loc, 3,
    9803              :                                                td, ptr, len);
    9804              : 
    9805            9 :         if (ptr_temp == NULL)
    9806            1 :           ptr = ptr->copy();
    9807              :         else
    9808            8 :           ptr = Expression::make_temporary_reference(ptr_temp, loc);
    9809            9 :         Expression* nil = Expression::make_nil(loc);
    9810            9 :         nil = Expression::make_cast(ptr->type(), nil, loc);
    9811            9 :         Expression* is_nil = Expression::make_binary(OPERATOR_EQEQ, ptr, nil,
    9812              :                                                      loc);
    9813              : 
    9814            9 :         if (len_temp == NULL)
    9815            7 :           len = len->copy();
    9816              :         else
    9817            2 :           len = Expression::make_temporary_reference(len_temp, loc);
    9818            9 :         Expression* zero = Expression::make_integer_ul(0, len->type(), loc);
    9819            9 :         Expression* is_zero = Expression::make_binary(OPERATOR_EQEQ, len, zero,
    9820              :                                                       loc);
    9821              : 
    9822            9 :         Expression* cond = Expression::make_binary(OPERATOR_ANDAND, is_nil,
    9823              :                                                    is_zero, loc);
    9824              : 
    9825            9 :         Type* slice_type = Type::make_array_type(ptr->type()->points_to(),
    9826              :                                                  NULL);
    9827            9 :         nil = Expression::make_nil(loc);
    9828            9 :         Expression* nil_slice = Expression::make_cast(slice_type, nil, loc);
    9829              : 
    9830            9 :         if (ptr_temp == NULL)
    9831            1 :           ptr = ptr->copy();
    9832              :         else
    9833            8 :           ptr = Expression::make_temporary_reference(ptr_temp, loc);
    9834              : 
    9835            9 :         if (len_temp == NULL)
    9836            7 :           len = len->copy();
    9837              :         else
    9838            2 :           len = Expression::make_temporary_reference(len_temp, loc);
    9839              : 
    9840            9 :         Expression* cap;
    9841            9 :         if (len_temp == NULL)
    9842            7 :           cap = len->copy();
    9843              :         else
    9844            2 :           cap = Expression::make_temporary_reference(len_temp, loc);
    9845              : 
    9846            9 :         Expression* slice = Expression::make_slice_value(slice_type, ptr,
    9847              :                                                          len, cap, loc);
    9848              : 
    9849            9 :         slice = Expression::make_conditional(cond, nil_slice, slice, loc);
    9850              : 
    9851            9 :         Expression* ret = Expression::make_compound(check, slice, loc);
    9852            9 :         ret->determine_type_no_context(gogo);
    9853            9 :         return ret;
    9854            9 :       }
    9855              :     }
    9856              : 
    9857       201183 :   return this;
    9858              : }
    9859              : 
    9860              : // Lower a make expression.
    9861              : 
    9862              : Expression*
    9863        15099 : Builtin_call_expression::lower_make(Gogo* gogo, Statement_inserter* inserter)
    9864              : {
    9865        15099 :   Location loc = this->location();
    9866              : 
    9867        15099 :   const Expression_list* args = this->args();
    9868              : 
    9869        15099 :   Expression_list::const_iterator parg = args->begin();
    9870              : 
    9871        15099 :   Expression* first_arg = *parg;
    9872        15099 :   go_assert(first_arg->is_type_expression());
    9873        15099 :   Type* type = first_arg->type();
    9874              : 
    9875        15099 :   bool is_slice = false;
    9876        15099 :   bool is_map = false;
    9877        15099 :   bool is_chan = false;
    9878        15099 :   if (type->is_slice_type())
    9879              :     is_slice = true;
    9880         6609 :   else if (type->map_type() != NULL)
    9881              :     is_map = true;
    9882        17862 :   else if (type->channel_type() != NULL)
    9883              :     is_chan = true;
    9884              :   else
    9885            0 :     go_unreachable();
    9886              : 
    9887        15099 :   ++parg;
    9888        15099 :   Expression* len_arg;
    9889        15099 :   bool len_small = false;
    9890        15099 :   if (parg == args->end())
    9891              :     {
    9892         4933 :       go_assert(!is_slice);
    9893         4933 :       len_arg = Expression::make_integer_ul(0, NULL, loc);
    9894         4933 :       len_small = true;
    9895              :     }
    9896              :   else
    9897              :     {
    9898        10166 :       len_arg = *parg;
    9899        10166 :       if (!this->check_int_value(len_arg, true, &len_small))
    9900            8 :         return Expression::make_error(this->location());
    9901        10158 :       ++parg;
    9902              :     }
    9903              : 
    9904        15091 :   Expression* cap_arg = NULL;
    9905        15091 :   bool cap_small = false;
    9906        15091 :   Numeric_constant nclen;
    9907        15091 :   Numeric_constant nccap;
    9908        15091 :   unsigned long vlen;
    9909        15091 :   unsigned long vcap;
    9910        15091 :   if (is_slice && parg != args->end())
    9911              :     {
    9912         1715 :       cap_arg = *parg;
    9913         1715 :       if (!this->check_int_value(cap_arg, false, &cap_small))
    9914            2 :         return Expression::make_error(this->location());
    9915              : 
    9916         1713 :       if (len_arg->numeric_constant_value(&nclen)
    9917         1614 :           && cap_arg->numeric_constant_value(&nccap)
    9918          554 :           && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
    9919          554 :           && nccap.to_unsigned_long(&vcap) == Numeric_constant::NC_UL_VALID
    9920         2267 :           && vlen > vcap)
    9921              :         {
    9922            1 :           this->report_error(_("len larger than cap"));
    9923            1 :           return Expression::make_error(this->location());
    9924              :         }
    9925              : 
    9926         1712 :       ++parg;
    9927              :     }
    9928              : 
    9929        15088 :   go_assert(parg == args->end());
    9930              : 
    9931        15088 :   Location type_loc = first_arg->location();
    9932              : 
    9933        15088 :   Expression* call;
    9934        15088 :   if (is_slice)
    9935              :     {
    9936         8479 :       Temporary_statement* len_temp = NULL;
    9937         8479 :       if (!len_arg->is_constant())
    9938              :         {
    9939         4458 :           len_temp = Statement::make_temporary(NULL, len_arg, loc);
    9940         4458 :           inserter->insert(len_temp);
    9941         4458 :           len_arg = Expression::make_temporary_reference(len_temp, loc);
    9942              :         }
    9943              : 
    9944         8479 :       if (cap_arg == NULL)
    9945              :         {
    9946         6767 :           cap_small = len_small;
    9947         6767 :           if (len_temp == NULL)
    9948         2408 :             cap_arg = len_arg->copy();
    9949              :           else
    9950         4359 :             cap_arg = Expression::make_temporary_reference(len_temp, loc);
    9951              :         }
    9952         1712 :       else if (!cap_arg->is_constant())
    9953              :         {
    9954         1138 :           Temporary_statement* cap_temp = Statement::make_temporary(NULL,
    9955              :                                                                     cap_arg,
    9956              :                                                                     loc);
    9957         1138 :           inserter->insert(cap_temp);
    9958         1138 :           cap_arg = Expression::make_temporary_reference(cap_temp, loc);
    9959              :         }
    9960              : 
    9961        16958 :       Type* et = type->array_type()->element_type();
    9962         8479 :       Expression* type_arg = Expression::make_type_descriptor(et, type_loc);
    9963         8479 :       Runtime::Function code = Runtime::MAKESLICE;
    9964         8479 :       if (!len_small || !cap_small)
    9965          120 :         code = Runtime::MAKESLICE64;
    9966         8479 :       Expression* mem = Runtime::make_call(gogo, code, loc, 3,
    9967              :                                            type_arg, len_arg, cap_arg);
    9968         8479 :       mem = Expression::make_unsafe_cast(Type::make_pointer_type(et), mem,
    9969              :                                          loc);
    9970         8479 :       Type* int_type = Type::lookup_integer_type("int");
    9971         8479 :       len_arg = Expression::make_cast(int_type, len_arg->copy(), loc);
    9972         8479 :       cap_arg = Expression::make_cast(int_type, cap_arg->copy(), loc);
    9973         8479 :       call = Expression::make_slice_value(type, mem, len_arg, cap_arg, loc);
    9974              :     }
    9975         6609 :   else if (is_map)
    9976              :     {
    9977         3846 :       Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
    9978         3846 :       if (!len_small)
    9979            2 :         call = Runtime::make_call(gogo, Runtime::MAKEMAP64, loc, 3, type_arg,
    9980              :                                   len_arg,
    9981              :                                   Expression::make_nil(loc));
    9982              :       else
    9983              :         {
    9984         3844 :           if (len_arg->numeric_constant_value(&nclen)
    9985         3485 :               && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
    9986         7329 :               && vlen <= Map_type::bucket_size)
    9987         3434 :             call = Runtime::make_call(gogo, Runtime::MAKEMAP_SMALL, loc, 0);
    9988              :           else
    9989          410 :             call = Runtime::make_call(gogo, Runtime::MAKEMAP, loc, 3, type_arg,
    9990              :                                       len_arg,
    9991              :                                       Expression::make_nil(loc));
    9992              :         }
    9993              :     }
    9994         2763 :   else if (is_chan)
    9995              :     {
    9996         2763 :       Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
    9997         2763 :       Runtime::Function code = Runtime::MAKECHAN;
    9998         2763 :       if (!len_small)
    9999            0 :         code = Runtime::MAKECHAN64;
   10000         2763 :       call = Runtime::make_call(gogo, code, loc, 2, type_arg, len_arg);
   10001              :     }
   10002              :   else
   10003            0 :     go_unreachable();
   10004              : 
   10005        15088 :   Expression* ret = Expression::make_unsafe_cast(type, call, loc);
   10006        15088 :   ret->determine_type_no_context(gogo);
   10007        15088 :   return ret;
   10008        15091 : }
   10009              : 
   10010              : // Flatten a call to the predeclared append function.  We do this in
   10011              : // the flatten phase, not the lowering phase, so that we run after
   10012              : // type checking and after order_evaluations.  If ASSIGN_LHS is not
   10013              : // NULL, this append is the right-hand-side of an assignment and
   10014              : // ASSIGN_LHS is the left-hand-side; in that case, set LHS directly
   10015              : // rather than returning a slice.  This lets us omit a write barrier
   10016              : // in common cases like a = append(a, ...) when the slice does not
   10017              : // need to grow.  ENCLOSING is not NULL iff ASSIGN_LHS is not NULL.
   10018              : 
   10019              : Expression*
   10020        15676 : Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
   10021              :                                         Statement_inserter* inserter,
   10022              :                                         Expression* assign_lhs,
   10023              :                                         Block* enclosing)
   10024              : {
   10025        15676 :   if (this->is_error_expression())
   10026            0 :     return this;
   10027              : 
   10028        15676 :   Location loc = this->location();
   10029              : 
   10030        15676 :   const Expression_list* args = this->args();
   10031        15676 :   go_assert(args != NULL && !args->empty());
   10032              : 
   10033        15676 :   Type* slice_type = args->front()->type();
   10034        15676 :   go_assert(slice_type->is_slice_type());
   10035        31352 :   Type* element_type = slice_type->array_type()->element_type();
   10036              : 
   10037        15676 :   if (args->size() == 1)
   10038              :     {
   10039              :       // append(s) evaluates to s.
   10040           23 :       if (assign_lhs != NULL)
   10041              :         return NULL;
   10042           23 :       return args->front();
   10043              :     }
   10044              : 
   10045        15653 :   Type* int_type = Type::lookup_integer_type("int");
   10046        15653 :   Type_context int_context(int_type, false);
   10047        15653 :   Type* uint_type = Type::lookup_integer_type("uint");
   10048              : 
   10049              :   // Implementing
   10050              :   //   append(s1, s2...)
   10051              :   // or
   10052              :   //   append(s1, a1, a2, a3, ...)
   10053              : 
   10054              :   // s1tmp := s1
   10055        15653 :   Temporary_statement* s1tmp = Statement::make_temporary(NULL, args->front(),
   10056              :                                                          loc);
   10057        15653 :   inserter->insert(s1tmp);
   10058              : 
   10059              :   // l1tmp := len(s1tmp)
   10060        15653 :   Named_object* lenfn = gogo->lookup_global("len");
   10061        15653 :   Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
   10062        15653 :   Expression_list* call_args = new Expression_list();
   10063        15653 :   call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
   10064        15653 :   Expression* len = Expression::make_call(lenref, call_args, false, loc);
   10065        15653 :   len->determine_type(gogo, &int_context);
   10066        15653 :   gogo->lower_expression(function, inserter, &len);
   10067        15653 :   gogo->flatten_expression(function, inserter, &len);
   10068        15653 :   Temporary_statement* l1tmp = Statement::make_temporary(int_type, len, loc);
   10069        15653 :   inserter->insert(l1tmp);
   10070              : 
   10071        15653 :   Temporary_statement* s2tmp = NULL;
   10072        15653 :   Temporary_statement* l2tmp = NULL;
   10073        15653 :   Expression_list* add = NULL;
   10074        15653 :   Expression* len2;
   10075        15653 :   Call_expression* makecall = NULL;
   10076        15653 :   if (this->is_varargs())
   10077              :     {
   10078         3556 :       go_assert(args->size() == 2);
   10079              : 
   10080         3556 :       std::pair<Call_expression*, Temporary_statement*> p =
   10081         3556 :         Expression::find_makeslice_call(args->back());
   10082         3556 :       makecall = p.first;
   10083         3556 :       if (makecall != NULL)
   10084              :         {
   10085              :           // We are handling
   10086              :           //    append(s, make([]T, len[, cap])...))
   10087              :           // which has already been lowered to
   10088              :           //    append(s, runtime.makeslice(T, len, cap)).
   10089              :           // We will optimize this to directly zeroing the tail,
   10090              :           // instead of allocating a new slice then copy.
   10091              : 
   10092              :           // Retrieve the length and capacity. Cannot reference s2 as
   10093              :           // we will remove the makeslice call.
   10094           27 :           Expression* len_arg = makecall->args()->at(1);
   10095           27 :           len_arg = Expression::make_cast(int_type, len_arg, loc);
   10096           27 :           l2tmp = Statement::make_temporary(int_type, len_arg, loc);
   10097           27 :           l2tmp->determine_types(gogo);
   10098           27 :           inserter->insert(l2tmp);
   10099              : 
   10100           27 :           Expression* cap_arg = makecall->args()->at(2);
   10101           27 :           cap_arg = Expression::make_cast(int_type, cap_arg, loc);
   10102           27 :           Temporary_statement* c2tmp =
   10103           27 :             Statement::make_temporary(int_type, cap_arg, loc);
   10104           27 :           c2tmp->determine_types(gogo);
   10105           27 :           inserter->insert(c2tmp);
   10106              : 
   10107              :           // Check bad len/cap here.
   10108              :           // checkmakeslice(type, len, cap)
   10109              :           // (Note that if len and cap are constants, we won't see a
   10110              :           // makeslice call here, as it will be rewritten to a stack
   10111              :           // allocated array by Mark_address_taken::expression.)
   10112           27 :           Expression* elem = Expression::make_type_descriptor(element_type,
   10113              :                                                               loc);
   10114           27 :           len2 = Expression::make_temporary_reference(l2tmp, loc);
   10115           27 :           Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc);
   10116           27 :           Expression* check = Runtime::make_call(gogo,
   10117              :                                                  Runtime::CHECK_MAKE_SLICE,
   10118           27 :                                                  loc, 3, elem, len2, cap2);
   10119           27 :           check->determine_type_no_context(gogo);
   10120           27 :           gogo->lower_expression(function, inserter, &check);
   10121           27 :           gogo->flatten_expression(function, inserter, &check);
   10122           27 :           Statement* s = Statement::make_statement(check, false);
   10123           27 :           inserter->insert(s);
   10124              : 
   10125              :           // Remove the original makeslice call.
   10126           27 :           Temporary_statement* ts = p.second;
   10127           27 :           if (ts != NULL && ts->uses() == 1)
   10128           27 :             ts->set_init(Expression::make_nil(loc));
   10129              :         }
   10130              :       else
   10131              :         {
   10132              :           // s2tmp := s2
   10133         3529 :           s2tmp = Statement::make_temporary(NULL, args->back(), loc);
   10134         3529 :           inserter->insert(s2tmp);
   10135              : 
   10136              :           // l2tmp := len(s2tmp)
   10137         3529 :           lenref = Expression::make_func_reference(lenfn, NULL, loc);
   10138         3529 :           call_args = new Expression_list();
   10139         3529 :           call_args->push_back(Expression::make_temporary_reference(s2tmp, loc));
   10140         3529 :           len = Expression::make_call(lenref, call_args, false, loc);
   10141         3529 :           len->determine_type(gogo, &int_context);
   10142         3529 :           gogo->lower_expression(function, inserter, &len);
   10143         3529 :           gogo->flatten_expression(function, inserter, &len);
   10144         3529 :           l2tmp = Statement::make_temporary(int_type, len, loc);
   10145         3529 :           l2tmp->determine_types(gogo);
   10146         3529 :           inserter->insert(l2tmp);
   10147              :         }
   10148              : 
   10149              :       // len2 = l2tmp
   10150         3556 :       len2 = Expression::make_temporary_reference(l2tmp, loc);
   10151              :     }
   10152              :   else
   10153              :     {
   10154              :       // We have to ensure that all the arguments are in variables
   10155              :       // now, because otherwise if one of them is an index expression
   10156              :       // into the current slice we could overwrite it before we fetch
   10157              :       // it.
   10158        12097 :       add = new Expression_list();
   10159        12097 :       Expression_list::const_iterator pa = args->begin();
   10160        26301 :       for (++pa; pa != args->end(); ++pa)
   10161              :         {
   10162        14204 :           if ((*pa)->is_multi_eval_safe())
   10163         7816 :             add->push_back(*pa);
   10164              :           else
   10165              :             {
   10166         6388 :               Temporary_statement* tmp = Statement::make_temporary(NULL, *pa,
   10167              :                                                                    loc);
   10168         6388 :               inserter->insert(tmp);
   10169         6388 :               add->push_back(Expression::make_temporary_reference(tmp, loc));
   10170              :             }
   10171              :         }
   10172              : 
   10173              :       // len2 = len(add)
   10174        12097 :       len2 = Expression::make_integer_ul(add->size(), int_type, loc);
   10175              :     }
   10176              : 
   10177              :   // ntmp := l1tmp + len2
   10178        15653 :   Expression* ref = Expression::make_temporary_reference(l1tmp, loc);
   10179        15653 :   Expression* sum = Expression::make_binary(OPERATOR_PLUS, ref, len2, loc);
   10180        15653 :   sum->determine_type(gogo, &int_context);
   10181        15653 :   gogo->lower_expression(function, inserter, &sum);
   10182        15653 :   gogo->flatten_expression(function, inserter, &sum);
   10183        15653 :   Temporary_statement* ntmp = Statement::make_temporary(int_type, sum, loc);
   10184        15653 :   ntmp->determine_types(gogo);
   10185        15653 :   inserter->insert(ntmp);
   10186              : 
   10187              :   // s1tmp = uint(ntmp) > uint(cap(s1tmp)) ?
   10188              :   //   growslice(type, s1tmp, ntmp) :
   10189              :   //   s1tmp[:ntmp]
   10190              :   // Using uint here means that if the computation of ntmp overflowed,
   10191              :   // we will call growslice which will panic.
   10192              : 
   10193        15653 :   Named_object* capfn = gogo->lookup_global("cap");
   10194        15653 :   Expression* capref = Expression::make_func_reference(capfn, NULL, loc);
   10195        15653 :   call_args = new Expression_list();
   10196        15653 :   call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
   10197        15653 :   Expression* cap = Expression::make_call(capref, call_args, false, loc);
   10198        15653 :   cap->determine_type(gogo, &int_context);
   10199        15653 :   gogo->lower_expression(function, inserter, &cap);
   10200        15653 :   gogo->flatten_expression(function, inserter, &cap);
   10201        15653 :   Temporary_statement* c1tmp = Statement::make_temporary(int_type, cap, loc);
   10202        15653 :   c1tmp->determine_types(gogo);
   10203        15653 :   inserter->insert(c1tmp);
   10204              : 
   10205        15653 :   Expression* left = Expression::make_temporary_reference(ntmp, loc);
   10206        15653 :   left = Expression::make_cast(uint_type, left, loc);
   10207        15653 :   Expression* right = Expression::make_temporary_reference(c1tmp, loc);
   10208        15653 :   right = Expression::make_cast(uint_type, right, loc);
   10209              : 
   10210        15653 :   Expression* cond = Expression::make_binary(OPERATOR_GT, left, right, loc);
   10211              : 
   10212        15653 :   Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
   10213        15653 :   Expression* a1 = Expression::make_type_descriptor(element_type, loc);
   10214        15653 :   Expression* a2 = Expression::make_temporary_reference(s1tmp, loc);
   10215        31306 :   a2 = slice_type->array_type()->get_value_pointer(gogo, a2);
   10216        15653 :   a2 = Expression::make_cast(unsafe_ptr_type, a2, loc);
   10217        15653 :   Expression* a3 = Expression::make_temporary_reference(l1tmp, loc);
   10218        15653 :   Expression* a4 = Expression::make_temporary_reference(c1tmp, loc);
   10219        15653 :   Expression* a5 = Expression::make_temporary_reference(ntmp, loc);
   10220        15653 :   Expression* call = Runtime::make_call(gogo, Runtime::GROWSLICE, loc, 5,
   10221        15653 :                                         a1, a2, a3, a4, a5);
   10222        15653 :   call = Expression::make_unsafe_cast(slice_type, call, loc);
   10223              : 
   10224        15653 :   ref = Expression::make_temporary_reference(s1tmp, loc);
   10225        15653 :   Expression* zero = Expression::make_integer_ul(0, int_type, loc);
   10226        15653 :   Expression* ref2 = Expression::make_temporary_reference(ntmp, loc);
   10227        15653 :   ref = Expression::make_array_index(ref, zero, ref2, NULL, loc);
   10228        15653 :   ref->array_index_expression()->set_needs_bounds_check(false);
   10229              : 
   10230        15653 :   if (assign_lhs == NULL)
   10231              :     {
   10232         2631 :       Expression* rhs = Expression::make_conditional(cond, call, ref, loc);
   10233              : 
   10234         2631 :       rhs->determine_type_no_context(gogo);
   10235         2631 :       gogo->lower_expression(function, inserter, &rhs);
   10236         2631 :       gogo->flatten_expression(function, inserter, &rhs);
   10237              : 
   10238         2631 :       ref = Expression::make_temporary_reference(s1tmp, loc);
   10239         2631 :       Statement* assign = Statement::make_assignment(ref, rhs, loc);
   10240         2631 :       assign->determine_types(gogo);
   10241         2631 :       inserter->insert(assign);
   10242              :     }
   10243              :   else
   10244              :     {
   10245        13022 :       cond->determine_type_no_context(gogo);
   10246        13022 :       gogo->lower_expression(function, inserter, &cond);
   10247        13022 :       gogo->flatten_expression(function, inserter, &cond);
   10248        13022 :       call->determine_type_no_context(gogo);
   10249        13022 :       gogo->lower_expression(function, inserter, &call);
   10250        13022 :       gogo->flatten_expression(function, inserter, &call);
   10251        13022 :       ref->determine_type_no_context(gogo);
   10252        13022 :       gogo->lower_expression(function, inserter, &ref);
   10253        13022 :       gogo->flatten_expression(function, inserter, &ref);
   10254              : 
   10255        13022 :       Block* then_block = new Block(enclosing, loc);
   10256        13022 :       Assignment_statement* assign =
   10257        13022 :         Statement::make_assignment(assign_lhs, call, loc);
   10258        13022 :       assign->determine_types(gogo);
   10259        13022 :       then_block->add_statement(assign);
   10260              : 
   10261        13022 :       Block* else_block = new Block(enclosing, loc);
   10262        13022 :       assign = Statement::make_assignment(assign_lhs->copy(), ref, loc);
   10263              :       // This assignment will not change the pointer value, so it does
   10264              :       // not need a write barrier.
   10265        13022 :       assign->set_omit_write_barrier();
   10266        13022 :       assign->determine_types(gogo);
   10267        13022 :       else_block->add_statement(assign);
   10268              : 
   10269        13022 :       Statement* s = Statement::make_if_statement(cond, then_block,
   10270              :                                                   else_block, loc);
   10271        13022 :       s->determine_types(gogo);
   10272        13022 :       inserter->insert(s);
   10273              : 
   10274        13022 :       ref = Expression::make_temporary_reference(s1tmp, loc);
   10275        13022 :       assign = Statement::make_assignment(ref, assign_lhs->copy(), loc);
   10276        13022 :       assign->determine_types(gogo);
   10277        13022 :       inserter->insert(assign);
   10278              :     }
   10279              : 
   10280        15653 :   Type* uintptr_type = Type::lookup_integer_type("uintptr");
   10281              : 
   10282        15653 :   if (this->is_varargs())
   10283              :     {
   10284         3556 :       if (makecall != NULL)
   10285              :         {
   10286              :           // memclr(&s1tmp[l1tmp], l2tmp*sizeof(elem))
   10287           27 :           a1 = Expression::make_temporary_reference(s1tmp, loc);
   10288           27 :           ref = Expression::make_temporary_reference(l1tmp, loc);
   10289           27 :           a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
   10290           27 :           a1->array_index_expression()->set_needs_bounds_check(false);
   10291           27 :           a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
   10292              : 
   10293           27 :           ref = Expression::make_temporary_reference(l2tmp, loc);
   10294           27 :           ref = Expression::make_cast(uintptr_type, ref, loc);
   10295           27 :           a2 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
   10296           27 :           a2 = Expression::make_binary(OPERATOR_MULT, a2, ref, loc);
   10297              : 
   10298           27 :           if (element_type->has_pointer())
   10299            7 :             call = Runtime::make_call(gogo, Runtime::MEMCLRHASPTR, loc, 2,
   10300              :                                       a1, a2);
   10301              :           else
   10302              :             {
   10303           20 :               Type* int32_type = Type::lookup_integer_type("int32");
   10304           20 :               zero = Expression::make_integer_ul(0, int32_type, loc);
   10305           20 :               call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMSET, loc, 3,
   10306              :                                         a1, zero, a2);
   10307              :             }
   10308              : 
   10309           27 :           if (element_type->has_pointer())
   10310              :             {
   10311              :               // For a slice containing pointers, growslice already zeroed
   10312              :               // the memory. We only need to zero in non-growing case.
   10313              :               // Note: growslice does not zero the memory in non-pointer case.
   10314            7 :               ref = Expression::make_temporary_reference(ntmp, loc);
   10315            7 :               ref = Expression::make_cast(uint_type, ref, loc);
   10316            7 :               ref2 = Expression::make_temporary_reference(c1tmp, loc);
   10317            7 :               ref2 = Expression::make_cast(uint_type, ref2, loc);
   10318            7 :               cond = Expression::make_binary(OPERATOR_GT, ref, ref2, loc);
   10319            7 :               zero = Expression::make_integer_ul(0, int_type, loc);
   10320            7 :               call = Expression::make_conditional(cond, zero, call, loc);
   10321              :             }
   10322              :         }
   10323              :       else
   10324              :         {
   10325         3529 :           if (element_type->has_pointer())
   10326              :             {
   10327              :               // copy(s1tmp[l1tmp:], s2tmp)
   10328         1251 :               a1 = Expression::make_temporary_reference(s1tmp, loc);
   10329         1251 :               ref = Expression::make_temporary_reference(l1tmp, loc);
   10330         1251 :               Expression* nil = Expression::make_nil(loc);
   10331         1251 :               a1 = Expression::make_array_index(a1, ref, nil, NULL, loc);
   10332         1251 :               a1->array_index_expression()->set_needs_bounds_check(false);
   10333              : 
   10334         1251 :               a2 = Expression::make_temporary_reference(s2tmp, loc);
   10335              : 
   10336         1251 :               Named_object* copyfn = gogo->lookup_global("copy");
   10337         1251 :               Expression* copyref = Expression::make_func_reference(copyfn, NULL, loc);
   10338         1251 :               call_args = new Expression_list();
   10339         1251 :               call_args->push_back(a1);
   10340         1251 :               call_args->push_back(a2);
   10341         1251 :               call = Expression::make_call(copyref, call_args, false, loc);
   10342              :             }
   10343              :           else
   10344              :             {
   10345              :               // memmove(&s1tmp[l1tmp], s2tmp.ptr, l2tmp*sizeof(elem))
   10346         2278 :               a1 = Expression::make_temporary_reference(s1tmp, loc);
   10347         2278 :               ref = Expression::make_temporary_reference(l1tmp, loc);
   10348         2278 :               a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
   10349         2278 :               a1->array_index_expression()->set_needs_bounds_check(false);
   10350         2278 :               a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
   10351              : 
   10352         2278 :               a2 = Expression::make_temporary_reference(s2tmp, loc);
   10353         2278 :               a2 = (a2->type()->is_string_type()
   10354         2278 :                     ? Expression::make_string_info(a2,
   10355              :                                                    STRING_INFO_DATA,
   10356              :                                                    loc)
   10357         1314 :                     : Expression::make_slice_info(a2,
   10358              :                                                   SLICE_INFO_VALUE_POINTER,
   10359              :                                                   loc));
   10360              : 
   10361         2278 :               ref = Expression::make_temporary_reference(l2tmp, loc);
   10362         2278 :               ref = Expression::make_cast(uintptr_type, ref, loc);
   10363         2278 :               a3 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
   10364         2278 :               a3 = Expression::make_binary(OPERATOR_MULT, a3, ref, loc);
   10365              : 
   10366         2278 :               call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMMOVE, loc, 3,
   10367              :                                         a1, a2, a3);
   10368              :             }
   10369              :         }
   10370         3556 :       call->determine_type_no_context(gogo);
   10371         3556 :       gogo->lower_expression(function, inserter, &call);
   10372         3556 :       gogo->flatten_expression(function, inserter, &call);
   10373         3556 :       inserter->insert(Statement::make_statement(call, false));
   10374              :     }
   10375              :   else
   10376              :     {
   10377              :       // For each argument:
   10378              :       //  s1tmp[l1tmp+i] = a
   10379        12097 :       unsigned long i = 0;
   10380        12097 :       for (Expression_list::const_iterator pa = add->begin();
   10381        26301 :            pa != add->end();
   10382        14204 :            ++pa, ++i)
   10383              :         {
   10384        14204 :           ref = Expression::make_temporary_reference(s1tmp, loc);
   10385        14204 :           ref2 = Expression::make_temporary_reference(l1tmp, loc);
   10386        14204 :           Expression* off = Expression::make_integer_ul(i, int_type, loc);
   10387        14204 :           ref2 = Expression::make_binary(OPERATOR_PLUS, ref2, off, loc);
   10388        14204 :           Expression* lhs = Expression::make_array_index(ref, ref2, NULL,
   10389        14204 :                                                          NULL, loc);
   10390        14204 :           lhs->array_index_expression()->set_needs_bounds_check(false);
   10391        14204 :           lhs->determine_type_no_context(gogo);
   10392        14204 :           gogo->lower_expression(function, inserter, &lhs);
   10393        14204 :           gogo->flatten_expression(function, inserter, &lhs);
   10394        14204 :       Expression* elem = *pa;
   10395        14204 :       if (!Type::are_identical(element_type, elem->type(), 0, NULL)
   10396        14204 :           && element_type->interface_type() != NULL)
   10397          504 :         elem = Expression::make_cast(element_type, elem, loc);
   10398              :           // The flatten pass runs after the write barrier pass, so we
   10399              :           // need to insert a write barrier here if necessary.
   10400              :           // However, if ASSIGN_LHS is not NULL, we have been called
   10401              :           // directly before the write barrier pass.
   10402        14204 :           Statement* assign;
   10403        14204 :           if (assign_lhs != NULL
   10404        14204 :               || !gogo->assign_needs_write_barrier(lhs, NULL))
   10405        12988 :             assign = Statement::make_assignment(lhs, elem, loc);
   10406              :           else
   10407              :             {
   10408         1216 :               Function* f = function == NULL ? NULL : function->func_value();
   10409         1216 :               assign = gogo->assign_with_write_barrier(f, NULL, inserter,
   10410              :                                                        lhs, elem, loc);
   10411              :             }
   10412        14204 :           assign->determine_types(gogo);
   10413        14204 :           inserter->insert(assign);
   10414              :         }
   10415              :     }
   10416              : 
   10417        15653 :   if (assign_lhs != NULL)
   10418              :     return NULL;
   10419              : 
   10420         2631 :   return Expression::make_temporary_reference(s1tmp, loc);
   10421              : }
   10422              : 
   10423              : // Return whether an expression has an integer value.  Report an error
   10424              : // if not.  This is used when handling calls to the predeclared make
   10425              : // function.  Set *SMALL if the value is known to fit in type "int".
   10426              : 
   10427              : bool
   10428        11881 : Builtin_call_expression::check_int_value(Expression* e, bool is_length,
   10429              :                                          bool *small)
   10430              : {
   10431        11881 :   *small = false;
   10432              : 
   10433        11881 :   Numeric_constant nc;
   10434        11881 :   if (e->numeric_constant_value(&nc))
   10435              :     {
   10436         5748 :       unsigned long v;
   10437         5748 :       switch (nc.to_unsigned_long(&v))
   10438              :         {
   10439              :         case Numeric_constant::NC_UL_VALID:
   10440              :           break;
   10441            1 :         case Numeric_constant::NC_UL_NOTINT:
   10442            1 :           go_error_at(e->location(), "non-integer %s argument to make",
   10443              :                       is_length ? "len" : "cap");
   10444            1 :           return false;
   10445            2 :         case Numeric_constant::NC_UL_NEGATIVE:
   10446            2 :           go_error_at(e->location(), "negative %s argument to make",
   10447              :                       is_length ? "len" : "cap");
   10448            2 :           return false;
   10449              :         case Numeric_constant::NC_UL_BIG:
   10450              :           // We don't want to give a compile-time error for a 64-bit
   10451              :           // value on a 32-bit target.
   10452              :           break;
   10453              :         }
   10454              : 
   10455         5745 :       mpz_t val;
   10456         5745 :       if (!nc.to_int(&val))
   10457            0 :         go_unreachable();
   10458         5745 :       int bits = mpz_sizeinbase(val, 2);
   10459         5745 :       mpz_clear(val);
   10460         5745 :       Type* int_type = Type::lookup_integer_type("int");
   10461        11490 :       if (bits >= int_type->integer_type()->bits())
   10462              :         {
   10463            1 :           go_error_at(e->location(), "%s argument too large for make",
   10464              :                       is_length ? "len" : "cap");
   10465            1 :           return false;
   10466              :         }
   10467              : 
   10468         5744 :       *small = true;
   10469         5744 :       return true;
   10470              :     }
   10471              : 
   10472         6133 :   if (e->type()->integer_type() != NULL)
   10473              :     {
   10474        12254 :       int ebits = e->type()->integer_type()->bits();
   10475        12254 :       int intbits = Type::lookup_integer_type("int")->integer_type()->bits();
   10476              : 
   10477              :       // We can treat ebits == intbits as small even for an unsigned
   10478              :       // integer type, because we will convert the value to int and
   10479              :       // then reject it in the runtime if it is negative.
   10480         6127 :       *small = ebits <= intbits;
   10481              : 
   10482         6127 :       return true;
   10483              :     }
   10484              : 
   10485            6 :   go_error_at(e->location(), "non-integer %s argument to make",
   10486              :               is_length ? "len" : "cap");
   10487            6 :   return false;
   10488        11881 : }
   10489              : 
   10490              : // Return the type of the real or imag functions, given the type of
   10491              : // the argument.  We need to map complex64 to float32 and complex128
   10492              : // to float64, so it has to be done by name.  This returns NULL if it
   10493              : // can't figure out the type.
   10494              : 
   10495              : Type*
   10496        22174 : Builtin_call_expression::real_imag_type(Type* arg_type)
   10497              : {
   10498        22174 :   if (arg_type == NULL || arg_type->is_abstract())
   10499           95 :     return NULL;
   10500        22079 :   Named_type* nt = arg_type->named_type();
   10501        22079 :   if (nt == NULL)
   10502              :     return NULL;
   10503        22080 :   while (nt->real_type()->named_type() != NULL)
   10504            5 :     nt = nt->real_type()->named_type();
   10505        22075 :   if (nt->name() == "complex64")
   10506          153 :     return Type::lookup_float_type("float32");
   10507        21922 :   else if (nt->name() == "complex128")
   10508        21859 :     return Type::lookup_float_type("float64");
   10509              :   else
   10510              :     return NULL;
   10511              : }
   10512              : 
   10513              : // Return the type of the complex function, given the type of one of the
   10514              : // argments.  Like real_imag_type, we have to map by name.
   10515              : 
   10516              : Type*
   10517        88910 : Builtin_call_expression::complex_type(Type* arg_type)
   10518              : {
   10519        88910 :   if (arg_type == NULL || arg_type->is_abstract())
   10520          305 :     return NULL;
   10521        88605 :   Named_type* nt = arg_type->named_type();
   10522        88605 :   if (nt == NULL)
   10523              :     return NULL;
   10524        88599 :   while (nt->real_type()->named_type() != NULL)
   10525            2 :     nt = nt->real_type()->named_type();
   10526        88597 :   if (nt->name() == "float32")
   10527          117 :     return Type::lookup_complex_type("complex64");
   10528        88480 :   else if (nt->name() == "float64")
   10529        88470 :     return Type::lookup_complex_type("complex128");
   10530              :   else
   10531              :     return NULL;
   10532              : }
   10533              : 
   10534              : // Return a single argument, or NULL if there isn't one.
   10535              : 
   10536              : Expression*
   10537       593023 : Builtin_call_expression::one_arg() const
   10538              : {
   10539       593023 :   const Expression_list* args = this->args();
   10540      1186046 :   if (args == NULL || args->size() != 1)
   10541              :     return NULL;
   10542       593023 :   return args->front();
   10543              : }
   10544              : 
   10545              : // A traversal class which looks for a call or receive expression.
   10546              : 
   10547        22831 : class Find_call_expression : public Traverse
   10548              : {
   10549              :  public:
   10550        22831 :   Find_call_expression()
   10551        22831 :     : Traverse(traverse_expressions),
   10552        22831 :       found_(false)
   10553              :   { }
   10554              : 
   10555              :   int
   10556              :   expression(Expression**);
   10557              : 
   10558              :   bool
   10559        22831 :   found()
   10560        22831 :   { return this->found_; }
   10561              : 
   10562              :  private:
   10563              :   bool found_;
   10564              : };
   10565              : 
   10566              : int
   10567        27379 : Find_call_expression::expression(Expression** pexpr)
   10568              : {
   10569        27379 :   Expression* expr = *pexpr;
   10570        27379 :   if (!expr->is_constant()
   10571        54529 :       && (expr->call_expression() != NULL
   10572           52 :           || expr->receive_expression() != NULL))
   10573              :     {
   10574           52 :       this->found_ = true;
   10575           52 :       return TRAVERSE_EXIT;
   10576              :     }
   10577              :   return TRAVERSE_CONTINUE;
   10578              : }
   10579              : 
   10580              : // Return whether calling len or cap on EXPR, of array type, is a
   10581              : // constant.  The language spec says "the expressions len(s) and
   10582              : // cap(s) are constants if the type of s is an array or pointer to an
   10583              : // array and the expression s does not contain channel receives or
   10584              : // (non-constant) function calls."
   10585              : 
   10586              : bool
   10587        22831 : Builtin_call_expression::array_len_is_constant(Expression* expr)
   10588              : {
   10589        91324 :   go_assert(expr->type()->deref()->array_type() != NULL
   10590              :             && !expr->type()->deref()->is_slice_type());
   10591        22831 :   if (expr->is_constant())
   10592              :     return true;
   10593        22831 :   Find_call_expression find_call;
   10594        22831 :   Expression::traverse(&expr, &find_call);
   10595        22831 :   return !find_call.found();
   10596        22831 : }
   10597              : 
   10598              : // Return whether this is constant: len of a string constant, or len
   10599              : // or cap of an array, or unsafe.Sizeof, unsafe.Offsetof,
   10600              : // unsafe.Alignof.
   10601              : 
   10602              : bool
   10603       508655 : Builtin_call_expression::do_is_constant() const
   10604              : {
   10605       508655 :   if (this->is_error_expression())
   10606              :     return true;
   10607       508655 :   switch (this->code_)
   10608              :     {
   10609       327550 :     case BUILTIN_LEN:
   10610       327550 :     case BUILTIN_CAP:
   10611       327550 :       {
   10612       327550 :         if (this->seen_)
   10613              :           return false;
   10614              : 
   10615       327550 :         Expression* arg = this->one_arg();
   10616       327550 :         if (arg == NULL)
   10617              :           return false;
   10618              : 
   10619              :         // We may be called before the determine_types pass.
   10620       327550 :         arg->determine_type_no_context(this->gogo_);
   10621              : 
   10622       327550 :         Type* arg_type = arg->type();
   10623       327550 :         if (arg_type->is_error())
   10624              :           return true;
   10625              : 
   10626       327547 :         if (arg_type->points_to() != NULL
   10627         9306 :             && arg_type->points_to()->array_type() != NULL
   10628       336847 :             && !arg_type->points_to()->is_slice_type())
   10629         9294 :           arg_type = arg_type->points_to();
   10630              : 
   10631       601776 :         if (arg_type->array_type() != NULL
   10632       274229 :             && arg_type->array_type()->length() != NULL)
   10633              :           {
   10634        13527 :             this->seen_ = true;
   10635        13527 :             bool ret = Builtin_call_expression::array_len_is_constant(arg);
   10636        13527 :             this->seen_ = false;
   10637        13527 :             return ret;
   10638              :           }
   10639              : 
   10640       594242 :         if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
   10641              :           {
   10642        50230 :             this->seen_ = true;
   10643        50230 :             bool ret = arg->is_constant();
   10644        50230 :             this->seen_ = false;
   10645        50230 :             return ret;
   10646              :           }
   10647              :       }
   10648              :       break;
   10649              : 
   10650         1625 :     case BUILTIN_SIZEOF:
   10651         1625 :     case BUILTIN_ALIGNOF:
   10652         1625 :       return this->one_arg() != NULL;
   10653              : 
   10654         1378 :     case BUILTIN_OFFSETOF:
   10655         1378 :       {
   10656         1378 :         Expression* arg = this->one_arg();
   10657         1378 :         if (arg == NULL)
   10658              :           return false;
   10659         1378 :         return (arg->field_reference_expression() != NULL
   10660         1122 :                 || arg->classification() == Expression::EXPRESSION_SELECTOR);
   10661              :       }
   10662              : 
   10663        49388 :     case BUILTIN_COMPLEX:
   10664        49388 :       {
   10665        49388 :         const Expression_list* args = this->args();
   10666        98776 :         if (args != NULL && args->size() == 2)
   10667        49388 :           return args->front()->is_constant() && args->back()->is_constant();
   10668              :       }
   10669              :       break;
   10670              : 
   10671         2195 :     case BUILTIN_REAL:
   10672         2195 :     case BUILTIN_IMAG:
   10673         2195 :       {
   10674         2195 :         Expression* arg = this->one_arg();
   10675         4390 :         return arg != NULL && arg->is_constant();
   10676              :       }
   10677              : 
   10678              :     default:
   10679              :       break;
   10680              :     }
   10681              : 
   10682              :   return false;
   10683              : }
   10684              : 
   10685              : // Return whether a builtin call is untyped.  Most builtin functions
   10686              : // have a known type, but complex, real, and imag can be untyped.
   10687              : 
   10688              : bool
   10689        56988 : Builtin_call_expression::do_is_untyped(Type** ptype) const
   10690              : {
   10691        56988 :   if (this->is_error_expression())
   10692              :     return false;
   10693              : 
   10694        56988 :   switch (this->code_)
   10695              :     {
   10696              :     default:
   10697              :       return false;
   10698              : 
   10699        13556 :     case BUILTIN_COMPLEX:
   10700        13556 :       {
   10701        13556 :         const Expression_list* args = this->args();
   10702        27112 :         if (args == NULL || args->size() != 2)
   10703              :           return false;
   10704        13556 :         Type* dummy;
   10705        13556 :         if (!args->front()->is_untyped(&dummy)
   10706        13556 :             || !args->back()->is_untyped(&dummy))
   10707        12065 :           return false;
   10708         1491 :         *ptype = Type::make_abstract_complex_type();
   10709         1491 :         return true;
   10710              :       }
   10711              : 
   10712         1197 :     case BUILTIN_REAL:
   10713         1197 :     case BUILTIN_IMAG:
   10714         1197 :       {
   10715         1197 :         Expression* arg = this->one_arg();
   10716         1197 :         if (arg == NULL)
   10717              :           return false;
   10718         1197 :         if (!arg->is_untyped(ptype))
   10719              :           return false;
   10720           32 :         *ptype = Type::make_abstract_float_type();
   10721           32 :         return true;
   10722              :       }
   10723              :     }
   10724              : }
   10725              : 
   10726              : // Return a numeric constant if possible.
   10727              : 
   10728              : bool
   10729       148021 : Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc)
   10730              : {
   10731       148021 :   if (this->code_ == BUILTIN_LEN
   10732       148021 :       || this->code_ == BUILTIN_CAP)
   10733              :     {
   10734       142023 :       Expression* arg = this->one_arg();
   10735       142023 :       if (arg == NULL)
   10736              :         return false;
   10737              : 
   10738              :       // We may be called before the determine_types pass.
   10739       142023 :       arg->determine_type_no_context(this->gogo_);
   10740              : 
   10741       142023 :       Type* arg_type = arg->type();
   10742       142023 :       if (arg_type->is_error())
   10743              :         return false;
   10744              : 
   10745       282621 :       if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
   10746              :         {
   10747        33992 :           std::string sval;
   10748        33992 :           if (arg->string_constant_value(&sval))
   10749              :             {
   10750         2376 :               nc->set_unsigned_long(Type::lookup_integer_type("int"),
   10751              :                                     sval.length());
   10752         2376 :               return true;
   10753              :             }
   10754        33992 :         }
   10755              : 
   10756       139647 :       if (arg_type->points_to() != NULL
   10757         9189 :           && arg_type->points_to()->array_type() != NULL
   10758       148836 :           && !arg_type->points_to()->is_slice_type())
   10759         9189 :         arg_type = arg_type->points_to();
   10760              : 
   10761       244731 :       if (arg_type->array_type() != NULL
   10762       105084 :           && arg_type->array_type()->length() != NULL)
   10763              :         {
   10764        12302 :           if (this->seen_)
   10765              :             return false;
   10766              : 
   10767        12302 :           if (!arg_type->is_error())
   10768              :             {
   10769        24604 :               Expression* e = arg_type->array_type()->length();
   10770        12302 :               this->seen_ = true;
   10771        12302 :               bool r = e->numeric_constant_value(nc);
   10772        12302 :               this->seen_ = false;
   10773        12302 :               if (r)
   10774              :                 {
   10775        12302 :                   if (!nc->set_type(Type::lookup_integer_type("int"), false,
   10776              :                                     this->location()))
   10777            0 :                     r = false;
   10778              :                 }
   10779        12302 :               return r;
   10780              :             }
   10781              :         }
   10782              :     }
   10783              :   else if (this->code_ == BUILTIN_SIZEOF
   10784              :            || this->code_ == BUILTIN_ALIGNOF)
   10785              :     {
   10786         1870 :       Expression* arg = this->one_arg();
   10787         1870 :       if (arg == NULL)
   10788              :         return false;
   10789              : 
   10790              :       // We may be called before the determine_types pass.
   10791         1870 :       arg->determine_type_no_context(this->gogo_);
   10792              : 
   10793         1870 :       Type* arg_type = arg->type();
   10794         1870 :       if (arg_type->is_error())
   10795              :         return false;
   10796         1870 :       if (arg_type->is_abstract())
   10797            0 :         arg_type = arg_type->make_non_abstract_type();
   10798         1870 :       if (this->seen_)
   10799              :         return false;
   10800              : 
   10801         1870 :       int64_t ret;
   10802         1870 :       if (this->code_ == BUILTIN_SIZEOF)
   10803              :         {
   10804         1859 :           this->seen_ = true;
   10805         1859 :           bool ok = arg_type->backend_type_size(this->gogo_, &ret);
   10806         1859 :           this->seen_ = false;
   10807         1859 :           if (!ok)
   10808              :             return false;
   10809              :         }
   10810           11 :       else if (this->code_ == BUILTIN_ALIGNOF)
   10811              :         {
   10812           11 :           bool ok;
   10813           11 :           this->seen_ = true;
   10814           11 :           if (arg->field_reference_expression() == NULL)
   10815            5 :             ok = arg_type->backend_type_align(this->gogo_, &ret);
   10816              :           else
   10817              :             {
   10818              :               // Calling unsafe.Alignof(s.f) returns the alignment of
   10819              :               // the type of f when it is used as a field in a struct.
   10820            6 :               ok = arg_type->backend_type_field_align(this->gogo_, &ret);
   10821              :             }
   10822           11 :           this->seen_ = false;
   10823           11 :           if (!ok)
   10824              :             return false;
   10825              :         }
   10826              :       else
   10827            0 :         go_unreachable();
   10828              : 
   10829         1870 :       mpz_t zval;
   10830         1870 :       set_mpz_from_int64(&zval, ret);
   10831         1870 :       nc->set_int(Type::lookup_integer_type("uintptr"), zval);
   10832         1870 :       mpz_clear(zval);
   10833         1870 :       return true;
   10834              :     }
   10835              :   else if (this->code_ == BUILTIN_OFFSETOF)
   10836              :     {
   10837          804 :       Expression* arg = this->one_arg();
   10838          804 :       if (arg == NULL)
   10839              :         return false;
   10840              : 
   10841              :       // We may be called before the determine_types pass.
   10842          804 :       arg->determine_type_no_context(this->gogo_);
   10843              : 
   10844          804 :       Field_reference_expression* farg = arg->field_reference_expression();
   10845          256 :       if (farg == NULL)
   10846              :         return false;
   10847          256 :       if (this->seen_)
   10848              :         return false;
   10849              : 
   10850              :       int64_t total_offset = 0;
   10851          966 :       while (true)
   10852              :         {
   10853          611 :           Expression* struct_expr = farg->expr();
   10854          611 :           Type* st = struct_expr->type();
   10855          611 :           if (st->struct_type() == NULL)
   10856            0 :             return false;
   10857          611 :           if (st->named_type() != NULL)
   10858          584 :             st->named_type()->convert(this->gogo_);
   10859          611 :           if (st->is_error_type())
   10860              :             {
   10861            0 :               go_assert(saw_errors());
   10862              :               return false;
   10863              :             }
   10864          611 :           int64_t offset;
   10865          611 :           this->seen_ = true;
   10866         1222 :           bool ok = st->struct_type()->backend_field_offset(this->gogo_,
   10867              :                                                             farg->field_index(),
   10868              :                                                             &offset);
   10869          611 :           this->seen_ = false;
   10870          611 :           if (!ok)
   10871              :             return false;
   10872          611 :           total_offset += offset;
   10873          611 :           if (farg->implicit() && struct_expr->field_reference_expression() != NULL)
   10874              :             {
   10875              :               // Go up until we reach the original base.
   10876          355 :               farg = struct_expr->field_reference_expression();
   10877          355 :               continue;
   10878              :             }
   10879          256 :           break;
   10880              :         }
   10881          256 :       mpz_t zval;
   10882          256 :       set_mpz_from_int64(&zval, total_offset);
   10883          256 :       nc->set_int(Type::lookup_integer_type("uintptr"), zval);
   10884          256 :       mpz_clear(zval);
   10885          256 :       return true;
   10886              :     }
   10887              :   else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG)
   10888              :     {
   10889          636 :       Expression* arg = this->one_arg();
   10890          636 :       if (arg == NULL)
   10891              :         return false;
   10892              : 
   10893          636 :       Numeric_constant argnc;
   10894          636 :       if (!arg->numeric_constant_value(&argnc))
   10895              :         return false;
   10896              : 
   10897           42 :       mpc_t val;
   10898           42 :       if (!argnc.to_complex(&val))
   10899              :         return false;
   10900              : 
   10901           42 :       Type* type = Builtin_call_expression::real_imag_type(argnc.type());
   10902           42 :       if (this->code_ == BUILTIN_REAL)
   10903           22 :         nc->set_float(type, mpc_realref(val));
   10904              :       else
   10905           20 :         nc->set_float(type, mpc_imagref(val));
   10906           42 :       mpc_clear(val);
   10907           42 :       return true;
   10908          636 :     }
   10909              :   else if (this->code_ == BUILTIN_COMPLEX)
   10910              :     {
   10911         1528 :       const Expression_list* args = this->args();
   10912         3056 :       if (args == NULL || args->size() != 2)
   10913              :         return false;
   10914              : 
   10915         1528 :       Numeric_constant rnc;
   10916         1528 :       if (!args->front()->numeric_constant_value(&rnc))
   10917              :         return false;
   10918         1527 :       Numeric_constant inc;
   10919         1527 :       if (!args->back()->numeric_constant_value(&inc))
   10920              :         return false;
   10921              : 
   10922         1527 :       if (rnc.type() != NULL
   10923         1527 :           && !rnc.type()->is_abstract()
   10924         1506 :           && inc.type() != NULL
   10925         1506 :           && !inc.type()->is_abstract()
   10926         3033 :           && !Type::are_identical(rnc.type(), inc.type(),
   10927              :                                   Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
   10928              :                                   NULL))
   10929              :         return false;
   10930              : 
   10931         1527 :       mpfr_t r;
   10932         1527 :       if (!rnc.to_float(&r))
   10933              :         return false;
   10934         1527 :       mpfr_t i;
   10935         1527 :       if (!inc.to_float(&i))
   10936              :         {
   10937            0 :           mpfr_clear(r);
   10938            0 :           return false;
   10939              :         }
   10940              : 
   10941         1527 :       Type* arg_type = rnc.type();
   10942         1527 :       if (arg_type == NULL || arg_type->is_abstract())
   10943           21 :         arg_type = inc.type();
   10944              : 
   10945         1527 :       mpc_t val;
   10946         1527 :       mpc_init2(val, mpc_precision);
   10947         1527 :       mpc_set_fr_fr(val, r, i, MPC_RNDNN);
   10948         1527 :       mpfr_clear(r);
   10949         1527 :       mpfr_clear(i);
   10950              : 
   10951         1527 :       Type* type = Builtin_call_expression::complex_type(arg_type);
   10952         1527 :       nc->set_complex(type, val);
   10953              : 
   10954         1527 :       mpc_clear(val);
   10955              : 
   10956         1527 :       return true;
   10957         1528 :     }
   10958              : 
   10959              :   return false;
   10960              : }
   10961              : 
   10962              : // Give an error if we are discarding the value of an expression which
   10963              : // should not normally be discarded.  We don't give an error for
   10964              : // discarding the value of an ordinary function call, but we do for
   10965              : // builtin functions, purely for consistency with the gc compiler.
   10966              : 
   10967              : bool
   10968        34613 : Builtin_call_expression::do_discarding_value()
   10969              : {
   10970        34613 :   switch (this->code_)
   10971              :     {
   10972            0 :     case BUILTIN_INVALID:
   10973            0 :     default:
   10974            0 :       go_unreachable();
   10975              : 
   10976           71 :     case BUILTIN_APPEND:
   10977           71 :     case BUILTIN_CAP:
   10978           71 :     case BUILTIN_COMPLEX:
   10979           71 :     case BUILTIN_IMAG:
   10980           71 :     case BUILTIN_LEN:
   10981           71 :     case BUILTIN_MAKE:
   10982           71 :     case BUILTIN_NEW:
   10983           71 :     case BUILTIN_REAL:
   10984           71 :     case BUILTIN_ADD:
   10985           71 :     case BUILTIN_ALIGNOF:
   10986           71 :     case BUILTIN_OFFSETOF:
   10987           71 :     case BUILTIN_SIZEOF:
   10988           71 :     case BUILTIN_SLICE:
   10989           71 :       this->unused_value_error();
   10990           71 :       return false;
   10991              : 
   10992              :     case BUILTIN_CLOSE:
   10993              :     case BUILTIN_COPY:
   10994              :     case BUILTIN_DELETE:
   10995              :     case BUILTIN_PANIC:
   10996              :     case BUILTIN_PRINT:
   10997              :     case BUILTIN_PRINTLN:
   10998              :     case BUILTIN_RECOVER:
   10999              :       return true;
   11000              :     }
   11001              : }
   11002              : 
   11003              : // Return the type.
   11004              : 
   11005              : Type*
   11006      1451500 : Builtin_call_expression::do_type()
   11007              : {
   11008      1451500 :   if (this->is_error_expression())
   11009         1941 :     return Type::make_error_type();
   11010              : 
   11011      1449559 :   Type* type = this->type();
   11012      1449559 :   if (type != NULL)
   11013              :     return type;
   11014              : 
   11015      1448018 :   switch (this->code_)
   11016              :     {
   11017            0 :     case BUILTIN_INVALID:
   11018            0 :     default:
   11019            0 :       return Type::make_error_type();
   11020              : 
   11021        14123 :     case BUILTIN_NEW:
   11022        14123 :       {
   11023        14123 :         const Expression_list* args = this->args();
   11024        14123 :         if (args == NULL || args->empty())
   11025            0 :           return Type::make_error_type();
   11026        14123 :         return Type::make_pointer_type(args->front()->type());
   11027              :       }
   11028              : 
   11029        24732 :     case BUILTIN_MAKE:
   11030        24732 :       {
   11031        24732 :         const Expression_list* args = this->args();
   11032        24732 :         if (args == NULL || args->empty())
   11033            0 :           return Type::make_error_type();
   11034        24732 :         return args->front()->type();
   11035              :       }
   11036              : 
   11037      1142751 :     case BUILTIN_CAP:
   11038      1142751 :     case BUILTIN_COPY:
   11039      1142751 :     case BUILTIN_LEN:
   11040      1142751 :       return Type::lookup_integer_type("int");
   11041              : 
   11042         3750 :     case BUILTIN_ALIGNOF:
   11043         3750 :     case BUILTIN_OFFSETOF:
   11044         3750 :     case BUILTIN_SIZEOF:
   11045         3750 :       return Type::lookup_integer_type("uintptr");
   11046              : 
   11047        75676 :     case BUILTIN_CLOSE:
   11048        75676 :     case BUILTIN_DELETE:
   11049        75676 :     case BUILTIN_PANIC:
   11050        75676 :     case BUILTIN_PRINT:
   11051        75676 :     case BUILTIN_PRINTLN:
   11052        75676 :       return Type::make_void_type();
   11053              : 
   11054         6835 :     case BUILTIN_RECOVER:
   11055         6835 :       return Type::make_empty_interface_type(Linemap::predeclared_location());
   11056              : 
   11057        85298 :     case BUILTIN_APPEND:
   11058        85298 :       {
   11059        85298 :         const Expression_list* args = this->args();
   11060        85298 :         if (args == NULL || args->empty())
   11061            0 :           return Type::make_error_type();
   11062        85298 :         Type *ret = args->front()->type();
   11063        85298 :         if (!ret->is_slice_type())
   11064            2 :           return Type::make_error_type();
   11065              :         return ret;
   11066              :       }
   11067              : 
   11068         8427 :     case BUILTIN_REAL:
   11069         8427 :     case BUILTIN_IMAG:
   11070         8427 :       {
   11071         8427 :         Expression* arg = this->one_arg();
   11072         8427 :         if (arg == NULL)
   11073            0 :           return Type::make_error_type();
   11074         8427 :         Type* t = arg->type();
   11075         8427 :         if (t->is_abstract())
   11076            0 :           t = t->make_non_abstract_type();
   11077         8427 :         t = Builtin_call_expression::real_imag_type(t);
   11078         8427 :         if (t == NULL)
   11079            4 :           t = Type::make_error_type();
   11080              :         return t;
   11081              :       }
   11082              : 
   11083        86335 :     case BUILTIN_COMPLEX:
   11084        86335 :       {
   11085        86335 :         const Expression_list* args = this->args();
   11086       172670 :         if (args == NULL || args->size() != 2)
   11087            0 :           return Type::make_error_type();
   11088        86335 :         Type* t = args->front()->type();
   11089        86335 :         if (t->is_abstract())
   11090              :           {
   11091            0 :             t = args->back()->type();
   11092            0 :             if (t->is_abstract())
   11093            0 :               t = t->make_non_abstract_type();
   11094              :           }
   11095        86335 :         t = Builtin_call_expression::complex_type(t);
   11096        86335 :         if (t == NULL)
   11097            1 :           t = Type::make_error_type();
   11098              :         return t;
   11099              :       }
   11100              : 
   11101           41 :     case BUILTIN_ADD:
   11102           41 :       return Type::make_pointer_type(Type::make_void_type());
   11103              : 
   11104           50 :     case BUILTIN_SLICE:
   11105           50 :       const Expression_list* args = this->args();
   11106          100 :       if (args == NULL || args->size() != 2)
   11107            0 :         return Type::make_error_type();
   11108           50 :       Type* pt = args->front()->type()->points_to();
   11109           50 :       if (pt == NULL)
   11110            0 :         return Type::make_error_type();
   11111           50 :       return Type::make_array_type(pt, NULL);
   11112              :     }
   11113              : }
   11114              : 
   11115              : // Determine the type.
   11116              : 
   11117              : void
   11118       295515 : Builtin_call_expression::do_determine_type(Gogo* gogo,
   11119              :                                            const Type_context* context)
   11120              : {
   11121       295515 :   if (!this->determining_types())
   11122              :     return;
   11123              : 
   11124       226650 :   this->fn()->determine_type_no_context(gogo);
   11125              : 
   11126       226650 :   this->simplify_multiple_results(gogo);
   11127              : 
   11128       226650 :   const Expression_list* args = this->args();
   11129              : 
   11130       226650 :   bool is_print;
   11131       226650 :   Type* arg_type = NULL;
   11132       226650 :   Type* trailing_arg_types = NULL;
   11133       226650 :   switch (this->code_)
   11134              :     {
   11135        15117 :     case BUILTIN_MAKE:
   11136        15117 :       trailing_arg_types = Type::lookup_integer_type("int");
   11137        15117 :       is_print = false;
   11138        15117 :       break;
   11139              : 
   11140        15153 :     case BUILTIN_PANIC:
   11141        15153 :       arg_type =
   11142        15153 :         Type::make_empty_interface_type(Linemap::predeclared_location());
   11143        15153 :       is_print = false;
   11144        15153 :       break;
   11145              : 
   11146              :     case BUILTIN_PRINT:
   11147              :     case BUILTIN_PRINTLN:
   11148              :       // Do not force a large integer constant to "int".
   11149              :       is_print = true;
   11150              :       break;
   11151              : 
   11152         1048 :     case BUILTIN_REAL:
   11153         1048 :     case BUILTIN_IMAG:
   11154         1048 :       {
   11155              :         // We need the argument to determine the type, so check it now
   11156              :         // before any call to the do_type method.
   11157         1048 :         const Expression_list* args = this->args();
   11158         2096 :         if (args == NULL || args->size() < 1)
   11159              :           {
   11160            0 :             this->report_error(_("not enough arguments"));
   11161            0 :             return;
   11162              :           }
   11163         1048 :         else if (args->size() > 1)
   11164              :           {
   11165            0 :             this->report_error(_("too many arguments"));
   11166            0 :             return;
   11167              :           }
   11168              : 
   11169         1048 :         Type* dummy;
   11170         1048 :         if (context->type != NULL
   11171          764 :             && context->type->is_numeric_type()
   11172         1803 :             && this->is_untyped(&dummy))
   11173              :           {
   11174           28 :             Type* type = context->type;
   11175           28 :             if (type->is_abstract() && !context->may_be_abstract)
   11176            0 :               type = type->make_non_abstract_type();
   11177           28 :             this->set_type(type);
   11178              :           }
   11179         1020 :         else if (context->may_be_abstract && this->is_constant())
   11180            5 :           this->set_type(Type::make_abstract_float_type());
   11181              : 
   11182         1048 :         arg_type = Builtin_call_expression::complex_type(context->type);
   11183         1048 :         if (arg_type == NULL)
   11184              :           {
   11185          301 :             if (context->may_be_abstract)
   11186            6 :               arg_type = Type::make_abstract_complex_type();
   11187              :             else
   11188          295 :               arg_type = Type::lookup_complex_type("complex128");
   11189              :           }
   11190              : 
   11191         1048 :         if (!args->front()->is_untyped(&dummy))
   11192              :           {
   11193          994 :             Type_context subcontext(arg_type, context->may_be_abstract);
   11194          994 :             args->front()->determine_type(gogo, &subcontext);
   11195              :           }
   11196              : 
   11197         1048 :         is_print = false;
   11198              :       }
   11199         1048 :       break;
   11200              : 
   11201        13710 :     case BUILTIN_COMPLEX:
   11202        13710 :       {
   11203              :         // We need the arguments to determine the type, so check them
   11204              :         // now before any call to the do_type method.
   11205        13710 :         const Expression_list* args = this->args();
   11206        27419 :         if (args == NULL || args->size() < 2)
   11207              :           {
   11208            4 :             this->report_error(_("not enough arguments"));
   11209            9 :             return;
   11210              :           }
   11211        13706 :         else if (args->size() > 2)
   11212              :           {
   11213            1 :             this->report_error(_("too many arguments"));
   11214            1 :             return;
   11215              :           }
   11216              : 
   11217        13705 :         Type* dummy;
   11218        13705 :         if (context->type != NULL
   11219        13615 :             && context->type->is_numeric_type()
   11220        27259 :             && this->is_untyped(&dummy))
   11221              :           {
   11222         1490 :             Type* type = context->type;
   11223         1490 :             if (type->is_abstract() && !context->may_be_abstract)
   11224            0 :               type = type->make_non_abstract_type();
   11225         1490 :             this->set_type(type);
   11226              :           }
   11227        12215 :         else if (context->may_be_abstract && this->is_constant())
   11228            6 :           this->set_type(Type::make_abstract_complex_type());
   11229              : 
   11230              :         // For the complex function the type of one operand can
   11231              :         // determine the type of the other, as in a binary expression.
   11232        13705 :         arg_type = Builtin_call_expression::real_imag_type(context->type);
   11233        13705 :         if (arg_type == NULL)
   11234              :           {
   11235          153 :             if (context->may_be_abstract)
   11236            6 :               arg_type = Type::make_abstract_float_type();
   11237              :             else
   11238          147 :               arg_type = Type::lookup_float_type("float64");
   11239              :           }
   11240              : 
   11241        13705 :         Type_context subcontext(arg_type, context->may_be_abstract);
   11242        13705 :         if (!args->front()->is_untyped(&dummy))
   11243              :           {
   11244        11127 :             args->front()->determine_type(gogo, &subcontext);
   11245        11127 :             arg_type = args->front()->type();
   11246              :           }
   11247         2578 :         else if (!args->back()->is_untyped(&dummy))
   11248              :           {
   11249         1054 :             args->back()->determine_type(gogo, &subcontext);
   11250         1054 :             arg_type = args->back()->type();
   11251              :           }
   11252              : 
   11253        13705 :         is_print = false;
   11254              :       }
   11255        13705 :       break;
   11256              : 
   11257        15743 :     case BUILTIN_APPEND:
   11258        15743 :       if (!this->is_varargs()
   11259        12154 :           && args != NULL
   11260        27897 :           && !args->empty())
   11261              :         {
   11262        12154 :           args->front()->determine_type_no_context(gogo);
   11263        12154 :           if (args->front()->type()->is_slice_type())
   11264        12152 :             trailing_arg_types =
   11265        24304 :               args->front()->type()->array_type()->element_type();
   11266              :         }
   11267        12152 :       is_print = false;
   11268        12152 :       break;
   11269              : 
   11270           18 :     case BUILTIN_ADD:
   11271           18 :     case BUILTIN_SLICE:
   11272              :       // Both unsafe.Add and unsafe.Slice take two arguments, and the
   11273              :       // second arguments defaults to "int".
   11274           36 :       if (args != NULL && args->size() == 2)
   11275              :         {
   11276           18 :           if (this->code_ == BUILTIN_SLICE)
   11277            9 :             args->front()->determine_type_no_context(gogo);
   11278              :           else
   11279              :             {
   11280            9 :               Type* pointer = Type::make_pointer_type(Type::make_void_type());
   11281            9 :               Type_context subcontext(pointer, false);
   11282            9 :               args->front()->determine_type(gogo, &subcontext);
   11283              :             }
   11284           18 :           Type* int_type = Type::lookup_integer_type("int");
   11285           18 :           Type_context subcontext(int_type, false);
   11286           18 :           args->back()->determine_type(gogo, &subcontext);
   11287           18 :           return;
   11288              :         }
   11289              :       is_print = false;
   11290              :       break;
   11291              : 
   11292          943 :     case BUILTIN_DELETE:
   11293         1885 :       if (args != NULL && args->size() == 2)
   11294              :         {
   11295          940 :           args->front()->determine_type_no_context(gogo);
   11296          940 :           Map_type* mt = args->front()->type()->map_type();
   11297          939 :           if (mt != NULL)
   11298          939 :             trailing_arg_types = mt->key_type();
   11299              :         }
   11300              :       is_print = false;
   11301              :       break;
   11302              : 
   11303              :     default:
   11304       152325 :       is_print = false;
   11305              :       break;
   11306              :     }
   11307              : 
   11308       226625 :   if (args != NULL)
   11309              :     {
   11310       522951 :       for (Expression_list::const_iterator pa = args->begin();
   11311       522951 :            pa != args->end();
   11312       297236 :            ++pa)
   11313              :         {
   11314       297236 :           Type_context subcontext;
   11315       297236 :           subcontext.type = arg_type;
   11316              : 
   11317       297236 :           if (is_print && (*pa)->is_constant())
   11318              :             {
   11319              :               // We want to print large constants, we so can't just
   11320              :               // use the appropriate nonabstract type.  Use uint64 for
   11321              :               // an integer if we know it is nonnegative, otherwise
   11322              :               // use int64 for a integer, otherwise use float64 for a
   11323              :               // float or complex128 for a complex.
   11324        26478 :               Type* atype;
   11325        26478 :               if ((*pa)->is_untyped(&atype))
   11326              :                 {
   11327        25189 :                   Type* want_type = NULL;
   11328        25189 :                   if (atype->integer_type() != NULL)
   11329              :                     {
   11330          505 :                       Numeric_constant nc;
   11331          505 :                       if (this->numeric_constant_value(&nc))
   11332              :                         {
   11333            0 :                           mpz_t val;
   11334            0 :                           if (nc.to_int(&val))
   11335              :                             {
   11336            0 :                               if (mpz_sgn(val) >= 0)
   11337            0 :                                 want_type = Type::lookup_integer_type("uint64");
   11338            0 :                               mpz_clear(val);
   11339              :                             }
   11340              :                         }
   11341            0 :                       if (want_type == NULL)
   11342          505 :                         want_type = Type::lookup_integer_type("int64");
   11343          505 :                     }
   11344        24684 :                   else if (atype->float_type() != NULL)
   11345           56 :                     want_type = Type::lookup_float_type("float64");
   11346        24628 :                   else if (atype->complex_type() != NULL)
   11347           14 :                     want_type = Type::lookup_complex_type("complex128");
   11348        24614 :                   else if (atype->is_abstract_string_type())
   11349        24588 :                     want_type = Type::lookup_string_type();
   11350           26 :                   else if (atype->is_abstract_boolean_type())
   11351           26 :                     want_type = Type::lookup_bool_type();
   11352              :                   else
   11353            0 :                     go_unreachable();
   11354        25189 :                   subcontext.type = want_type;
   11355              :                 }
   11356              :             }
   11357              : 
   11358       297236 :           (*pa)->determine_type(gogo, &subcontext);
   11359              : 
   11360       297236 :           if (trailing_arg_types != NULL)
   11361              :             {
   11362        28208 :               arg_type = trailing_arg_types;
   11363        28208 :               trailing_arg_types = NULL;
   11364              :             }
   11365              :         }
   11366              :     }
   11367              : }
   11368              : 
   11369              : // If there is exactly one argument, return true.  Otherwise give an
   11370              : // error message and return false.
   11371              : 
   11372              : bool
   11373        80123 : Builtin_call_expression::check_one_arg()
   11374              : {
   11375        80123 :   const Expression_list* args = this->args();
   11376       160246 :   if (args == NULL || args->size() < 1)
   11377              :     {
   11378            0 :       this->report_error(_("not enough arguments"));
   11379            0 :       return false;
   11380              :     }
   11381        80123 :   else if (args->size() > 1)
   11382              :     {
   11383            0 :       this->report_error(_("too many arguments"));
   11384            0 :       return false;
   11385              :     }
   11386        80123 :   if (args->front()->is_error_expression()
   11387        80123 :       || args->front()->type()->is_error())
   11388              :     {
   11389            5 :       this->set_is_error();
   11390            5 :       return false;
   11391              :     }
   11392              :   return true;
   11393              : }
   11394              : 
   11395              : // Check argument types for a builtin function.
   11396              : 
   11397              : void
   11398       145801 : Builtin_call_expression::do_check_types(Gogo* gogo)
   11399              : {
   11400       145801 :   if (this->is_error_expression())
   11401              :     return;
   11402              : 
   11403       145724 :   if (this->is_varargs() && this->code_ != BUILTIN_APPEND)
   11404              :     {
   11405            8 :       go_error_at(this->location(),
   11406              :                   "invalid use of %<...%> with built-in function");
   11407            8 :       this->set_is_error();
   11408            8 :       return;
   11409              :     }
   11410              : 
   11411       145716 :   switch (this->code_)
   11412              :     {
   11413              :     case BUILTIN_INVALID:
   11414              :       return;
   11415              : 
   11416         7322 :     case BUILTIN_NEW:
   11417         7322 :       if (this->check_one_arg())
   11418              :         {
   11419         7322 :           Expression* arg = this->one_arg();
   11420         7322 :           if (!arg->is_type_expression())
   11421              :             {
   11422            0 :               go_error_at(arg->location(), "expected type");
   11423            0 :               this->set_is_error();
   11424              :             }
   11425              :         }
   11426              :       break;
   11427              : 
   11428        15106 :     case BUILTIN_MAKE:
   11429        15106 :       {
   11430        15106 :         const Expression_list* args = this->args();
   11431        30212 :         if (args == NULL || args->size() < 1)
   11432              :           {
   11433            0 :             this->report_error(_("not enough arguments"));
   11434            0 :             return;
   11435              :           }
   11436              : 
   11437        15106 :         Expression* first_arg = args->front();
   11438        15106 :         if (!first_arg->is_type_expression())
   11439              :           {
   11440            0 :             go_error_at(first_arg->location(), "expected type");
   11441            0 :             this->set_is_error();
   11442            0 :             return;
   11443              :           }
   11444              : 
   11445        15106 :         Type* type = first_arg->type();
   11446        15106 :         if (!type->in_heap())
   11447            0 :           go_error_at(first_arg->location(),
   11448              :                       "cannot make slice of go:notinheap type");
   11449              : 
   11450        15106 :         bool is_slice = type->is_slice_type();
   11451        15106 :         if (!is_slice
   11452         2766 :             && type->map_type() == NULL
   11453        21721 :             && type->channel_type() == NULL)
   11454              :           {
   11455            0 :             this->report_error(_("invalid type for make function"));
   11456            0 :             return;
   11457              :           }
   11458              : 
   11459        15106 :         Expression_list::const_iterator parg = args->begin();
   11460        15106 :         ++parg;
   11461        15106 :         if (parg == args->end())
   11462              :           {
   11463         4935 :             if (is_slice)
   11464              :               {
   11465            0 :                 this->report_error(_("length required when "
   11466              :                                      "allocating a slice"));
   11467            0 :                 return;
   11468              :               }
   11469              :           }
   11470              :         else
   11471              :           {
   11472        10171 :             if ((*parg)->type()->integer_type() == NULL)
   11473              :               {
   11474            8 :                 go_error_at((*parg)->location(),
   11475              :                             "non-integer len argument in make");
   11476            8 :                 return;
   11477              :               }
   11478        10163 :             ++parg;
   11479              : 
   11480        10163 :             if (is_slice && parg != args->end())
   11481              :               {
   11482         1716 :                 if ((*parg)->type()->integer_type() == NULL)
   11483              :                   {
   11484            5 :                     go_error_at((*parg)->location(),
   11485              :                                 "non-integer cap argument in make");
   11486            5 :                     return;
   11487              :                   }
   11488         1711 :                 ++parg;
   11489              :               }
   11490              :           }
   11491              : 
   11492        15093 :         if (parg != args->end())
   11493              :           {
   11494            1 :             this->report_error(_("too many arguments to make"));
   11495            1 :             return;
   11496              :           }
   11497              :       }
   11498              :       break;
   11499              : 
   11500          892 :     case BUILTIN_DELETE:
   11501          892 :       {
   11502          892 :         const Expression_list* args = this->args();
   11503         1783 :         if (args == NULL || args->size() < 2)
   11504            2 :           this->report_error(_("not enough arguments"));
   11505          890 :         else if (args->size() > 2)
   11506            1 :           this->report_error(_("too many arguments"));
   11507          889 :         else if (args->front()->type()->map_type() == NULL)
   11508            1 :           this->report_error(_("argument 1 must be a map"));
   11509              :         else
   11510              :           {
   11511          888 :             Type* key_type =
   11512         1776 :               args->front()->type()->map_type()->key_type();
   11513          888 :             Expression_list::iterator pa = this->args()->begin();
   11514          888 :             pa++;
   11515          888 :             Type* arg_type = (*pa)->type();
   11516          888 :             std::string reason;
   11517          888 :             if (!Type::are_assignable(key_type, arg_type, &reason))
   11518              :               {
   11519            0 :                 if (reason.empty())
   11520            0 :                   go_error_at(this->location(),
   11521              :                               "argument 2 has incompatible type");
   11522              :                 else
   11523            0 :                   go_error_at(this->location(),
   11524              :                               "argument 2 has incompatible type (%s)",
   11525              :                               reason.c_str());
   11526            0 :                 this->set_is_error();
   11527              :               }
   11528          888 :           }
   11529              :       }
   11530              :       break;
   11531              : 
   11532        54786 :     case BUILTIN_LEN:
   11533        54786 :     case BUILTIN_CAP:
   11534        54786 :       {
   11535              :         // The single argument may be either a string or an array or a
   11536              :         // map or a channel, or a pointer to a closed array.
   11537        54786 :         if (this->check_one_arg())
   11538              :           {
   11539        54783 :             Type* arg_type = this->one_arg()->type();
   11540        54783 :             if (arg_type->points_to() != NULL
   11541          204 :                 && arg_type->points_to()->array_type() != NULL
   11542        54981 :                 && !arg_type->points_to()->is_slice_type())
   11543          192 :               arg_type = arg_type->points_to();
   11544        54783 :             if (this->code_ == BUILTIN_CAP)
   11545              :               {
   11546          944 :                 if (!arg_type->is_error()
   11547           54 :                     && arg_type->array_type() == NULL
   11548          944 :                     && arg_type->channel_type() == NULL)
   11549            3 :                   this->report_error(_("argument must be array or slice "
   11550              :                                        "or channel"));
   11551              :               }
   11552              :             else
   11553              :               {
   11554        53839 :                 if (!arg_type->is_error()
   11555        53839 :                     && !arg_type->is_string_type()
   11556         1230 :                     && arg_type->array_type() == NULL
   11557           42 :                     && arg_type->map_type() == NULL
   11558        53839 :                     && arg_type->channel_type() == NULL)
   11559            9 :                   this->report_error(_("argument must be string or "
   11560              :                                        "array or slice or map or channel"));
   11561              :               }
   11562              :           }
   11563              :       }
   11564              :       break;
   11565              : 
   11566        16165 :     case BUILTIN_PRINT:
   11567        16165 :     case BUILTIN_PRINTLN:
   11568        16165 :       {
   11569        16165 :         const Expression_list* args = this->args();
   11570        16165 :         if (args != NULL)
   11571              :           {
   11572        16111 :             for (Expression_list::const_iterator p = args->begin();
   11573        54836 :                  p != args->end();
   11574        38725 :                  ++p)
   11575              :               {
   11576        38725 :                 Type* type = (*p)->type();
   11577        38725 :                 if (type->is_error()
   11578        38712 :                     || type->is_string_type()
   11579        39671 :                     || type->integer_type() != NULL
   11580        39442 :                     || type->float_type() != NULL
   11581        39366 :                     || type->complex_type() != NULL
   11582          641 :                     || type->is_boolean_type()
   11583          482 :                     || type->points_to() != NULL
   11584        38752 :                     || type->interface_type() != NULL
   11585        38750 :                     || type->channel_type() != NULL
   11586        38747 :                     || type->map_type() != NULL
   11587        38725 :                     || type->function_type() != NULL
   11588        38745 :                     || type->is_slice_type())
   11589              :                   ;
   11590            1 :                 else if ((*p)->is_type_expression())
   11591              :                   {
   11592              :                     // If this is a type expression it's going to give
   11593              :                     // an error anyhow, so we don't need one here.
   11594              :                   }
   11595              :                 else
   11596              :                   {
   11597              :                     // Report errors in the expression first.
   11598            1 :                     (*p)->check_types(gogo);
   11599            1 :                     if (!(*p)->is_error_expression())
   11600            0 :                       this->report_error(_("unsupported argument type to "
   11601              :                                            "builtin function"));
   11602              :                   }
   11603              :               }
   11604              :           }
   11605              :       }
   11606              :       break;
   11607              : 
   11608          863 :     case BUILTIN_CLOSE:
   11609          863 :       if (this->check_one_arg())
   11610              :         {
   11611          863 :           if (this->one_arg()->type()->channel_type() == NULL)
   11612            1 :             this->report_error(_("argument must be channel"));
   11613         1724 :           else if (!this->one_arg()->type()->channel_type()->may_send())
   11614            1 :             this->report_error(_("cannot close receive-only channel"));
   11615              :         }
   11616              :       break;
   11617              : 
   11618        14972 :     case BUILTIN_PANIC:
   11619        14972 :     case BUILTIN_SIZEOF:
   11620        14972 :     case BUILTIN_ALIGNOF:
   11621        14972 :       if (this->check_one_arg())
   11622              :         {
   11623        14972 :           Expression* arg = this->one_arg();
   11624        14972 :           if (arg->type()->is_void_type())
   11625            0 :             this->report_error(_("argument to builtin has void type"));
   11626              :         }
   11627              :       break;
   11628              : 
   11629          848 :     case BUILTIN_RECOVER:
   11630          848 :       if (this->args() != NULL
   11631            1 :           && !this->args()->empty()
   11632          849 :           && !this->recover_arg_is_set_)
   11633            0 :         this->report_error(_("too many arguments"));
   11634              :       break;
   11635              : 
   11636         1156 :     case BUILTIN_OFFSETOF:
   11637         1156 :       if (this->check_one_arg())
   11638              :         {
   11639         1156 :           Expression* arg = this->one_arg();
   11640         1156 :           if (arg->classification() == Expression::EXPRESSION_SELECTOR)
   11641              :             {
   11642         1156 :               Selector_expression* se = static_cast<Selector_expression*>(arg);
   11643         1156 :               Expression* resolved = se->resolved();
   11644         1156 :               if (resolved != NULL)
   11645         1156 :                 arg = resolved;
   11646              :             }
   11647         1156 :           if (arg->is_error_expression())
   11648              :             ;
   11649         1156 :           else if (arg->bound_method_expression() != NULL
   11650            2 :                    || arg->interface_field_reference_expression() != NULL)
   11651            2 :             this->report_error(_("invalid use of method value as "
   11652              :                                  "argument of Offsetof"));
   11653         1154 :           else if (arg->field_reference_expression() == NULL)
   11654            0 :             this->report_error(_("argument must be a field reference"));
   11655              :         }
   11656              :       break;
   11657              : 
   11658         3229 :     case BUILTIN_COPY:
   11659         3229 :       {
   11660         3229 :         const Expression_list* args = this->args();
   11661         6458 :         if (args == NULL || args->size() < 2)
   11662              :           {
   11663            0 :             this->report_error(_("not enough arguments"));
   11664            0 :             break;
   11665              :           }
   11666         3229 :         else if (args->size() > 2)
   11667              :           {
   11668            0 :             this->report_error(_("too many arguments"));
   11669            0 :             break;
   11670              :           }
   11671         3229 :         Type* arg1_type = args->front()->type();
   11672         3229 :         Type* arg2_type = args->back()->type();
   11673         3229 :         if (arg1_type->is_error() || arg2_type->is_error())
   11674              :           {
   11675            0 :             this->set_is_error();
   11676            0 :             break;
   11677              :           }
   11678              : 
   11679         3229 :         Type* e1;
   11680         3229 :         if (arg1_type->is_slice_type())
   11681         6456 :           e1 = arg1_type->array_type()->element_type();
   11682              :         else
   11683              :           {
   11684            1 :             this->report_error(_("left argument must be a slice"));
   11685            1 :             break;
   11686              :           }
   11687              : 
   11688         3228 :         if (arg2_type->is_slice_type())
   11689              :           {
   11690         5700 :             Type* e2 = arg2_type->array_type()->element_type();
   11691         2850 :             if (!Type::are_identical(e1, e2, Type::COMPARE_TAGS, NULL))
   11692            0 :               this->report_error(_("element types must be the same"));
   11693              :           }
   11694          378 :         else if (arg2_type->is_string_type())
   11695              :           {
   11696         1131 :             if (e1->integer_type() == NULL || !e1->integer_type()->is_byte())
   11697            0 :               this->report_error(_("first argument must be []byte"));
   11698              :           }
   11699              :         else
   11700            1 :             this->report_error(_("second argument must be slice or string"));
   11701              :       }
   11702              :       break;
   11703              : 
   11704        15645 :     case BUILTIN_APPEND:
   11705        15645 :       {
   11706        15645 :         const Expression_list* args = this->args();
   11707        15645 :         if (args == NULL || args->empty())
   11708              :           {
   11709            0 :             this->report_error(_("not enough arguments"));
   11710            0 :             break;
   11711              :           }
   11712              : 
   11713        15645 :         Type* slice_type = args->front()->type();
   11714        15645 :         if (!slice_type->is_slice_type())
   11715              :           {
   11716            2 :             if (slice_type->is_error_type())
   11717              :               break;
   11718            2 :             if (slice_type->is_nil_type())
   11719            1 :               go_error_at(args->front()->location(), "use of untyped nil");
   11720              :             else
   11721            1 :               go_error_at(args->front()->location(),
   11722              :                           "argument 1 must be a slice");
   11723            2 :             this->set_is_error();
   11724            2 :             break;
   11725              :           }
   11726              : 
   11727        31286 :         Type* element_type = slice_type->array_type()->element_type();
   11728        15643 :         if (!element_type->in_heap())
   11729            0 :           go_error_at(args->front()->location(),
   11730              :                       "cannot append to slice of go:notinheap type");
   11731        15643 :         if (this->is_varargs())
   11732              :           {
   11733         3553 :             if (!args->back()->type()->is_slice_type()
   11734         3553 :                 && !args->back()->type()->is_string_type())
   11735              :               {
   11736            0 :                 go_error_at(args->back()->location(),
   11737              :                             "invalid use of %<...%> with non-slice/non-string");
   11738            0 :                 this->set_is_error();
   11739            0 :                 break;
   11740              :               }
   11741              : 
   11742         3553 :             if (args->size() < 2)
   11743              :               {
   11744            0 :                 this->report_error(_("not enough arguments"));
   11745            0 :                 break;
   11746              :               }
   11747         3553 :             if (args->size() > 2)
   11748              :               {
   11749            0 :                 this->report_error(_("too many arguments"));
   11750            0 :                 break;
   11751              :               }
   11752              : 
   11753         3553 :             if (args->back()->type()->is_string_type()
   11754          942 :                 && element_type->integer_type() != NULL
   11755         4495 :                 && element_type->integer_type()->is_byte())
   11756              :               {
   11757              :                 // Permit append(s1, s2...) when s1 is a slice of
   11758              :                 // bytes and s2 is a string type.
   11759              :               }
   11760              :             else
   11761              :               {
   11762              :                 // We have to test for assignment compatibility to a
   11763              :                 // slice of the element type, which is not necessarily
   11764              :                 // the same as the type of the first argument: the
   11765              :                 // first argument might have a named type.
   11766         2611 :                 Type* check_type = Type::make_array_type(element_type, NULL);
   11767         2611 :                 std::string reason;
   11768         2611 :                 if (!Type::are_assignable(check_type, args->back()->type(),
   11769              :                                           &reason))
   11770              :                   {
   11771            0 :                     if (reason.empty())
   11772            0 :                       go_error_at(args->back()->location(),
   11773              :                                   "argument 2 has invalid type");
   11774              :                     else
   11775            0 :                       go_error_at(args->back()->location(),
   11776              :                                   "argument 2 has invalid type (%s)",
   11777              :                                   reason.c_str());
   11778            0 :                     this->set_is_error();
   11779            0 :                     break;
   11780              :                   }
   11781         2611 :               }
   11782              :           }
   11783              :         else
   11784              :           {
   11785        12090 :             Expression_list::const_iterator pa = args->begin();
   11786        12090 :             int i = 2;
   11787        26264 :             for (++pa; pa != args->end(); ++pa, ++i)
   11788              :               {
   11789        14174 :                 std::string reason;
   11790        14174 :                 if (!Type::are_assignable(element_type, (*pa)->type(),
   11791              :                                           &reason))
   11792              :                   {
   11793            2 :                     if (reason.empty())
   11794            0 :                       go_error_at((*pa)->location(),
   11795              :                                   "argument %d has incompatible type", i);
   11796              :                     else
   11797            2 :                       go_error_at((*pa)->location(),
   11798              :                                   "argument %d has incompatible type (%s)",
   11799              :                                   i, reason.c_str());
   11800            2 :                     this->set_is_error();
   11801              :                   }
   11802        14174 :               }
   11803              :           }
   11804              :       }
   11805              :       break;
   11806              : 
   11807         1024 :     case BUILTIN_REAL:
   11808         1024 :     case BUILTIN_IMAG:
   11809         1024 :       if (this->check_one_arg())
   11810              :         {
   11811         1022 :           if (this->one_arg()->type()->complex_type() == NULL)
   11812            2 :             this->report_error(_("argument must have complex type"));
   11813              :         }
   11814              :       break;
   11815              : 
   11816        13690 :     case BUILTIN_COMPLEX:
   11817        13690 :       {
   11818        13690 :         const Expression_list* args = this->args();
   11819        27380 :         go_assert(args != NULL && args->size() == 2);
   11820        13690 :         if (args->front()->is_error_expression()
   11821        13683 :             || args->front()->type()->is_error()
   11822        13683 :             || args->back()->is_error_expression()
   11823        27371 :             || args->back()->type()->is_error())
   11824            9 :           this->set_is_error();
   11825        13681 :         else if (!Type::are_identical(args->front()->type(),
   11826        13681 :                                       args->back()->type(),
   11827              :                                       Type::COMPARE_TAGS, NULL))
   11828            6 :           this->report_error(_("complex arguments must have identical types"));
   11829        13675 :         else if (args->front()->type()->float_type() == NULL)
   11830            1 :           this->report_error(_("complex arguments must have "
   11831              :                                "floating-point type"));
   11832              :       }
   11833              :       break;
   11834              : 
   11835           18 :     case BUILTIN_ADD:
   11836           18 :     case BUILTIN_SLICE:
   11837           18 :       {
   11838           18 :         Numeric_constant nc;
   11839           18 :         unsigned long v;
   11840           18 :         const Expression_list* args = this->args();
   11841           36 :         if (args == NULL || args->size() < 2)
   11842            0 :           this->report_error(_("not enough arguments"));
   11843           18 :         else if (args->size() > 2)
   11844            0 :           this->report_error(_("too many arguments"));
   11845           18 :         else if (args->front()->is_error_expression()
   11846           18 :                  || args->front()->type()->is_error()
   11847           18 :                  || args->back()->is_error_expression()
   11848           36 :                  || args->back()->type()->is_error())
   11849            0 :           this->set_is_error();
   11850           18 :         else if (args->back()->type()->integer_type() == NULL
   11851            0 :                  && (!args->back()->type()->is_abstract()
   11852            0 :                      || !args->back()->numeric_constant_value(&nc)
   11853            0 :                      || (nc.to_unsigned_long(&v)
   11854              :                          == Numeric_constant::NC_UL_NOTINT)))
   11855              :           {
   11856            0 :             if (this->code_ == BUILTIN_ADD)
   11857            0 :               go_error_at(args->back()->location(), "non-integer offset");
   11858              :             else
   11859            0 :               go_error_at(args->back()->location(), "non-integer size");
   11860              :           }
   11861           18 :         else if (this->code_ == BUILTIN_ADD)
   11862              :           {
   11863            9 :             Type* pointer_type =
   11864            9 :               Type::make_pointer_type(Type::make_void_type());
   11865            9 :             std::string reason;
   11866            9 :             if (!Type::are_assignable(pointer_type, args->front()->type(),
   11867              :                                       &reason))
   11868              :               {
   11869            0 :                 if (reason.empty())
   11870            0 :                   go_error_at(args->front()->location(),
   11871              :                               "argument 1 has incompatible type");
   11872              :                 else
   11873            0 :                   go_error_at(args->front()->location(),
   11874              :                               "argument 1 has incompatible type (%s)",
   11875              :                               reason.c_str());
   11876            0 :                 this->set_is_error();
   11877              :               }
   11878            9 :           }
   11879              :         else
   11880              :           {
   11881            9 :             if (args->front()->type()->points_to() == NULL)
   11882              :               {
   11883            0 :                 go_error_at(args->front()->location(),
   11884              :                             "argument 1 must be a pointer");
   11885            0 :                 this->set_is_error();
   11886              :               }
   11887              : 
   11888            9 :             unsigned int int_bits =
   11889           18 :               Type::lookup_integer_type("int")->integer_type()->bits();
   11890              : 
   11891            9 :             mpz_t ival;
   11892            9 :             if (args->back()->numeric_constant_value(&nc) && nc.to_int(&ival))
   11893              :               {
   11894            7 :                 if (mpz_sgn(ival) < 0
   11895            7 :                     || mpz_sizeinbase(ival, 2) >= int_bits)
   11896              :                   {
   11897            0 :                     go_error_at(args->back()->location(),
   11898              :                                 "slice length out of range");
   11899            0 :                     this->set_is_error();
   11900              :                   }
   11901            7 :                 mpz_clear(ival);
   11902              :               }
   11903              :           }
   11904           18 :       }
   11905           18 :       break;
   11906              : 
   11907            0 :     default:
   11908            0 :       go_unreachable();
   11909              :     }
   11910              : }
   11911              : 
   11912              : Expression*
   11913            0 : Builtin_call_expression::do_copy()
   11914              : {
   11915            0 :   Call_expression* bce =
   11916              :     new Builtin_call_expression(this->gogo_, this->fn()->copy(),
   11917            0 :                                 (this->args() == NULL
   11918              :                                  ? NULL
   11919            0 :                                  : this->args()->copy()),
   11920            0 :                                 this->is_varargs(),
   11921            0 :                                 this->location());
   11922              : 
   11923            0 :   if (this->varargs_are_lowered())
   11924            0 :     bce->set_varargs_are_lowered();
   11925            0 :   if (this->is_deferred())
   11926            0 :     bce->set_is_deferred();
   11927            0 :   if (this->is_concurrent())
   11928            0 :     bce->set_is_concurrent();
   11929            0 :   return bce;
   11930              : }
   11931              : 
   11932              : // Return the backend representation for a builtin function.
   11933              : 
   11934              : Bexpression*
   11935       164888 : Builtin_call_expression::do_get_backend(Translate_context* context)
   11936              : {
   11937       164888 :   Gogo* gogo = context->gogo();
   11938       164888 :   Location location = this->location();
   11939              : 
   11940       164888 :   if (this->is_erroneous_call())
   11941              :     {
   11942           29 :       go_assert(saw_errors());
   11943           29 :       return gogo->backend()->error_expression();
   11944              :     }
   11945              : 
   11946       164859 :   switch (this->code_)
   11947              :     {
   11948            0 :     case BUILTIN_INVALID:
   11949            0 :     case BUILTIN_NEW:
   11950            0 :     case BUILTIN_MAKE:
   11951            0 :     case BUILTIN_ADD:
   11952            0 :     case BUILTIN_SLICE:
   11953            0 :       go_unreachable();
   11954              : 
   11955       119501 :     case BUILTIN_LEN:
   11956       119501 :     case BUILTIN_CAP:
   11957       119501 :       {
   11958       119501 :         const Expression_list* args = this->args();
   11959       239002 :         go_assert(args != NULL && args->size() == 1);
   11960       119501 :         Expression* arg = args->front();
   11961       119501 :         Type* arg_type = arg->type();
   11962              : 
   11963       119501 :         if (this->seen_)
   11964              :           {
   11965            0 :             go_assert(saw_errors());
   11966            0 :             return context->backend()->error_expression();
   11967              :           }
   11968       119501 :         this->seen_ = true;
   11969       119501 :         this->seen_ = false;
   11970       119501 :         if (arg_type->points_to() != NULL)
   11971              :           {
   11972            6 :             arg_type = arg_type->points_to();
   11973           12 :             go_assert(arg_type->array_type() != NULL
   11974              :                        && !arg_type->is_slice_type());
   11975            6 :             arg = Expression::make_dereference(arg, NIL_CHECK_DEFAULT,
   11976              :                                                location);
   11977              :           }
   11978              : 
   11979       119501 :         Type* int_type = Type::lookup_integer_type("int");
   11980       119501 :         Expression* val;
   11981       119501 :         if (this->code_ == BUILTIN_LEN)
   11982              :           {
   11983       102918 :             if (arg_type->is_string_type())
   11984        16417 :               val = Expression::make_string_info(arg, STRING_INFO_LENGTH,
   11985              :                                                  location);
   11986        86501 :             else if (arg_type->array_type() != NULL)
   11987              :               {
   11988        85290 :                 if (this->seen_)
   11989              :                   {
   11990            0 :                     go_assert(saw_errors());
   11991            0 :                     return context->backend()->error_expression();
   11992              :                   }
   11993        85290 :                 this->seen_ = true;
   11994       170580 :                 val = arg_type->array_type()->get_length(gogo, arg);
   11995        85290 :                 this->seen_ = false;
   11996              :               }
   11997         1244 :             else if (arg_type->map_type() != NULL
   11998         1211 :                      || arg_type->channel_type() != NULL)
   11999              :               {
   12000              :                 // The first field is the length.  If the pointer is
   12001              :                 // nil, the length is zero.
   12002         1211 :                 Type* pint_type = Type::make_pointer_type(int_type);
   12003         1211 :                 arg = Expression::make_unsafe_cast(pint_type, arg, location);
   12004         1211 :                 Expression* nil = Expression::make_nil(location);
   12005         1211 :                 nil = Expression::make_cast(pint_type, nil, location);
   12006         1211 :                 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
   12007              :                                                           arg, nil, location);
   12008         1211 :                 Expression* zero = Expression::make_integer_ul(0, int_type,
   12009              :                                                                location);
   12010         1211 :                 Expression* indir =
   12011         1211 :                     Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED,
   12012              :                                                  location);
   12013         1211 :                 val = Expression::make_conditional(cmp, zero, indir, location);
   12014              :               }
   12015              :             else
   12016            0 :               go_unreachable();
   12017              :           }
   12018              :         else
   12019              :           {
   12020        16583 :             if (arg_type->array_type() != NULL)
   12021              :               {
   12022        16532 :                 if (this->seen_)
   12023              :                   {
   12024            0 :                     go_assert(saw_errors());
   12025            0 :                     return context->backend()->error_expression();
   12026              :                   }
   12027        16532 :                 this->seen_ = true;
   12028        33064 :                 val = arg_type->array_type()->get_capacity(gogo, arg);
   12029        16532 :                 this->seen_ = false;
   12030              :               }
   12031           51 :             else if (arg_type->channel_type() != NULL)
   12032              :               {
   12033              :                 // The second field is the capacity.  If the pointer
   12034              :                 // is nil, the capacity is zero.
   12035           51 :                 Type* uintptr_type = Type::lookup_integer_type("uintptr");
   12036           51 :                 Type* pint_type = Type::make_pointer_type(int_type);
   12037           51 :                 Expression* parg = Expression::make_unsafe_cast(uintptr_type,
   12038              :                                                                 arg,
   12039              :                                                                 location);
   12040          102 :                 int off = int_type->integer_type()->bits() / 8;
   12041           51 :                 Expression* eoff = Expression::make_integer_ul(off,
   12042              :                                                                uintptr_type,
   12043              :                                                                location);
   12044           51 :                 parg = Expression::make_binary(OPERATOR_PLUS, parg, eoff,
   12045              :                                                location);
   12046           51 :                 parg = Expression::make_unsafe_cast(pint_type, parg, location);
   12047           51 :                 Expression* nil = Expression::make_nil(location);
   12048           51 :                 nil = Expression::make_cast(pint_type, nil, location);
   12049           51 :                 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
   12050              :                                                           arg, nil, location);
   12051           51 :                 Expression* zero = Expression::make_integer_ul(0, int_type,
   12052              :                                                                location);
   12053           51 :                 Expression* indir =
   12054           51 :                     Expression::make_dereference(parg, NIL_CHECK_NOT_NEEDED,
   12055              :                                                  location);
   12056           51 :                 val = Expression::make_conditional(cmp, zero, indir, location);
   12057              :               }
   12058              :             else
   12059            0 :               go_unreachable();
   12060              :           }
   12061              : 
   12062       119501 :         Expression* e = Expression::make_cast(int_type, val, location);
   12063       119501 :         e->determine_type_no_context(gogo);
   12064       119501 :         return e->get_backend(context);
   12065              :       }
   12066              : 
   12067        15643 :     case BUILTIN_PRINT:
   12068        15643 :     case BUILTIN_PRINTLN:
   12069        15643 :       {
   12070        15643 :         const bool is_ln = this->code_ == BUILTIN_PRINTLN;
   12071              : 
   12072        15643 :         Expression* print_stmts = Runtime::make_call(gogo, Runtime::PRINTLOCK,
   12073              :                                                      location, 0);
   12074              : 
   12075        15643 :         const Expression_list* call_args = this->args();
   12076        15643 :         if (call_args != NULL)
   12077              :           {
   12078        15596 :             for (Expression_list::const_iterator p = call_args->begin();
   12079        52179 :                  p != call_args->end();
   12080        36583 :                  ++p)
   12081              :               {
   12082        36583 :                 if (is_ln && p != call_args->begin())
   12083              :                   {
   12084        15284 :                     Expression* print_space =
   12085        15284 :                       Runtime::make_call(gogo, Runtime::PRINTSP, location, 0);
   12086              : 
   12087        15284 :                     print_stmts =
   12088        15284 :                         Expression::make_compound(print_stmts, print_space,
   12089              :                                                   location);
   12090              :                   }
   12091              : 
   12092        36583 :                 Expression* arg = *p;
   12093        36583 :                 Type* type = arg->type();
   12094        36583 :                 Runtime::Function code;
   12095        36583 :                 if (type->is_string_type())
   12096              :                   code = Runtime::PRINTSTRING;
   12097        19704 :                 else if (type->integer_type() != NULL
   12098         9466 :                          && type->integer_type()->is_unsigned())
   12099              :                   {
   12100         4454 :                     Type* itype = Type::lookup_integer_type("uint64");
   12101         4454 :                     arg = Expression::make_cast(itype, arg, location);
   12102         8908 :                     if (gogo->compiling_runtime()
   12103         1686 :                         && type->named_type() != NULL
   12104        10594 :                         && gogo->unpack_hidden_name(type->named_type()->name())
   12105         1686 :                            == "hex")
   12106              :                       code = Runtime::PRINTHEX;
   12107              :                     else
   12108         3964 :                       code = Runtime::PRINTUINT;
   12109              :                   }
   12110         5784 :                 else if (type->integer_type() != NULL)
   12111              :                   {
   12112         5012 :                     Type* itype = Type::lookup_integer_type("int64");
   12113         5012 :                     arg = Expression::make_cast(itype, arg, location);
   12114         5012 :                     code = Runtime::PRINTINT;
   12115              :                   }
   12116          772 :                 else if (type->float_type() != NULL)
   12117              :                   {
   12118          220 :                     Type* dtype = Type::lookup_float_type("float64");
   12119          220 :                     arg = Expression::make_cast(dtype, arg, location);
   12120          220 :                     code = Runtime::PRINTFLOAT;
   12121              :                   }
   12122          552 :                 else if (type->complex_type() != NULL)
   12123              :                   {
   12124           76 :                     Type* ctype = Type::lookup_complex_type("complex128");
   12125           76 :                     arg = Expression::make_cast(ctype, arg, location);
   12126           76 :                     code = Runtime::PRINTCOMPLEX;
   12127              :                   }
   12128          476 :                 else if (type->is_boolean_type())
   12129              :                   code = Runtime::PRINTBOOL;
   12130          349 :                 else if (type->points_to() != NULL
   12131           54 :                          || type->channel_type() != NULL
   12132          351 :                          || type->map_type() != NULL
   12133          356 :                          || type->function_type() != NULL)
   12134              :                   {
   12135          300 :                     arg = Expression::make_cast(type, arg, location);
   12136          300 :                     code = Runtime::PRINTPOINTER;
   12137              :                   }
   12138           49 :                 else if (type->interface_type() != NULL)
   12139              :                   {
   12140           60 :                     if (type->interface_type()->is_empty())
   12141              :                       code = Runtime::PRINTEFACE;
   12142              :                     else
   12143            4 :                       code = Runtime::PRINTIFACE;
   12144              :                   }
   12145           19 :                 else if (type->is_slice_type())
   12146              :                   code = Runtime::PRINTSLICE;
   12147              :                 else
   12148              :                   {
   12149            0 :                     go_assert(saw_errors());
   12150            0 :                     return context->backend()->error_expression();
   12151              :                   }
   12152              : 
   12153        36583 :                 Expression* call = Runtime::make_call(gogo, code, location, 1,
   12154              :                                                       arg);
   12155        36583 :                 print_stmts = Expression::make_compound(print_stmts, call,
   12156              :                                                         location);
   12157              :               }
   12158              :           }
   12159              : 
   12160        15643 :         if (is_ln)
   12161              :           {
   12162        13300 :             Expression* print_nl =
   12163        13300 :               Runtime::make_call(gogo, Runtime::PRINTNL, location, 0);
   12164        13300 :             print_stmts = Expression::make_compound(print_stmts, print_nl,
   12165              :                                                     location);
   12166              :           }
   12167              : 
   12168        15643 :         Expression* unlock = Runtime::make_call(gogo, Runtime::PRINTUNLOCK,
   12169              :                                                 location, 0);
   12170        15643 :         print_stmts = Expression::make_compound(print_stmts, unlock, location);
   12171              : 
   12172        15643 :         print_stmts->determine_type_no_context(gogo);
   12173              : 
   12174        15643 :         return print_stmts->get_backend(context);
   12175              :       }
   12176              : 
   12177        14856 :     case BUILTIN_PANIC:
   12178        14856 :       {
   12179        14856 :         const Expression_list* args = this->args();
   12180        29712 :         go_assert(args != NULL && args->size() == 1);
   12181        14856 :         Expression* arg = args->front();
   12182        14856 :         Type *empty =
   12183        14856 :           Type::make_empty_interface_type(Linemap::predeclared_location());
   12184        14856 :         arg = Expression::convert_for_assignment(gogo, empty, arg, location);
   12185              : 
   12186        14856 :         Expression* panic =
   12187        14856 :           Runtime::make_call(gogo, Runtime::GOPANIC, location, 1, arg);
   12188        14856 :         panic->determine_type_no_context(gogo);
   12189        14856 :         return panic->get_backend(context);
   12190              :       }
   12191              : 
   12192          847 :     case BUILTIN_RECOVER:
   12193          847 :       {
   12194              :         // The argument is set when building recover thunks.  It's a
   12195              :         // boolean value which is true if we can recover a value now.
   12196          847 :         const Expression_list* args = this->args();
   12197         1694 :         go_assert(args != NULL && args->size() == 1);
   12198          847 :         Expression* arg = args->front();
   12199          847 :         Type *empty =
   12200          847 :           Type::make_empty_interface_type(Linemap::predeclared_location());
   12201              : 
   12202          847 :         Expression* nil = Expression::make_nil(location);
   12203          847 :         nil = Expression::make_interface_value(empty, nil, nil, location);
   12204              : 
   12205              :         // We need to handle a deferred call to recover specially,
   12206              :         // because it changes whether it can recover a panic or not.
   12207              :         // See test7 in test/recover1.go.
   12208          847 :         Expression* recover = Runtime::make_call(gogo,
   12209          847 :                                                  (this->is_deferred()
   12210              :                                                   ? Runtime::DEFERREDRECOVER
   12211              :                                                   : Runtime::GORECOVER),
   12212              :                                                  location, 0);
   12213          847 :         Expression* cond =
   12214          847 :             Expression::make_conditional(arg, recover, nil, location);
   12215          847 :         cond->determine_type_no_context(gogo);
   12216          847 :         return cond->get_backend(context);
   12217              :       }
   12218              : 
   12219          861 :     case BUILTIN_CLOSE:
   12220          861 :       {
   12221          861 :         const Expression_list* args = this->args();
   12222         1722 :         go_assert(args != NULL && args->size() == 1);
   12223          861 :         Expression* arg = args->front();
   12224          861 :         Expression* close = Runtime::make_call(gogo, Runtime::CLOSE, location,
   12225              :                                                1, arg);
   12226          861 :         close->determine_type_no_context(gogo);
   12227          861 :         return close->get_backend(context);
   12228              :       }
   12229              : 
   12230            0 :     case BUILTIN_SIZEOF:
   12231            0 :     case BUILTIN_OFFSETOF:
   12232            0 :     case BUILTIN_ALIGNOF:
   12233            0 :       {
   12234            0 :         Numeric_constant nc;
   12235            0 :         unsigned long val;
   12236            0 :         if (!this->numeric_constant_value(&nc)
   12237            0 :             || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
   12238              :           {
   12239            0 :             go_assert(saw_errors());
   12240            0 :             return context->backend()->error_expression();
   12241              :           }
   12242            0 :         Type* uintptr_type = Type::lookup_integer_type("uintptr");
   12243            0 :         mpz_t ival;
   12244            0 :         nc.get_int(&ival);
   12245            0 :         Expression* int_cst =
   12246            0 :             Expression::make_integer_z(&ival, uintptr_type, location);
   12247            0 :         mpz_clear(ival);
   12248            0 :         return int_cst->get_backend(context);
   12249            0 :       }
   12250              : 
   12251            0 :     case BUILTIN_COPY:
   12252              :       // Handled in Builtin_call_expression::do_flatten.
   12253            0 :       go_unreachable();
   12254              : 
   12255            0 :     case BUILTIN_APPEND:
   12256              :       // Handled in Builtin_call_expression::flatten_append.
   12257            0 :       go_unreachable();
   12258              : 
   12259          986 :     case BUILTIN_REAL:
   12260          986 :     case BUILTIN_IMAG:
   12261          986 :       {
   12262          986 :         const Expression_list* args = this->args();
   12263         1972 :         go_assert(args != NULL && args->size() == 1);
   12264              : 
   12265          986 :         Bexpression* ret;
   12266          986 :         Bexpression* bcomplex = args->front()->get_backend(context);
   12267          986 :         if (this->code_ == BUILTIN_REAL)
   12268          460 :           ret = gogo->backend()->real_part_expression(bcomplex, location);
   12269              :         else
   12270          526 :           ret = gogo->backend()->imag_part_expression(bcomplex, location);
   12271              :         return ret;
   12272              :       }
   12273              : 
   12274        12165 :     case BUILTIN_COMPLEX:
   12275        12165 :       {
   12276        12165 :         const Expression_list* args = this->args();
   12277        24330 :         go_assert(args != NULL && args->size() == 2);
   12278        12165 :         Bexpression* breal = args->front()->get_backend(context);
   12279        12165 :         Bexpression* bimag = args->back()->get_backend(context);
   12280        12165 :         return gogo->backend()->complex_expression(breal, bimag, location);
   12281              :       }
   12282              : 
   12283            0 :     default:
   12284            0 :       go_unreachable();
   12285              :     }
   12286              : }
   12287              : 
   12288              : // We have to support exporting a builtin call expression, because
   12289              : // code can set a constant to the result of a builtin expression.
   12290              : 
   12291              : void
   12292         4252 : Builtin_call_expression::do_export(Export_function_body* efb) const
   12293              : {
   12294         4252 :   if (this->code_ == BUILTIN_ADD || this->code_ == BUILTIN_SLICE)
   12295              :     {
   12296            0 :       char buf[50];
   12297            0 :       snprintf(buf, sizeof buf, "<p%d>%s", efb->unsafe_package_index(),
   12298              :                (this->code_ == BUILTIN_ADD ? "Add" : "Slice"));
   12299            0 :       efb->write_c_string(buf);
   12300            0 :       this->export_arguments(efb);
   12301              :     }
   12302              :   else
   12303              :     {
   12304         4252 :       const char *s = NULL;
   12305         4252 :       switch (this->code_)
   12306              :         {
   12307            0 :         default:
   12308            0 :           go_unreachable();
   12309              :         case BUILTIN_APPEND:
   12310              :           s = "append";
   12311              :           break;
   12312           54 :         case BUILTIN_COPY:
   12313           54 :           s = "copy";
   12314           54 :           break;
   12315         3177 :         case BUILTIN_LEN:
   12316         3177 :           s = "len";
   12317         3177 :           break;
   12318           14 :         case BUILTIN_CAP:
   12319           14 :           s = "cap";
   12320           14 :           break;
   12321           24 :         case BUILTIN_DELETE:
   12322           24 :           s = "delete";
   12323           24 :           break;
   12324           13 :         case BUILTIN_PRINT:
   12325           13 :           s = "print";
   12326           13 :           break;
   12327           17 :         case BUILTIN_PRINTLN:
   12328           17 :           s = "println";
   12329           17 :           break;
   12330          519 :         case BUILTIN_PANIC:
   12331          519 :           s = "panic";
   12332          519 :           break;
   12333           13 :         case BUILTIN_RECOVER:
   12334           13 :           s = "recover";
   12335           13 :           break;
   12336            9 :         case BUILTIN_CLOSE:
   12337            9 :           s = "close";
   12338            9 :           break;
   12339           64 :         case BUILTIN_REAL:
   12340           64 :           s = "real";
   12341           64 :           break;
   12342           76 :         case BUILTIN_IMAG:
   12343           76 :           s = "imag";
   12344           76 :           break;
   12345           66 :         case BUILTIN_COMPLEX:
   12346           66 :           s = "complex";
   12347           66 :           break;
   12348              :         }
   12349         4252 :       efb->write_c_string(s);
   12350         4252 :       this->export_arguments(efb);
   12351              :     }
   12352         4252 : }
   12353              : 
   12354              : // Class Call_expression.
   12355              : 
   12356              : // A Go function can be viewed in a couple of different ways.  The
   12357              : // code of a Go function becomes a backend function with parameters
   12358              : // whose types are simply the backend representation of the Go types.
   12359              : // If there are multiple results, they are returned as a backend
   12360              : // struct.
   12361              : 
   12362              : // However, when Go code refers to a function other than simply
   12363              : // calling it, the backend type of that function is actually a struct.
   12364              : // The first field of the struct points to the Go function code
   12365              : // (sometimes a wrapper as described below).  The remaining fields
   12366              : // hold addresses of closed-over variables.  This struct is called a
   12367              : // closure.
   12368              : 
   12369              : // There are a few cases to consider.
   12370              : 
   12371              : // A direct function call of a known function in package scope.  In
   12372              : // this case there are no closed-over variables, and we know the name
   12373              : // of the function code.  We can simply produce a backend call to the
   12374              : // function directly, and not worry about the closure.
   12375              : 
   12376              : // A direct function call of a known function literal.  In this case
   12377              : // we know the function code and we know the closure.  We generate the
   12378              : // function code such that it expects an additional final argument of
   12379              : // the closure type.  We pass the closure as the last argument, after
   12380              : // the other arguments.
   12381              : 
   12382              : // An indirect function call.  In this case we have a closure.  We
   12383              : // load the pointer to the function code from the first field of the
   12384              : // closure.  We pass the address of the closure as the last argument.
   12385              : 
   12386              : // A call to a method of an interface.  Type methods are always at
   12387              : // package scope, so we call the function directly, and don't worry
   12388              : // about the closure.
   12389              : 
   12390              : // This means that for a function at package scope we have two cases.
   12391              : // One is the direct call, which has no closure.  The other is the
   12392              : // indirect call, which does have a closure.  We can't simply ignore
   12393              : // the closure, even though it is the last argument, because that will
   12394              : // fail on targets where the function pops its arguments.  So when
   12395              : // generating a closure for a package-scope function we set the
   12396              : // function code pointer in the closure to point to a wrapper
   12397              : // function.  This wrapper function accepts a final argument that
   12398              : // points to the closure, ignores it, and calls the real function as a
   12399              : // direct function call.  This wrapper will normally be efficient, and
   12400              : // can often simply be a tail call to the real function.
   12401              : 
   12402              : // We don't use GCC's static chain pointer because 1) we don't need
   12403              : // it; 2) GCC only permits using a static chain to call a known
   12404              : // function, so we can't use it for an indirect call anyhow.  Since we
   12405              : // can't use it for an indirect call, we may as well not worry about
   12406              : // using it for a direct call either.
   12407              : 
   12408              : // We pass the closure last rather than first because it means that
   12409              : // the function wrapper we put into a closure for a package-scope
   12410              : // function can normally just be a tail call to the real function.
   12411              : 
   12412              : // For method expressions we generate a wrapper that loads the
   12413              : // receiver from the closure and then calls the method.  This
   12414              : // unfortunately forces reshuffling the arguments, since there is a
   12415              : // new first argument, but we can't avoid reshuffling either for
   12416              : // method expressions or for indirect calls of package-scope
   12417              : // functions, and since the latter are more common we reshuffle for
   12418              : // method expressions.
   12419              : 
   12420              : // Note that the Go code retains the Go types.  The extra final
   12421              : // argument only appears when we convert to the backend
   12422              : // representation.
   12423              : 
   12424              : // Traversal.
   12425              : 
   12426              : int
   12427     17229502 : Call_expression::do_traverse(Traverse* traverse)
   12428              : {
   12429     17229502 :   if (this->lowered_ != NULL)
   12430       347105 :     return Expression::traverse(&this->lowered_, traverse);
   12431              : 
   12432              :   // If we are calling a function in a different package that returns
   12433              :   // an unnamed type, this may be the only chance we get to traverse
   12434              :   // that type.  We don't traverse this->type_ because it may be a
   12435              :   // Call_multiple_result_type that will just lead back here.
   12436     16882397 :   if (this->type_ != NULL && !this->type_->is_error_type())
   12437              :     {
   12438     12523828 :       Function_type *fntype = this->get_function_type();
   12439     12523828 :       if (fntype != NULL && Type::traverse(fntype, traverse) == TRAVERSE_EXIT)
   12440              :         return TRAVERSE_EXIT;
   12441              :     }
   12442     16880257 :   if (Expression::traverse(&this->fn_, traverse) == TRAVERSE_EXIT)
   12443              :     return TRAVERSE_EXIT;
   12444     16281475 :   if (this->args_ != NULL)
   12445              :     {
   12446     14759903 :       if (this->args_->traverse(traverse) == TRAVERSE_EXIT)
   12447              :         return TRAVERSE_EXIT;
   12448              :     }
   12449              :   return TRAVERSE_CONTINUE;
   12450              : }
   12451              : 
   12452              : // Lower a Call_expression to a Builtin_call_expression.  This happens
   12453              : // early on, before determine_types.
   12454              : 
   12455              : Expression*
   12456      3894877 : Call_expression::lower_builtin(Gogo* gogo)
   12457              : {
   12458              :   // This is called before determine_types, so we can't call
   12459              :   // this->fn_->type().  Fortunately builtin calls require a direct
   12460              :   // reference to the builtin.
   12461      3894877 :   Expression* fn = this->fn_;
   12462      3894877 :   Named_object* no;
   12463      3894877 :   if (fn->func_expression() != NULL)
   12464      2459852 :     no = fn->func_expression()->named_object();
   12465      1435025 :   else if (fn->unknown_expression() != NULL)
   12466              :     {
   12467       446148 :       no = fn->unknown_expression()->named_object();
   12468       446148 :       if (no->is_unknown())
   12469              :         {
   12470       446148 :           no = no->unknown_value()->real_named_object();
   12471       446148 :           if (no == NULL)
   12472           10 :             return this;
   12473              :         }
   12474              :     }
   12475              :   else
   12476       988877 :     return this;
   12477              : 
   12478      2905990 :   if (!no->is_function_declaration())
   12479       854597 :     return this;
   12480      2051393 :   if (!no->func_declaration_value()->type()->is_builtin())
   12481      1810627 :     return this;
   12482              : 
   12483       240766 :   if (fn->unknown_expression() != NULL)
   12484       143737 :     fn = Expression::make_func_reference(no, NULL, fn->location());
   12485              : 
   12486       240766 :   Builtin_call_expression* bce = new Builtin_call_expression(gogo, fn,
   12487              :                                                              this->args_,
   12488       240766 :                                                              this->is_varargs_,
   12489       240766 :                                                              this->location());
   12490       240766 :   if (this->is_deferred_)
   12491          344 :     bce->set_is_deferred();
   12492       240766 :   if (this->is_concurrent_)
   12493           27 :     bce->set_is_concurrent();
   12494              :   return bce;
   12495              : }
   12496              : 
   12497              : // A type conversion can be a constant.
   12498              : 
   12499              : bool
   12500       177932 : Call_expression::do_is_constant() const
   12501              : {
   12502       177932 :   if (this->lowered_ != NULL)
   12503          635 :     return this->lowered_->is_constant();
   12504       177297 :   if (this->fn_->is_type_expression()
   12505        40307 :       && this->args_ != NULL
   12506       217604 :       && this->args_->size() == 1)
   12507        40307 :     return this->args_->front()->is_constant();
   12508              :   return false;
   12509              : }
   12510              : 
   12511              : bool
   12512       172549 : Call_expression::do_is_untyped(Type** ptype) const
   12513              : {
   12514       172549 :   if (this->lowered_ != NULL)
   12515            2 :     return this->lowered_->is_untyped(ptype);
   12516              :   return false;
   12517              : }
   12518              : 
   12519              : bool
   12520       132233 : Call_expression::do_numeric_constant_value(Numeric_constant* nc)
   12521              : {
   12522       132233 :   if (this->lowered_ != NULL)
   12523        10307 :     return this->lowered_->numeric_constant_value(nc);
   12524       121926 :   if (this->fn_->is_type_expression()
   12525           34 :       && this->args_ != NULL
   12526       121960 :       && this->args_->size() == 1)
   12527              :     {
   12528              :       // If we get here, it's before the determine_types pass, so we
   12529              :       // have to pull apart the type carefully.  This is a hack that
   12530              :       // is needed because the finalize_methods needs to be able to
   12531              :       // determine whether the length of an array is 1.
   12532              : 
   12533           34 :       Type* type;
   12534           34 :       if (this->fn_->classification() == EXPRESSION_TYPE)
   12535            0 :         type = this->fn_->type();
   12536       121927 :       else if (this->fn_->unknown_expression() != NULL)
   12537              :         {
   12538           34 :           Named_object* no = this->fn_->unknown_expression()->named_object();
   12539           34 :           if (no->is_unknown())
   12540              :             {
   12541           34 :               no = no->unknown_value()->real_named_object();
   12542           34 :               go_assert(no != NULL);
   12543              :             }
   12544           34 :           type = no->type_value();
   12545              :         }
   12546              :       else
   12547              :         return false;
   12548              : 
   12549           34 :       if (!type->is_numeric_type())
   12550              :         return false;
   12551           34 :       if (!this->args_->front()->numeric_constant_value(nc))
   12552              :         return false;
   12553           33 :       return nc->set_type(type, false, this->location());
   12554              :     }
   12555              :   return false;
   12556              : }
   12557              : 
   12558              : bool
   12559       243404 : Call_expression::do_discarding_value()
   12560              : {
   12561       243404 :   if (this->fn_->is_type_expression())
   12562              :     {
   12563            4 :       this->unused_value_error();
   12564            4 :       return false;
   12565              :     }
   12566              :   return true;
   12567              : }
   12568              : 
   12569              : // Lower a call statement.
   12570              : 
   12571              : Expression*
   12572      1493644 : Call_expression::do_lower(Gogo* gogo, Named_object*,
   12573              :                           Statement_inserter* inserter)
   12574              : {
   12575      1493644 :   if (this->lowered_ != NULL)
   12576              :     return this->lowered_;
   12577              : 
   12578      1328393 :   Location loc = this->location();
   12579              : 
   12580      1328393 :   if (this->is_error_expression())
   12581           96 :     return Expression::make_error(loc);
   12582              : 
   12583              :   // Although we've already lowered calls to builtin functions, we may
   12584              :   // still see calls generated to builtins elsewhere in the lowering
   12585              :   // pass.  It's simpler to handle them here.
   12586      1328297 :   Expression* builtin = this->lower_builtin(gogo);
   12587      1328297 :   if (builtin != this)
   12588              :     return builtin;
   12589              : 
   12590              :   // If this call returns multiple results, create a temporary
   12591              :   // variable to hold them.
   12592      1308691 :   if (this->result_count() > 1 && this->call_temp_ == NULL)
   12593              :     {
   12594        93382 :       Struct_field_list* sfl = new Struct_field_list();
   12595        93382 :       const Typed_identifier_list* results =
   12596        93382 :         this->get_function_type()->results();
   12597              : 
   12598        93382 :       int i = 0;
   12599        93382 :       char buf[20];
   12600        93382 :       for (Typed_identifier_list::const_iterator p = results->begin();
   12601       290003 :            p != results->end();
   12602       196621 :            ++p, ++i)
   12603              :         {
   12604       196621 :           snprintf(buf, sizeof buf, "res%d", i);
   12605       393242 :           sfl->push_back(Struct_field(Typed_identifier(buf, p->type(), loc)));
   12606              :         }
   12607              : 
   12608        93382 :       Struct_type* st = Type::make_struct_type(sfl, loc);
   12609        93382 :       st->set_is_struct_incomparable();
   12610        93382 :       st->set_is_results_struct();
   12611        93382 :       this->call_temp_ = Statement::make_temporary(st, NULL, loc);
   12612        93382 :       inserter->insert(this->call_temp_);
   12613              :     }
   12614              : 
   12615              :   // If this is call to a method, call the method directly passing the
   12616              :   // object as the first parameter.
   12617      1308691 :   Bound_method_expression* bme = this->fn_->bound_method_expression();
   12618       264234 :   if (bme != NULL && !this->is_deferred_ && !this->is_concurrent_)
   12619              :     {
   12620       258280 :       Named_object* methodfn = bme->function();
   12621       258280 :       Function_type* mft = (methodfn->is_function()
   12622       258280 :                             ? methodfn->func_value()->type()
   12623       123936 :                             : methodfn->func_declaration_value()->type());
   12624       258280 :       Expression* first_arg = bme->first_argument();
   12625              : 
   12626              :       // We always pass a pointer when calling a method, except for
   12627              :       // direct interface types when calling a value method.
   12628       258280 :       if (!first_arg->type()->is_error()
   12629       258279 :           && first_arg->type()->points_to() == NULL
   12630       298190 :           && !first_arg->type()->is_direct_iface_type())
   12631              :         {
   12632        35412 :           first_arg = Expression::make_unary(OPERATOR_AND, first_arg, loc);
   12633              :           // We may need to create a temporary variable so that we can
   12634              :           // take the address.  We can't do that here because it will
   12635              :           // mess up the order of evaluation.
   12636        35412 :           Unary_expression* ue = static_cast<Unary_expression*>(first_arg);
   12637        35412 :           ue->set_create_temp();
   12638              :         }
   12639       222868 :       else if (mft->receiver()->type()->points_to() == NULL
   12640         6612 :                && first_arg->type()->points_to() != NULL
   12641       224981 :                && first_arg->type()->points_to()->is_direct_iface_type())
   12642           45 :         first_arg = Expression::make_dereference(first_arg,
   12643              :                                                  Expression::NIL_CHECK_DEFAULT,
   12644              :                                                  loc);
   12645              : 
   12646              :       // If we are calling a method which was inherited from an
   12647              :       // embedded struct, and the method did not get a stub, then the
   12648              :       // first type may be wrong.
   12649       258280 :       Type* fatype = bme->first_argument_type();
   12650       258280 :       if (fatype != NULL)
   12651              :         {
   12652            0 :           if (fatype->points_to() == NULL)
   12653            0 :             fatype = Type::make_pointer_type(fatype);
   12654            0 :           first_arg = Expression::make_unsafe_cast(fatype, first_arg, loc);
   12655              :         }
   12656              : 
   12657       258280 :       first_arg->determine_type_no_context(gogo);
   12658       258280 :       first_arg->check_types(gogo);
   12659              : 
   12660       258280 :       Expression_list* new_args = new Expression_list();
   12661       258280 :       new_args->push_back(first_arg);
   12662       258280 :       if (this->args_ != NULL)
   12663              :         {
   12664       156432 :           for (Expression_list::const_iterator p = this->args_->begin();
   12665       405779 :                p != this->args_->end();
   12666       249347 :                ++p)
   12667       249347 :             new_args->push_back(*p);
   12668              :         }
   12669              : 
   12670              :       // We have to change in place because this structure may be
   12671              :       // referenced by Call_result_expressions.  We can't delete the
   12672              :       // old arguments, because we may be traversing them up in some
   12673              :       // caller.  FIXME.
   12674       258280 :       this->args_ = new_args;
   12675       258280 :       this->fn_ = Expression::make_func_reference(methodfn, NULL,
   12676              :                                                   bme->location());
   12677              :     }
   12678              : 
   12679              :   // If this is a call to an imported function for which we have an
   12680              :   // inlinable function body, add it to the list of functions to give
   12681              :   // to the backend as inlining opportunities.
   12682      1308691 :   Func_expression* fe = this->fn_->func_expression();
   12683      1200143 :   if (fe != NULL
   12684      1200143 :       && fe->named_object()->is_function_declaration()
   12685       719437 :       && fe->named_object()->func_declaration_value()->has_imported_body())
   12686        82289 :     gogo->add_imported_inlinable_function(fe->named_object());
   12687              : 
   12688              :   return this;
   12689              : }
   12690              : 
   12691              : // Flatten a call with multiple results into a temporary.
   12692              : 
   12693              : Expression*
   12694      1039120 : Call_expression::do_flatten(Gogo* gogo, Named_object*,
   12695              :                             Statement_inserter* inserter)
   12696              : {
   12697      1039120 :   if (this->is_erroneous_call())
   12698              :     {
   12699         3209 :       go_assert(saw_errors());
   12700         3209 :       return Expression::make_error(this->location());
   12701              :     }
   12702              : 
   12703      1035911 :   if (this->is_flattened_)
   12704       153795 :     return this;
   12705       882116 :   this->is_flattened_ = true;
   12706              : 
   12707              :   // Add temporary variables for all arguments that require type
   12708              :   // conversion.
   12709       882116 :   Function_type* fntype = this->get_function_type();
   12710       882116 :   if (fntype == NULL)
   12711              :     {
   12712            0 :       go_assert(saw_errors());
   12713            0 :       return this;
   12714              :     }
   12715       829367 :   if (this->args_ != NULL && !this->args_->empty()
   12716      1703276 :       && fntype->parameters() != NULL && !fntype->parameters()->empty())
   12717              :     {
   12718       719811 :       bool is_interface_method =
   12719       719811 :         this->fn_->interface_field_reference_expression() != NULL;
   12720              : 
   12721       719811 :       Expression_list *args = new Expression_list();
   12722       719811 :       Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
   12723       719811 :       Expression_list::const_iterator pa = this->args_->begin();
   12724       719811 :       if (!is_interface_method && fntype->is_method())
   12725              :         {
   12726              :           // The receiver argument.
   12727       155666 :           args->push_back(*pa);
   12728       155666 :           ++pa;
   12729              :         }
   12730      2248040 :       for (; pa != this->args_->end(); ++pa, ++pp)
   12731              :         {
   12732      1528229 :           go_assert(pp != fntype->parameters()->end());
   12733      1528229 :           if (Type::are_identical(pp->type(), (*pa)->type(),
   12734              :                                   Type::COMPARE_TAGS, NULL))
   12735      1512105 :             args->push_back(*pa);
   12736              :           else
   12737              :             {
   12738        16124 :               Location loc = (*pa)->location();
   12739        16124 :               Expression* arg = *pa;
   12740        16124 :               if (!arg->is_multi_eval_safe())
   12741              :                 {
   12742        14979 :                   Temporary_statement *temp =
   12743        14979 :                     Statement::make_temporary(NULL, arg, loc);
   12744        14979 :                   inserter->insert(temp);
   12745        14979 :                   arg = Expression::make_temporary_reference(temp, loc);
   12746              :                 }
   12747        16124 :               arg = Expression::convert_for_assignment(gogo, pp->type(), arg,
   12748              :                                                        loc);
   12749        16124 :               args->push_back(arg);
   12750              :             }
   12751              :         }
   12752       719811 :       delete this->args_;
   12753       719811 :       this->args_ = args;
   12754              :     }
   12755              : 
   12756              :   // Lower to compiler intrinsic if possible.
   12757       882116 :   Func_expression* fe = this->fn_->func_expression();
   12758       879619 :   if (!this->is_concurrent_ && !this->is_deferred_
   12759       871094 :       && fe != NULL
   12760      1702719 :       && (fe->named_object()->is_function_declaration()
   12761       345636 :           || fe->named_object()->is_function()))
   12762              :     {
   12763       820603 :       Expression* ret = this->intrinsify(gogo, inserter);
   12764       820603 :       if (ret != NULL)
   12765              :         {
   12766         6161 :           ret->determine_type_no_context(gogo);
   12767         6161 :           return ret;
   12768              :         }
   12769              :     }
   12770              : 
   12771              :   // Add an implicit conversion to a boolean type, if needed.  See the
   12772              :   // comment in Binary_expression::lower_array_comparison.
   12773       875955 :   if (this->is_equal_function_
   12774          961 :       && this->type_ != NULL
   12775       876916 :       && this->type_ != Type::lookup_bool_type())
   12776            0 :     return Expression::make_cast(this->type_, this, this->location());
   12777              : 
   12778       875955 :   return this;
   12779              : }
   12780              : 
   12781              : // Lower a call to a compiler intrinsic if possible.
   12782              : // Returns NULL if it is not an intrinsic.
   12783              : 
   12784              : Expression*
   12785       820603 : Call_expression::intrinsify(Gogo* gogo,
   12786              :                             Statement_inserter* inserter)
   12787              : {
   12788       820603 :   Func_expression* fe = this->fn_->func_expression();
   12789       820603 :   Named_object* no = fe->named_object();
   12790       820603 :   std::string name = Gogo::unpack_hidden_name(no->name());
   12791       820603 :   std::string package = (no->package() != NULL
   12792       264826 :                          ? no->package()->pkgpath()
   12793       820603 :                          : gogo->pkgpath());
   12794       820603 :   bool is_method = ((no->is_function() && no->func_value()->is_method())
   12795      1031135 :                     || (no->is_function_declaration()
   12796       474967 :                         && no->func_declaration_value()->is_method()));
   12797       820603 :   Location loc = this->location();
   12798              : 
   12799       820603 :   Type* int_type = Type::lookup_integer_type("int");
   12800       820603 :   Type* int32_type = Type::lookup_integer_type("int32");
   12801       820603 :   Type* int64_type = Type::lookup_integer_type("int64");
   12802       820603 :   Type* uint_type = Type::lookup_integer_type("uint");
   12803       820603 :   Type* uint8_type = Type::lookup_integer_type("uint8");
   12804       820603 :   Type* uint32_type = Type::lookup_integer_type("uint32");
   12805       820603 :   Type* uint64_type = Type::lookup_integer_type("uint64");
   12806       820603 :   Type* uintptr_type = Type::lookup_integer_type("uintptr");
   12807       820603 :   Type* pointer_type = Type::make_pointer_type(Type::make_void_type());
   12808              : 
   12809      1641206 :   int int_size = int_type->named_type()->real_type()->integer_type()->bits() / 8;
   12810      1641206 :   int ptr_size = uintptr_type->named_type()->real_type()->integer_type()->bits() / 8;
   12811              : 
   12812       820603 :   if (package == "sync/atomic")
   12813              :     {
   12814         2095 :       if (is_method)
   12815              :         return NULL;
   12816              : 
   12817              :       // sync/atomic functions and runtime/internal/atomic functions
   12818              :       // are very similar. In order not to duplicate code, we just
   12819              :       // redirect to the latter and let the code below to handle them.
   12820              :       // Note: no StorePointer, SwapPointer, and CompareAndSwapPointer,
   12821              :       // as they need write barriers.
   12822         1717 :       if (name == "LoadInt32")
   12823          201 :         name = "Loadint32";
   12824         1516 :       else if (name == "LoadInt64")
   12825           39 :         name = "Loadint64";
   12826         1477 :       else if (name == "LoadUint32")
   12827          147 :         name = "Load";
   12828         1330 :       else if (name == "LoadUint64")
   12829          104 :         name = "Load64";
   12830         1226 :       else if (name == "LoadUintptr")
   12831           16 :         name = "Loaduintptr";
   12832         1210 :       else if (name == "LoadPointer")
   12833          102 :         name = "Loadp";
   12834         1108 :       else if (name == "StoreInt32")
   12835          125 :         name = "Storeint32";
   12836          983 :       else if (name == "StoreInt64")
   12837           20 :         name = "Storeint64";
   12838          963 :       else if (name == "StoreUint32")
   12839          111 :         name = "Store";
   12840          852 :       else if (name == "StoreUint64")
   12841           25 :         name = "Store64";
   12842          827 :       else if (name == "StoreUintptr")
   12843           12 :         name = "Storeuintptr";
   12844          815 :       else if (name == "AddInt32")
   12845          161 :         name = "Xaddint32";
   12846          654 :       else if (name == "AddInt64")
   12847           40 :         name = "Xaddint64";
   12848          614 :       else if (name == "AddUint32")
   12849           52 :         name = "Xadd";
   12850          562 :       else if (name == "AddUint64")
   12851           57 :         name = "Xadd64";
   12852          505 :       else if (name == "AddUintptr")
   12853           14 :         name = "Xadduintptr";
   12854          491 :       else if (name == "SwapInt32")
   12855            6 :         name = "Xchgint32";
   12856          485 :       else if (name == "SwapInt64")
   12857            6 :         name = "Xchgint64";
   12858          479 :       else if (name == "SwapUint32")
   12859            7 :         name = "Xchg";
   12860          472 :       else if (name == "SwapUint64")
   12861            6 :         name = "Xchg64";
   12862          466 :       else if (name == "SwapUintptr")
   12863            7 :         name = "Xchguintptr";
   12864          459 :       else if (name == "CompareAndSwapInt32")
   12865          101 :         name = "Casint32";
   12866          358 :       else if (name == "CompareAndSwapInt64")
   12867            8 :         name = "Casint64";
   12868          350 :       else if (name == "CompareAndSwapUint32")
   12869           21 :         name = "Cas";
   12870          329 :       else if (name == "CompareAndSwapUint64")
   12871           60 :         name = "Cas64";
   12872          269 :       else if (name == "CompareAndSwapUintptr")
   12873           16 :         name = "Casuintptr";
   12874              :       else
   12875              :         return NULL;
   12876              : 
   12877         1464 :       package = "runtime/internal/atomic";
   12878              :     }
   12879              : 
   12880       819972 :   if (package == "runtime/internal/sys")
   12881              :     {
   12882          308 :       if (is_method)
   12883              :         return NULL;
   12884              : 
   12885              :       // runtime/internal/sys functions and math/bits functions
   12886              :       // are very similar. In order not to duplicate code, we just
   12887              :       // redirect to the latter and let the code below to handle them.
   12888          308 :       if (name == "Bswap32")
   12889            2 :         name = "ReverseBytes32";
   12890          306 :       else if (name == "Bswap64")
   12891            2 :         name = "ReverseBytes64";
   12892          304 :       else if (name == "Ctz32")
   12893            5 :         name = "TrailingZeros32";
   12894          299 :       else if (name == "Ctz64")
   12895           27 :         name = "TrailingZeros64";
   12896              :       else
   12897              :         return NULL;
   12898              : 
   12899           36 :       package = "math/bits";
   12900              :     }
   12901              : 
   12902       819700 :   if (package == "runtime")
   12903              :     {
   12904        73025 :       if (is_method)
   12905              :         return NULL;
   12906              : 
   12907              :       // Handle a couple of special runtime functions.  In the runtime
   12908              :       // package, getcallerpc returns the PC of the caller, and
   12909              :       // getcallersp returns the frame pointer of the caller.  Implement
   12910              :       // these by turning them into calls to GCC builtin functions.  We
   12911              :       // could implement them in normal code, but then we would have to
   12912              :       // explicitly unwind the stack.  These functions are intended to be
   12913              :       // efficient.  Note that this technique obviously only works for
   12914              :       // direct calls, but that is the only way they are used.
   12915        50939 :       if (name == "getcallerpc"
   12916        50939 :           && (this->args_ == NULL || this->args_->size() == 0))
   12917              :         {
   12918          216 :           Expression* arg = Expression::make_integer_ul(0, uint32_type, loc);
   12919          216 :           Expression* call =
   12920          216 :             Runtime::make_call(gogo, Runtime::BUILTIN_RETURN_ADDRESS, loc,
   12921              :                                1, arg);
   12922              :           // The builtin functions return void*, but the Go functions return uintptr.
   12923          216 :           return Expression::make_cast(uintptr_type, call, loc);
   12924              :         }
   12925        50723 :       else if (name == "getcallersp"
   12926        50723 :                && (this->args_ == NULL || this->args_->size() == 0))
   12927              : 
   12928              :         {
   12929           28 :           Expression* call =
   12930           28 :             Runtime::make_call(gogo, Runtime::BUILTIN_DWARF_CFA, loc, 0);
   12931              :           // The builtin functions return void*, but the Go functions return uintptr.
   12932           28 :           return Expression::make_cast(uintptr_type, call, loc);
   12933              :         }
   12934              :     }
   12935       746675 :   else if (package == "math/bits")
   12936              :     {
   12937        12928 :       if (is_method)
   12938              :         return NULL;
   12939              : 
   12940        12922 :       if ((name == "ReverseBytes16" || name == "ReverseBytes32"
   12941        12902 :            || name == "ReverseBytes64" || name == "ReverseBytes")
   12942        12988 :           && this->args_ != NULL && this->args_->size() == 1)
   12943              :         {
   12944           66 :           Runtime::Function code;
   12945           66 :           if (name == "ReverseBytes16")
   12946              :             code = Runtime::BUILTIN_BSWAP16;
   12947           60 :           else if (name == "ReverseBytes32")
   12948              :             code = Runtime::BUILTIN_BSWAP32;
   12949           40 :           else if (name == "ReverseBytes64")
   12950              :             code = Runtime::BUILTIN_BSWAP64;
   12951            4 :           else if (name == "ReverseBytes")
   12952           24 :             code = (int_size == 8 ? Runtime::BUILTIN_BSWAP64 : Runtime::BUILTIN_BSWAP32);
   12953              :           else
   12954            0 :             go_unreachable();
   12955           66 :           Expression* arg = this->args_->front();
   12956           66 :           Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
   12957           66 :           if (name == "ReverseBytes")
   12958            4 :             return Expression::make_cast(uint_type, call, loc);
   12959              :           return call;
   12960              :         }
   12961        12856 :       else if ((name == "TrailingZeros8" || name == "TrailingZeros16")
   12962        12868 :                && this->args_ != NULL && this->args_->size() == 1)
   12963              :         {
   12964              :           // GCC does not have a ctz8 or ctz16 intrinsic. We do
   12965              :           // ctz32(0x100 | arg) or ctz32(0x10000 | arg).
   12966           12 :           Expression* arg = this->args_->front();
   12967           12 :           arg = Expression::make_cast(uint32_type, arg, loc);
   12968           12 :           unsigned long mask = (name == "TrailingZeros8" ? 0x100 : 0x10000);
   12969           12 :           Expression* c = Expression::make_integer_ul(mask, uint32_type, loc);
   12970           12 :           arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
   12971           12 :           Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
   12972              :                                                 loc, 1, arg);
   12973           12 :           return Expression::make_cast(int_type, call, loc);
   12974              :         }
   12975        12850 :       else if ((name == "TrailingZeros32"
   12976        12823 :                 || (name == "TrailingZeros" && int_size == 4))
   12977        12861 :                && this->args_ != NULL && this->args_->size() == 1)
   12978              :         {
   12979           38 :           Expression* arg = this->args_->front();
   12980           38 :           if (!arg->is_multi_eval_safe())
   12981              :             {
   12982           28 :               Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
   12983           28 :               inserter->insert(ts);
   12984           28 :               arg = Expression::make_temporary_reference(ts, loc);
   12985              :             }
   12986              :           // arg == 0 ? 32 : __builtin_ctz(arg)
   12987           38 :           Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
   12988           38 :           Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
   12989           38 :           Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
   12990           38 :           Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
   12991              :                                                 loc, 1, arg->copy());
   12992           38 :           call = Expression::make_cast(int_type, call, loc);
   12993           38 :           return Expression::make_conditional(cmp, c32, call, loc);
   12994              :         }
   12995        12812 :       else if ((name == "TrailingZeros64"
   12996        12747 :                 || (name == "TrailingZeros" && int_size == 8))
   12997        12823 :                && this->args_ != NULL && this->args_->size() == 1)
   12998              :         {
   12999           76 :           Expression* arg = this->args_->front();
   13000           76 :           if (!arg->is_multi_eval_safe())
   13001              :             {
   13002           52 :               Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
   13003           52 :               inserter->insert(ts);
   13004           52 :               arg = Expression::make_temporary_reference(ts, loc);
   13005              :             }
   13006              :           // arg == 0 ? 64 : __builtin_ctzll(arg)
   13007           76 :           Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
   13008           76 :           Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
   13009           76 :           Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
   13010           76 :           Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZLL,
   13011              :                                                 loc, 1, arg->copy());
   13012           76 :           call = Expression::make_cast(int_type, call, loc);
   13013           76 :           return Expression::make_conditional(cmp, c64, call, loc);
   13014              :         }
   13015        12730 :       else if ((name == "LeadingZeros8" || name == "LeadingZeros16"
   13016        12724 :                 || name == "Len8" || name == "Len16")
   13017        12766 :                && this->args_ != NULL && this->args_->size() == 1)
   13018              :         {
   13019              :           // GCC does not have a clz8 ir clz16 intrinsic. We do
   13020              :           // clz32(arg<<24 | 0xffffff) or clz32(arg<<16 | 0xffff).
   13021           36 :           Expression* arg = this->args_->front();
   13022           36 :           arg = Expression::make_cast(uint32_type, arg, loc);
   13023           36 :           unsigned long shift =
   13024           36 :             ((name == "LeadingZeros8" || name == "Len8") ? 24 : 16);
   13025           36 :           Expression* c = Expression::make_integer_ul(shift, uint32_type, loc);
   13026           36 :           arg = Expression::make_binary(OPERATOR_LSHIFT, arg, c, loc);
   13027           36 :           unsigned long mask =
   13028           36 :             ((name == "LeadingZeros8" || name == "Len8") ? 0xffffff : 0xffff);
   13029           36 :           c = Expression::make_integer_ul(mask, uint32_type, loc);
   13030           36 :           arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
   13031           36 :           Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
   13032              :                                                 loc, 1, arg);
   13033           36 :           call = Expression::make_cast(int_type, call, loc);
   13034              :           // len = width - clz
   13035           36 :           if (name == "Len8")
   13036              :             {
   13037           12 :               c = Expression::make_integer_ul(8, int_type, loc);
   13038           12 :               return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
   13039              :             }
   13040           24 :           else if (name == "Len16")
   13041              :             {
   13042           12 :               c = Expression::make_integer_ul(16, int_type, loc);
   13043           12 :               return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
   13044              :             }
   13045              :           return call;
   13046              :         }
   13047        12694 :       else if ((name == "LeadingZeros32" || name == "Len32"
   13048        12669 :                 || ((name == "LeadingZeros" || name == "Len") && int_size == 4))
   13049        12745 :                && this->args_ != NULL && this->args_->size() == 1)
   13050              :         {
   13051           51 :           Expression* arg = this->args_->front();
   13052           51 :           if (!arg->is_multi_eval_safe())
   13053              :             {
   13054           26 :               Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
   13055           26 :               inserter->insert(ts);
   13056           26 :               arg = Expression::make_temporary_reference(ts, loc);
   13057              :             }
   13058              :           // arg == 0 ? 32 : __builtin_clz(arg)
   13059           51 :           Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
   13060           51 :           Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
   13061           51 :           Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
   13062           51 :           Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
   13063              :                                                 loc, 1, arg->copy());
   13064           51 :           call = Expression::make_cast(int_type, call, loc);
   13065           51 :           Expression* cond = Expression::make_conditional(cmp, c32, call, loc);
   13066              :           // len = 32 - clz
   13067           51 :           if (name == "Len32" || name == "Len")
   13068           40 :             return Expression::make_binary(OPERATOR_MINUS, c32->copy(), cond, loc);
   13069              :           return cond;
   13070              :         }
   13071        12569 :       else if ((name == "LeadingZeros64" || name == "Len64"
   13072        12485 :                 || ((name == "LeadingZeros" || name == "Len") && int_size == 8))
   13073        12753 :                && this->args_ != NULL && this->args_->size() == 1)
   13074              :         {
   13075          184 :           Expression* arg = this->args_->front();
   13076          184 :           if (!arg->is_multi_eval_safe())
   13077              :             {
   13078           51 :               Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
   13079           51 :               inserter->insert(ts);
   13080           51 :               arg = Expression::make_temporary_reference(ts, loc);
   13081              :             }
   13082              :           // arg == 0 ? 64 : __builtin_clzll(arg)
   13083          184 :           Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
   13084          184 :           Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
   13085          184 :           Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
   13086          184 :           Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZLL,
   13087              :                                                 loc, 1, arg->copy());
   13088          184 :           call = Expression::make_cast(int_type, call, loc);
   13089          184 :           Expression* cond = Expression::make_conditional(cmp, c64, call, loc);
   13090              :           // len = 64 - clz
   13091          184 :           if (name == "Len64" || name == "Len")
   13092           99 :             return Expression::make_binary(OPERATOR_MINUS, c64->copy(), cond, loc);
   13093              :           return cond;
   13094              :         }
   13095        12441 :       else if ((name == "OnesCount8" || name == "OnesCount16"
   13096        12435 :            || name == "OnesCount32" || name == "OnesCount64"
   13097        12411 :            || name == "OnesCount")
   13098        12501 :           && this->args_ != NULL && this->args_->size() == 1)
   13099              :         {
   13100           60 :           Runtime::Function code;
   13101           60 :           if (name == "OnesCount64")
   13102              :             code = Runtime::BUILTIN_POPCOUNTLL;
   13103           46 :           else if (name == "OnesCount")
   13104            6 :             code = (int_size == 8 ? Runtime::BUILTIN_POPCOUNTLL : Runtime::BUILTIN_POPCOUNT);
   13105              :           else
   13106              :             code = Runtime::BUILTIN_POPCOUNT;
   13107           60 :           Expression* arg = this->args_->front();
   13108           60 :           Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
   13109           60 :           return Expression::make_cast(int_type, call, loc);
   13110              :         }
   13111              :     }
   13112       733747 :   else if (package == "runtime/internal/atomic")
   13113              :     {
   13114         6502 :       int memorder = __ATOMIC_SEQ_CST;
   13115              : 
   13116         6502 :       if (is_method)
   13117              :         {
   13118          580 :           Function_type* ftype = (no->is_function()
   13119          580 :                                   ? no->func_value()->type()
   13120          568 :                                   : no->func_declaration_value()->type());
   13121          580 :           Type* rtype = ftype->receiver()->type()->deref();
   13122          580 :           go_assert(rtype->named_type() != NULL);
   13123          580 :           const std::string& rname(rtype->named_type()->name());
   13124          580 :           if (rname == "Int32")
   13125              :             {
   13126           42 :               if (name == "Load")
   13127           35 :                 name = "LoadInt32";
   13128            7 :               else if (name == "Store")
   13129            7 :                 name = "Storeint32";
   13130            0 :               else if (name == "CompareAndSwap")
   13131            0 :                 name = "Casint32";
   13132            0 :               else if (name == "Swap")
   13133            0 :                 name = "Xchgint32";
   13134            0 :               else if (name == "Add")
   13135            0 :                 name = "Xaddint32";
   13136              :               else
   13137            0 :                 go_unreachable();
   13138              :             }
   13139          538 :           else if (rname == "Int64")
   13140              :             {
   13141          100 :               if (name == "Load")
   13142           42 :                 name = "LoadInt64";
   13143           58 :               else if (name == "Store")
   13144           21 :                 name = "Storeint64";
   13145           37 :               else if (name == "CompareAndSwap")
   13146            0 :                 name = "Casint64";
   13147           37 :               else if (name == "Swap")
   13148            0 :                 name = "Xchgint64";
   13149           37 :               else if (name == "Add")
   13150           37 :                 name = "Xaddint64";
   13151              :               else
   13152            0 :                 go_unreachable();
   13153              :             }
   13154          438 :           else if (rname == "Uint8")
   13155              :             {
   13156            0 :               if (name == "Load")
   13157            0 :                 name = "Load8";
   13158            0 :               else if (name == "Store")
   13159            0 :                 name = "Store8";
   13160            0 :               else if (name == "And")
   13161            0 :                 name = "And8";
   13162            0 :               else if (name == "Or")
   13163            0 :                 name = "Or8";
   13164              :               else
   13165            0 :                 go_unreachable();
   13166              :             }
   13167          438 :           else if (rname == "Uint32")
   13168              :             {
   13169          119 :               if (name == "Load")
   13170           70 :                 name = "Load";
   13171           49 :               else if (name == "LoadAcquire")
   13172            0 :                 name = "LoadAcq";
   13173           49 :               else if (name == "Store")
   13174           14 :                 name = "Store";
   13175           35 :               else if (name == "CompareAndSwap")
   13176           35 :                 name = "Cas";
   13177            0 :               else if (name == "CompareAndSwapRelease")
   13178            0 :                 name = "CasRel";
   13179            0 :               else if (name == "Swap")
   13180            0 :                 name = "Xchg";
   13181            0 :               else if (name == "And")
   13182            0 :                 name = "And";
   13183            0 :               else if (name == "Or")
   13184            0 :                 name = "Or";
   13185            0 :               else if (name == "Add")
   13186            0 :                 name = "Xadd";
   13187              :               else
   13188            0 :                 go_unreachable();
   13189              :             }
   13190          319 :           else if (rname == "Uint64")
   13191              :             {
   13192          120 :               if (name == "Load")
   13193           58 :                 name = "Load64";
   13194           62 :               else if (name == "Store")
   13195           34 :                 name = "Store64";
   13196           28 :               else if (name == "CompareAndSwap")
   13197            0 :                 name = "Cas64";
   13198           28 :               else if (name == "Swap")
   13199            0 :                 name = "Xchgt64";
   13200           28 :               else if (name == "Add")
   13201           28 :                 name = "Xadd64";
   13202              :               else
   13203            0 :                 go_unreachable();
   13204              :             }
   13205          199 :           else if (rname == "Uintptr")
   13206              :             {
   13207          133 :               if (name == "Load")
   13208           49 :                 name = "Loaduintptr";
   13209           84 :               else if (name == "LoadAcquire")
   13210            0 :                 name = "Loadacquintptr";
   13211           84 :               else if (name == "Store")
   13212           35 :                 name = "Storeuintptr";
   13213           49 :               else if (name == "StoreRelease")
   13214            0 :                 name = "StoreReluintptr";
   13215           49 :               else if (name == "CompareAndSwap")
   13216           28 :                 name = "Casuintptr";
   13217           21 :               else if (name == "Swap")
   13218            7 :                 name = "Xchguintptr";
   13219           14 :               else if (name == "Add")
   13220           14 :                 name = "Xadduintptr";
   13221              :               else
   13222            0 :                 go_unreachable();
   13223              :             }
   13224           66 :           else if (rname == "Float64")
   13225              :             {
   13226              :               // Needs unsafe type conversion.  Don't intrinsify for now.
   13227              :               return NULL;
   13228              :             }
   13229            0 :           else if (rname == "UnsafePointer")
   13230              :             {
   13231            0 :               if (name == "Load")
   13232            0 :                 name = "Loadp";
   13233            0 :               else if (name == "StoreNoWB")
   13234            0 :                 name = "StorepoWB";
   13235            0 :               else if (name == "CompareAndSwapNoWB")
   13236            0 :                 name = "Casp1";
   13237              :               else
   13238            0 :                 go_unreachable();
   13239              :             }
   13240              :           else
   13241            0 :             go_unreachable();
   13242              :         }
   13243              : 
   13244         5460 :       if ((name == "Load" || name == "Load64" || name == "Loadint64" || name == "Loadp"
   13245         4594 :            || name == "Loaduint" || name == "Loaduintptr" || name == "LoadAcq"
   13246         4321 :            || name == "Loadint32" || name == "Load8")
   13247         7827 :           && this->args_ != NULL && this->args_->size() == 1)
   13248              :         {
   13249         2367 :           if (int_size < 8 && (name == "Load64" || name == "Loadint64"))
   13250              :             // On 32-bit architectures we need to check alignment.
   13251              :             // Not intrinsify for now.
   13252              :             return NULL;
   13253              : 
   13254         2075 :           Runtime::Function code;
   13255         2075 :           Type* res_type;
   13256         2075 :           if (name == "Load")
   13257              :             {
   13258              :               code = Runtime::ATOMIC_LOAD_4;
   13259              :               res_type = uint32_type;
   13260              :             }
   13261         1099 :           else if (name == "Load64")
   13262              :             {
   13263              :               code = Runtime::ATOMIC_LOAD_8;
   13264              :               res_type = uint64_type;
   13265              :             }
   13266          768 :           else if (name == "Loadint32")
   13267              :             {
   13268              :               code = Runtime::ATOMIC_LOAD_4;
   13269              :               res_type = int32_type;
   13270              :             }
   13271          561 :           else if (name == "Loadint64")
   13272              :             {
   13273              :               code = Runtime::ATOMIC_LOAD_8;
   13274              :               res_type = int64_type;
   13275              :             }
   13276          524 :           else if (name == "Loaduint")
   13277              :             {
   13278            3 :               code = (int_size == 8
   13279            7 :                       ? Runtime::ATOMIC_LOAD_8
   13280              :                       : Runtime::ATOMIC_LOAD_4);
   13281              :               res_type = uint_type;
   13282              :             }
   13283          517 :           else if (name == "Loaduintptr")
   13284              :             {
   13285           92 :               code = (ptr_size == 8
   13286          211 :                       ? Runtime::ATOMIC_LOAD_8
   13287              :                       : Runtime::ATOMIC_LOAD_4);
   13288              :               res_type = uintptr_type;
   13289              :             }
   13290          306 :           else if (name == "Loadp")
   13291              :             {
   13292           96 :               code = (ptr_size == 8
   13293          206 :                       ? Runtime::ATOMIC_LOAD_8
   13294              :                       : Runtime::ATOMIC_LOAD_4);
   13295              :               res_type = pointer_type;
   13296              :             }
   13297          100 :           else if (name == "LoadAcq")
   13298              :             {
   13299              :               code = Runtime::ATOMIC_LOAD_4;
   13300              :               res_type = uint32_type;
   13301              :               memorder = __ATOMIC_ACQUIRE;
   13302              :             }
   13303           45 :           else if (name == "Load8")
   13304              :             {
   13305              :               code = Runtime::ATOMIC_LOAD_1;
   13306              :               res_type = uint8_type;
   13307              :             }
   13308              :           else
   13309            0 :             go_unreachable();
   13310         2075 :           Expression* a1 = this->args_->front();
   13311         2075 :           Expression* a2 = Expression::make_integer_ul(memorder, int32_type, loc);
   13312         2075 :           Expression* call = Runtime::make_call(gogo, code, loc, 2, a1, a2);
   13313         2075 :           return Expression::make_unsafe_cast(res_type, call, loc);
   13314              :         }
   13315              : 
   13316         3586 :       if ((name == "Store" || name == "Store64" || name == "StorepNoWB"
   13317         3226 :            || name == "Storeuintptr" || name == "StoreRel"
   13318         3097 :            || name == "Storeint32" || name == "Storeint64")
   13319         4743 :           && this->args_ != NULL && this->args_->size() == 2)
   13320              :         {
   13321         1157 :           if (int_size < 8 && (name == "Store64" || name == "Storeint64"))
   13322              :             return NULL;
   13323              : 
   13324         1019 :           Runtime::Function code;
   13325         1019 :           Expression* a1 = this->args_->at(0);
   13326         1019 :           Expression* a2 = this->args_->at(1);
   13327         1019 :           if (name == "Store")
   13328              :             code = Runtime::ATOMIC_STORE_4;
   13329          536 :           else if (name == "Store64")
   13330              :             code = Runtime::ATOMIC_STORE_8;
   13331          391 :           else if (name == "Storeint32")
   13332              :             code = Runtime::ATOMIC_STORE_4;
   13333          253 :           else if (name == "Storeint64")
   13334              :             code = Runtime::ATOMIC_STORE_8;
   13335          228 :           else if (name == "Storeuintptr")
   13336          102 :             code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
   13337          126 :           else if (name == "StorepNoWB")
   13338              :             {
   13339           99 :               code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
   13340           99 :               a2 = Expression::make_unsafe_cast(uintptr_type, a2, loc);
   13341           99 :               a2 = Expression::make_cast(uint64_type, a2, loc);
   13342              :             }
   13343           27 :           else if (name == "StoreRel")
   13344              :             {
   13345              :               code = Runtime::ATOMIC_STORE_4;
   13346              :               memorder = __ATOMIC_RELEASE;
   13347              :             }
   13348            0 :           else if (name == "Store8")
   13349              :             code = Runtime::ATOMIC_STORE_1;
   13350              :           else
   13351            0 :             go_unreachable();
   13352         1019 :           Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
   13353         1019 :           return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
   13354              :         }
   13355              : 
   13356         2848 :       if ((name == "Xchg" || name == "Xchg64" || name == "Xchguintptr"
   13357         2798 :            || name == "Xchgint32" || name == "Xchgint64")
   13358         2986 :           && this->args_ != NULL && this->args_->size() == 2)
   13359              :         {
   13360          138 :           if (int_size < 8 && (name == "Xchg64" || name == "Xchgint64"))
   13361              :             return NULL;
   13362              : 
   13363          118 :           Runtime::Function code;
   13364          118 :           Type* res_type;
   13365          118 :           if (name == "Xchg")
   13366              :             {
   13367              :               code = Runtime::ATOMIC_EXCHANGE_4;
   13368              :               res_type = uint32_type;
   13369              :             }
   13370           54 :           else if (name == "Xchg64")
   13371              :             {
   13372              :               code = Runtime::ATOMIC_EXCHANGE_8;
   13373              :               res_type = uint64_type;
   13374              :             }
   13375           38 :           else if (name == "Xchgint32")
   13376              :             {
   13377              :               code = Runtime::ATOMIC_EXCHANGE_4;
   13378              :               res_type = int32_type;
   13379              :             }
   13380           26 :           else if (name == "Xchgint64")
   13381              :             {
   13382              :               code = Runtime::ATOMIC_EXCHANGE_8;
   13383              :               res_type = int64_type;
   13384              :             }
   13385           20 :           else if (name == "Xchguintptr")
   13386              :             {
   13387            9 :               code = (ptr_size == 8
   13388           20 :                       ? Runtime::ATOMIC_EXCHANGE_8
   13389              :                       : Runtime::ATOMIC_EXCHANGE_4);
   13390              :               res_type = uintptr_type;
   13391              :             }
   13392              :           else
   13393            0 :             go_unreachable();
   13394          118 :           Expression* a1 = this->args_->at(0);
   13395          118 :           Expression* a2 = this->args_->at(1);
   13396          118 :           Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
   13397          118 :           Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
   13398          118 :           return Expression::make_cast(res_type, call, loc);
   13399              :         }
   13400              : 
   13401         2197 :       if ((name == "Cas" || name == "Cas64" || name == "Casuintptr"
   13402         1963 :            || name == "Casp1" || name == "CasRel"
   13403         1923 :            || name == "Casint32" || name == "Casint64")
   13404         3176 :           && this->args_ != NULL && this->args_->size() == 3)
   13405              :         {
   13406          979 :           if (int_size < 8 && (name == "Cas64" || name == "Casint64"))
   13407              :             return NULL;
   13408              : 
   13409          903 :           Runtime::Function code;
   13410          903 :           Expression* a1 = this->args_->at(0);
   13411              : 
   13412              :           // Builtin cas takes a pointer to the old value.
   13413              :           // Store it in a temporary and take the address.
   13414          903 :           Expression* a2 = this->args_->at(1);
   13415          903 :           Temporary_statement* ts = Statement::make_temporary(NULL, a2, loc);
   13416          903 :           inserter->insert(ts);
   13417          903 :           a2 = Expression::make_temporary_reference(ts, loc);
   13418          903 :           a2 = Expression::make_unary(OPERATOR_AND, a2, loc);
   13419              : 
   13420          903 :           Expression* a3 = this->args_->at(2);
   13421          903 :           if (name == "Cas")
   13422              :             code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
   13423          326 :           else if (name == "Cas64")
   13424              :             code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
   13425          250 :           else if (name == "Casint32")
   13426              :             code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
   13427          143 :           else if (name == "Casint64")
   13428              :             code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
   13429          132 :           else if (name == "Casuintptr")
   13430           41 :             code = (ptr_size == 8
   13431           92 :                     ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
   13432              :                     : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
   13433           40 :           else if (name == "Casp1")
   13434              :             {
   13435            3 :               code = (ptr_size == 8
   13436            6 :                       ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
   13437              :                       : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
   13438            6 :               a3 = Expression::make_unsafe_cast(uintptr_type, a3, loc);
   13439            6 :               a3 = Expression::make_cast(uint64_type, a3, loc);
   13440              :             }
   13441           34 :           else if (name == "CasRel")
   13442              :             {
   13443              :               code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
   13444              :               memorder = __ATOMIC_RELEASE;
   13445              :             }
   13446              :           else
   13447            0 :             go_unreachable();
   13448          903 :           Expression* a4 = Expression::make_boolean(false, loc);
   13449          903 :           Expression* a5 = Expression::make_integer_ul(memorder, int32_type, loc);
   13450          903 :           Expression* a6 = Expression::make_integer_ul(__ATOMIC_RELAXED, int32_type, loc);
   13451          903 :           return Runtime::make_call(gogo, code, loc, 6, a1, a2, a3, a4, a5, a6);
   13452              :         }
   13453              : 
   13454         1287 :       if ((name == "Xadd" || name == "Xadd64" || name == "Xaddint64"
   13455          787 :            || name == "Xadduintptr" || name == "Xaddint32")
   13456         2581 :           && this->args_ != NULL && this->args_->size() == 2)
   13457              :         {
   13458         1294 :           if (int_size < 8 && (name == "Xadd64" || name == "Xaddint64"))
   13459              :             return NULL;
   13460              : 
   13461         1079 :           Runtime::Function code;
   13462         1079 :           Type* res_type;
   13463         1079 :           if (name == "Xadd")
   13464              :             {
   13465              :               code = Runtime::ATOMIC_ADD_FETCH_4;
   13466              :               res_type = uint32_type;
   13467              :             }
   13468          571 :           else if (name == "Xadd64")
   13469              :             {
   13470              :               code = Runtime::ATOMIC_ADD_FETCH_8;
   13471              :               res_type = uint64_type;
   13472              :             }
   13473          432 :           else if (name == "Xaddint32")
   13474              :             {
   13475              :               code = Runtime::ATOMIC_ADD_FETCH_4;
   13476              :               res_type = int32_type;
   13477              :             }
   13478          265 :           else if (name == "Xaddint64")
   13479              :             {
   13480              :               code = Runtime::ATOMIC_ADD_FETCH_8;
   13481              :               res_type = int64_type;
   13482              :             }
   13483          119 :           else if (name == "Xadduintptr")
   13484              :             {
   13485           53 :               code = (ptr_size == 8
   13486          119 :                       ? Runtime::ATOMIC_ADD_FETCH_8
   13487              :                       : Runtime::ATOMIC_ADD_FETCH_4);
   13488              :               res_type = uintptr_type;
   13489              :             }
   13490              :           else
   13491            0 :             go_unreachable();
   13492         1079 :           Expression* a1 = this->args_->at(0);
   13493         1079 :           Expression* a2 = this->args_->at(1);
   13494         1079 :           Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
   13495         1079 :           Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
   13496         1079 :           return Expression::make_cast(res_type, call, loc);
   13497              :         }
   13498              : 
   13499          457 :       if ((name == "And8" || name == "Or8")
   13500          580 :           && this->args_ != NULL && this->args_->size() == 2)
   13501              :         {
   13502          123 :           Runtime::Function code;
   13503          123 :           if (name == "And8")
   13504              :             code = Runtime::ATOMIC_AND_FETCH_1;
   13505           79 :           else if (name == "Or8")
   13506              :             code = Runtime::ATOMIC_OR_FETCH_1;
   13507              :           else
   13508            0 :             go_unreachable();
   13509          123 :           Expression* a1 = this->args_->at(0);
   13510          123 :           Expression* a2 = this->args_->at(1);
   13511          123 :           Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
   13512          123 :           return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
   13513              :         }
   13514              :     }
   13515       727245 :   else if (package == "internal/abi"
   13516       727245 :            || package == "bootstrap/internal/abi") // for bootstrapping gc
   13517              :     {
   13518           77 :       if (is_method)
   13519              :         return NULL;
   13520              : 
   13521           71 :       if ((name == "FuncPCABI0" || name == "FuncPCABIInternal")
   13522           77 :           && this->args_ != NULL
   13523          154 :           && this->args_->size() == 1)
   13524              :         {
   13525              :           // We expect to see a conversion from the expression to "any".
   13526           77 :           Expression* expr = this->args_->front();
   13527           77 :           Type_conversion_expression* tce = expr->conversion_expression();
   13528           75 :           if (tce != NULL)
   13529           75 :             expr = tce->expr();
   13530           77 :           Func_expression* fe = expr->func_expression();
   13531           77 :           Interface_field_reference_expression* interface_method =
   13532           77 :             expr->interface_field_reference_expression();
   13533           77 :           if (fe != NULL)
   13534              :             {
   13535           75 :               Named_object* no = fe->named_object();
   13536           75 :               Expression* ref = Expression::make_func_code_reference(no, loc);
   13537           75 :               Type* uintptr_type = Type::lookup_integer_type("uintptr");
   13538           75 :               return Expression::make_cast(uintptr_type, ref, loc);
   13539              :             }
   13540            2 :           else if (interface_method != NULL)
   13541            0 :             return interface_method->get_function();
   13542              :           else
   13543              :             {
   13544            2 :               expr = this->args_->front();
   13545            6 :               go_assert(expr->type()->interface_type() != NULL
   13546              :                         && expr->type()->interface_type()->is_empty());
   13547            2 :               expr = Expression::make_interface_info(expr,
   13548              :                                                      INTERFACE_INFO_OBJECT,
   13549              :                                                      loc);
   13550              :               // Trust that this is a function type, which means that
   13551              :               // it is a direct iface type and we can use EXPR
   13552              :               // directly.  The backend representation of this
   13553              :               // function is a pointer to a struct whose first field
   13554              :               // is the actual function to call.
   13555            2 :               Type* pvoid = Type::make_pointer_type(Type::make_void_type());
   13556            2 :               Type* pfntype = Type::make_pointer_type(pvoid);
   13557            2 :               Expression* ref = make_unsafe_cast(pfntype, expr, loc);
   13558            2 :               return Expression::make_dereference(ref, NIL_CHECK_NOT_NEEDED,
   13559            2 :                                                   loc);
   13560              :             }
   13561              :         }
   13562              :     }
   13563              : 
   13564              :   return NULL;
   13565       820603 : }
   13566              : 
   13567              : // Make implicit type conversions explicit.
   13568              : 
   13569              : void
   13570       834516 : Call_expression::do_add_conversions()
   13571              : {
   13572              :   // Skip call that requires a thunk. We generate conversions inside the thunk.
   13573       834516 :   if (this->is_concurrent_ || this->is_deferred_)
   13574       304608 :     return;
   13575              : 
   13576       820773 :   if (this->args_ == NULL || this->args_->empty())
   13577              :     return;
   13578              : 
   13579       760824 :   Function_type* fntype = this->get_function_type();
   13580       760824 :   if (fntype == NULL)
   13581              :     {
   13582            0 :       go_assert(saw_errors());
   13583              :       return;
   13584              :     }
   13585       760824 :   if (fntype->parameters() == NULL || fntype->parameters()->empty())
   13586              :     return;
   13587              : 
   13588       529908 :   Location loc = this->location();
   13589       529908 :   Expression_list::iterator pa = this->args_->begin();
   13590       529908 :   Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
   13591       529908 :   bool is_interface_method =
   13592       529908 :     this->fn_->interface_field_reference_expression() != NULL;
   13593       529908 :   size_t argcount = this->args_->size();
   13594       529908 :   if (!is_interface_method && fntype->is_method())
   13595              :     {
   13596              :       // Skip the receiver argument, which cannot be interface.
   13597       155666 :       pa++;
   13598       155666 :       argcount--;
   13599              :     }
   13600       529908 :   if (argcount != fntype->parameters()->size())
   13601              :     {
   13602            0 :       go_assert(saw_errors());
   13603              :       return;
   13604              :     }
   13605      1522980 :   for (; pa != this->args_->end(); ++pa, ++pp)
   13606              :     {
   13607       993072 :       Type* pt = pp->type();
   13608       993072 :       if (!Type::are_identical(pt, (*pa)->type(), 0, NULL)
   13609      1068791 :           && pt->interface_type() != NULL)
   13610        59595 :         *pa = Expression::make_cast(pt, *pa, loc);
   13611              :     }
   13612              : }
   13613              : 
   13614              : // Get the function type.  This can return NULL in error cases.
   13615              : 
   13616              : Function_type*
   13617     24775571 : Call_expression::get_function_type() const
   13618              : {
   13619     24775571 :   return this->fn_->type()->function_type();
   13620              : }
   13621              : 
   13622              : // Return the number of values which this call will return.
   13623              : 
   13624              : size_t
   13625      2920417 : Call_expression::result_count() const
   13626              : {
   13627      2920417 :   const Function_type* fntype = this->get_function_type();
   13628      2920417 :   if (fntype == NULL)
   13629              :     return 0;
   13630      2908353 :   if (fntype->results() == NULL)
   13631              :     return 0;
   13632      2331939 :   return fntype->results()->size();
   13633              : }
   13634              : 
   13635              : // Return the temporary that holds the result for a call with multiple
   13636              : // results.
   13637              : 
   13638              : Temporary_statement*
   13639       167662 : Call_expression::results() const
   13640              : {
   13641       167662 :   if (this->call_temp_ == NULL)
   13642              :     {
   13643            0 :       go_assert(saw_errors());
   13644              :       return NULL;
   13645              :     }
   13646              :   return this->call_temp_;
   13647              : }
   13648              : 
   13649              : // Set the number of results expected from a call expression.
   13650              : 
   13651              : void
   13652        64962 : Call_expression::set_expected_result_count(size_t count)
   13653              : {
   13654        64962 :   go_assert(this->expected_result_count_ == 0);
   13655        64962 :   go_assert(!this->types_are_determined_);
   13656        64962 :   this->expected_result_count_ = count;
   13657        64962 : }
   13658              : 
   13659              : // Return whether this is a call to the predeclared function recover.
   13660              : 
   13661              : bool
   13662        16490 : Call_expression::is_recover_call() const
   13663              : {
   13664        16490 :   return this->do_is_recover_call();
   13665              : }
   13666              : 
   13667              : // Set the argument to the recover function.
   13668              : 
   13669              : void
   13670          857 : Call_expression::set_recover_arg(Expression* arg)
   13671              : {
   13672          857 :   this->do_set_recover_arg(arg);
   13673          857 : }
   13674              : 
   13675              : // Virtual functions also implemented by Builtin_call_expression.
   13676              : 
   13677              : bool
   13678        14910 : Call_expression::do_is_recover_call() const
   13679              : {
   13680        14910 :   return false;
   13681              : }
   13682              : 
   13683              : void
   13684            0 : Call_expression::do_set_recover_arg(Expression*)
   13685              : {
   13686            0 :   go_unreachable();
   13687              : }
   13688              : 
   13689              : // We have found an error with this call expression; return true if
   13690              : // we should report it.
   13691              : 
   13692              : bool
   13693            9 : Call_expression::issue_error()
   13694              : {
   13695            9 :   if (this->issued_error_)
   13696              :     return false;
   13697              :   else
   13698              :     {
   13699            5 :       this->issued_error_ = true;
   13700            5 :       return true;
   13701              :     }
   13702              : }
   13703              : 
   13704              : // Whether or not this call contains errors, either in the call or the
   13705              : // arguments to the call.
   13706              : 
   13707              : bool
   13708      1204008 : Call_expression::is_erroneous_call()
   13709              : {
   13710      1204008 :   if (this->is_error_expression() || this->fn()->is_error_expression())
   13711              :     return true;
   13712              : 
   13713      1204007 :   if (this->args() == NULL)
   13714              :     return false;
   13715      3457485 :   for (Expression_list::iterator pa = this->args()->begin();
   13716      3457485 :        pa != this->args()->end();
   13717      2315560 :        ++pa)
   13718              :     {
   13719      2318797 :       if ((*pa)->type()->is_error_type() || (*pa)->is_error_expression())
   13720         3238 :         return true;
   13721              :     }
   13722              :   return false;
   13723              : }
   13724              : 
   13725              : // Get the type.
   13726              : 
   13727              : Type*
   13728      6213156 : Call_expression::do_type()
   13729              : {
   13730      6213156 :   if (this->is_error_expression())
   13731           36 :     return Type::make_error_type();
   13732      6213120 :   if (this->lowered_ != NULL)
   13733       140189 :     return this->lowered_->type();
   13734      6072931 :   go_assert(this->type_ != NULL);
   13735              :   return this->type_;
   13736              : }
   13737              : 
   13738              : // Determine types for a call expression.  We can use the function
   13739              : // parameter types to set the types of the arguments.  We simplify
   13740              : // some of the call cases here, storing the result in the lowered_
   13741              : // field.
   13742              : 
   13743              : void
   13744      2243966 : Call_expression::do_determine_type(Gogo* gogo, const Type_context* context)
   13745              : {
   13746      2243966 :   if (!this->determining_types())
   13747      2243966 :     return;
   13748              : 
   13749      1730105 :   if (this->lowered_== NULL)
   13750              :     {
   13751      1730105 :       Expression* builtin = this->lower_builtin(gogo);
   13752      1730105 :       if (builtin != this)
   13753        75182 :         this->lowered_ = builtin;
   13754              :     }
   13755              : 
   13756      1730105 :   if (this->lowered_ != NULL)
   13757              :     {
   13758        75182 :       this->lowered_->determine_type(gogo, context);
   13759        75182 :       return;
   13760              :     }
   13761              : 
   13762      1654923 :   this->fn_->determine_type_no_context(gogo);
   13763              : 
   13764              :   // Simplify a type conversion.
   13765              : 
   13766      1654923 :   if (this->fn_->is_type_expression()
   13767        89712 :       && this->args_ != NULL
   13768        89712 :       && this->args_->size() == 1
   13769      1744635 :       && (this->expected_result_count_ == 0
   13770              :           || this->expected_result_count_ == 1))
   13771              :     {
   13772        89712 :       this->lowered_ = Expression::make_cast(this->fn_->type(),
   13773        89712 :                                              this->args_->front(),
   13774              :                                              this->location());
   13775        89712 :       this->lowered_->determine_type(gogo, context);
   13776        89712 :       return;
   13777              :     }
   13778              : 
   13779              :   // Get the type of the function we are calling.
   13780              : 
   13781      1565211 :   Function_type* fntype = this->get_function_type();
   13782      1565211 :   if (fntype == NULL)
   13783              :     {
   13784              :       // We report the error here so that we can reasonably return an
   13785              :       // error type in do_type.
   13786           56 :       if (!this->fn_->type()->is_error())
   13787            5 :         this->report_error(_("expected function"));
   13788              :       else
   13789           51 :         this->set_is_error();
   13790           56 :       if (this->args_ != NULL)
   13791              :         {
   13792           34 :           for (Expression_list::iterator p = this->args_->begin();
   13793           34 :                p != this->args_->end();
   13794           18 :                ++p)
   13795           18 :             (*p)->determine_type_no_context(gogo);
   13796              :         }
   13797           56 :       return;
   13798              :     }
   13799              : 
   13800              :   // Simplify f(g()) where g() returns multiple results.
   13801              : 
   13802      1565155 :   this->simplify_multiple_results(gogo);
   13803              : 
   13804              :   // Set the type of this expression.
   13805              : 
   13806      1565155 :   go_assert(this->type_ == NULL);
   13807      1565155 :   const Typed_identifier_list* results = fntype->results();
   13808      1565155 :   if (results == NULL || results->empty())
   13809       889677 :     this->type_ = Type::make_void_type();
   13810       675478 :   else if (results->size() == 1)
   13811              :     {
   13812              :       // If this is a call to a generated equality function, we
   13813              :       // determine the type based on the context.  See the comment in
   13814              :       // Binary_expression::lower_array_comparison.
   13815       582084 :       if (this->is_equal_function_
   13816          961 :           && !context->may_be_abstract
   13817          961 :           && context->type != NULL
   13818       582084 :           && context->type->is_boolean_type())
   13819            0 :         this->type_ = context->type;
   13820              :       else
   13821       582084 :         this->type_ = results->begin()->type();
   13822              :     }
   13823              :   else
   13824        93394 :     this->type_ = Type::make_call_multiple_result_type();
   13825              : 
   13826              :   // Determine the types of the arguments.
   13827              : 
   13828      1565155 :   if (this->args_ == NULL)
   13829              :     {
   13830       165646 :       if (fntype->is_varargs())
   13831              :         {
   13832          193 :           if (!this->rewrite_varargs())
   13833            0 :             this->set_is_error();
   13834              :         }
   13835       165646 :       return;
   13836              :     }
   13837              : 
   13838      1399509 :   const Typed_identifier_list* parameters = fntype->parameters();
   13839      1399509 :   Typed_identifier_list::const_iterator pt;
   13840      1399509 :   if (parameters != NULL)
   13841      1236667 :     pt = parameters->begin();
   13842      1399509 :   bool first = true;
   13843      4174810 :   for (Expression_list::const_iterator pa = this->args_->begin();
   13844      4174810 :        pa != this->args_->end();
   13845      2775301 :        ++pa)
   13846              :     {
   13847      2775301 :       if (first)
   13848              :         {
   13849      1236667 :           first = false;
   13850              :           // If this is a method, the first argument is the
   13851              :           // receiver.
   13852      1236667 :           if (fntype != NULL && fntype->is_method())
   13853              :             {
   13854            0 :               Type* rtype = fntype->receiver()->type();
   13855              :               // The receiver is always passed as a pointer.
   13856            0 :               if (rtype->points_to() == NULL)
   13857            0 :                 rtype = Type::make_pointer_type(rtype);
   13858            0 :               Type_context subcontext(rtype, false);
   13859            0 :               (*pa)->determine_type(gogo, &subcontext);
   13860            0 :               continue;
   13861            0 :             }
   13862              :         }
   13863              : 
   13864      2770686 :       if ((this->is_varargs_ || this->varargs_are_lowered_)
   13865        27434 :           && fntype->is_varargs()
   13866         4632 :           && pa + 1 == this->args_->end()
   13867         2308 :           && parameters != NULL
   13868      2777609 :           && pt + 1 == parameters->end())
   13869              :         {
   13870         2308 :           Type_context subcontext(pt->type(), false);
   13871         2308 :           (*pa)->determine_type(gogo, &subcontext);
   13872         2308 :           continue;
   13873         2308 :         }
   13874              : 
   13875      2772993 :       if (!this->is_varargs_
   13876      2770670 :           && fntype->is_varargs()
   13877       177215 :           && parameters != NULL
   13878      2950208 :           && pt + 1 == parameters->end())
   13879              :         {
   13880       114906 :           go_assert(pt->type()->is_slice_type());
   13881       114906 :           Type_context subcontext(pt->type()->array_type()->element_type(),
   13882       229812 :                                   false);
   13883       114906 :           (*pa)->determine_type(gogo, &subcontext);
   13884       114906 :           continue;
   13885       114906 :         }
   13886              : 
   13887      2658087 :       if (parameters != NULL && pt != parameters->end())
   13888              :         {
   13889      2658085 :           Type_context subcontext(pt->type(), false);
   13890      2658085 :           (*pa)->determine_type(gogo, &subcontext);
   13891      2658085 :           if (!fntype->is_varargs() || pt + 1 != parameters->end())
   13892      2658082 :             ++pt;
   13893              :         }
   13894              :       else
   13895            2 :         (*pa)->determine_type_no_context(gogo);
   13896              :     }
   13897              : 
   13898      1399509 :   if (fntype->is_varargs())
   13899              :     {
   13900        72617 :       if (!this->rewrite_varargs())
   13901            6 :         this->set_is_error();
   13902              :     }
   13903              : }
   13904              : 
   13905              : // Called when determining types for a Call_expression.  Return true
   13906              : // if we should go ahead, false if they have already been determined.
   13907              : 
   13908              : bool
   13909      2539481 : Call_expression::determining_types()
   13910              : {
   13911      2539481 :   if (this->types_are_determined_)
   13912              :     return false;
   13913              :   else
   13914              :     {
   13915      1956755 :       this->types_are_determined_ = true;
   13916      1956755 :       return true;
   13917              :     }
   13918              : }
   13919              : 
   13920              : // Simplify f(g()) where g() returns multiple results.  Called by
   13921              : // do_determine_types of both Call_expression and
   13922              : // Builtin_call_expression.
   13923              : 
   13924              : void
   13925      1791805 : Call_expression::simplify_multiple_results(Gogo* gogo)
   13926              : {
   13927      1791805 :   if (this->args_ == NULL || this->args_->size() != 1)
   13928              :     return;
   13929              : 
   13930       489705 :   Call_expression* call = this->args_->front()->call_expression();
   13931        23895 :   if (call == NULL || call->is_builtin())
   13932       467170 :     return;
   13933              : 
   13934        22535 :   call->determine_type_no_context(gogo);
   13935        22535 :   size_t rc = call->result_count();
   13936        22535 :   Function_type* fntype = this->get_function_type();
   13937        22535 :   if (rc > 1
   13938        22535 :       && ((fntype->parameters() != NULL
   13939          288 :            && (fntype->parameters()->size() == rc
   13940           16 :                || (fntype->is_varargs()
   13941           16 :                    && fntype->parameters()->size() - 1 <= rc)))
   13942           12 :           || fntype->is_builtin()))
   13943              :     {
   13944          300 :       if (this->is_varargs_)
   13945              :         {
   13946            2 :           go_error_at(call->location(),
   13947              :                       "multiple-value argument in single-value context");
   13948            2 :           this->set_is_error();
   13949              :         }
   13950              : 
   13951          300 :       call->set_is_multi_value_arg();
   13952          300 :       Expression_list* args = new Expression_list;
   13953          987 :       for (size_t i = 0; i < rc; ++i)
   13954          687 :         args->push_back(Expression::make_call_result(call, i));
   13955              :       // We can't create a new Call_expression here because this
   13956              :       // one may be referred to by Call_result expressions.
   13957          300 :       this->args_ = args;
   13958              :     }
   13959              : }
   13960              : 
   13961              : // Lower a call to a varargs function by rewriting the value(s) passed
   13962              : // to the varargs argument into a slice.  Called during the
   13963              : // determine_types pass.
   13964              : 
   13965              : bool
   13966        72810 : Call_expression::rewrite_varargs()
   13967              : {
   13968        72810 :   if (this->varargs_are_lowered_)
   13969              :     return true;
   13970        72491 :   this->varargs_are_lowered_ = true;
   13971              : 
   13972        72491 :   Function_type* fntype = this->get_function_type();
   13973              : 
   13974        72491 :   const Typed_identifier_list* parameters = fntype->parameters();
   13975        72491 :   go_assert(parameters != NULL && !parameters->empty());
   13976        72491 :   size_t param_count = parameters->size();
   13977              : 
   13978        72491 :   Type* varargs_type = parameters->back().type();
   13979        72491 :   go_assert(varargs_type->is_slice_type());
   13980              : 
   13981        72491 :   size_t arg_count = this->args_ == NULL ? 0 : this->args_->size();
   13982        72491 :   if (arg_count < param_count - 1)
   13983              :     {
   13984            0 :       if (!this->is_error_expression())
   13985            0 :         this->report_error(_("not enough arguments"));
   13986            0 :       return false;
   13987              :     }
   13988              : 
   13989        72491 :   bool ret = true;
   13990        72491 :   Expression_list* old_args = this->args_;
   13991        72491 :   Expression_list* new_args = new Expression_list();
   13992        72491 :   bool push_empty_arg = false;
   13993        72491 :   if (old_args == NULL || old_args->empty())
   13994              :     {
   13995          193 :       go_assert(param_count == 1);
   13996              :       push_empty_arg = true;
   13997              :     }
   13998              :   else
   13999              :     {
   14000              :       Expression_list::const_iterator pa;
   14001              :       size_t i = 1;
   14002       136625 :       for (pa = old_args->begin(); pa != old_args->end(); ++pa, ++i)
   14003              :         {
   14004       130282 :           if (i == param_count)
   14005              :             break;
   14006        64327 :           new_args->push_back(*pa);
   14007              :         }
   14008              : 
   14009              :       // We have reached the varargs parameter.
   14010              : 
   14011        72298 :       if (pa == old_args->end())
   14012              :         push_empty_arg = true;
   14013        65955 :       else if (pa + 1 == old_args->end() && this->is_varargs_)
   14014         1987 :         new_args->push_back(*pa);
   14015        63968 :       else if (this->is_varargs_)
   14016              :         {
   14017            2 :           if (!this->is_error_expression())
   14018              :             {
   14019            1 :               if ((*pa)->type()->is_slice_type())
   14020            1 :                 this->report_error(_("too many arguments"));
   14021              :               else
   14022              :                 {
   14023            0 :                   go_error_at(this->location(),
   14024              :                               "invalid use of %<...%> with non-slice");
   14025            0 :                   this->set_is_error();
   14026              :                 }
   14027              :             }
   14028            2 :           return false;
   14029              :         }
   14030              :       else
   14031              :         {
   14032       127932 :           Type* element_type = varargs_type->array_type()->element_type();
   14033        63966 :           Expression_list* vals = new Expression_list;
   14034       178872 :           for (; pa != old_args->end(); ++pa, ++i)
   14035              :             {
   14036       114906 :               Type* patype = (*pa)->type();
   14037       114906 :               Location paloc = (*pa)->location();
   14038       114906 :               if (!this->check_argument_type(i, element_type, patype, paloc))
   14039              :                 {
   14040            4 :                   ret = false;
   14041            4 :                   continue;
   14042              :                 }
   14043       114902 :               vals->push_back(*pa);
   14044              :             }
   14045        63966 :           Expression* val =
   14046        63966 :             Expression::make_slice_composite_literal(varargs_type, vals,
   14047              :                                                      this->location());
   14048        63966 :           new_args->push_back(val);
   14049              :         }
   14050              :     }
   14051              : 
   14052        65953 :   if (push_empty_arg)
   14053         6536 :     new_args->push_back(Expression::make_nil(this->location()));
   14054              : 
   14055              :   // We can't create a new Call_expression here because this
   14056              :   // one may be referred to by Call_result expressions.
   14057        72489 :   this->args_ = new_args;
   14058              : 
   14059        72489 :   return ret;
   14060              : }
   14061              : 
   14062              : // Check types for parameter I.
   14063              : 
   14064              : bool
   14065       975026 : Call_expression::check_argument_type(int i, const Type* parameter_type,
   14066              :                                      const Type* argument_type,
   14067              :                                      Location argument_location)
   14068              : {
   14069       975026 :   std::string reason;
   14070       975026 :   if (!Type::are_assignable(parameter_type, argument_type, &reason))
   14071              :     {
   14072           27 :       if (reason.empty())
   14073            0 :         go_error_at(argument_location, "argument %d has incompatible type", i);
   14074              :       else
   14075           27 :         go_error_at(argument_location,
   14076              :                     "argument %d has incompatible type (%s)",
   14077              :                     i, reason.c_str());
   14078           27 :       this->set_is_error();
   14079           27 :       return false;
   14080              :     }
   14081              :   return true;
   14082       975026 : }
   14083              : 
   14084              : // Check types.
   14085              : 
   14086              : void
   14087       723626 : Call_expression::do_check_types(Gogo*)
   14088              : {
   14089       723626 :   if (this->is_error_expression()
   14090       723561 :       || this->fn_->is_error_expression()
   14091      1447187 :       || this->fn_->type()->is_error())
   14092           66 :     return;
   14093       723560 :   if (this->lowered_ != NULL)
   14094              :     return;
   14095              : 
   14096       633878 :   Function_type* fntype = this->get_function_type();
   14097       633878 :   go_assert(fntype != NULL);
   14098              : 
   14099       633878 :   if (this->expected_result_count_ != 0
   14100       633878 :       && this->expected_result_count_ != this->result_count())
   14101              :     {
   14102            5 :       if (this->issue_error())
   14103            3 :         this->report_error(_("function result count mismatch"));
   14104            5 :       this->set_is_error();
   14105            5 :       return;
   14106              :     }
   14107              : 
   14108       633873 :   if (this->is_varargs_ && !fntype->is_varargs())
   14109              :     {
   14110            1 :       go_error_at(this->location(),
   14111              :                   "invalid use of %<...%> calling non-variadic function");
   14112            1 :       this->set_is_error();
   14113            1 :       return;
   14114              :     }
   14115              : 
   14116       633872 :   bool is_method = fntype->is_method();
   14117       633872 :   if (is_method)
   14118              :     {
   14119         1987 :       go_assert(this->args_ != NULL && !this->args_->empty());
   14120         1987 :       Type* rtype = fntype->receiver()->type();
   14121         1987 :       Expression* first_arg = this->args_->front();
   14122              :       // We dereference the values since receivers are always passed
   14123              :       // as pointers.
   14124         1987 :       std::string reason;
   14125         5961 :       if (!Type::are_assignable(rtype->deref(), first_arg->type()->deref(),
   14126              :                                 &reason))
   14127              :         {
   14128            0 :           if (reason.empty())
   14129            0 :             this->report_error(_("incompatible type for receiver"));
   14130              :           else
   14131              :             {
   14132            0 :               go_error_at(this->location(),
   14133              :                           "incompatible type for receiver (%s)",
   14134              :                           reason.c_str());
   14135            0 :               this->set_is_error();
   14136              :             }
   14137              :         }
   14138         1987 :     }
   14139              : 
   14140       633872 :   const Typed_identifier_list* parameters = fntype->parameters();
   14141       633872 :   if (this->args_ == NULL || this->args_->empty())
   14142              :     {
   14143       158039 :       if (parameters != NULL && !parameters->empty())
   14144            9 :         this->report_error(_("not enough arguments"));
   14145              :     }
   14146       475833 :   else if (parameters == NULL)
   14147              :     {
   14148         1170 :       if (!is_method || this->args_->size() > 1)
   14149            0 :         this->report_error(_("too many arguments"));
   14150              :     }
   14151       474663 :   else if (this->args_->size() == 1
   14152       243598 :            && this->args_->front()->call_expression() != NULL
   14153       494584 :            && this->args_->front()->call_expression()->result_count() > 1)
   14154              :     {
   14155              :       // This is F(G()) when G returns more than one result.  If the
   14156              :       // results can be matched to parameters, it would have been
   14157              :       // rewritten in determine_types.  If we get here we know there
   14158              :       // is a mismatch.
   14159            0 :       if (this->args_->front()->call_expression()->result_count()
   14160            0 :           < parameters->size())
   14161            0 :         this->report_error(_("not enough arguments"));
   14162              :       else
   14163            0 :         this->report_error(_("too many arguments"));
   14164              :     }
   14165              :   else
   14166              :     {
   14167       474663 :       int i = 0;
   14168       474663 :       Expression_list::const_iterator pa = this->args_->begin();
   14169       474663 :       if (is_method)
   14170          817 :         ++pa;
   14171       474663 :       for (Typed_identifier_list::const_iterator pt = parameters->begin();
   14172      1334783 :            pt != parameters->end();
   14173       860120 :            ++pt, ++pa, ++i)
   14174              :         {
   14175       860121 :           if (pa == this->args_->end())
   14176              :             {
   14177            1 :               this->report_error(_("not enough arguments"));
   14178            1 :               return;
   14179              :             }
   14180       860120 :           this->check_argument_type(i + 1, pt->type(), (*pa)->type(),
   14181       860120 :                                     (*pa)->location());
   14182              :         }
   14183       474662 :       if (pa != this->args_->end())
   14184            2 :         this->report_error(_("too many arguments"));
   14185              :     }
   14186              : }
   14187              : 
   14188              : Expression*
   14189           11 : Call_expression::do_copy()
   14190              : {
   14191           11 :   Call_expression* call =
   14192           22 :     Expression::make_call(this->fn_->copy(),
   14193           11 :                           (this->args_ == NULL
   14194              :                            ? NULL
   14195           11 :                            : this->args_->copy()),
   14196           11 :                           this->is_varargs_, this->location());
   14197              : 
   14198           11 :   if (this->varargs_are_lowered_)
   14199            0 :     call->set_varargs_are_lowered();
   14200           11 :   if (this->is_deferred_)
   14201            0 :     call->set_is_deferred();
   14202           11 :   if (this->is_concurrent_)
   14203            0 :     call->set_is_concurrent();
   14204           11 :   return call;
   14205              : }
   14206              : 
   14207              : // Return whether we have to use a temporary variable to ensure that
   14208              : // we evaluate this call expression in order.  If the call returns no
   14209              : // results then it will inevitably be executed last.
   14210              : 
   14211              : bool
   14212       974114 : Call_expression::do_must_eval_in_order() const
   14213              : {
   14214       974114 :   return this->result_count() > 0;
   14215              : }
   14216              : 
   14217              : // Get the function and the first argument to use when calling an
   14218              : // interface method.
   14219              : 
   14220              : Expression*
   14221        31774 : Call_expression::interface_method_function(
   14222              :     Interface_field_reference_expression* interface_method,
   14223              :     Expression** first_arg_ptr,
   14224              :     Location location)
   14225              : {
   14226        31774 :   Expression* object = interface_method->get_underlying_object();
   14227        31774 :   Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
   14228        63548 :   *first_arg_ptr =
   14229        31774 :       Expression::make_unsafe_cast(unsafe_ptr_type, object, location);
   14230        31774 :   return interface_method->get_function();
   14231              : }
   14232              : 
   14233              : // Build the call expression.
   14234              : 
   14235              : Bexpression*
   14236      1754598 : Call_expression::do_get_backend(Translate_context* context)
   14237              : {
   14238      1754598 :   Location location = this->location();
   14239              : 
   14240      1754598 :   if (this->call_ != NULL)
   14241              :     {
   14242              :       // If the call returns multiple results, make a new reference to
   14243              :       // the temporary.
   14244           95 :       if (this->call_temp_ != NULL)
   14245              :         {
   14246           95 :           Expression* ref =
   14247           95 :             Expression::make_temporary_reference(this->call_temp_, location);
   14248           95 :           return ref->get_backend(context);
   14249              :         }
   14250              : 
   14251              :       return this->call_;
   14252              :     }
   14253              : 
   14254      1754503 :   Function_type* fntype = this->get_function_type();
   14255      1754503 :   if (fntype == NULL)
   14256            0 :     return context->backend()->error_expression();
   14257              : 
   14258      1754503 :   if (this->fn_->is_error_expression())
   14259            0 :     return context->backend()->error_expression();
   14260              : 
   14261      1754503 :   Gogo* gogo = context->gogo();
   14262              : 
   14263      1754503 :   Func_expression* func = this->fn_->func_expression();
   14264      1754503 :   Interface_field_reference_expression* interface_method =
   14265      1754503 :     this->fn_->interface_field_reference_expression();
   14266      1754503 :   const bool has_closure = func != NULL && func->closure() != NULL;
   14267      3454044 :   const bool is_interface_method = interface_method != NULL;
   14268              : 
   14269      1753810 :   bool has_closure_arg;
   14270      1753810 :   if (has_closure)
   14271              :     has_closure_arg = true;
   14272      1753810 :   else if (func != NULL)
   14273              :     has_closure_arg = false;
   14274        54269 :   else if (is_interface_method)
   14275              :     has_closure_arg = false;
   14276              :   else
   14277              :     has_closure_arg = true;
   14278              : 
   14279      1722729 :   Expression* first_arg = NULL;
   14280      1722729 :   if (!is_interface_method && fntype->is_method())
   14281              :     {
   14282       256652 :       first_arg = this->args_->front();
   14283       256652 :       if (first_arg->type()->points_to() == NULL
   14284       261195 :           && first_arg->type()->is_direct_iface_type())
   14285         4543 :         first_arg = Expression::unpack_direct_iface(first_arg,
   14286              :                                                     first_arg->location());
   14287              :     }
   14288              : 
   14289      1754503 :   int nargs;
   14290      1754503 :   std::vector<Bexpression*> fn_args;
   14291      1754503 :   if (this->args_ == NULL || this->args_->empty())
   14292              :     {
   14293       215243 :       nargs = is_interface_method ? 1 : 0;
   14294        19932 :       if (nargs > 0)
   14295        19932 :         fn_args.resize(1);
   14296              :     }
   14297      1539260 :   else if (fntype->parameters() == NULL || fntype->parameters()->empty())
   14298              :     {
   14299              :       // Passing a receiver parameter.
   14300       101195 :       go_assert(!is_interface_method
   14301              :                 && fntype->is_method()
   14302              :                 && this->args_->size() == 1);
   14303       101195 :       nargs = 1;
   14304       101195 :       fn_args.resize(1);
   14305       101195 :       fn_args[0] = first_arg->get_backend(context);
   14306              :     }
   14307              :   else
   14308              :     {
   14309      1438065 :       const Typed_identifier_list* params = fntype->parameters();
   14310              : 
   14311      1438065 :       nargs = this->args_->size();
   14312      1438065 :       int i = is_interface_method ? 1 : 0;
   14313      1438065 :       nargs += i;
   14314      1438065 :       fn_args.resize(nargs);
   14315              : 
   14316      1438065 :       Typed_identifier_list::const_iterator pp = params->begin();
   14317      1438065 :       Expression_list::const_iterator pe = this->args_->begin();
   14318      1438065 :       if (!is_interface_method && fntype->is_method())
   14319              :         {
   14320       155457 :           fn_args[i] = first_arg->get_backend(context);
   14321       155457 :           ++pe;
   14322       155457 :           ++i;
   14323              :         }
   14324      4360716 :       for (; pe != this->args_->end(); ++pe, ++pp, ++i)
   14325              :         {
   14326      2922651 :           go_assert(pp != params->end());
   14327      2922651 :           Expression* arg =
   14328      2922651 :               Expression::convert_for_assignment(gogo, pp->type(), *pe,
   14329              :                                                  location);
   14330      2922651 :           fn_args[i] = arg->get_backend(context);
   14331              :         }
   14332      1438065 :       go_assert(pp == params->end());
   14333      1438065 :       go_assert(i == nargs);
   14334              :     }
   14335              : 
   14336      1754503 :   Expression* fn;
   14337      1754503 :   Expression* closure = NULL;
   14338      1754503 :   if (func != NULL)
   14339              :     {
   14340      1700234 :       Named_object* no = func->named_object();
   14341      1700234 :       fn = Expression::make_func_code_reference(no, location);
   14342      1700234 :       if (has_closure)
   14343          693 :         closure = func->closure();
   14344              :     }
   14345        54269 :   else if (!is_interface_method)
   14346              :     {
   14347        22495 :       closure = this->fn_;
   14348              : 
   14349              :       // The backend representation of this function type is a pointer
   14350              :       // to a struct whose first field is the actual function to call.
   14351        22495 :       Type* pfntype =
   14352        22495 :           Type::make_pointer_type(
   14353        22495 :               Type::make_pointer_type(Type::make_void_type()));
   14354        22495 :       fn = Expression::make_unsafe_cast(pfntype, this->fn_, location);
   14355        22495 :       fn = Expression::make_dereference(fn, NIL_CHECK_NOT_NEEDED, location);
   14356              :     }
   14357              :   else
   14358              :     {
   14359        31774 :       Expression* arg0;
   14360        31774 :       fn = this->interface_method_function(interface_method, &arg0,
   14361              :                                            location);
   14362        31774 :       fn_args[0] = arg0->get_backend(context);
   14363              :     }
   14364              : 
   14365      1754503 :   Bexpression* bclosure = NULL;
   14366      1754503 :   if (has_closure_arg)
   14367        23188 :     bclosure = closure->get_backend(context);
   14368              :   else
   14369      1731315 :     go_assert(closure == NULL);
   14370              : 
   14371      1754503 :   Bexpression* bfn = fn->get_backend(context);
   14372              : 
   14373              :   // When not calling a named function directly, use a type conversion
   14374              :   // in case the type of the function is a recursive type which refers
   14375              :   // to itself.  We don't do this for an interface method because 1)
   14376              :   // an interface method never refers to itself, so we always have a
   14377              :   // function type here; 2) we pass an extra first argument to an
   14378              :   // interface method, so fntype is not correct.
   14379      1754503 :   if (func == NULL && !is_interface_method)
   14380              :     {
   14381        22495 :       Btype* bft = fntype->get_backend_fntype(gogo);
   14382        22495 :       bfn = gogo->backend()->convert_expression(bft, bfn, location);
   14383              :     }
   14384              : 
   14385      1754503 :   Bfunction* bfunction = NULL;
   14386      1754503 :   if (context->function())
   14387      1750503 :     bfunction = context->function()->func_value()->get_decl();
   14388      1754503 :   Bexpression* call = gogo->backend()->call_expression(bfunction, bfn,
   14389              :                                                        fn_args, bclosure,
   14390              :                                                        location);
   14391              : 
   14392      1754503 :   if (this->call_temp_ != NULL)
   14393              :     {
   14394              :       // This case occurs when the call returns multiple results.
   14395              : 
   14396        92971 :       Expression* ref = Expression::make_temporary_reference(this->call_temp_,
   14397              :                                                              location);
   14398        92971 :       Bexpression* bref = ref->get_backend(context);
   14399        92971 :       Bstatement* bassn = gogo->backend()->assignment_statement(bfunction,
   14400              :                                                                 bref, call,
   14401              :                                                                 location);
   14402              : 
   14403        92971 :       ref = Expression::make_temporary_reference(this->call_temp_, location);
   14404        92971 :       this->call_ = ref->get_backend(context);
   14405              : 
   14406        92971 :       return gogo->backend()->compound_expression(bassn, this->call_,
   14407        92971 :                                                   location);
   14408              :     }
   14409              : 
   14410      1661532 :   this->call_ = call;
   14411      1661532 :   return this->call_;
   14412      1754503 : }
   14413              : 
   14414              : // The cost of inlining a call expression.
   14415              : 
   14416              : int
   14417       915929 : Call_expression::do_inlining_cost() const
   14418              : {
   14419       915929 :   Func_expression* fn = this->fn_->func_expression();
   14420              : 
   14421              :   // FIXME: We don't yet support all kinds of calls.
   14422       889802 :   if (fn != NULL && fn->closure() != NULL)
   14423              :     return 0x100000;
   14424      1495716 :   if (this->fn_->interface_field_reference_expression())
   14425              :     return 0x100000;
   14426       896176 :   if (this->get_function_type()->is_method())
   14427              :     return 0x100000;
   14428              : 
   14429              :   return 5;
   14430              : }
   14431              : 
   14432              : // Export a call expression.
   14433              : 
   14434              : void
   14435        10850 : Call_expression::do_export(Export_function_body* efb) const
   14436              : {
   14437        10850 :   bool simple_call = (this->fn_->func_expression() != NULL);
   14438          194 :   if (!simple_call)
   14439          194 :     efb->write_c_string("(");
   14440        10850 :   this->fn_->export_expression(efb);
   14441        10850 :   if (!simple_call)
   14442          194 :     efb->write_c_string(")");
   14443        10850 :   this->export_arguments(efb);
   14444        10850 : }
   14445              : 
   14446              : // Export call expression arguments.
   14447              : 
   14448              : void
   14449        15102 : Call_expression::export_arguments(Export_function_body* efb) const
   14450              : {
   14451        15102 :   efb->write_c_string("(");
   14452        15102 :   if (this->args_ != NULL && !this->args_->empty())
   14453              :     {
   14454        12676 :       Expression_list::const_iterator pa = this->args_->begin();
   14455        12676 :       (*pa)->export_expression(efb);
   14456        22352 :       for (pa++; pa != this->args_->end(); pa++)
   14457              :         {
   14458         9676 :           efb->write_c_string(", ");
   14459         9676 :           (*pa)->export_expression(efb);
   14460              :         }
   14461        12676 :       if (this->is_varargs_)
   14462          199 :         efb->write_c_string("...");
   14463              :     }
   14464        15102 :   efb->write_c_string(")");
   14465        15102 : }
   14466              : 
   14467              : // Dump ast representation for a call expression.
   14468              : 
   14469              : void
   14470            0 : Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
   14471              : {
   14472            0 :   this->fn_->dump_expression(ast_dump_context);
   14473            0 :   ast_dump_context->ostream() << "(";
   14474            0 :   if (args_ != NULL)
   14475            0 :     ast_dump_context->dump_expression_list(this->args_);
   14476              : 
   14477            0 :   ast_dump_context->ostream() << ") ";
   14478            0 : }
   14479              : 
   14480              : // Make a call expression.
   14481              : 
   14482              : Call_expression*
   14483      2128957 : Expression::make_call(Expression* fn, Expression_list* args, bool is_varargs,
   14484              :                       Location location)
   14485              : {
   14486      2128957 :   return new Call_expression(fn, args, is_varargs, location);
   14487              : }
   14488              : 
   14489              : // Class Call_result_expression.
   14490              : 
   14491              : // Traverse a call result.
   14492              : 
   14493              : int
   14494      3067286 : Call_result_expression::do_traverse(Traverse* traverse)
   14495              : {
   14496      3067286 :   if (traverse->remember_expression(this->call_))
   14497              :     {
   14498              :       // We have already traversed the call expression.
   14499              :       return TRAVERSE_CONTINUE;
   14500              :     }
   14501      1669260 :   return Expression::traverse(&this->call_, traverse);
   14502              : }
   14503              : 
   14504              : // Get the type.
   14505              : 
   14506              : Type*
   14507      1990403 : Call_result_expression::do_type()
   14508              : {
   14509      1990403 :   if (this->classification() == EXPRESSION_ERROR)
   14510           30 :     return Type::make_error_type();
   14511              : 
   14512              :   // THIS->CALL_ can be replaced with a temporary reference due to
   14513              :   // Call_expression::do_must_eval_in_order when there is an error.
   14514      1990373 :   Call_expression* ce = this->call_->call_expression();
   14515      1990373 :   if (ce == NULL)
   14516              :     {
   14517           12 :       this->set_is_error();
   14518           12 :       return Type::make_error_type();
   14519              :     }
   14520      1990361 :   Function_type* fntype = ce->get_function_type();
   14521      1990361 :   if (fntype == NULL)
   14522              :     {
   14523            0 :       if (ce->issue_error())
   14524              :         {
   14525            0 :           if (!ce->fn()->type()->is_error())
   14526            0 :             this->report_error(_("expected function"));
   14527              :         }
   14528            0 :       this->set_is_error();
   14529            0 :       return Type::make_error_type();
   14530              :     }
   14531      1990361 :   const Typed_identifier_list* results = fntype->results();
   14532      3980722 :   if (results == NULL || results->size() < 2)
   14533              :     {
   14534            4 :       if (ce->issue_error())
   14535            2 :         this->report_error(_("number of results does not match "
   14536              :                              "number of values"));
   14537            4 :       return Type::make_error_type();
   14538              :     }
   14539              :   Typed_identifier_list::const_iterator pr = results->begin();
   14540      3206421 :   for (unsigned int i = 0; i < this->index_; ++i)
   14541              :     {
   14542      1216064 :       if (pr == results->end())
   14543              :         break;
   14544      1216064 :       ++pr;
   14545              :     }
   14546      1990357 :   if (pr == results->end())
   14547              :     {
   14548            0 :       if (ce->issue_error())
   14549            0 :         this->report_error(_("number of results does not match "
   14550              :                              "number of values"));
   14551            0 :       return Type::make_error_type();
   14552              :     }
   14553      1990357 :   return pr->type();
   14554              : }
   14555              : 
   14556              : // Check the type.  Just make sure that we trigger the warning in
   14557              : // do_type.
   14558              : 
   14559              : void
   14560       146270 : Call_result_expression::do_check_types(Gogo*)
   14561              : {
   14562       146270 :   this->type();
   14563       146270 : }
   14564              : 
   14565              : // Determine the type.  We have nothing to do here, but the 0 result
   14566              : // needs to pass down to the caller.
   14567              : 
   14568              : void
   14569       193148 : Call_result_expression::do_determine_type(Gogo* gogo, const Type_context*)
   14570              : {
   14571       193148 :   this->call_->determine_type_no_context(gogo);
   14572       193148 : }
   14573              : 
   14574              : // Return the backend representation.  We just refer to the temporary set by the
   14575              : // call expression.  We don't do this at lowering time because it makes it
   14576              : // hard to evaluate the call at the right time.
   14577              : 
   14578              : Bexpression*
   14579       167662 : Call_result_expression::do_get_backend(Translate_context* context)
   14580              : {
   14581       167662 :   Call_expression* ce = this->call_->call_expression();
   14582       167662 :   if (ce == NULL)
   14583              :     {
   14584            0 :       go_assert(this->call_->is_error_expression());
   14585            0 :       return context->backend()->error_expression();
   14586              :     }
   14587       167662 :   Temporary_statement* ts = ce->results();
   14588       167662 :   if (ts == NULL)
   14589              :     {
   14590            0 :       go_assert(saw_errors());
   14591            0 :       return context->backend()->error_expression();
   14592              :     }
   14593       167662 :   Expression* ref = Expression::make_temporary_reference(ts, this->location());
   14594       167662 :   ref = Expression::make_field_reference(ref, this->index_, this->location());
   14595       167662 :   return ref->get_backend(context);
   14596              : }
   14597              : 
   14598              : // Dump ast representation for a call result expression.
   14599              : 
   14600              : void
   14601            0 : Call_result_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
   14602              :     const
   14603              : {
   14604              :   // FIXME: Wouldn't it be better if the call is assigned to a temporary
   14605              :   // (struct) and the fields are referenced instead.
   14606            0 :   ast_dump_context->ostream() << this->index_ << "@(";
   14607            0 :   ast_dump_context->dump_expression(this->call_);
   14608            0 :   ast_dump_context->ostream() << ")";
   14609            0 : }
   14610              : 
   14611              : // Make a reference to a single result of a call which returns
   14612              : // multiple results.
   14613              : 
   14614              : Expression*
   14615       168017 : Expression::make_call_result(Call_expression* call, unsigned int index)
   14616              : {
   14617       168017 :   return new Call_result_expression(call, index);
   14618              : }
   14619              : 
   14620              : // Class Index_expression.
   14621              : 
   14622              : // Report whether EXPR is a map index expression.  This is called when
   14623              : // types are determined but before lowering.
   14624              : 
   14625              : bool
   14626        34763 : Index_expression::is_map_index(Expression* expr)
   14627              : {
   14628        34763 :   if (expr->map_index_expression() != NULL)
   14629              :     return true;
   14630        34763 :   if (expr->index_expression() != NULL)
   14631        14232 :     return expr->index_expression()->left_->type()->map_type() != NULL;
   14632              :   return false;
   14633              : }
   14634              : 
   14635              : // Traversal.
   14636              : 
   14637              : int
   14638       823151 : Index_expression::do_traverse(Traverse* traverse)
   14639              : {
   14640       823151 :   if (Expression::traverse(&this->left_, traverse) == TRAVERSE_EXIT
   14641       823151 :       || Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT
   14642       823150 :       || (this->end_ != NULL
   14643       238856 :           && Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
   14644      1646301 :       || (this->cap_ != NULL
   14645        19045 :           && Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT))
   14646            1 :     return TRAVERSE_EXIT;
   14647              :   return TRAVERSE_CONTINUE;
   14648              : }
   14649              : 
   14650              : void
   14651       213061 : Index_expression::do_determine_type(Gogo* gogo, const Type_context*)
   14652              : {
   14653       213061 :   this->left_->determine_type_no_context(gogo);
   14654              : 
   14655       213061 :   Type_context end_context;
   14656       213061 :   Type* type = this->left_->type();
   14657       213061 :   if (type->array_type() != NULL
   14658        51651 :       || (type->points_to() != NULL
   14659        51652 :           && type->points_to()->array_type() != NULL
   14660        15822 :           && !type->points_to()->is_slice_type())
   14661        35829 :       || type->is_string_type())
   14662              :     {
   14663       196990 :       Type_context index_context(Type::lookup_integer_type("int"), false);
   14664       196990 :       this->start_->determine_type(gogo, &index_context);
   14665       196990 :       end_context = index_context;
   14666              :     }
   14667        16071 :   else if (type->map_type() != NULL)
   14668              :     {
   14669        32128 :       Type_context key_context(type->map_type()->key_type(), false);
   14670        16064 :       this->start_->determine_type(gogo, &key_context);
   14671              :     }
   14672            7 :   else if (type->is_error())
   14673            1 :     this->set_is_error();
   14674              :   else
   14675              :     {
   14676            6 :       if (this->cap_ != NULL)
   14677            0 :         this->report_error(_("invalid 3-index slice of object "
   14678              :                              "that is not a slice"));
   14679            6 :       else if (this->end_ != NULL)
   14680            5 :         this->report_error(_("attempt to slice object that is not "
   14681              :                              "array, slice, or string"));
   14682              :       else
   14683            1 :         this->report_error(_("attempt to index object that is not "
   14684              :                              "array, slice, string, or map"));
   14685              : 
   14686            6 :       this->start_->determine_type_no_context(gogo);
   14687              :     }
   14688              : 
   14689       213061 :   if (this->end_ != NULL)
   14690        50072 :     this->end_->determine_type(gogo, &end_context);
   14691       213061 :   if (this->cap_ != NULL)
   14692         3824 :     this->cap_->determine_type(gogo, &end_context);
   14693       213061 : }
   14694              : 
   14695              : Type*
   14696       364616 : Index_expression::do_type()
   14697              : {
   14698       364616 :   if (this->is_error_expression())
   14699           10 :     return Type::make_error_type();
   14700              : 
   14701       364606 :   Type* type = this->left_->type();
   14702       364606 :   if (this->end_ != NULL)
   14703              :     {
   14704              :       // A slice of an array is a slice type.  A slice of a slice or
   14705              :       // string type is that same type.
   14706       112050 :       Array_type* at = type->deref()->array_type();
   14707        43426 :       if (at != NULL && !at->is_slice_type())
   14708        16257 :         return Type::make_array_type(at->element_type(), NULL);
   14709        39768 :       return type;
   14710              :     }
   14711       617162 :   if (type->deref()->array_type() != NULL)
   14712       816789 :     return type->deref()->array_type()->element_type();
   14713        36318 :   else if (type->is_string_type())
   14714        14018 :     return Type::lookup_integer_type("byte");
   14715        22300 :   else if (type->map_type() != NULL)
   14716        44600 :     return type->map_type()->val_type();
   14717              :   else
   14718            0 :     return Type::make_error_type();
   14719              : }
   14720              : 
   14721              : void
   14722       157136 : Index_expression::do_check_types(Gogo*)
   14723              : {
   14724       157136 :   if (this->is_error_expression())
   14725              :     return;
   14726              : 
   14727       157129 :   Type* ltype = this->left_->type();
   14728       157129 :   if (ltype->is_error())
   14729              :     {
   14730            0 :       go_assert(saw_errors());
   14731              :       return;
   14732              :     }
   14733              : 
   14734       157129 :   if (this->left_->is_type_expression())
   14735              :     {
   14736            0 :       this->report_error(_("attempt to index type expression"));
   14737            0 :       return;
   14738              :     }
   14739              : 
   14740       157129 :   if (ltype->array_type() != NULL)
   14741              :     {
   14742       110274 :       if (!Array_index_expression::check_indexes(this->left_, this->start_,
   14743              :                                                  this->end_, this->cap_,
   14744              :                                                  this->location()))
   14745         1535 :         this->set_is_error();
   14746              :     }
   14747        46855 :   else if (ltype->points_to() != NULL
   14748        15637 :            && ltype->points_to()->array_type() != NULL
   14749        62492 :            && !ltype->points_to()->is_slice_type())
   14750              :     {
   14751        15637 :       Expression* deref = Expression::make_dereference(this->left_,
   14752              :                                                        NIL_CHECK_DEFAULT,
   14753              :                                                        this->location());
   14754        15637 :       if (!Array_index_expression::check_indexes(deref, this->start_,
   14755              :                                                  this->end_, this->cap_,
   14756              :                                                  this->location()))
   14757          979 :         this->set_is_error();
   14758        15637 :       delete deref;
   14759              :     }
   14760        31218 :   else if (ltype->is_string_type())
   14761              :     {
   14762        17514 :       if (this->cap_ != NULL)
   14763            8 :         this->report_error(_("invalid 3-index slice of string"));
   14764              :       else
   14765              :         {
   14766        17506 :           if (!String_index_expression::check_indexes(this->left_,
   14767              :                                                       this->start_,
   14768              :                                                       this->end_,
   14769              :                                                       this->location()))
   14770           15 :             this->set_is_error();
   14771              :         }
   14772              :     }
   14773        13704 :   else if (ltype->map_type() != NULL)
   14774              :     {
   14775        13704 :       if (this->end_ != NULL || this->cap_ != NULL)
   14776            0 :         this->report_error(_("invalid slice of map"));
   14777              :       else
   14778              :         {
   14779        13704 :           Map_type* mt = ltype->map_type();
   14780        13704 :           std::string reason;
   14781        13704 :           if (!Type::are_assignable(mt->key_type(), this->start_->type(),
   14782              :                                     &reason))
   14783              :             {
   14784            1 :               if (reason.empty())
   14785            0 :                 this->report_error(_("incompatible type for map index"));
   14786              :               else
   14787              :                 {
   14788            1 :                   go_error_at(this->location(),
   14789              :                               "incompatible type for map index (%s)",
   14790              :                               reason.c_str());
   14791            1 :                   this->set_is_error();
   14792              :                 }
   14793              :             }
   14794        13704 :         }
   14795              :     }
   14796              :   else
   14797            0 :     go_unreachable();
   14798              : }
   14799              : 
   14800              : bool
   14801        40649 : Index_expression::do_is_addressable() const
   14802              : {
   14803        40649 :   if (this->is_error_expression())
   14804              :     return true;
   14805              : 
   14806        40649 :   Type* type = this->left_->type();
   14807        40649 :   if (type->is_error())
   14808              :     return true;
   14809              : 
   14810              :   // A slice index is addressable, and an index of an addressable
   14811              :   // array is addressable.
   14812              : 
   14813        40649 :   bool is_pointer = false;
   14814        40649 :   if (type->points_to() != NULL
   14815         3647 :       && type->points_to()->array_type() != NULL
   14816        44296 :       && !type->points_to()->is_slice_type())
   14817              :     {
   14818         3647 :       type = type->points_to();
   14819         3647 :       is_pointer = true;
   14820              :     }
   14821              : 
   14822        46452 :   if (type->array_type() == NULL)
   14823              :     return false;
   14824              : 
   14825        34904 :   if (this->end_ != NULL)
   14826              :     return false;
   14827        34850 :   if (type->is_slice_type())
   14828              :     return true;
   14829        13523 :   return is_pointer || this->left_->is_addressable();
   14830              : }
   14831              : 
   14832              : // We need to do a nil check of any pointer dereference.
   14833              : 
   14834              : void
   14835         4655 : Index_expression::do_issue_nil_check()
   14836              : {
   14837         4655 :   this->left_->issue_nil_check();
   14838         4655 :   this->needs_nil_check_ = true;
   14839         4655 : }
   14840              : 
   14841              : // Lower an index expression.  This converts the generic index
   14842              : // expression into an array index, a string index, or a map index.
   14843              : 
   14844              : Expression*
   14845       189160 : Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
   14846              : {
   14847       189160 :   if (this->is_error_expression())
   14848         2543 :     return Expression::make_error(this->location());
   14849              : 
   14850       186617 :   Location location = this->location();
   14851       186617 :   Expression* left = this->left_;
   14852       186617 :   Expression* start = this->start_;
   14853       186617 :   Expression* end = this->end_;
   14854       186617 :   Expression* cap = this->cap_;
   14855              : 
   14856       186617 :   Type* type = left->type();
   14857       186617 :   if (type->is_error())
   14858              :     {
   14859            1 :       go_assert(saw_errors());
   14860            1 :       return Expression::make_error(location);
   14861              :     }
   14862       186616 :   else if (type->array_type() != NULL)
   14863       138128 :     return Expression::make_array_index(left, start, end, cap, location);
   14864        48488 :   else if (type->points_to() != NULL
   14865        14748 :            && type->points_to()->array_type() != NULL
   14866        63236 :            && !type->points_to()->is_slice_type())
   14867              :     {
   14868        14748 :       Expression* deref =
   14869        14748 :           Expression::make_dereference(left, NIL_CHECK_DEFAULT, location);
   14870              : 
   14871              :       // For an ordinary index into the array, the pointer will be
   14872              :       // dereferenced.  For a slice it will not--the resulting slice
   14873              :       // will simply reuse the pointer, which is incorrect if that
   14874              :       // pointer is nil.  We may also be in a context that requires a
   14875              :       // nil check.
   14876        14748 :       if (end != NULL || cap != NULL || this->needs_nil_check_)
   14877         3964 :         deref->issue_nil_check();
   14878              : 
   14879        14748 :       return Expression::make_array_index(deref, start, end, cap, location);
   14880              :     }
   14881        33740 :   else if (type->is_string_type())
   14882              :     {
   14883        19681 :       go_assert(cap == NULL);
   14884        19681 :       return Expression::make_string_index(left, start, end, location);
   14885              :     }
   14886        14059 :   else if (type->map_type() != NULL)
   14887              :     {
   14888        14059 :       go_assert(end == NULL && cap == NULL);
   14889        14059 :       return Expression::make_map_index(left, start, location);
   14890              :     }
   14891              :   else
   14892            0 :     go_unreachable();
   14893              : }
   14894              : 
   14895              : // Write an indexed expression
   14896              : // (expr[expr:expr:expr], expr[expr:expr] or expr[expr]) to a dump context.
   14897              : 
   14898              : void
   14899            0 : Index_expression::dump_index_expression(Ast_dump_context* ast_dump_context,
   14900              :                                         const Expression* expr,
   14901              :                                         const Expression* start,
   14902              :                                         const Expression* end,
   14903              :                                         const Expression* cap)
   14904              : {
   14905            0 :   expr->dump_expression(ast_dump_context);
   14906            0 :   ast_dump_context->ostream() << "[";
   14907            0 :   start->dump_expression(ast_dump_context);
   14908            0 :   if (end != NULL)
   14909              :     {
   14910            0 :       ast_dump_context->ostream() << ":";
   14911            0 :       end->dump_expression(ast_dump_context);
   14912              :     }
   14913            0 :   if (cap != NULL)
   14914              :     {
   14915            0 :       ast_dump_context->ostream() << ":";
   14916            0 :       cap->dump_expression(ast_dump_context);
   14917              :     }
   14918            0 :   ast_dump_context->ostream() << "]";
   14919            0 : }
   14920              : 
   14921              : // Dump ast representation for an index expression.
   14922              : 
   14923              : void
   14924            0 : Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
   14925              :     const
   14926              : {
   14927            0 :   Index_expression::dump_index_expression(ast_dump_context, this->left_,
   14928            0 :                                           this->start_, this->end_, this->cap_);
   14929            0 : }
   14930              : 
   14931              : // Make an index expression.
   14932              : 
   14933              : Expression*
   14934       181155 : Expression::make_index(Expression* left, Expression* start, Expression* end,
   14935              :                        Expression* cap, Location location)
   14936              : {
   14937       181155 :   return new Index_expression(left, start, end, cap, location);
   14938              : }
   14939              : 
   14940              : // Class Array_index_expression.
   14941              : 
   14942              : // Array index traversal.
   14943              : 
   14944              : int
   14945      2785745 : Array_index_expression::do_traverse(Traverse* traverse)
   14946              : {
   14947      2785745 :   if (Expression::traverse(&this->array_, traverse) == TRAVERSE_EXIT)
   14948              :     return TRAVERSE_EXIT;
   14949      2759773 :   if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
   14950              :     return TRAVERSE_EXIT;
   14951      2756656 :   if (this->end_ != NULL)
   14952              :     {
   14953       629217 :       if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
   14954              :         return TRAVERSE_EXIT;
   14955              :     }
   14956      2756562 :   if (this->cap_ != NULL)
   14957              :     {
   14958        58788 :       if (Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
   14959              :         return TRAVERSE_EXIT;
   14960              :     }
   14961              :   return TRAVERSE_CONTINUE;
   14962              : }
   14963              : 
   14964              : // Return the type of an array index.
   14965              : 
   14966              : Type*
   14967      2601412 : Array_index_expression::do_type()
   14968              : {
   14969      2601412 :   if (this->type_ == NULL)
   14970              :     {
   14971       218694 :      Array_type* type = this->array_->type()->array_type();
   14972       218694 :       if (type == NULL)
   14973            0 :         this->type_ = Type::make_error_type();
   14974       218694 :       else if (this->end_ == NULL)
   14975       166047 :         this->type_ = type->element_type();
   14976        52647 :       else if (type->is_slice_type())
   14977              :         {
   14978              :           // A slice of a slice has the same type as the original
   14979              :           // slice.
   14980        79858 :           this->type_ = this->array_->type()->deref();
   14981              :         }
   14982              :       else
   14983              :         {
   14984              :           // A slice of an array is a slice.
   14985        12718 :           this->type_ = Type::make_array_type(type->element_type(), NULL);
   14986              :         }
   14987              :     }
   14988      2601412 :   return this->type_;
   14989              : }
   14990              : 
   14991              : // Set the type of an array index.
   14992              : 
   14993              : void
   14994       183534 : Array_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
   14995              : {
   14996       183534 :   this->array_->determine_type_no_context(gogo);
   14997              : 
   14998       183534 :   Type_context index_context(Type::lookup_integer_type("int"), false);
   14999       183534 :   this->start_->determine_type(gogo, &index_context);
   15000       183534 :   if (this->end_ != NULL)
   15001        56850 :     this->end_->determine_type(gogo, &index_context);
   15002       183534 :   if (this->cap_ != NULL)
   15003         3342 :     this->cap_->determine_type(gogo, &index_context);
   15004       183534 : }
   15005              : 
   15006              : // Check types of an array index.
   15007              : 
   15008              : void
   15009          551 : Array_index_expression::do_check_types(Gogo*)
   15010              : {
   15011          551 :   if (!Array_index_expression::check_indexes(this->array_, this->start_,
   15012              :                                              this->end_, this->cap_,
   15013              :                                              this->location()))
   15014            0 :     this->set_is_error();
   15015          551 : }
   15016              : 
   15017              : // A static function to check array index types.  This is also called
   15018              : // by Index_expression::do_check_types.  It reports whether type
   15019              : // checking succeeded.
   15020              : 
   15021              : bool
   15022       126462 : Array_index_expression::check_indexes(Expression* array, Expression* start,
   15023              :                                       Expression* end, Expression* cap,
   15024              :                                       Location loc)
   15025              : {
   15026       126462 :   bool ret = true;
   15027              : 
   15028       126462 :   Numeric_constant nc;
   15029       126462 :   unsigned long v;
   15030       126467 :   if (start->type()->integer_type() == NULL
   15031            5 :       && !start->type()->is_error()
   15032            5 :       && (!start->type()->is_abstract()
   15033            0 :           || !start->numeric_constant_value(&nc)
   15034            0 :           || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
   15035              :     {
   15036            5 :       go_error_at(loc, "index must be integer");
   15037            5 :       ret = false;
   15038              :     }
   15039              : 
   15040       126462 :   if (end != NULL
   15041        53125 :       && end->type()->integer_type() == NULL
   15042        15763 :       && !end->type()->is_error()
   15043        15754 :       && !end->is_nil_expression()
   15044            0 :       && !end->is_error_expression()
   15045       126462 :       && (!end->type()->is_abstract()
   15046            0 :           || !end->numeric_constant_value(&nc)
   15047            0 :           || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
   15048              :     {
   15049            0 :       go_error_at(loc, "slice end must be integer");
   15050            0 :       ret = false;
   15051              :     }
   15052              : 
   15053       126462 :   if (cap != NULL
   15054         3809 :       && cap->type()->integer_type() == NULL
   15055            8 :       && !cap->type()->is_error()
   15056            0 :       && !cap->is_nil_expression()
   15057            0 :       && !cap->is_error_expression()
   15058       126462 :       && (!cap->type()->is_abstract()
   15059            0 :           || !cap->numeric_constant_value(&nc)
   15060            0 :           || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
   15061              :     {
   15062            0 :       go_error_at(loc, "slice capacity must be integer");
   15063            0 :       ret = false;
   15064              :     }
   15065              : 
   15066       126462 :   Array_type* array_type = array->type()->array_type();
   15067       126462 :   if (array_type == NULL)
   15068              :     {
   15069            0 :       go_assert(array->type()->is_error());
   15070              :       return false;
   15071              :     }
   15072              : 
   15073       126462 :   unsigned int int_bits =
   15074       252924 :     Type::lookup_integer_type("int")->integer_type()->bits();
   15075              : 
   15076       126462 :   Numeric_constant lvalnc;
   15077       126462 :   mpz_t lval;
   15078       126462 :   bool lval_valid = (array_type->length() != NULL
   15079        51618 :                      && array_type->length()->numeric_constant_value(&lvalnc)
   15080       178080 :                      && lvalnc.to_int(&lval));
   15081       126462 :   Numeric_constant inc;
   15082       126462 :   mpz_t ival;
   15083       126462 :   bool ival_valid = false;
   15084       126462 :   if (start->numeric_constant_value(&inc) && inc.to_int(&ival))
   15085              :     {
   15086        71376 :       ival_valid = true;
   15087       106799 :       if (mpz_sgn(ival) < 0
   15088        70400 :           || mpz_sizeinbase(ival, 2) >= int_bits
   15089        70398 :           || (lval_valid
   15090        24171 :               && (end == NULL
   15091        24171 :                   ? mpz_cmp(ival, lval) >= 0
   15092        11252 :                   : mpz_cmp(ival, lval) > 0)))
   15093              :         {
   15094         1491 :           go_error_at(start->location(), "array index out of bounds");
   15095         1491 :           ret = false;
   15096              :         }
   15097              :     }
   15098              : 
   15099       126462 :   if (end != NULL && !end->is_nil_expression())
   15100              :     {
   15101        21608 :       Numeric_constant enc;
   15102        21608 :       mpz_t eval;
   15103        21608 :       bool eval_valid = false;
   15104        21608 :       if (end->numeric_constant_value(&enc) && enc.to_int(&eval))
   15105              :         {
   15106         7697 :           eval_valid = true;
   15107         7697 :           if (mpz_sgn(eval) < 0
   15108         6723 :               || mpz_sizeinbase(eval, 2) >= int_bits
   15109         6721 :               || (lval_valid && mpz_cmp(eval, lval) > 0))
   15110              :             {
   15111         1489 :               go_error_at(end->location(), "array index out of bounds");
   15112         1489 :               ret = false;
   15113              :             }
   15114         6208 :           else if (ival_valid && mpz_cmp(ival, eval) > 0)
   15115              :             {
   15116           14 :               go_error_at(loc, "inverted slice range");
   15117           14 :               ret = false;
   15118              :             }
   15119              :         }
   15120              : 
   15121        21608 :       Numeric_constant cnc;
   15122        21608 :       mpz_t cval;
   15123        21608 :       if (cap != NULL
   15124        25409 :           && cap->numeric_constant_value(&cnc) && cnc.to_int(&cval))
   15125              :         {
   15126         1201 :           if (mpz_sgn(cval) < 0
   15127         1201 :               || mpz_sizeinbase(cval, 2) >= int_bits
   15128         1201 :               || (lval_valid && mpz_cmp(cval, lval) > 0))
   15129              :             {
   15130            3 :               go_error_at(cap->location(), "array index out of bounds");
   15131            3 :               ret = false;
   15132              :             }
   15133         1198 :           else if (ival_valid && mpz_cmp(ival, cval) > 0)
   15134              :             {
   15135           10 :               go_error_at(cap->location(),
   15136              :                           "invalid slice index: capacity less than start");
   15137           10 :               ret = false;
   15138              :             }
   15139         1188 :           else if (eval_valid && mpz_cmp(eval, cval) > 0)
   15140              :             {
   15141            6 :               go_error_at(cap->location(),
   15142              :                           "invalid slice index: capacity less than length");
   15143            6 :               ret = false;
   15144              :             }
   15145         1201 :           mpz_clear(cval);
   15146              :         }
   15147              : 
   15148        21608 :       if (eval_valid)
   15149         7697 :         mpz_clear(eval);
   15150        21608 :     }
   15151       126462 :   if (ival_valid)
   15152        71376 :     mpz_clear(ival);
   15153       126462 :   if (lval_valid)
   15154        51618 :     mpz_clear(lval);
   15155              : 
   15156              :   // A slice of an array requires an addressable array.  A slice of a
   15157              :   // slice is always possible.
   15158       126462 :   if (end != NULL && !array_type->is_slice_type())
   15159              :     {
   15160        14285 :       if (!array->is_addressable())
   15161              :         {
   15162            4 :           go_error_at(loc, "slice of unaddressable value");
   15163            4 :           ret = false;
   15164              :         }
   15165              :       else
   15166              :         {
   15167              :           // Set the array address taken but not escape. The escape
   15168              :           // analysis will make it escape to heap when needed.
   15169        14281 :           array->address_taken(false);
   15170              :         }
   15171              :     }
   15172              : 
   15173       126462 :   return ret;
   15174       126462 : }
   15175              : 
   15176              : // The subexpressions of an array index must be evaluated in order.
   15177              : // If this is indexing into an array, rather than a slice, then only
   15178              : // the index should be evaluated.  Since this is called for values on
   15179              : // the left hand side of an assigment, evaluating the array, meaning
   15180              : // copying the array, will cause a different array to be modified.
   15181              : 
   15182              : bool
   15183         4166 : Array_index_expression::do_must_eval_subexpressions_in_order(
   15184              :     int* skip) const
   15185              : {
   15186         4166 :   *skip = this->array_->type()->is_slice_type() ? 0 : 1;
   15187         4166 :   return true;
   15188              : }
   15189              : 
   15190              : // Flatten array indexing: add temporary variables and bounds checks.
   15191              : 
   15192              : Expression*
   15193       249462 : Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
   15194              :                                    Statement_inserter* inserter)
   15195              : {
   15196       249462 :   if (this->is_flattened_)
   15197        40350 :     return this;
   15198       209112 :   this->is_flattened_ = true;
   15199              : 
   15200       209112 :   Location loc = this->location();
   15201              : 
   15202       209112 :   if (this->is_error_expression())
   15203            0 :     return Expression::make_error(loc);
   15204              : 
   15205       209112 :   Expression* array = this->array_;
   15206       209112 :   Expression* start = this->start_;
   15207       209112 :   Expression* end = this->end_;
   15208       209112 :   Expression* cap = this->cap_;
   15209       209112 :   if (array->is_error_expression()
   15210       209112 :       || array->type()->is_error_type()
   15211       209112 :       || start->is_error_expression()
   15212       208675 :       || start->type()->is_error_type()
   15213       208675 :       || (end != NULL
   15214       104236 :           && (end->is_error_expression() || end->type()->is_error_type()))
   15215       417491 :       || (cap != NULL
   15216         7536 :           && (cap->is_error_expression() || cap->type()->is_error_type())))
   15217              :     {
   15218          737 :       go_assert(saw_errors());
   15219          737 :       return Expression::make_error(loc);
   15220              :     }
   15221              : 
   15222       208375 :   Array_type* array_type = this->array_->type()->array_type();
   15223       208375 :   if (array_type == NULL)
   15224              :     {
   15225            0 :       go_assert(saw_errors());
   15226            0 :       return Expression::make_error(loc);
   15227              :     }
   15228              : 
   15229       208375 :   Temporary_statement* temp;
   15230       208375 :   if (array_type->is_slice_type() && !array->is_multi_eval_safe())
   15231              :     {
   15232        18925 :       temp = Statement::make_temporary(NULL, array, loc);
   15233        18925 :       inserter->insert(temp);
   15234        18925 :       this->array_ = Expression::make_temporary_reference(temp, loc);
   15235        18925 :       array = this->array_;
   15236              :     }
   15237       208375 :   if (!start->is_multi_eval_safe())
   15238              :     {
   15239        28762 :       temp = Statement::make_temporary(NULL, start, loc);
   15240        28762 :       inserter->insert(temp);
   15241        28762 :       this->start_ = Expression::make_temporary_reference(temp, loc);
   15242        28762 :       start = this->start_;
   15243              :     }
   15244       208375 :   if (end != NULL
   15245        51966 :       && !end->is_nil_expression()
   15246       243893 :       && !end->is_multi_eval_safe())
   15247              :     {
   15248         3946 :       temp = Statement::make_temporary(NULL, end, loc);
   15249         3946 :       inserter->insert(temp);
   15250         3946 :       this->end_ = Expression::make_temporary_reference(temp, loc);
   15251         3946 :       end = this->end_;
   15252              :     }
   15253       208375 :   if (cap != NULL && !cap->is_multi_eval_safe())
   15254              :     {
   15255          328 :       temp = Statement::make_temporary(NULL, cap, loc);
   15256          328 :       inserter->insert(temp);
   15257          328 :       this->cap_ = Expression::make_temporary_reference(temp, loc);
   15258          328 :       cap = this->cap_;
   15259              :     }
   15260              : 
   15261       208375 :   if (!this->needs_bounds_check_)
   15262        33694 :     return this;
   15263              : 
   15264       174681 :   Expression* len;
   15265       174681 :   if (!array_type->is_slice_type())
   15266              :     {
   15267        80221 :       len = array_type->get_length(gogo, this->array_);
   15268        80221 :       go_assert(len->is_constant());
   15269              :     }
   15270              :   else
   15271              :     {
   15272        94460 :       len = array_type->get_length(gogo, this->array_->copy());
   15273        94460 :       temp = Statement::make_temporary(NULL, len, loc);
   15274        94460 :       temp->determine_types(gogo);
   15275        94460 :       inserter->insert(temp);
   15276        94460 :       len = Expression::make_temporary_reference(temp, loc);
   15277              :     }
   15278              : 
   15279       174681 :   Expression* scap = NULL;
   15280       174681 :   if (array_type->is_slice_type())
   15281              :     {
   15282        94460 :       scap = array_type->get_capacity(gogo, this->array_->copy());
   15283        94460 :       temp = Statement::make_temporary(NULL, scap, loc);
   15284        94460 :       temp->determine_types(gogo);
   15285        94460 :       inserter->insert(temp);
   15286        94460 :       scap = Expression::make_temporary_reference(temp, loc);
   15287              :     }
   15288              : 
   15289              :   // The order of bounds checks here matches the order used by the gc
   15290              :   // compiler, as tested by issue30116[u].go.
   15291              : 
   15292       174681 :   if (cap != NULL)
   15293              :     {
   15294         3766 :       if (array_type->is_slice_type())
   15295         2260 :         Expression::check_bounds(gogo, cap, OPERATOR_LE, scap,
   15296              :                                  Runtime::PANIC_SLICE3_ACAP,
   15297              :                                  Runtime::PANIC_SLICE3_ACAP_U,
   15298              :                                  Runtime::PANIC_EXTEND_SLICE3_ACAP,
   15299              :                                  Runtime::PANIC_EXTEND_SLICE3_ACAP_U,
   15300              :                                  inserter, loc);
   15301              :       else
   15302         1506 :         Expression::check_bounds(gogo, cap, OPERATOR_LE, len,
   15303              :                                  Runtime::PANIC_SLICE3_ALEN,
   15304              :                                  Runtime::PANIC_SLICE3_ALEN_U,
   15305              :                                  Runtime::PANIC_EXTEND_SLICE3_ALEN,
   15306              :                                  Runtime::PANIC_EXTEND_SLICE3_ALEN_U,
   15307              :                                  inserter, loc);
   15308              : 
   15309         3766 :       Expression* start_bound = cap;
   15310         3766 :       if (end != NULL && !end->is_nil_expression())
   15311              :         {
   15312         3766 :           Expression::check_bounds(gogo, end, OPERATOR_LE, cap,
   15313              :                                    Runtime::PANIC_SLICE3_B,
   15314              :                                    Runtime::PANIC_SLICE3_B_U,
   15315              :                                    Runtime::PANIC_EXTEND_SLICE3_B,
   15316              :                                    Runtime::PANIC_EXTEND_SLICE3_B_U,
   15317              :                                    inserter, loc);
   15318         3766 :           start_bound = end;
   15319              :         }
   15320              : 
   15321         3766 :       Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
   15322              :                                Runtime::PANIC_SLICE3_C,
   15323              :                                Runtime::PANIC_SLICE3_C_U,
   15324              :                                Runtime::PANIC_EXTEND_SLICE3_C,
   15325              :                                Runtime::PANIC_EXTEND_SLICE3_C_U,
   15326              :                                inserter, loc);
   15327              :     }
   15328       170915 :   else if (end != NULL && !end->is_nil_expression())
   15329              :     {
   15330        16099 :       if (array_type->is_slice_type())
   15331        11950 :         Expression::check_bounds(gogo, end, OPERATOR_LE, scap,
   15332              :                                  Runtime::PANIC_SLICE_ACAP,
   15333              :                                  Runtime::PANIC_SLICE_ACAP_U,
   15334              :                                  Runtime::PANIC_EXTEND_SLICE_ACAP,
   15335              :                                  Runtime::PANIC_EXTEND_SLICE_ACAP_U,
   15336              :                                  inserter, loc);
   15337              :       else
   15338         4149 :         Expression::check_bounds(gogo, end, OPERATOR_LE, len,
   15339              :                                  Runtime::PANIC_SLICE_ALEN,
   15340              :                                  Runtime::PANIC_SLICE_ALEN_U,
   15341              :                                  Runtime::PANIC_EXTEND_SLICE_ALEN,
   15342              :                                  Runtime::PANIC_EXTEND_SLICE_ALEN_U,
   15343              :                                  inserter, loc);
   15344              : 
   15345        16099 :       Expression::check_bounds(gogo, start, OPERATOR_LE, end,
   15346              :                                Runtime::PANIC_SLICE_B,
   15347              :                                Runtime::PANIC_SLICE_B_U,
   15348              :                                Runtime::PANIC_EXTEND_SLICE_B,
   15349              :                                Runtime::PANIC_EXTEND_SLICE_B_U,
   15350              :                                inserter, loc);
   15351              :     }
   15352       154816 :   else if (end != NULL)
   15353              :     {
   15354        15197 :       Expression* start_bound;
   15355        15197 :       if (array_type->is_slice_type())
   15356              :         start_bound = scap;
   15357              :       else
   15358         6666 :         start_bound = len;
   15359        15197 :       Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
   15360              :                                Runtime::PANIC_SLICE_B,
   15361              :                                Runtime::PANIC_SLICE_B_U,
   15362              :                                Runtime::PANIC_EXTEND_SLICE_B,
   15363              :                                Runtime::PANIC_EXTEND_SLICE_B_U,
   15364              :                                inserter, loc);
   15365              :     }
   15366              :   else
   15367       139619 :     Expression::check_bounds(gogo, start, OPERATOR_LT, len,
   15368              :                              Runtime::PANIC_INDEX,
   15369              :                              Runtime::PANIC_INDEX_U,
   15370              :                              Runtime::PANIC_EXTEND_INDEX,
   15371              :                              Runtime::PANIC_EXTEND_INDEX_U,
   15372              :                              inserter, loc);
   15373              : 
   15374       174681 :   return this;
   15375              : }
   15376              : 
   15377              : // Return whether this expression is addressable.
   15378              : 
   15379              : bool
   15380         1158 : Array_index_expression::do_is_addressable() const
   15381              : {
   15382              :   // A slice expression is not addressable.
   15383         1158 :   if (this->end_ != NULL)
   15384              :     return false;
   15385              : 
   15386              :   // An index into a slice is addressable.
   15387         1104 :   if (this->array_->type()->is_slice_type())
   15388              :     return true;
   15389              : 
   15390              :   // An index into an array is addressable if the array is
   15391              :   // addressable.
   15392          432 :   return this->array_->is_addressable();
   15393              : }
   15394              : 
   15395              : void
   15396        13984 : Array_index_expression::do_address_taken(bool escapes)
   15397              : {
   15398              :   // In &x[0], if x is a slice, then x's address is not taken.
   15399        13984 :   if (!this->array_->type()->is_slice_type())
   15400         4590 :     this->array_->address_taken(escapes);
   15401        13984 : }
   15402              : 
   15403              : // Get the backend representation for an array index.
   15404              : 
   15405              : Bexpression*
   15406       207326 : Array_index_expression::do_get_backend(Translate_context* context)
   15407              : {
   15408       207326 :   Array_type* array_type = this->array_->type()->array_type();
   15409       207326 :   if (array_type == NULL)
   15410              :     {
   15411            0 :       go_assert(this->array_->type()->is_error());
   15412            0 :       return context->backend()->error_expression();
   15413              :     }
   15414       207326 :   go_assert(!array_type->is_slice_type()
   15415              :             || this->array_->is_multi_eval_safe());
   15416              : 
   15417       207326 :   Location loc = this->location();
   15418       207326 :   Gogo* gogo = context->gogo();
   15419              : 
   15420       207326 :   Type* int_type = Type::lookup_integer_type("int");
   15421       207326 :   Btype* int_btype = int_type->get_backend(gogo);
   15422              : 
   15423              :   // Convert the length and capacity to "int".  FIXME: Do we need to
   15424              :   // do this?
   15425       207326 :   Bexpression* length = NULL;
   15426       207326 :   if (this->end_ == NULL || this->end_->is_nil_expression())
   15427              :     {
   15428       171814 :       Expression* len = array_type->get_length(gogo, this->array_);
   15429       171814 :       length = len->get_backend(context);
   15430       171814 :       length = gogo->backend()->convert_expression(int_btype, length, loc);
   15431              :     }
   15432              : 
   15433       207326 :   Bexpression* capacity = NULL;
   15434       207326 :   if (this->end_ != NULL)
   15435              :     {
   15436        51960 :       Expression* cap = array_type->get_capacity(gogo, this->array_);
   15437        51960 :       capacity = cap->get_backend(context);
   15438        51960 :       capacity = gogo->backend()->convert_expression(int_btype, capacity, loc);
   15439              :     }
   15440              : 
   15441       207326 :   Bexpression* cap_arg = capacity;
   15442       207326 :   if (this->cap_ != NULL)
   15443              :     {
   15444         3766 :       cap_arg = this->cap_->get_backend(context);
   15445         3766 :       cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
   15446              :     }
   15447              : 
   15448       207326 :   if (length == NULL)
   15449        35512 :     length = cap_arg;
   15450              : 
   15451       207326 :   if (this->start_->type()->integer_type() == NULL
   15452            0 :       && !Type::are_convertible(int_type, this->start_->type(), NULL))
   15453              :     {
   15454            0 :       go_assert(saw_errors());
   15455            0 :       return context->backend()->error_expression();
   15456              :     }
   15457              : 
   15458       207326 :   Bexpression* start = this->start_->get_backend(context);
   15459       207326 :   start = gogo->backend()->convert_expression(int_btype, start, loc);
   15460              : 
   15461       207326 :   Bfunction* bfn = context->function()->func_value()->get_decl();
   15462       207326 :   if (this->end_ == NULL)
   15463              :     {
   15464              :       // Simple array indexing.
   15465       155366 :       Bexpression* ret;
   15466       155366 :       if (!array_type->is_slice_type())
   15467              :         {
   15468        66928 :           Bexpression* array = this->array_->get_backend(context);
   15469        66928 :           ret = gogo->backend()->array_index_expression(array, start, loc);
   15470              :         }
   15471              :       else
   15472              :         {
   15473        88438 :           Expression* valptr = array_type->get_value_pointer(gogo,
   15474              :                                                              this->array_);
   15475        88438 :           Bexpression* ptr = valptr->get_backend(context);
   15476        88438 :           ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc);
   15477              : 
   15478       176876 :           Type* ele_type = this->array_->type()->array_type()->element_type();
   15479        88438 :           Btype* ele_btype = ele_type->get_backend(gogo);
   15480        88438 :           ret = gogo->backend()->indirect_expression(ele_btype, ptr, false,
   15481              :                                                      loc);
   15482              :         }
   15483       155366 :       return ret;
   15484              :     }
   15485              : 
   15486              :   // Slice expression.
   15487              : 
   15488        51960 :   Bexpression* end;
   15489        51960 :   if (this->end_->is_nil_expression())
   15490              :     end = length;
   15491              :   else
   15492              :     {
   15493        35512 :       end = this->end_->get_backend(context);
   15494        35512 :       end = gogo->backend()->convert_expression(int_btype, end, loc);
   15495              :     }
   15496              : 
   15497        51960 :   Bexpression* result_length =
   15498        51960 :     gogo->backend()->binary_expression(OPERATOR_MINUS, end, start, loc);
   15499              : 
   15500        51960 :   Bexpression* result_capacity =
   15501        51960 :     gogo->backend()->binary_expression(OPERATOR_MINUS, cap_arg, start, loc);
   15502              : 
   15503              :   // If the new capacity is zero, don't change val.  Otherwise we can
   15504              :   // get a pointer to the next object in memory, keeping it live
   15505              :   // unnecessarily.  When the capacity is zero, the actual pointer
   15506              :   // value doesn't matter.
   15507        51960 :   Bexpression* zero =
   15508        51960 :     Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
   15509        51960 :   Bexpression* cond =
   15510        51960 :     gogo->backend()->binary_expression(OPERATOR_EQEQ, result_capacity, zero,
   15511              :                                        loc);
   15512        51960 :   Bexpression* offset = gogo->backend()->conditional_expression(bfn, int_btype,
   15513              :                                                                 cond, zero,
   15514              :                                                                 start, loc);
   15515        51960 :   Expression* valptr = array_type->get_value_pointer(gogo, this->array_);
   15516        51960 :   Bexpression* val = valptr->get_backend(context);
   15517        51960 :   val = gogo->backend()->pointer_offset_expression(val, offset, loc);
   15518              : 
   15519        51960 :   Btype* struct_btype = this->type()->get_backend(gogo);
   15520        51960 :   std::vector<Bexpression*> init;
   15521        51960 :   init.push_back(val);
   15522        51960 :   init.push_back(result_length);
   15523        51960 :   init.push_back(result_capacity);
   15524              : 
   15525        51960 :   return gogo->backend()->constructor_expression(struct_btype, init, loc);
   15526        51960 : }
   15527              : 
   15528              : // Export an array index expression.
   15529              : 
   15530              : void
   15531         3549 : Array_index_expression::do_export(Export_function_body* efb) const
   15532              : {
   15533         3549 :   efb->write_c_string("(");
   15534         3549 :   this->array_->export_expression(efb);
   15535         3549 :   efb->write_c_string(")[");
   15536              : 
   15537         3549 :   Type* old_context = efb->type_context();
   15538         3549 :   efb->set_type_context(Type::lookup_integer_type("int"));
   15539              : 
   15540         3549 :   this->start_->export_expression(efb);
   15541         3549 :   if (this->end_ == NULL)
   15542         2760 :     go_assert(this->cap_ == NULL);
   15543              :   else
   15544              :     {
   15545          789 :       efb->write_c_string(":");
   15546          789 :       if (!this->end_->is_nil_expression())
   15547          427 :         this->end_->export_expression(efb);
   15548          789 :       if (this->cap_ != NULL)
   15549              :         {
   15550            0 :           efb->write_c_string(":");
   15551            0 :           this->cap_->export_expression(efb);
   15552              :         }
   15553              :     }
   15554              : 
   15555         3549 :   efb->set_type_context(old_context);
   15556              : 
   15557         3549 :   efb->write_c_string("]");
   15558         3549 : }
   15559              : 
   15560              : // Dump ast representation for an array index expression.
   15561              : 
   15562              : void
   15563            0 : Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
   15564              :     const
   15565              : {
   15566            0 :   Index_expression::dump_index_expression(ast_dump_context, this->array_,
   15567            0 :                                           this->start_, this->end_, this->cap_);
   15568            0 : }
   15569              : 
   15570              : // Make an array index expression.  END and CAP may be NULL.
   15571              : 
   15572              : Expression*
   15573       218694 : Expression::make_array_index(Expression* array, Expression* start,
   15574              :                              Expression* end, Expression* cap,
   15575              :                              Location location)
   15576              : {
   15577       218694 :   return new Array_index_expression(array, start, end, cap, location);
   15578              : }
   15579              : 
   15580              : // Class String_index_expression.
   15581              : 
   15582              : // String index traversal.
   15583              : 
   15584              : int
   15585       314914 : String_index_expression::do_traverse(Traverse* traverse)
   15586              : {
   15587       314914 :   if (Expression::traverse(&this->string_, traverse) == TRAVERSE_EXIT)
   15588              :     return TRAVERSE_EXIT;
   15589       314671 :   if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
   15590              :     return TRAVERSE_EXIT;
   15591       314622 :   if (this->end_ != NULL)
   15592              :     {
   15593       179740 :       if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
   15594              :         return TRAVERSE_EXIT;
   15595              :     }
   15596              :   return TRAVERSE_CONTINUE;
   15597              : }
   15598              : 
   15599              : Expression*
   15600        21435 : String_index_expression::do_flatten(Gogo* gogo, Named_object*,
   15601              :                                     Statement_inserter* inserter)
   15602              : {
   15603        21435 :   if (this->is_flattened_)
   15604         1203 :     return this;
   15605        20232 :   this->is_flattened_ = true;
   15606              : 
   15607        20232 :   Location loc = this->location();
   15608              : 
   15609        20232 :   if (this->is_error_expression())
   15610            0 :     return Expression::make_error(loc);
   15611              : 
   15612        20232 :   Expression* string = this->string_;
   15613        20232 :   Expression* start = this->start_;
   15614        20232 :   Expression* end = this->end_;
   15615        20232 :   if (string->is_error_expression()
   15616        20232 :       || string->type()->is_error_type()
   15617        20232 :       || start->is_error_expression()
   15618        20229 :       || start->type()->is_error_type()
   15619        40461 :       || (end != NULL
   15620        22840 :           && (end->is_error_expression() || end->type()->is_error_type())))
   15621              :     {
   15622            3 :       go_assert(saw_errors());
   15623            3 :       return Expression::make_error(loc);
   15624              :     }
   15625              : 
   15626        20229 :   Temporary_statement* temp;
   15627        20229 :   if (!string->is_multi_eval_safe())
   15628              :     {
   15629         3072 :       temp = Statement::make_temporary(NULL, string, loc);
   15630         3072 :       inserter->insert(temp);
   15631         3072 :       this->string_ = Expression::make_temporary_reference(temp, loc);
   15632         3072 :       string = this->string_;
   15633              :     }
   15634        20229 :   if (!start->is_multi_eval_safe())
   15635              :     {
   15636         4291 :       temp = Statement::make_temporary(NULL, start, loc);
   15637         4291 :       inserter->insert(temp);
   15638         4291 :       this->start_ = Expression::make_temporary_reference(temp, loc);
   15639         4291 :       start = this->start_;
   15640              :     }
   15641        20229 :   if (end != NULL
   15642        11420 :       && !end->is_nil_expression()
   15643        26163 :       && !end->is_multi_eval_safe())
   15644              :     {
   15645         1800 :       temp = Statement::make_temporary(NULL, end, loc);
   15646         1800 :       inserter->insert(temp);
   15647         1800 :       this->end_ = Expression::make_temporary_reference(temp, loc);
   15648         1800 :       end = this->end_;
   15649              :     }
   15650              : 
   15651        20229 :   Expression* len = Expression::make_string_info(string->copy(),
   15652              :                                                  STRING_INFO_LENGTH, loc);
   15653        20229 :   temp = Statement::make_temporary(NULL, len, loc);
   15654        20229 :   temp->determine_types(gogo);
   15655        20229 :   inserter->insert(temp);
   15656        20229 :   len = Expression::make_temporary_reference(temp, loc);
   15657              : 
   15658              :   // The order of bounds checks here matches the order used by the gc
   15659              :   // compiler, as tested by issue30116[u].go.
   15660              : 
   15661        20229 :   if (end != NULL && !end->is_nil_expression())
   15662              :     {
   15663         5934 :       Expression::check_bounds(gogo, end, OPERATOR_LE, len,
   15664              :                                Runtime::PANIC_SLICE_ALEN,
   15665              :                                Runtime::PANIC_SLICE_ALEN_U,
   15666              :                                Runtime::PANIC_EXTEND_SLICE_ALEN,
   15667              :                                Runtime::PANIC_EXTEND_SLICE_ALEN_U,
   15668              :                                inserter, loc);
   15669         5934 :       Expression::check_bounds(gogo, start, OPERATOR_LE, end,
   15670              :                                Runtime::PANIC_SLICE_B,
   15671              :                                Runtime::PANIC_SLICE_B_U,
   15672              :                                Runtime::PANIC_EXTEND_SLICE_B,
   15673              :                                Runtime::PANIC_EXTEND_SLICE_B_U,
   15674              :                                inserter, loc);
   15675              :     }
   15676        14295 :   else if (end != NULL)
   15677         5486 :     Expression::check_bounds(gogo, start, OPERATOR_LE, len,
   15678              :                              Runtime::PANIC_SLICE_B,
   15679              :                              Runtime::PANIC_SLICE_B_U,
   15680              :                              Runtime::PANIC_EXTEND_SLICE_B,
   15681              :                              Runtime::PANIC_EXTEND_SLICE_B_U,
   15682              :                              inserter, loc);
   15683              :   else
   15684         8809 :     Expression::check_bounds(gogo, start, OPERATOR_LT, len,
   15685              :                              Runtime::PANIC_INDEX,
   15686              :                              Runtime::PANIC_INDEX_U,
   15687              :                              Runtime::PANIC_EXTEND_INDEX,
   15688              :                              Runtime::PANIC_EXTEND_INDEX_U,
   15689              :                              inserter, loc);
   15690              : 
   15691        20229 :   return this;
   15692              : }
   15693              : 
   15694              : // Return the type of a string index.
   15695              : 
   15696              : Type*
   15697       256128 : String_index_expression::do_type()
   15698              : {
   15699       256128 :   if (this->end_ == NULL)
   15700       120127 :     return Type::lookup_integer_type("byte");
   15701              :   else
   15702       136001 :     return this->string_->type();
   15703              : }
   15704              : 
   15705              : // Determine the type of a string index.
   15706              : 
   15707              : void
   15708        10575 : String_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
   15709              : {
   15710        10575 :   this->string_->determine_type_no_context(gogo);
   15711              : 
   15712        10575 :   Type_context index_context(Type::lookup_integer_type("int"), false);
   15713        10575 :   this->start_->determine_type(gogo, &index_context);
   15714        10575 :   if (this->end_ != NULL)
   15715         4547 :     this->end_->determine_type(gogo, &index_context);
   15716        10575 : }
   15717              : 
   15718              : // Check types of a string index.
   15719              : 
   15720              : void
   15721            0 : String_index_expression::do_check_types(Gogo*)
   15722              : {
   15723            0 :   if (!String_index_expression::check_indexes(this->string_, this->start_,
   15724              :                                               this->end_, this->location()))
   15725            0 :     this->set_is_error();
   15726            0 : }
   15727              : 
   15728              : // A static function to check string index types.  This is also called
   15729              : // by Index_expression::do_check_types.  It reports whether type
   15730              : // checking succeeded.
   15731              : 
   15732              : bool
   15733        17506 : String_index_expression::check_indexes(Expression* string, Expression* start,
   15734              :                                        Expression* end, Location loc)
   15735              : {
   15736        17506 :   bool ret = true;
   15737              : 
   15738        17506 :   Numeric_constant nc;
   15739        17506 :   unsigned long v;
   15740        17509 :   if (start->type()->integer_type() == NULL
   15741            3 :       && !start->type()->is_error()
   15742            3 :       && (!start->type()->is_abstract()
   15743            0 :           || !start->numeric_constant_value(&nc)
   15744            0 :           || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
   15745              :     {
   15746            3 :       go_error_at(loc, "index must be integer");
   15747            3 :       ret = false;
   15748              :     }
   15749              : 
   15750        17506 :   if (end != NULL
   15751        14387 :       && end->type()->integer_type() == NULL
   15752         4709 :       && !end->type()->is_error()
   15753         4709 :       && !end->is_nil_expression()
   15754            0 :       && !end->is_error_expression()
   15755        17506 :       && (!end->type()->is_abstract()
   15756            0 :           || !end->numeric_constant_value(&nc)
   15757            0 :           || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
   15758              :     {
   15759            0 :       go_error_at(loc, "slice end must be integer");
   15760            0 :       ret = false;
   15761              :     }
   15762              : 
   15763        17506 :   std::string sval;
   15764        17506 :   bool sval_valid = string->string_constant_value(&sval);
   15765              : 
   15766        17506 :   Numeric_constant inc;
   15767        17506 :   mpz_t ival;
   15768        17506 :   bool ival_valid = false;
   15769        17506 :   if (start->numeric_constant_value(&inc) && inc.to_int(&ival))
   15770              :     {
   15771         9360 :       ival_valid = true;
   15772         9360 :       if (mpz_sgn(ival) < 0
   15773         9360 :           || (sval_valid
   15774           21 :               && (end == NULL
   15775           21 :                   ? mpz_cmp_ui(ival, sval.length()) >= 0
   15776          811 :                   : mpz_cmp_ui(ival, sval.length()) > 0)))
   15777              :         {
   15778            7 :           go_error_at(start->location(), "string index out of bounds");
   15779            7 :           ret = false;
   15780              :         }
   15781              :     }
   15782              : 
   15783        17506 :   if (end != NULL && !end->is_nil_expression())
   15784              :     {
   15785         4969 :       Numeric_constant enc;
   15786         4969 :       mpz_t eval;
   15787         4969 :       if (end->numeric_constant_value(&enc) && enc.to_int(&eval))
   15788              :         {
   15789         1334 :           if (mpz_sgn(eval) < 0
   15790         2107 :               || (sval_valid && mpz_cmp_ui(eval, sval.length()) > 0))
   15791              :             {
   15792            5 :               go_error_at(end->location(), "string index out of bounds");
   15793            5 :               ret = false;
   15794              :             }
   15795         1329 :           else if (ival_valid && mpz_cmp(ival, eval) > 0)
   15796              :             {
   15797            2 :               go_error_at(loc, "inverted slice range");
   15798            2 :               ret = false;
   15799              :             }
   15800         1334 :           mpz_clear(eval);
   15801              :         }
   15802         4969 :     }
   15803        17506 :   if (ival_valid)
   15804         9360 :     mpz_clear(ival);
   15805              : 
   15806        35012 :   return ret;
   15807        17506 : }
   15808              : 
   15809              : // Get the backend representation for a string index.
   15810              : 
   15811              : Bexpression*
   15812        20228 : String_index_expression::do_get_backend(Translate_context* context)
   15813              : {
   15814        20228 :   Location loc = this->location();
   15815        20228 :   Gogo* gogo = context->gogo();
   15816              : 
   15817        20228 :   Type* int_type = Type::lookup_integer_type("int");
   15818              : 
   15819              :   // It is possible that an error occurred earlier because the start index
   15820              :   // cannot be represented as an integer type.  In this case, we shouldn't
   15821              :   // try casting the starting index into an integer since
   15822              :   // Type_conversion_expression will fail to get the backend representation.
   15823              :   // FIXME.
   15824        20228 :   if (this->start_->type()->integer_type() == NULL
   15825            0 :       && !Type::are_convertible(int_type, this->start_->type(), NULL))
   15826              :     {
   15827            0 :       go_assert(saw_errors());
   15828            0 :       return context->backend()->error_expression();
   15829              :     }
   15830              : 
   15831        20228 :   go_assert(this->string_->is_multi_eval_safe());
   15832        20228 :   go_assert(this->start_->is_multi_eval_safe());
   15833              : 
   15834        20228 :   Expression* start = Expression::make_cast(int_type, this->start_, loc);
   15835        20228 :   Bfunction* bfn = context->function()->func_value()->get_decl();
   15836              : 
   15837        20228 :   Expression* length =
   15838        20228 :     Expression::make_string_info(this->string_, STRING_INFO_LENGTH, loc);
   15839        20228 :   Expression* bytes =
   15840        20228 :     Expression::make_string_info(this->string_, STRING_INFO_DATA, loc);
   15841              : 
   15842        20228 :   Bexpression* bstart = start->get_backend(context);
   15843        20228 :   Bexpression* ptr = bytes->get_backend(context);
   15844              : 
   15845        20228 :   if (this->end_ == NULL)
   15846              :     {
   15847         8808 :       ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc);
   15848         8808 :       Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
   15849         8808 :       return gogo->backend()->indirect_expression(ubtype, ptr, false, loc);
   15850              :     }
   15851              : 
   15852        11420 :   Expression* end = NULL;
   15853        11420 :   if (this->end_->is_nil_expression())
   15854              :     end = length;
   15855              :   else
   15856              :     {
   15857         5934 :       go_assert(this->end_->is_multi_eval_safe());
   15858         5934 :       end = Expression::make_cast(int_type, this->end_, loc);
   15859              :     }
   15860              : 
   15861        11420 :   end = end->copy();
   15862        11420 :   Bexpression* bend = end->get_backend(context);
   15863        11420 :   Bexpression* new_length =
   15864        11420 :     gogo->backend()->binary_expression(OPERATOR_MINUS, bend, bstart, loc);
   15865              : 
   15866              :   // If the new length is zero, don't change pointer.  Otherwise we can
   15867              :   // get a pointer to the next object in memory, keeping it live
   15868              :   // unnecessarily.  When the length is zero, the actual pointer
   15869              :   // value doesn't matter.
   15870        11420 :   Btype* int_btype = int_type->get_backend(gogo);
   15871        11420 :   Bexpression* zero =
   15872        11420 :     Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
   15873        11420 :   Bexpression* cond =
   15874        11420 :     gogo->backend()->binary_expression(OPERATOR_EQEQ, new_length, zero,
   15875              :                                        loc);
   15876        11420 :   Bexpression* offset =
   15877        11420 :     gogo->backend()->conditional_expression(bfn, int_btype, cond, zero,
   15878              :                                             bstart, loc);
   15879              : 
   15880        11420 :   ptr = gogo->backend()->pointer_offset_expression(ptr, offset, loc);
   15881              : 
   15882        11420 :   Btype* str_btype = this->type()->get_backend(gogo);
   15883        11420 :   std::vector<Bexpression*> init;
   15884        11420 :   init.push_back(ptr);
   15885        11420 :   init.push_back(new_length);
   15886        11420 :   return gogo->backend()->constructor_expression(str_btype, init, loc);
   15887        11420 : }
   15888              : 
   15889              : // Export a string index expression.
   15890              : 
   15891              : void
   15892          944 : String_index_expression::do_export(Export_function_body* efb) const
   15893              : {
   15894          944 :   efb->write_c_string("(");
   15895          944 :   this->string_->export_expression(efb);
   15896          944 :   efb->write_c_string(")[");
   15897              : 
   15898          944 :   Type* old_context = efb->type_context();
   15899          944 :   efb->set_type_context(Type::lookup_integer_type("int"));
   15900              : 
   15901          944 :   this->start_->export_expression(efb);
   15902          944 :   if (this->end_ != NULL)
   15903              :     {
   15904          550 :       efb->write_c_string(":");
   15905          550 :       if (!this->end_->is_nil_expression())
   15906          340 :         this->end_->export_expression(efb);
   15907              :     }
   15908              : 
   15909          944 :   efb->set_type_context(old_context);
   15910              : 
   15911          944 :   efb->write_c_string("]");
   15912          944 : }
   15913              : 
   15914              : // Dump ast representation for a string index expression.
   15915              : 
   15916              : void
   15917            0 : String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
   15918              :     const
   15919              : {
   15920            0 :   Index_expression::dump_index_expression(ast_dump_context, this->string_,
   15921            0 :                                           this->start_, this->end_, NULL);
   15922            0 : }
   15923              : 
   15924              : // Make a string index expression.  END may be NULL.
   15925              : 
   15926              : Expression*
   15927        20293 : Expression::make_string_index(Expression* string, Expression* start,
   15928              :                               Expression* end, Location location)
   15929              : {
   15930        20293 :   return new String_index_expression(string, start, end, location);
   15931              : }
   15932              : 
   15933              : // Class Map_index.
   15934              : 
   15935              : // Get the type of the map.
   15936              : 
   15937              : Map_type*
   15938       107930 : Map_index_expression::get_map_type() const
   15939              : {
   15940       107930 :   Map_type* mt = this->map_->type()->map_type();
   15941            0 :   if (mt == NULL)
   15942            0 :     go_assert(saw_errors());
   15943       107930 :   return mt;
   15944              : }
   15945              : 
   15946              : // Map index traversal.
   15947              : 
   15948              : int
   15949       115905 : Map_index_expression::do_traverse(Traverse* traverse)
   15950              : {
   15951       115905 :   if (Expression::traverse(&this->map_, traverse) == TRAVERSE_EXIT)
   15952              :     return TRAVERSE_EXIT;
   15953       105985 :   return Expression::traverse(&this->index_, traverse);
   15954              : }
   15955              : 
   15956              : void
   15957         2555 : Map_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
   15958              : {
   15959         2555 :   this->map_->determine_type_no_context(gogo);
   15960         2555 :   Map_type* mt = this->map_->type()->map_type();
   15961            0 :   go_assert(mt != NULL);
   15962         2555 :   Type_context index_context(mt->key_type(), false);
   15963         2555 :   this->index_->determine_type(gogo, &index_context);
   15964         2555 :   if (this->value_pointer_ != NULL)
   15965          686 :     this->value_pointer_->determine_type_no_context(gogo);
   15966         2555 : }
   15967              : 
   15968              : void
   15969           15 : Map_index_expression::do_check_types(Gogo*)
   15970              : {
   15971              :   // Types should have been checked before this was created, so this
   15972              :   // will probably never be called.  Check it anyhow to be sure.
   15973           15 :   Map_type* mt = this->map_->type()->map_type();
   15974            0 :   go_assert(mt != NULL);
   15975           15 :   if (!Type::are_assignable(mt->key_type(), this->index_->type(), NULL))
   15976            0 :     this->report_error(_("incompatible type for map index"));
   15977           15 : }
   15978              : 
   15979              : // We need to pass in a pointer to the key, so flatten the index into a
   15980              : // temporary variable if it isn't already.  The value pointer will be
   15981              : // dereferenced and checked for nil, so flatten into a temporary to avoid
   15982              : // recomputation.
   15983              : 
   15984              : Expression*
   15985         6260 : Map_index_expression::do_flatten(Gogo* gogo, Named_object*,
   15986              :                                  Statement_inserter* inserter)
   15987              : {
   15988         6260 :   Location loc = this->location();
   15989         6260 :   Map_type* mt = this->get_map_type();
   15990         6260 :   if (this->index()->is_error_expression()
   15991         6260 :       || this->index()->type()->is_error_type()
   15992        12520 :       || mt->is_error_type())
   15993              :     {
   15994            0 :       go_assert(saw_errors());
   15995            0 :       return Expression::make_error(loc);
   15996              :     }
   15997              : 
   15998              :   // Avoid copy for string([]byte) conversions used in map keys.
   15999              :   // mapaccess doesn't keep the reference, so this is safe.
   16000         6260 :   Type_conversion_expression* ce = this->index_->conversion_expression();
   16001          209 :   if (ce != NULL && ce->type()->is_string_type()
   16002           68 :       && ce->expr()->type()->is_slice_type())
   16003           52 :     ce->set_no_copy(true);
   16004              : 
   16005         6260 :   if (!Type::are_identical(mt->key_type(), this->index_->type(),
   16006              :                            Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
   16007              :                            NULL))
   16008              :     {
   16009            6 :       if (this->index_->type()->interface_type() != NULL
   16010            0 :           && !this->index_->is_multi_eval_safe())
   16011              :         {
   16012            0 :           Temporary_statement* temp =
   16013            0 :             Statement::make_temporary(NULL, this->index_, loc);
   16014            0 :           inserter->insert(temp);
   16015            0 :           this->index_ = Expression::make_temporary_reference(temp, loc);
   16016              :         }
   16017            6 :       this->index_ = Expression::convert_for_assignment(gogo, mt->key_type(),
   16018              :                                                         this->index_, loc);
   16019              :     }
   16020              : 
   16021         6260 :   if (!this->index_->is_multi_eval_safe())
   16022              :     {
   16023         2178 :       Temporary_statement* temp = Statement::make_temporary(NULL, this->index_,
   16024              :                                                             loc);
   16025         2178 :       inserter->insert(temp);
   16026         2178 :       this->index_ = Expression::make_temporary_reference(temp, loc);
   16027              :     }
   16028              : 
   16029         6260 :   if (this->value_pointer_ == NULL)
   16030         5862 :     this->get_value_pointer(gogo);
   16031         6260 :   if (this->value_pointer_->is_error_expression()
   16032         6260 :       || this->value_pointer_->type()->is_error_type())
   16033            0 :     return Expression::make_error(loc);
   16034         6260 :   if (!this->value_pointer_->is_multi_eval_safe())
   16035              :     {
   16036         5862 :       Temporary_statement* temp =
   16037         5862 :         Statement::make_temporary(NULL, this->value_pointer_, loc);
   16038         5862 :       inserter->insert(temp);
   16039         5862 :       this->value_pointer_ = Expression::make_temporary_reference(temp, loc);
   16040              :     }
   16041              : 
   16042         6260 :   return this;
   16043              : }
   16044              : 
   16045              : // Return the type of a map index.
   16046              : 
   16047              : Type*
   16048        81619 : Map_index_expression::do_type()
   16049              : {
   16050        81619 :   Map_type* mt = this->get_map_type();
   16051        81619 :   if (mt == NULL)
   16052            0 :     return Type::make_error_type();
   16053        81619 :   return mt->val_type();
   16054              : }
   16055              : 
   16056              : // Add explicit type conversions.
   16057              : 
   16058              : void
   16059         5862 : Map_index_expression::do_add_conversions()
   16060              : {
   16061         5862 :   Map_type* mt = this->get_map_type();
   16062         5862 :   if (mt == NULL)
   16063              :     return;
   16064         5862 :   Type* lt = mt->key_type();
   16065         5862 :   Type* rt = this->index_->type();
   16066         5862 :   if (!Type::are_identical(lt, rt, 0, NULL)
   16067         5862 :       && lt->interface_type() != NULL)
   16068          123 :     this->index_ = Expression::make_cast(lt, this->index_, this->location());
   16069              : }
   16070              : 
   16071              : // Get the backend representation for a map index.
   16072              : 
   16073              : Bexpression*
   16074         5866 : Map_index_expression::do_get_backend(Translate_context* context)
   16075              : {
   16076         5866 :   Map_type* type = this->get_map_type();
   16077         5866 :   if (type == NULL)
   16078              :     {
   16079            0 :       go_assert(saw_errors());
   16080            0 :       return context->backend()->error_expression();
   16081              :     }
   16082              : 
   16083         5866 :   go_assert(this->value_pointer_ != NULL
   16084              :             && this->value_pointer_->is_multi_eval_safe());
   16085              : 
   16086         5866 :   Expression* val = Expression::make_dereference(this->value_pointer_,
   16087              :                                                  NIL_CHECK_NOT_NEEDED,
   16088              :                                                  this->location());
   16089         5866 :   return val->get_backend(context);
   16090              : }
   16091              : 
   16092              : // Get an expression for the map index.  This returns an expression
   16093              : // that evaluates to a pointer to a value.  If the key is not in the
   16094              : // map, the pointer will point to a zero value.
   16095              : 
   16096              : Expression*
   16097         5862 : Map_index_expression::get_value_pointer(Gogo* gogo)
   16098              : {
   16099         5862 :   if (this->value_pointer_ == NULL)
   16100              :     {
   16101         5862 :       Map_type* type = this->get_map_type();
   16102         5862 :       if (type == NULL)
   16103              :         {
   16104            0 :           go_assert(saw_errors());
   16105            0 :           return Expression::make_error(this->location());
   16106              :         }
   16107              : 
   16108         5862 :       Location loc = this->location();
   16109         5862 :       Expression* map_ref = this->map_;
   16110              : 
   16111         5862 :       Expression* index_ptr = Expression::make_unary(OPERATOR_AND,
   16112              :                                                      this->index_,
   16113              :                                                      loc);
   16114              : 
   16115         5862 :       Expression* type_expr = Expression::make_type_descriptor(type, loc);
   16116         5862 :       Expression* zero = type->fat_zero_value(gogo);
   16117         5862 :       Expression* map_index;
   16118         5862 :       if (zero == NULL)
   16119              :         {
   16120         5859 :           Runtime::Function code;
   16121         5859 :           Expression* key;
   16122         5859 :           switch (type->algorithm(gogo))
   16123              :             {
   16124          614 :               case Map_type::MAP_ALG_FAST32:
   16125          614 :               case Map_type::MAP_ALG_FAST32PTR:
   16126          614 :                 {
   16127          614 :                   Type* uint32_type = Type::lookup_integer_type("uint32");
   16128          614 :                   Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
   16129          614 :                   key = Expression::make_unsafe_cast(uint32_ptr_type, index_ptr,
   16130              :                                                      loc);
   16131          614 :                   key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
   16132              :                                                      loc);
   16133          614 :                   code = Runtime::MAPACCESS1_FAST32;
   16134          614 :                   break;
   16135              :                 }
   16136         1169 :               case Map_type::MAP_ALG_FAST64:
   16137         1169 :               case Map_type::MAP_ALG_FAST64PTR:
   16138         1169 :                 {
   16139         1169 :                   Type* uint64_type = Type::lookup_integer_type("uint64");
   16140         1169 :                   Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
   16141         1169 :                   key = Expression::make_unsafe_cast(uint64_ptr_type, index_ptr,
   16142              :                                                      loc);
   16143         1169 :                   key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
   16144              :                                                      loc);
   16145         1169 :                   code = Runtime::MAPACCESS1_FAST64;
   16146         1169 :                   break;
   16147              :                 }
   16148         2897 :               case Map_type::MAP_ALG_FASTSTR:
   16149         2897 :                 key = this->index_;
   16150         2897 :                 code = Runtime::MAPACCESS1_FASTSTR;
   16151         2897 :                 break;
   16152              :               default:
   16153              :                 key = index_ptr;
   16154              :                 code = Runtime::MAPACCESS1;
   16155              :                 break;
   16156              :             }
   16157         5859 :           map_index = Runtime::make_call(gogo, code, loc, 3,
   16158              :                                          type_expr, map_ref, key);
   16159              :         }
   16160              :       else
   16161            3 :         map_index = Runtime::make_call(gogo, Runtime::MAPACCESS1_FAT, loc, 4,
   16162              :                                        type_expr, map_ref, index_ptr, zero);
   16163              : 
   16164         5862 :       Type* val_type = type->val_type();
   16165        11724 :       this->value_pointer_ =
   16166         5862 :           Expression::make_unsafe_cast(Type::make_pointer_type(val_type),
   16167              :                                        map_index, this->location());
   16168         5862 :       this->value_pointer_->determine_type_no_context(gogo);
   16169              :     }
   16170              : 
   16171         5862 :   return this->value_pointer_;
   16172              : }
   16173              : 
   16174              : // Export a map index expression.
   16175              : 
   16176              : void
   16177           96 : Map_index_expression::do_export(Export_function_body* efb) const
   16178              : {
   16179           96 :   efb->write_c_string("(");
   16180           96 :   this->map_->export_expression(efb);
   16181           96 :   efb->write_c_string(")[");
   16182              : 
   16183           96 :   Type* old_context = efb->type_context();
   16184           96 :   efb->set_type_context(this->get_map_type()->key_type());
   16185              : 
   16186           96 :   this->index_->export_expression(efb);
   16187              : 
   16188           96 :   efb->set_type_context(old_context);
   16189              : 
   16190           96 :   efb->write_c_string("]");
   16191           96 : }
   16192              : 
   16193              : // Dump ast representation for a map index expression
   16194              : 
   16195              : void
   16196            0 : Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
   16197              :     const
   16198              : {
   16199            0 :   Index_expression::dump_index_expression(ast_dump_context, this->map_,
   16200            0 :                                           this->index_, NULL, NULL);
   16201            0 : }
   16202              : 
   16203              : // Make a map index expression.
   16204              : 
   16205              : Map_index_expression*
   16206        14200 : Expression::make_map_index(Expression* map, Expression* index,
   16207              :                            Location location)
   16208              : {
   16209        14200 :   return new Map_index_expression(map, index, location);
   16210              : }
   16211              : 
   16212              : // Class Field_reference_expression.
   16213              : 
   16214              : // Lower a field reference expression.  There is nothing to lower, but
   16215              : // this is where we generate the tracking information for fields with
   16216              : // the magic go:"track" tag.
   16217              : 
   16218              : Expression*
   16219      1328845 : Field_reference_expression::do_lower(Gogo* gogo, Named_object* function,
   16220              :                                      Statement_inserter* inserter)
   16221              : {
   16222      1328845 :   Struct_type* struct_type = this->expr_->type()->struct_type();
   16223      1328845 :   if (struct_type == NULL)
   16224              :     {
   16225              :       // Error will be reported elsewhere.
   16226            2 :       return this;
   16227              :     }
   16228      1328843 :   const Struct_field* field = struct_type->field(this->field_index_);
   16229      1328843 :   if (field == NULL)
   16230            0 :     return this;
   16231      1328843 :   if (!field->has_tag())
   16232      1309887 :     return this;
   16233        18956 :   if (field->tag().find("go:\"track\"") == std::string::npos)
   16234        18956 :     return this;
   16235              : 
   16236              :   // References from functions generated by the compiler don't count.
   16237            0 :   if (function != NULL && function->func_value()->is_type_specific_function())
   16238            0 :     return this;
   16239              : 
   16240              :   // We have found a reference to a tracked field.  Build a call to
   16241              :   // the runtime function __go_fieldtrack with a string that describes
   16242              :   // the field.  FIXME: We should only call this once per referenced
   16243              :   // field per function, not once for each reference to the field.
   16244              : 
   16245            0 :   if (this->called_fieldtrack_)
   16246            0 :     return this;
   16247            0 :   this->called_fieldtrack_ = true;
   16248              : 
   16249            0 :   Location loc = this->location();
   16250              : 
   16251            0 :   std::string s = "fieldtrack \"";
   16252            0 :   Named_type* nt = this->expr_->type()->unalias()->named_type();
   16253            0 :   if (nt == NULL || nt->named_object()->package() == NULL)
   16254            0 :     s.append(gogo->pkgpath());
   16255              :   else
   16256            0 :     s.append(nt->named_object()->package()->pkgpath());
   16257            0 :   s.push_back('.');
   16258            0 :   if (nt != NULL)
   16259            0 :     s.append(Gogo::unpack_hidden_name(nt->name()));
   16260            0 :   s.push_back('.');
   16261            0 :   s.append(Gogo::unpack_hidden_name(field->field_name()));
   16262            0 :   s.push_back('"');
   16263              : 
   16264              :   // We can't use a string here, because internally a string holds a
   16265              :   // pointer to the actual bytes; when the linker garbage collects the
   16266              :   // string, it won't garbage collect the bytes.  So we use a
   16267              :   // [...]byte.
   16268              : 
   16269            0 :   Expression* length_expr = Expression::make_integer_ul(s.length(), NULL, loc);
   16270              : 
   16271            0 :   Type* byte_type = Type::lookup_integer_type("byte");
   16272            0 :   Array_type* array_type = Type::make_array_type(byte_type, length_expr);
   16273            0 :   array_type->set_is_array_incomparable();
   16274              : 
   16275            0 :   Expression_list* bytes = new Expression_list();
   16276            0 :   for (std::string::const_iterator p = s.begin(); p != s.end(); p++)
   16277              :     {
   16278            0 :       unsigned char c = static_cast<unsigned char>(*p);
   16279            0 :       bytes->push_back(Expression::make_integer_ul(c, NULL, loc));
   16280              :     }
   16281              : 
   16282            0 :   Expression* e = Expression::make_composite_literal(array_type, 0, false,
   16283              :                                                      bytes, false, loc);
   16284              : 
   16285            0 :   Variable* var = new Variable(array_type, e, true, false, false, loc);
   16286              : 
   16287            0 :   static int count;
   16288            0 :   char buf[50];
   16289            0 :   snprintf(buf, sizeof buf, "fieldtrack.%d", count);
   16290            0 :   ++count;
   16291              : 
   16292            0 :   Named_object* no = gogo->add_variable(buf, var);
   16293            0 :   e = Expression::make_var_reference(no, loc);
   16294            0 :   e = Expression::make_unary(OPERATOR_AND, e, loc);
   16295              : 
   16296            0 :   Expression* call = Runtime::make_call(gogo, Runtime::FIELDTRACK, loc, 1, e);
   16297            0 :   call->determine_type_no_context(gogo);
   16298            0 :   gogo->lower_expression(function, inserter, &call);
   16299            0 :   inserter->insert(Statement::make_statement(call, false));
   16300              : 
   16301              :   // Put this function, and the global variable we just created, into
   16302              :   // unique sections.  This will permit the linker to garbage collect
   16303              :   // them if they are not referenced.  The effect is that the only
   16304              :   // strings, indicating field references, that will wind up in the
   16305              :   // executable will be those for functions that are actually needed.
   16306            0 :   if (function != NULL)
   16307            0 :     function->func_value()->set_in_unique_section();
   16308            0 :   var->set_in_unique_section();
   16309              : 
   16310            0 :   return this;
   16311            0 : }
   16312              : 
   16313              : // Return the type of a field reference.
   16314              : 
   16315              : Type*
   16316     12705023 : Field_reference_expression::do_type()
   16317              : {
   16318     12705023 :   Type* type = this->expr_->type();
   16319     12705023 :   if (type->is_error())
   16320              :     return type;
   16321     12705003 :   Struct_type* struct_type = type->struct_type();
   16322            0 :   go_assert(struct_type != NULL);
   16323     12705003 :   return struct_type->field(this->field_index_)->type();
   16324              : }
   16325              : 
   16326              : // Check the types for a field reference.
   16327              : 
   16328              : void
   16329        43952 : Field_reference_expression::do_check_types(Gogo*)
   16330              : {
   16331        43952 :   Type* type = this->expr_->type();
   16332        43952 :   if (type->is_error())
   16333              :     return;
   16334        43951 :   Struct_type* struct_type = type->struct_type();
   16335            0 :   go_assert(struct_type != NULL);
   16336        43951 :   go_assert(struct_type->field(this->field_index_) != NULL);
   16337              : }
   16338              : 
   16339              : // Get the backend representation for a field reference.
   16340              : 
   16341              : Bexpression*
   16342       981990 : Field_reference_expression::do_get_backend(Translate_context* context)
   16343              : {
   16344       981990 :   Bexpression* bstruct = this->expr_->get_backend(context);
   16345       981990 :   return context->gogo()->backend()->struct_field_expression(bstruct,
   16346       981990 :                                                              this->field_index_,
   16347       981990 :                                                              this->location());
   16348              : }
   16349              : 
   16350              : // Dump ast representation for a field reference expression.
   16351              : 
   16352              : void
   16353            0 : Field_reference_expression::do_dump_expression(
   16354              :     Ast_dump_context* ast_dump_context) const
   16355              : {
   16356            0 :   this->expr_->dump_expression(ast_dump_context);
   16357            0 :   ast_dump_context->ostream() << "." <<  this->field_index_;
   16358            0 : }
   16359              : 
   16360              : // Make a reference to a qualified identifier in an expression.
   16361              : 
   16362              : Field_reference_expression*
   16363       987040 : Expression::make_field_reference(Expression* expr, unsigned int field_index,
   16364              :                                  Location location)
   16365              : {
   16366       987040 :   return new Field_reference_expression(expr, field_index, location);
   16367              : }
   16368              : 
   16369              : // Class Interface_field_reference_expression.
   16370              : 
   16371              : // Return an expression for the pointer to the function to call.
   16372              : 
   16373              : Expression*
   16374        31774 : Interface_field_reference_expression::get_function()
   16375              : {
   16376        31774 :   Expression* ref = this->expr_;
   16377        31774 :   Location loc = this->location();
   16378        31774 :   if (ref->type()->points_to() != NULL)
   16379         1160 :     ref = Expression::make_dereference(ref, NIL_CHECK_DEFAULT, loc);
   16380              : 
   16381        31774 :   Expression* mtable =
   16382        31774 :       Expression::make_interface_info(ref, INTERFACE_INFO_METHODS, loc);
   16383        31774 :   Struct_type* mtable_type = mtable->type()->points_to()->struct_type();
   16384              : 
   16385        31774 :   std::string name = Gogo::unpack_hidden_name(this->name_);
   16386        31774 :   unsigned int index;
   16387        31774 :   const Struct_field* field = mtable_type->find_local_field(name, &index);
   16388        31774 :   go_assert(field != NULL);
   16389              : 
   16390        31774 :   mtable = Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, loc);
   16391        31774 :   return Expression::make_field_reference(mtable, index, loc);
   16392        31774 : }
   16393              : 
   16394              : // Return an expression for the first argument to pass to the interface
   16395              : // function.
   16396              : 
   16397              : Expression*
   16398        31774 : Interface_field_reference_expression::get_underlying_object()
   16399              : {
   16400        31774 :   Expression* expr = this->expr_;
   16401        31774 :   if (expr->type()->points_to() != NULL)
   16402         1160 :     expr = Expression::make_dereference(expr, NIL_CHECK_DEFAULT,
   16403              :                                         this->location());
   16404        31774 :   return Expression::make_interface_info(expr, INTERFACE_INFO_OBJECT,
   16405        31774 :                                          this->location());
   16406              : }
   16407              : 
   16408              : // Traversal.
   16409              : 
   16410              : int
   16411       495980 : Interface_field_reference_expression::do_traverse(Traverse* traverse)
   16412              : {
   16413       495980 :   return Expression::traverse(&this->expr_, traverse);
   16414              : }
   16415              : 
   16416              : // Lower the expression.  If this expression is not called, we need to
   16417              : // evaluate the expression twice when converting to the backend
   16418              : // interface.  So introduce a temporary variable if necessary.
   16419              : 
   16420              : Expression*
   16421        39774 : Interface_field_reference_expression::do_flatten(Gogo*, Named_object*,
   16422              :                                                  Statement_inserter* inserter)
   16423              : {
   16424        39774 :   if (this->expr_->is_error_expression()
   16425        39774 :       || this->expr_->type()->is_error_type())
   16426              :     {
   16427            1 :       go_assert(saw_errors());
   16428            1 :       return Expression::make_error(this->location());
   16429              :     }
   16430              : 
   16431        39773 :   if (!this->expr_->is_multi_eval_safe())
   16432              :     {
   16433        10225 :       Temporary_statement* temp =
   16434        10225 :         Statement::make_temporary(NULL, this->expr_, this->location());
   16435        10225 :       inserter->insert(temp);
   16436        10225 :       this->expr_ = Expression::make_temporary_reference(temp, this->location());
   16437              :     }
   16438        39773 :   return this;
   16439              : }
   16440              : 
   16441              : // Return the type of an interface field reference.
   16442              : 
   16443              : Type*
   16444      1455651 : Interface_field_reference_expression::do_type()
   16445              : {
   16446      1455651 :   Type* expr_type = this->expr_->type();
   16447              : 
   16448      1455651 :   Type* points_to = expr_type->points_to();
   16449      1455651 :   if (points_to != NULL)
   16450        66180 :     expr_type = points_to;
   16451              : 
   16452      1455651 :   Interface_type* interface_type = expr_type->interface_type();
   16453      1455651 :   if (interface_type == NULL)
   16454           16 :     return Type::make_error_type();
   16455              : 
   16456      1455635 :   const Typed_identifier* method = interface_type->find_method(this->name_);
   16457      1455635 :   if (method == NULL)
   16458            0 :     return Type::make_error_type();
   16459              : 
   16460      1455635 :   return method->type();
   16461              : }
   16462              : 
   16463              : // Determine types.
   16464              : 
   16465              : void
   16466        33019 : Interface_field_reference_expression::do_determine_type(Gogo* gogo,
   16467              :                                                         const Type_context*)
   16468              : {
   16469        33019 :   this->expr_->determine_type_no_context(gogo);
   16470        33019 : }
   16471              : 
   16472              : // Check the types for an interface field reference.
   16473              : 
   16474              : void
   16475         1292 : Interface_field_reference_expression::do_check_types(Gogo*)
   16476              : {
   16477         1292 :   Type* type = this->expr_->type();
   16478              : 
   16479         1292 :   Type* points_to = type->points_to();
   16480         1292 :   if (points_to != NULL)
   16481         1160 :     type = points_to;
   16482              : 
   16483         1292 :   Interface_type* interface_type = type->interface_type();
   16484         1292 :   if (interface_type == NULL)
   16485              :     {
   16486            1 :       if (!type->is_error_type())
   16487            0 :         this->report_error(_("expected interface or pointer to interface"));
   16488              :     }
   16489              :   else
   16490              :     {
   16491         1291 :       const Typed_identifier* method =
   16492         1291 :         interface_type->find_method(this->name_);
   16493         1291 :       if (method == NULL)
   16494              :         {
   16495            0 :           go_error_at(this->location(), "method %qs not in interface",
   16496            0 :                       Gogo::message_name(this->name_).c_str());
   16497            0 :           this->set_is_error();
   16498              :         }
   16499              :     }
   16500         1292 : }
   16501              : 
   16502              : // If an interface field reference is not simply called, then it is
   16503              : // represented as a closure.  The closure will hold a single variable,
   16504              : // the value of the interface on which the method should be called.
   16505              : // The function will be a simple thunk that pulls the value from the
   16506              : // closure and calls the method with the remaining arguments.
   16507              : 
   16508              : // Because method values are not common, we don't build all thunks for
   16509              : // all possible interface methods, but instead only build them as we
   16510              : // need them.  In particular, we even build them on demand for
   16511              : // interface methods defined in other packages.
   16512              : 
   16513              : Interface_field_reference_expression::Interface_method_thunks
   16514              :   Interface_field_reference_expression::interface_method_thunks;
   16515              : 
   16516              : // Find or create the thunk to call method NAME on TYPE.
   16517              : 
   16518              : Named_object*
   16519          105 : Interface_field_reference_expression::create_thunk(Gogo* gogo,
   16520              :                                                    Interface_type* type,
   16521              :                                                    const std::string& name)
   16522              : {
   16523          105 :   std::pair<Interface_type*, Method_thunks*> val(type, NULL);
   16524          105 :   std::pair<Interface_method_thunks::iterator, bool> ins =
   16525          105 :     Interface_field_reference_expression::interface_method_thunks.insert(val);
   16526          105 :   if (ins.second)
   16527              :     {
   16528              :       // This is the first time we have seen this interface.
   16529           52 :       ins.first->second = new Method_thunks();
   16530              :     }
   16531              : 
   16532          114 :   for (Method_thunks::const_iterator p = ins.first->second->begin();
   16533          114 :        p != ins.first->second->end();
   16534            9 :        p++)
   16535           53 :     if (p->first == name)
   16536           44 :       return p->second;
   16537              : 
   16538           61 :   Location loc = type->location();
   16539              : 
   16540           61 :   const Typed_identifier* method_id = type->find_method(name);
   16541           61 :   if (method_id == NULL)
   16542            0 :     return Named_object::make_erroneous_name(gogo->thunk_name());
   16543              : 
   16544           61 :   Function_type* orig_fntype = method_id->type()->function_type();
   16545           61 :   if (orig_fntype == NULL)
   16546            0 :     return Named_object::make_erroneous_name(gogo->thunk_name());
   16547              : 
   16548           61 :   Struct_field_list* sfl = new Struct_field_list();
   16549              :   // The type here is wrong--it should be the C function type.  But it
   16550              :   // doesn't really matter.
   16551           61 :   Type* vt = Type::make_pointer_type(Type::make_void_type());
   16552          122 :   sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
   16553          122 :   sfl->push_back(Struct_field(Typed_identifier("val", type, loc)));
   16554           61 :   Struct_type* st = Type::make_struct_type(sfl, loc);
   16555           61 :   st->set_is_struct_incomparable();
   16556           61 :   Type* closure_type = Type::make_pointer_type(st);
   16557              : 
   16558           61 :   Function_type* new_fntype = orig_fntype->copy_with_names();
   16559              : 
   16560           61 :   std::string thunk_name = gogo->thunk_name();
   16561           61 :   Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
   16562           61 :                                               false, loc);
   16563              : 
   16564           61 :   Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
   16565           61 :   cvar->set_is_used();
   16566           61 :   cvar->set_is_closure();
   16567           61 :   Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
   16568              :                                                  NULL, cvar);
   16569           61 :   new_no->func_value()->set_closure_var(cp);
   16570              : 
   16571           61 :   gogo->start_block(loc);
   16572              : 
   16573              :   // Field 0 of the closure is the function code pointer, field 1 is
   16574              :   // the value on which to invoke the method.
   16575           61 :   Expression* arg = Expression::make_var_reference(cp, loc);
   16576           61 :   arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
   16577           61 :   arg = Expression::make_field_reference(arg, 1, loc);
   16578              : 
   16579           61 :   Expression *ifre = Expression::make_interface_field_reference(arg, name,
   16580              :                                                                 loc);
   16581              : 
   16582           61 :   const Typed_identifier_list* orig_params = orig_fntype->parameters();
   16583           61 :   Expression_list* args;
   16584           61 :   if (orig_params == NULL || orig_params->empty())
   16585              :     args = NULL;
   16586              :   else
   16587              :     {
   16588           38 :       const Typed_identifier_list* new_params = new_fntype->parameters();
   16589           38 :       args = new Expression_list();
   16590           38 :       for (Typed_identifier_list::const_iterator p = new_params->begin();
   16591           92 :            p != new_params->end();
   16592           54 :            ++p)
   16593              :         {
   16594           54 :           Named_object* p_no = gogo->lookup(p->name(), NULL);
   16595           54 :           go_assert(p_no != NULL
   16596              :                     && p_no->is_variable()
   16597              :                     && p_no->var_value()->is_parameter());
   16598           54 :           args->push_back(Expression::make_var_reference(p_no, loc));
   16599              :         }
   16600              :     }
   16601              : 
   16602           61 :   Call_expression* call = Expression::make_call(ifre, args,
   16603           61 :                                                 orig_fntype->is_varargs(),
   16604              :                                                 loc);
   16605           61 :   call->set_varargs_are_lowered();
   16606              : 
   16607           61 :   Statement* s = Statement::make_return_from_call(new_no, call, loc);
   16608           61 :   s->determine_types(gogo);
   16609           61 :   gogo->add_statement(s);
   16610           61 :   Block* b = gogo->finish_block(loc);
   16611           61 :   gogo->add_block(b, loc);
   16612              : 
   16613              :   // This is called after lowering.
   16614           61 :   gogo->lower_block(new_no, b);
   16615              : 
   16616           61 :   gogo->finish_function(loc);
   16617              : 
   16618          122 :   ins.first->second->push_back(std::make_pair(name, new_no));
   16619           61 :   return new_no;
   16620           61 : }
   16621              : 
   16622              : // Lookup a thunk to call method NAME on TYPE.
   16623              : 
   16624              : Named_object*
   16625          105 : Interface_field_reference_expression::lookup_thunk(Interface_type* type,
   16626              :                                                    const std::string& name)
   16627              : {
   16628          105 :   Interface_method_thunks::const_iterator p =
   16629          105 :     Interface_field_reference_expression::interface_method_thunks.find(type);
   16630          105 :   if (p == Interface_field_reference_expression::interface_method_thunks.end())
   16631              :     return NULL;
   16632          114 :   for (Method_thunks::const_iterator pm = p->second->begin();
   16633          114 :        pm != p->second->end();
   16634            9 :        ++pm)
   16635          114 :     if (pm->first == name)
   16636          105 :       return pm->second;
   16637              :   return NULL;
   16638              : }
   16639              : 
   16640              : // Get the backend representation for a method value.
   16641              : 
   16642              : Bexpression*
   16643          105 : Interface_field_reference_expression::do_get_backend(Translate_context* context)
   16644              : {
   16645          105 :   Interface_type* type = this->expr_->type()->interface_type();
   16646          105 :   if (type == NULL)
   16647              :     {
   16648            0 :       go_assert(saw_errors());
   16649            0 :       return context->backend()->error_expression();
   16650              :     }
   16651              : 
   16652          105 :   Named_object* thunk =
   16653          105 :     Interface_field_reference_expression::lookup_thunk(type, this->name_);
   16654              : 
   16655              :   // The thunk should have been created during the
   16656              :   // create_function_descriptors pass.
   16657          105 :   if (thunk == NULL || thunk->is_erroneous())
   16658              :     {
   16659            0 :       go_assert(saw_errors());
   16660            0 :       return context->backend()->error_expression();
   16661              :     }
   16662              : 
   16663              :   // FIXME: We should lower this earlier, but we can't it lower it in
   16664              :   // the lowering pass because at that point we don't know whether we
   16665              :   // need to create the thunk or not.  If the expression is called, we
   16666              :   // don't need the thunk.
   16667              : 
   16668          105 :   Location loc = this->location();
   16669              : 
   16670          105 :   Struct_field_list* fields = new Struct_field_list();
   16671          210 :   fields->push_back(Struct_field(Typed_identifier("fn",
   16672          105 :                                                   thunk->func_value()->type(),
   16673          105 :                                                   loc)));
   16674          210 :   fields->push_back(Struct_field(Typed_identifier("val",
   16675          105 :                                                   this->expr_->type(),
   16676          210 :                                                   loc)));
   16677          105 :   Struct_type* st = Type::make_struct_type(fields, loc);
   16678          105 :   st->set_is_struct_incomparable();
   16679              : 
   16680          105 :   Expression_list* vals = new Expression_list();
   16681          105 :   vals->push_back(Expression::make_func_code_reference(thunk, loc));
   16682          105 :   vals->push_back(this->expr_);
   16683              : 
   16684          105 :   Expression* expr = Expression::make_struct_composite_literal(st, vals, loc);
   16685          105 :   Bexpression* bclosure =
   16686          105 :     Expression::make_heap_expression(expr, loc)->get_backend(context);
   16687              : 
   16688          105 :   Gogo* gogo = context->gogo();
   16689          105 :   Btype* btype = this->type()->get_backend(gogo);
   16690          105 :   bclosure = gogo->backend()->convert_expression(btype, bclosure, loc);
   16691              : 
   16692          105 :   Expression* nil_check =
   16693          105 :       Expression::make_binary(OPERATOR_EQEQ, this->expr_,
   16694              :                               Expression::make_nil(loc), loc);
   16695          105 :   Bexpression* bnil_check = nil_check->get_backend(context);
   16696              : 
   16697          105 :   Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
   16698          105 :   crash->determine_type_no_context(gogo);
   16699          105 :   Bexpression* bcrash = crash->get_backend(context);
   16700              : 
   16701          105 :   Bfunction* bfn = context->function()->func_value()->get_decl();
   16702          105 :   Bexpression* bcond =
   16703          105 :       gogo->backend()->conditional_expression(bfn, NULL,
   16704              :                                               bnil_check, bcrash, NULL, loc);
   16705          105 :   Bfunction* bfunction = context->function()->func_value()->get_decl();
   16706          105 :   Bstatement* cond_statement =
   16707          105 :       gogo->backend()->expression_statement(bfunction, bcond);
   16708          105 :   return gogo->backend()->compound_expression(cond_statement, bclosure, loc);
   16709              : }
   16710              : 
   16711              : // Dump ast representation for an interface field reference.
   16712              : 
   16713              : void
   16714            0 : Interface_field_reference_expression::do_dump_expression(
   16715              :     Ast_dump_context* ast_dump_context) const
   16716              : {
   16717            0 :   this->expr_->dump_expression(ast_dump_context);
   16718            0 :   ast_dump_context->ostream() << "." << this->name_;
   16719            0 : }
   16720              : 
   16721              : // Make a reference to a field in an interface.
   16722              : 
   16723              : Expression*
   16724        32971 : Expression::make_interface_field_reference(Expression* expr,
   16725              :                                            const std::string& field,
   16726              :                                            Location location)
   16727              : {
   16728        32971 :   return new Interface_field_reference_expression(expr, field, location);
   16729              : }
   16730              : 
   16731              : // Class Allocation_expression.
   16732              : 
   16733              : int
   16734       132210 : Allocation_expression::do_traverse(Traverse* traverse)
   16735              : {
   16736       132210 :   return Type::traverse(this->type_, traverse);
   16737              : }
   16738              : 
   16739              : Type*
   16740       150444 : Allocation_expression::do_type()
   16741              : {
   16742       150444 :   return Type::make_pointer_type(this->type_);
   16743              : }
   16744              : 
   16745              : void
   16746         1911 : Allocation_expression::do_check_types(Gogo*)
   16747              : {
   16748         1911 :   if (!this->type_->in_heap())
   16749            0 :     go_error_at(this->location(), "cannot heap allocate go:notinheap type");
   16750         1911 : }
   16751              : 
   16752              : // Make a copy of an allocation expression.
   16753              : 
   16754              : Expression*
   16755            0 : Allocation_expression::do_copy()
   16756              : {
   16757            0 :   Allocation_expression* alloc =
   16758            0 :     new Allocation_expression(this->type_->copy_expressions(),
   16759            0 :                               this->location());
   16760            0 :   if (this->allocate_on_stack_)
   16761            0 :     alloc->set_allocate_on_stack();
   16762            0 :   if (this->no_zero_)
   16763            0 :     alloc->set_no_zero();
   16764            0 :   return alloc;
   16765              : }
   16766              : 
   16767              : // Return the backend representation for an allocation expression.
   16768              : 
   16769              : Bexpression*
   16770       239412 : Allocation_expression::do_get_backend(Translate_context* context)
   16771              : {
   16772       239412 :   Gogo* gogo = context->gogo();
   16773       239412 :   Location loc = this->location();
   16774       239412 :   Btype* btype = this->type_->get_backend(gogo);
   16775              : 
   16776       239412 :   if (this->allocate_on_stack_)
   16777              :     {
   16778        35031 :       int64_t size;
   16779        35031 :       bool ok = this->type_->backend_type_size(gogo, &size);
   16780        35031 :       if (!ok)
   16781              :         {
   16782            0 :           go_assert(saw_errors());
   16783            0 :           return gogo->backend()->error_expression();
   16784              :         }
   16785        35031 :       Bstatement* decl;
   16786        35031 :       Named_object* fn = context->function();
   16787        35031 :       go_assert(fn != NULL);
   16788        35031 :       Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
   16789        35031 :       Bexpression* init = (this->no_zero_
   16790        35031 :                            ? NULL
   16791        21813 :                            : gogo->backend()->zero_expression(btype));
   16792        35031 :       Bvariable* temp =
   16793        35031 :         gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
   16794              :                                             init,
   16795              :                                             Backend::variable_address_is_taken,
   16796              :                                             loc, &decl);
   16797        35031 :       Bexpression* ret = gogo->backend()->var_expression(temp, loc);
   16798        35031 :       ret = gogo->backend()->address_expression(ret, loc);
   16799        35031 :       ret = gogo->backend()->compound_expression(decl, ret, loc);
   16800        35031 :       return ret;
   16801              :     }
   16802              : 
   16803       204381 :   Bexpression* space =
   16804       204381 :     gogo->allocate_memory(this->type_, loc)->get_backend(context);
   16805       204381 :   Btype* pbtype = gogo->backend()->pointer_type(btype);
   16806       204381 :   return gogo->backend()->convert_expression(pbtype, space, loc);
   16807              : }
   16808              : 
   16809              : // Dump ast representation for an allocation expression.
   16810              : 
   16811              : void
   16812            0 : Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
   16813              :     const
   16814              : {
   16815            0 :   ast_dump_context->ostream() << "new(";
   16816            0 :   ast_dump_context->dump_type(this->type_);
   16817            0 :   ast_dump_context->ostream() << ")";
   16818            0 : }
   16819              : 
   16820              : // Make an allocation expression.
   16821              : 
   16822              : Expression*
   16823       241329 : Expression::make_allocation(Type* type, Location location)
   16824              : {
   16825       241329 :   return new Allocation_expression(type, location);
   16826              : }
   16827              : 
   16828              : // Class Ordered_value_list.
   16829              : 
   16830              : int
   16831      5308929 : Ordered_value_list::traverse_vals(Traverse* traverse)
   16832              : {
   16833      5308929 :   if (this->vals_ != NULL)
   16834              :     {
   16835      5125530 :       if (this->traverse_order_ == NULL)
   16836              :         {
   16837      4272759 :           if (this->vals_->traverse(traverse) == TRAVERSE_EXIT)
   16838              :             return TRAVERSE_EXIT;
   16839              :         }
   16840              :       else
   16841              :         {
   16842      2357312 :           for (std::vector<unsigned long>::const_iterator p =
   16843       852771 :                    this->traverse_order_->begin();
   16844      3210083 :                p != this->traverse_order_->end();
   16845      2357312 :                ++p)
   16846              :             {
   16847      2365211 :               if (Expression::traverse(&this->vals_->at(*p), traverse)
   16848              :                   == TRAVERSE_EXIT)
   16849        38154 :                 return TRAVERSE_EXIT;
   16850              :             }
   16851              :         }
   16852              :     }
   16853              :   return TRAVERSE_CONTINUE;
   16854              : }
   16855              : 
   16856              : // Class Struct_construction_expression.
   16857              : 
   16858              : // Traversal.
   16859              : 
   16860              : int
   16861      3301508 : Struct_construction_expression::do_traverse(Traverse* traverse)
   16862              : {
   16863      3301508 :   if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
   16864              :     return TRAVERSE_EXIT;
   16865      3283870 :   if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
   16866              :     return TRAVERSE_EXIT;
   16867              :   return TRAVERSE_CONTINUE;
   16868              : }
   16869              : 
   16870              : // Return whether this is a constant initializer.
   16871              : 
   16872              : bool
   16873            0 : Struct_construction_expression::is_constant_struct() const
   16874              : {
   16875            0 :   if (this->vals() == NULL)
   16876              :     return true;
   16877            0 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   16878            0 :        pv != this->vals()->end();
   16879            0 :        ++pv)
   16880              :     {
   16881            0 :       if (*pv != NULL
   16882            0 :           && !(*pv)->is_constant()
   16883            0 :           && (!(*pv)->is_composite_literal()
   16884            0 :               || (*pv)->is_nonconstant_composite_literal()))
   16885            0 :         return false;
   16886              :     }
   16887              : 
   16888            0 :   const Struct_field_list* fields = this->type_->struct_type()->fields();
   16889            0 :   for (Struct_field_list::const_iterator pf = fields->begin();
   16890            0 :        pf != fields->end();
   16891            0 :        ++pf)
   16892              :     {
   16893              :       // There are no constant constructors for interfaces.
   16894            0 :       if (pf->type()->interface_type() != NULL)
   16895            0 :         return false;
   16896              :     }
   16897              : 
   16898              :   return true;
   16899              : }
   16900              : 
   16901              : // Return whether this is a zero value.
   16902              : 
   16903              : bool
   16904           36 : Struct_construction_expression::do_is_zero_value() const
   16905              : {
   16906           36 :   if (this->vals() == NULL)
   16907              :     return true;
   16908            9 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   16909            9 :        pv != this->vals()->end();
   16910            0 :        ++pv)
   16911            9 :     if (*pv != NULL && !(*pv)->is_zero_value())
   16912            9 :       return false;
   16913              : 
   16914            0 :   const Struct_field_list* fields = this->type_->struct_type()->fields();
   16915            0 :   for (Struct_field_list::const_iterator pf = fields->begin();
   16916            0 :        pf != fields->end();
   16917            0 :        ++pf)
   16918              :     {
   16919              :       // Interface conversion may cause a zero value being converted
   16920              :       // to a non-zero value, like interface{}(0).  Be conservative.
   16921            0 :       if (pf->type()->interface_type() != NULL)
   16922            9 :         return false;
   16923              :     }
   16924              : 
   16925              :   return true;
   16926              : }
   16927              : 
   16928              : // Return whether this struct can be used as a constant initializer.
   16929              : 
   16930              : bool
   16931       867757 : Struct_construction_expression::do_is_static_initializer() const
   16932              : {
   16933       867757 :   if (this->vals() == NULL)
   16934              :     return true;
   16935      4571484 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   16936      4571484 :        pv != this->vals()->end();
   16937      3704306 :        ++pv)
   16938              :     {
   16939      3708608 :       if (*pv != NULL && !(*pv)->is_static_initializer())
   16940         4374 :         return false;
   16941              :     }
   16942              : 
   16943      1725752 :   const Struct_field_list* fields = this->type_->struct_type()->fields();
   16944       862876 :   for (Struct_field_list::const_iterator pf = fields->begin();
   16945      4562353 :        pf != fields->end();
   16946      3699477 :        ++pf)
   16947              :     {
   16948              :       // There are no constant constructors for interfaces.
   16949      7399026 :       if (pf->type()->interface_type() != NULL)
   16950         4374 :         return false;
   16951              :     }
   16952              : 
   16953              :   return true;
   16954              : }
   16955              : 
   16956              : // Final type determination.
   16957              : 
   16958              : void
   16959      1801044 : Struct_construction_expression::do_determine_type(Gogo* gogo,
   16960              :                                                   const Type_context*)
   16961              : {
   16962      1801044 :   if (this->vals() == NULL)
   16963              :     return;
   16964      3586930 :   const Struct_field_list* fields = this->type_->struct_type()->fields();
   16965      1793465 :   Expression_list::const_iterator pv = this->vals()->begin();
   16966      1793465 :   for (Struct_field_list::const_iterator pf = fields->begin();
   16967     11669636 :        pf != fields->end();
   16968      9876171 :        ++pf, ++pv)
   16969              :     {
   16970      9876171 :       if (pv == this->vals()->end())
   16971      1801044 :         return;
   16972      9876171 :       if (*pv != NULL)
   16973              :         {
   16974      9828704 :           Type_context subcontext(pf->type(), false);
   16975      9828704 :           (*pv)->determine_type(gogo, &subcontext);
   16976              :         }
   16977              :     }
   16978              :   // Extra values are an error we will report elsewhere; we still want
   16979              :   // to determine the type to avoid knockon errors.
   16980      1832107 :   for (; pv != this->vals()->end(); ++pv)
   16981        38642 :     (*pv)->determine_type_no_context(gogo);
   16982              : }
   16983              : 
   16984              : // Check types.
   16985              : 
   16986              : void
   16987        29829 : Struct_construction_expression::do_check_types(Gogo* gogo)
   16988              : {
   16989        29829 :   Struct_construction_expression::check_value_types(gogo, this->type_,
   16990              :                                                     this->vals(),
   16991              :                                                     this->location());
   16992        29829 : }
   16993              : 
   16994              : // Check types.  This static function is also called by
   16995              : // Composite_literal_expression::do_check_types.  Reports whether type
   16996              : // checking succeeded.
   16997              : 
   16998              : bool
   16999       203788 : Struct_construction_expression::check_value_types(Gogo* gogo,
   17000              :                                                   Type* type,
   17001              :                                                   Expression_list* vals,
   17002              :                                                   Location loc)
   17003              : {
   17004       203788 :   if (vals == NULL || vals->empty())
   17005              :     return true;
   17006              : 
   17007       194860 :   Struct_type* st = type->struct_type();
   17008       194860 :   if (vals->size() > st->field_count())
   17009              :     {
   17010            4 :       go_error_at(loc, "too many expressions for struct");
   17011            4 :       return false;
   17012              :     }
   17013              : 
   17014       194856 :   bool imported_type =
   17015       194856 :     (type->named_type() != NULL
   17016       194856 :      && type->named_type()->named_object()->package() != NULL);
   17017              : 
   17018       194856 :   bool ret = true;
   17019       194856 :   const Struct_field_list* fields = st->fields();
   17020       194856 :   Expression_list::const_iterator pv = vals->begin();
   17021       194856 :   int i = 0;
   17022       194856 :   for (Struct_field_list::const_iterator pf = fields->begin();
   17023       819924 :        pf != fields->end();
   17024       625068 :        ++pf, ++pv, ++i)
   17025              :     {
   17026       625071 :       if (pv == vals->end())
   17027              :         {
   17028            3 :           go_error_at(loc, "too few expressions for struct");
   17029            3 :           return false;
   17030              :         }
   17031              : 
   17032       625068 :       if (*pv == NULL)
   17033        95925 :         continue;
   17034              : 
   17035       529143 :       if (imported_type
   17036       529143 :           && (Gogo::is_hidden_name(pf->field_name())
   17037        60732 :               || pf->is_embedded_builtin(gogo)))
   17038              :         {
   17039            2 :           go_error_at(loc,
   17040              :                       "assignment of unexported field %qs in %qs literal",
   17041            4 :                       Gogo::message_name(pf->field_name()).c_str(),
   17042            2 :                       type->named_type()->message_name().c_str());
   17043            2 :           ret = false;
   17044              :         }
   17045              : 
   17046       529143 :       std::string reason;
   17047       529143 :       if (!Type::are_assignable(pf->type(), (*pv)->type(), &reason))
   17048              :         {
   17049            4 :           if (reason.empty())
   17050            0 :             go_error_at((*pv)->location(),
   17051              :                         "incompatible type for field %d in struct construction",
   17052              :                         i + 1);
   17053              :           else
   17054            4 :             go_error_at((*pv)->location(),
   17055              :                         ("incompatible type for field %d in "
   17056              :                          "struct construction (%s)"),
   17057              :                         i + 1, reason.c_str());
   17058              :           ret = false;
   17059              :         }
   17060       529143 :     }
   17061       194853 :   go_assert(pv == vals->end());
   17062              :   return ret;
   17063              : }
   17064              : 
   17065              : // Copy.
   17066              : 
   17067              : Expression*
   17068            0 : Struct_construction_expression::do_copy()
   17069              : {
   17070            0 :   Struct_construction_expression* ret =
   17071            0 :     new Struct_construction_expression(this->type_->copy_expressions(),
   17072            0 :                                        (this->vals() == NULL
   17073              :                                         ? NULL
   17074            0 :                                         : this->vals()->copy()),
   17075            0 :                                        this->location());
   17076            0 :   if (this->traverse_order() != NULL)
   17077            0 :     ret->set_traverse_order(this->traverse_order());
   17078            0 :   return ret;
   17079              : }
   17080              : 
   17081              : // Make implicit type conversions explicit.
   17082              : 
   17083              : void
   17084       186522 : Struct_construction_expression::do_add_conversions()
   17085              : {
   17086       186522 :   if (this->vals() == NULL)
   17087         7698 :     return;
   17088              : 
   17089       178824 :   Location loc = this->location();
   17090       357648 :   const Struct_field_list* fields = this->type_->struct_type()->fields();
   17091       178824 :   Expression_list::iterator pv = this->vals()->begin();
   17092       178824 :   for (Struct_field_list::const_iterator pf = fields->begin();
   17093       778677 :        pf != fields->end();
   17094       599853 :        ++pf, ++pv)
   17095              :     {
   17096       599853 :       if (pv == this->vals()->end())
   17097              :         break;
   17098       599853 :       if (*pv != NULL)
   17099              :         {
   17100       503885 :           Type* ft = pf->type();
   17101       503885 :           if (!Type::are_identical(ft, (*pv)->type(), 0, NULL)
   17102       618116 :               && ft->interface_type() != NULL)
   17103        15177 :            *pv = Expression::make_cast(ft, *pv, loc);
   17104              :         }
   17105              :     }
   17106              : }
   17107              : 
   17108              : // Return the backend representation for constructing a struct.
   17109              : 
   17110              : Bexpression*
   17111      1134830 : Struct_construction_expression::do_get_backend(Translate_context* context)
   17112              : {
   17113      1134830 :   Gogo* gogo = context->gogo();
   17114              : 
   17115      1134830 :   Btype* btype = this->type_->get_backend(gogo);
   17116      1134830 :   if (this->vals() == NULL)
   17117         7690 :     return gogo->backend()->zero_expression(btype);
   17118              : 
   17119      2254280 :   const Struct_field_list* fields = this->type_->struct_type()->fields();
   17120      1127140 :   Expression_list::const_iterator pv = this->vals()->begin();
   17121      1127140 :   std::vector<Bexpression*> init;
   17122      6882990 :   for (Struct_field_list::const_iterator pf = fields->begin();
   17123      6882990 :        pf != fields->end();
   17124      5755850 :        ++pf)
   17125              :     {
   17126      5755850 :       Btype* fbtype = pf->type()->get_backend(gogo);
   17127      5755850 :       if (pv == this->vals()->end())
   17128            0 :         init.push_back(gogo->backend()->zero_expression(fbtype));
   17129      5755850 :       else if (*pv == NULL)
   17130              :         {
   17131        95942 :           init.push_back(gogo->backend()->zero_expression(fbtype));
   17132        95942 :           ++pv;
   17133              :         }
   17134              :       else
   17135              :         {
   17136      5659908 :           Expression* val =
   17137      5659908 :               Expression::convert_for_assignment(gogo, pf->type(),
   17138      5659908 :                                                  *pv, this->location());
   17139      5659908 :           init.push_back(val->get_backend(context));
   17140      5659908 :           ++pv;
   17141              :         }
   17142              :     }
   17143      2254280 :   if (this->type_->struct_type()->has_padding())
   17144              :     {
   17145              :       // Feed an extra value if there is a padding field.
   17146          250 :       Btype *fbtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
   17147          250 :       init.push_back(gogo->backend()->zero_expression(fbtype));
   17148              :     }
   17149      1127140 :   return gogo->backend()->constructor_expression(btype, init, this->location());
   17150      1127140 : }
   17151              : 
   17152              : // Export a struct construction.
   17153              : 
   17154              : void
   17155            0 : Struct_construction_expression::do_export(Export_function_body* efb) const
   17156              : {
   17157            0 :   efb->write_c_string("$convert(");
   17158            0 :   efb->write_type(this->type_);
   17159            0 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   17160            0 :        pv != this->vals()->end();
   17161            0 :        ++pv)
   17162              :     {
   17163            0 :       efb->write_c_string(", ");
   17164            0 :       if (*pv != NULL)
   17165            0 :         (*pv)->export_expression(efb);
   17166              :     }
   17167            0 :   efb->write_c_string(")");
   17168            0 : }
   17169              : 
   17170              : // Dump ast representation of a struct construction expression.
   17171              : 
   17172              : void
   17173            0 : Struct_construction_expression::do_dump_expression(
   17174              :     Ast_dump_context* ast_dump_context) const
   17175              : {
   17176            0 :   ast_dump_context->dump_type(this->type_);
   17177            0 :   ast_dump_context->ostream() << "{";
   17178            0 :   ast_dump_context->dump_expression_list(this->vals());
   17179            0 :   ast_dump_context->ostream() << "}";
   17180            0 : }
   17181              : 
   17182              : // Make a struct composite literal.  This used by the thunk code.
   17183              : 
   17184              : Expression*
   17185      1370917 : Expression::make_struct_composite_literal(Type* type, Expression_list* vals,
   17186              :                                           Location location)
   17187              : {
   17188      1370917 :   go_assert(type->struct_type() != NULL);
   17189      1370917 :   return new Struct_construction_expression(type, vals, location);
   17190              : }
   17191              : 
   17192              : // Class Array_construction_expression.
   17193              : 
   17194              : // Traversal.
   17195              : 
   17196              : int
   17197      2007421 : Array_construction_expression::do_traverse(Traverse* traverse)
   17198              : {
   17199      2007421 :   if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
   17200              :     return TRAVERSE_EXIT;
   17201      1986905 :   if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
   17202              :     return TRAVERSE_EXIT;
   17203              :   return TRAVERSE_CONTINUE;
   17204              : }
   17205              : 
   17206              : // Return whether this is a constant initializer.
   17207              : 
   17208              : bool
   17209            0 : Array_construction_expression::is_constant_array() const
   17210              : {
   17211            0 :   if (this->vals() == NULL)
   17212              :     return true;
   17213              : 
   17214              :   // There are no constant constructors for interfaces.
   17215            0 :   if (this->type_->array_type()->element_type()->interface_type() != NULL)
   17216              :     return false;
   17217              : 
   17218            0 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   17219            0 :        pv != this->vals()->end();
   17220            0 :        ++pv)
   17221              :     {
   17222            0 :       if (*pv != NULL
   17223            0 :           && !(*pv)->is_constant()
   17224            0 :           && (!(*pv)->is_composite_literal()
   17225            0 :               || (*pv)->is_nonconstant_composite_literal()))
   17226            0 :         return false;
   17227              :     }
   17228              :   return true;
   17229              : }
   17230              : 
   17231              : // Return whether this is a zero value.
   17232              : 
   17233              : bool
   17234           10 : Array_construction_expression::do_is_zero_value() const
   17235              : {
   17236           10 :   if (this->vals() == NULL)
   17237              :     return true;
   17238              : 
   17239              :   // Interface conversion may cause a zero value being converted
   17240              :   // to a non-zero value, like interface{}(0).  Be conservative.
   17241           12 :   if (this->type_->array_type()->element_type()->interface_type() != NULL)
   17242              :     return false;
   17243              : 
   17244            4 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   17245            4 :        pv != this->vals()->end();
   17246            0 :        ++pv)
   17247            4 :     if (*pv != NULL && !(*pv)->is_zero_value())
   17248            4 :       return false;
   17249              : 
   17250              :   return true;
   17251              : }
   17252              : 
   17253              : // Return whether this can be used a constant initializer.
   17254              : 
   17255              : bool
   17256       860940 : Array_construction_expression::do_is_static_initializer() const
   17257              : {
   17258       860940 :   if (this->vals() == NULL)
   17259              :     return true;
   17260              : 
   17261              :   // There are no constant constructors for interfaces.
   17262      1384561 :   if (this->type_->array_type()->element_type()->interface_type() != NULL)
   17263              :     return false;
   17264              : 
   17265      2774895 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   17266      2774895 :        pv != this->vals()->end();
   17267      2194040 :        ++pv)
   17268              :     {
   17269      2237101 :       if (*pv != NULL && !(*pv)->is_static_initializer())
   17270       102991 :         return false;
   17271              :     }
   17272              :   return true;
   17273              : }
   17274              : 
   17275              : // Final type determination.
   17276              : 
   17277              : void
   17278       494472 : Array_construction_expression::do_determine_type(Gogo* gogo,
   17279              :                                                  const Type_context*)
   17280              : {
   17281       494472 :   if (this->is_error_expression())
   17282              :     {
   17283            0 :       go_assert(saw_errors());
   17284       148833 :       return;
   17285              :     }
   17286              : 
   17287       494472 :   if (this->vals() == NULL)
   17288              :     return;
   17289       345639 :   Array_type* at = this->type_->array_type();
   17290       345639 :   if (at == NULL || at->is_error() || at->element_type()->is_error())
   17291              :     {
   17292            0 :       go_assert(saw_errors());
   17293            0 :       this->set_is_error();
   17294            0 :       return;
   17295              :     }
   17296       345639 :   Type_context subcontext(at->element_type(), false);
   17297      1556007 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   17298      1556007 :        pv != this->vals()->end();
   17299      1210368 :        ++pv)
   17300              :     {
   17301      1210368 :       if (*pv != NULL)
   17302      1210368 :         (*pv)->determine_type(gogo, &subcontext);
   17303              :     }
   17304              : }
   17305              : 
   17306              : // Check types.
   17307              : 
   17308              : void
   17309        64037 : Array_construction_expression::do_check_types(Gogo*)
   17310              : {
   17311        64037 :   if (this->is_error_expression())
   17312              :     {
   17313            0 :       go_assert(saw_errors());
   17314              :       return;
   17315              :     }
   17316              : 
   17317        64037 :   if (this->vals() == NULL)
   17318              :     return;
   17319              : 
   17320        64028 :   Array_type* at = this->type_->array_type();
   17321        64028 :   if (at == NULL || at->is_error() || at->element_type()->is_error())
   17322              :     {
   17323            0 :       go_assert(saw_errors());
   17324            0 :       this->set_is_error();
   17325            0 :       return;
   17326              :     }
   17327        64028 :   int i = 0;
   17328        64028 :   Type* element_type = at->element_type();
   17329        64028 :   for (Expression_list::const_iterator pv = this->vals()->begin();
   17330       179313 :        pv != this->vals()->end();
   17331       115285 :        ++pv, ++i)
   17332              :     {
   17333       115285 :       if (*pv != NULL
   17334       115285 :           && !Type::are_assignable(element_type, (*pv)->type(), NULL))
   17335              :         {
   17336            0 :           go_error_at((*pv)->location(),
   17337              :                       "incompatible type for element %d in composite literal",
   17338              :                       i + 1);
   17339            0 :           this->set_is_error();
   17340              :         }
   17341              :     }
   17342              : }
   17343              : 
   17344              : // Make implicit type conversions explicit.
   17345              : 
   17346              : void
   17347       117250 : Array_construction_expression::do_add_conversions()
   17348              : {
   17349       117250 :   if (this->is_error_expression())
   17350              :     {
   17351            0 :       go_assert(saw_errors());
   17352        57385 :       return;
   17353              :     }
   17354              : 
   17355       117250 :   if (this->vals() == NULL)
   17356              :     return;
   17357              : 
   17358       226692 :   Type* et = this->type_->array_type()->element_type();
   17359       170731 :   if (et->interface_type() == NULL)
   17360              :     return;
   17361              : 
   17362        59865 :   Location loc = this->location();
   17363       169313 :   for (Expression_list::iterator pv = this->vals()->begin();
   17364       169313 :        pv != this->vals()->end();
   17365       109448 :        ++pv)
   17366       109448 :     if (!Type::are_identical(et, (*pv)->type(), 0, NULL))
   17367       107390 :       *pv = Expression::make_cast(et, *pv, loc);
   17368              : }
   17369              : 
   17370              : // Get a constructor expression for the array values.
   17371              : 
   17372              : Bexpression*
   17373       434395 : Array_construction_expression::get_constructor(Translate_context* context,
   17374              :                                                Btype* array_btype)
   17375              : {
   17376       868790 :   Type* element_type = this->type_->array_type()->element_type();
   17377              : 
   17378       434395 :   std::vector<unsigned long> indexes;
   17379       434395 :   std::vector<Bexpression*> vals;
   17380       434395 :   Gogo* gogo = context->gogo();
   17381       434395 :   if (this->vals() != NULL)
   17382              :     {
   17383       362808 :       size_t i = 0;
   17384       362808 :       std::vector<unsigned long>::const_iterator pi;
   17385       362808 :       if (this->indexes_ != NULL)
   17386          448 :         pi = this->indexes_->begin();
   17387       362808 :       for (Expression_list::const_iterator pv = this->vals()->begin();
   17388      2054176 :            pv != this->vals()->end();
   17389      1691368 :            ++pv, ++i)
   17390              :         {
   17391      1691368 :           if (this->indexes_ != NULL)
   17392       110395 :             go_assert(pi != this->indexes_->end());
   17393              : 
   17394      1691368 :           if (this->indexes_ == NULL)
   17395      1580973 :             indexes.push_back(i);
   17396              :           else
   17397       110395 :             indexes.push_back(*pi);
   17398      1691368 :           if (*pv == NULL)
   17399              :             {
   17400            0 :               Btype* ebtype = element_type->get_backend(gogo);
   17401            0 :               Bexpression *zv = gogo->backend()->zero_expression(ebtype);
   17402            0 :               vals.push_back(zv);
   17403              :             }
   17404              :           else
   17405              :             {
   17406      1691368 :               Expression* val_expr =
   17407      1691368 :                   Expression::convert_for_assignment(gogo, element_type, *pv,
   17408              :                                                      this->location());
   17409      1691368 :               vals.push_back(val_expr->get_backend(context));
   17410              :             }
   17411      1691368 :           if (this->indexes_ != NULL)
   17412       110395 :             ++pi;
   17413              :         }
   17414       362808 :       if (this->indexes_ != NULL)
   17415          448 :         go_assert(pi == this->indexes_->end());
   17416              :     }
   17417       434395 :   return gogo->backend()->array_constructor_expression(array_btype, indexes,
   17418       434395 :                                                        vals, this->location());
   17419       434395 : }
   17420              : 
   17421              : // Export an array construction.
   17422              : 
   17423              : void
   17424            0 : Array_construction_expression::do_export(Export_function_body* efb) const
   17425              : {
   17426            0 :   efb->write_c_string("$convert(");
   17427            0 :   efb->write_type(this->type_);
   17428            0 :   if (this->vals() != NULL)
   17429              :     {
   17430            0 :       std::vector<unsigned long>::const_iterator pi;
   17431            0 :       if (this->indexes_ != NULL)
   17432            0 :         pi = this->indexes_->begin();
   17433            0 :       for (Expression_list::const_iterator pv = this->vals()->begin();
   17434            0 :            pv != this->vals()->end();
   17435            0 :            ++pv)
   17436              :         {
   17437            0 :           efb->write_c_string(", ");
   17438              : 
   17439            0 :           if (this->indexes_ != NULL)
   17440              :             {
   17441            0 :               char buf[100];
   17442            0 :               snprintf(buf, sizeof buf, "%lu", *pi);
   17443            0 :               efb->write_c_string(buf);
   17444            0 :               efb->write_c_string(":");
   17445              :             }
   17446              : 
   17447            0 :           if (*pv != NULL)
   17448            0 :             (*pv)->export_expression(efb);
   17449              : 
   17450            0 :           if (this->indexes_ != NULL)
   17451            0 :             ++pi;
   17452              :         }
   17453              :     }
   17454            0 :   efb->write_c_string(")");
   17455            0 : }
   17456              : 
   17457              : // Dump ast representation of an array construction expression.
   17458              : 
   17459              : void
   17460            0 : Array_construction_expression::do_dump_expression(
   17461              :     Ast_dump_context* ast_dump_context) const
   17462              : {
   17463            0 :   Expression* length = this->type_->array_type()->length();
   17464              : 
   17465            0 :   ast_dump_context->ostream() << "[" ;
   17466            0 :   if (length != NULL)
   17467              :     {
   17468            0 :       ast_dump_context->dump_expression(length);
   17469              :     }
   17470            0 :   ast_dump_context->ostream() << "]" ;
   17471            0 :   ast_dump_context->dump_type(this->type_);
   17472            0 :   this->dump_slice_storage_expression(ast_dump_context);
   17473            0 :   ast_dump_context->ostream() << "{" ;
   17474            0 :   if (this->indexes_ == NULL)
   17475            0 :     ast_dump_context->dump_expression_list(this->vals());
   17476              :   else
   17477              :     {
   17478            0 :       Expression_list::const_iterator pv = this->vals()->begin();
   17479            0 :       for (std::vector<unsigned long>::const_iterator pi =
   17480            0 :              this->indexes_->begin();
   17481            0 :            pi != this->indexes_->end();
   17482            0 :            ++pi, ++pv)
   17483              :         {
   17484            0 :           if (pi != this->indexes_->begin())
   17485            0 :             ast_dump_context->ostream() << ", ";
   17486            0 :           ast_dump_context->ostream() << *pi << ':';
   17487            0 :           ast_dump_context->dump_expression(*pv);
   17488              :         }
   17489              :     }
   17490            0 :   ast_dump_context->ostream() << "}" ;
   17491              : 
   17492            0 : }
   17493              : 
   17494              : // Class Fixed_array_construction_expression.
   17495              : 
   17496       434435 : Fixed_array_construction_expression::Fixed_array_construction_expression(
   17497              :     Type* type, const std::vector<unsigned long>* indexes,
   17498       434435 :     Expression_list* vals, Location location)
   17499              :   : Array_construction_expression(EXPRESSION_FIXED_ARRAY_CONSTRUCTION,
   17500       434435 :                                   type, indexes, vals, location)
   17501       868870 : { go_assert(type->array_type() != NULL && !type->is_slice_type()); }
   17502              : 
   17503              : 
   17504              : // Copy.
   17505              : 
   17506              : Expression*
   17507            0 : Fixed_array_construction_expression::do_copy()
   17508              : {
   17509            0 :   Type* t = this->type()->copy_expressions();
   17510            0 :   return new Fixed_array_construction_expression(t, this->indexes(),
   17511            0 :                                                  (this->vals() == NULL
   17512              :                                                   ? NULL
   17513            0 :                                                   : this->vals()->copy()),
   17514            0 :                                                  this->location());
   17515              : }
   17516              : 
   17517              : // Return the backend representation for constructing a fixed array.
   17518              : 
   17519              : Bexpression*
   17520       434395 : Fixed_array_construction_expression::do_get_backend(Translate_context* context)
   17521              : {
   17522       434395 :   Type* type = this->type();
   17523       434395 :   Btype* btype = type->get_backend(context->gogo());
   17524       434395 :   return this->get_constructor(context, btype);
   17525              : }
   17526              : 
   17527              : Expression*
   17528        36248 : Expression::make_array_composite_literal(Type* type, Expression_list* vals,
   17529              :                                          Location location)
   17530              : {
   17531        72496 :   go_assert(type->array_type() != NULL && !type->is_slice_type());
   17532        36248 :   return new Fixed_array_construction_expression(type, NULL, vals, location);
   17533              : }
   17534              : 
   17535              : // Class Slice_construction_expression.
   17536              : 
   17537       434136 : Slice_construction_expression::Slice_construction_expression(
   17538              :   Type* type, const std::vector<unsigned long>* indexes,
   17539       434136 :   Expression_list* vals, Location location)
   17540              :   : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
   17541              :                                   type, indexes, vals, location),
   17542       434136 :     valtype_(NULL), array_val_(NULL), slice_storage_(NULL),
   17543       434136 :     storage_escapes_(true)
   17544              : {
   17545       434136 :   go_assert(type->is_slice_type());
   17546              : 
   17547       434136 :   unsigned long lenval;
   17548       434136 :   Expression* length;
   17549       434136 :   if (vals == NULL || vals->empty())
   17550              :     lenval = 0;
   17551              :   else
   17552              :     {
   17553       345107 :       if (this->indexes() == NULL)
   17554       344977 :         lenval = vals->size();
   17555              :       else
   17556          130 :         lenval = indexes->back() + 1;
   17557              :     }
   17558       434136 :   Type* int_type = Type::lookup_integer_type("int");
   17559       434136 :   length = Expression::make_integer_ul(lenval, int_type, location);
   17560       868272 :   Type* element_type = type->array_type()->element_type();
   17561       434136 :   Array_type* array_type = Type::make_array_type(element_type, length);
   17562       434136 :   array_type->set_is_array_incomparable();
   17563       434136 :   this->valtype_ = array_type;
   17564       434136 : }
   17565              : 
   17566              : // Traversal.
   17567              : 
   17568              : int
   17569      1644060 : Slice_construction_expression::do_traverse(Traverse* traverse)
   17570              : {
   17571      1644060 :   if (this->Array_construction_expression::do_traverse(traverse)
   17572              :       == TRAVERSE_EXIT)
   17573              :     return TRAVERSE_EXIT;
   17574      1626367 :   if (Type::traverse(this->valtype_, traverse) == TRAVERSE_EXIT)
   17575              :     return TRAVERSE_EXIT;
   17576      1624835 :   if (this->array_val_ != NULL
   17577      1624835 :       && Expression::traverse(&this->array_val_, traverse) == TRAVERSE_EXIT)
   17578              :     return TRAVERSE_EXIT;
   17579      1624835 :   if (this->slice_storage_ != NULL
   17580      1624835 :       && Expression::traverse(&this->slice_storage_, traverse) == TRAVERSE_EXIT)
   17581              :     return TRAVERSE_EXIT;
   17582              :   return TRAVERSE_CONTINUE;
   17583              : }
   17584              : 
   17585              : // Helper routine to create fixed array value underlying the slice literal.
   17586              : // May be called during flattening, or later during do_get_backend().
   17587              : 
   17588              : Expression*
   17589       377512 : Slice_construction_expression::create_array_val()
   17590              : {
   17591       377512 :   Array_type* array_type = this->type()->array_type();
   17592       377512 :   if (array_type == NULL)
   17593              :     {
   17594            0 :       go_assert(this->type()->is_error());
   17595              :       return NULL;
   17596              :     }
   17597              : 
   17598       377512 :   Location loc = this->location();
   17599       377512 :   go_assert(this->valtype_ != NULL);
   17600              : 
   17601       377512 :   Expression_list* vals = this->vals();
   17602       377512 :   return new Fixed_array_construction_expression(
   17603       377512 :       this->valtype_, this->indexes(), vals, loc);
   17604              : }
   17605              : 
   17606              : // If we're previous established that the slice storage does not
   17607              : // escape, then create a separate array temp val here for it. We
   17608              : // need to do this as part of flattening so as to be able to insert
   17609              : // the new temp statement.
   17610              : 
   17611              : Expression*
   17612       113370 : Slice_construction_expression::do_flatten(Gogo*, Named_object*,
   17613              :                                           Statement_inserter* inserter)
   17614              : {
   17615       113370 :   if (this->type()->array_type() == NULL)
   17616              :     {
   17617            0 :       go_assert(saw_errors());
   17618            0 :       return Expression::make_error(this->location());
   17619              :     }
   17620              : 
   17621              :   // Create a stack-allocated storage temp if storage won't escape
   17622       113370 :   if (!this->storage_escapes_
   17623        35047 :       && this->slice_storage_ == NULL
   17624       179126 :       && this->element_count() > 0)
   17625              :     {
   17626        32759 :       Location loc = this->location();
   17627        32759 :       this->array_val_ = this->create_array_val();
   17628        32759 :       go_assert(this->array_val_ != NULL);
   17629        32759 :       Temporary_statement* temp =
   17630        32759 :           Statement::make_temporary(this->valtype_, this->array_val_, loc);
   17631        32759 :       inserter->insert(temp);
   17632        32759 :       this->slice_storage_ = Expression::make_temporary_reference(temp, loc);
   17633              :     }
   17634              :   return this;
   17635              : }
   17636              : 
   17637              : // When dumping a slice construction expression that has an explicit
   17638              : // storeage temp, emit the temp here (if we don't do this the storage
   17639              : // temp appears unused in the AST dump).
   17640              : 
   17641              : void
   17642            0 : Slice_construction_expression::
   17643              : dump_slice_storage_expression(Ast_dump_context* ast_dump_context) const
   17644              : {
   17645            0 :   if (this->slice_storage_ == NULL)
   17646              :     return;
   17647            0 :   ast_dump_context->ostream() << "storage=" ;
   17648            0 :   ast_dump_context->dump_expression(this->slice_storage_);
   17649              : }
   17650              : 
   17651              : // Copy.
   17652              : 
   17653              : Expression*
   17654            0 : Slice_construction_expression::do_copy()
   17655              : {
   17656            0 :   return new Slice_construction_expression(this->type()->copy_expressions(),
   17657              :                                            this->indexes(),
   17658            0 :                                            (this->vals() == NULL
   17659              :                                             ? NULL
   17660            0 :                                             : this->vals()->copy()),
   17661            0 :                                            this->location());
   17662              : }
   17663              : 
   17664              : // Return the backend representation for constructing a slice.
   17665              : 
   17666              : Bexpression*
   17667       377508 : Slice_construction_expression::do_get_backend(Translate_context* context)
   17668              : {
   17669       377508 :   if (this->array_val_ == NULL)
   17670       344753 :     this->array_val_ = this->create_array_val();
   17671       377508 :   if (this->array_val_ == NULL)
   17672              :     {
   17673            0 :       go_assert(this->type()->is_error());
   17674            0 :       return context->backend()->error_expression();
   17675              :     }
   17676              : 
   17677       377508 :   Location loc = this->location();
   17678              : 
   17679       377508 :   bool is_static_initializer = this->array_val_->is_static_initializer();
   17680              : 
   17681              :   // We have to copy the initial values into heap memory if we are in
   17682              :   // a function or if the values are not constants.
   17683       377508 :   bool copy_to_heap = context->function() != NULL || !is_static_initializer;
   17684              : 
   17685       377508 :   Expression* space;
   17686              : 
   17687       377508 :   if (this->slice_storage_ != NULL)
   17688              :     {
   17689        32755 :       go_assert(!this->storage_escapes_);
   17690        32755 :       space = Expression::make_unary(OPERATOR_AND, this->slice_storage_, loc);
   17691              :     }
   17692       344753 :   else if (!copy_to_heap)
   17693              :     {
   17694              :       // The initializer will only run once.
   17695       287144 :       space = Expression::make_unary(OPERATOR_AND, this->array_val_, loc);
   17696       287144 :       space->unary_expression()->set_is_slice_init();
   17697              :     }
   17698              :   else
   17699              :     {
   17700        57639 :       go_assert(this->storage_escapes_ || this->element_count() == 0);
   17701        57609 :       space = Expression::make_heap_expression(this->array_val_, loc);
   17702              :     }
   17703       377508 :   Array_type* at = this->valtype_->array_type();
   17704       377508 :   Type* et = at->element_type();
   17705       377508 :   space = Expression::make_unsafe_cast(Type::make_pointer_type(et),
   17706              :                                        space, loc);
   17707              : 
   17708              :   // Build a constructor for the slice.
   17709       377508 :   Expression* len = at->length();
   17710       377508 :   Expression* slice_val =
   17711       377508 :     Expression::make_slice_value(this->type(), space, len, len, loc);
   17712       377508 :   return slice_val->get_backend(context);
   17713              : }
   17714              : 
   17715              : // Make a slice composite literal.  This is used by the type
   17716              : // descriptor code.
   17717              : 
   17718              : Slice_construction_expression*
   17719       402841 : Expression::make_slice_composite_literal(Type* type, Expression_list* vals,
   17720              :                                          Location location)
   17721              : {
   17722       402841 :   go_assert(type->is_slice_type());
   17723       402841 :   return new Slice_construction_expression(type, NULL, vals, location);
   17724              : }
   17725              : 
   17726              : // Class Map_construction_expression.
   17727              : 
   17728              : // Traversal.
   17729              : 
   17730              : int
   17731        53169 : Map_construction_expression::do_traverse(Traverse* traverse)
   17732              : {
   17733        53169 :   if (this->vals_ != NULL
   17734        53169 :       && this->vals_->traverse(traverse) == TRAVERSE_EXIT)
   17735              :     return TRAVERSE_EXIT;
   17736        52785 :   if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
   17737              :     return TRAVERSE_EXIT;
   17738              :   return TRAVERSE_CONTINUE;
   17739              : }
   17740              : 
   17741              : void
   17742         2433 : Map_construction_expression::do_determine_type(Gogo* gogo, const Type_context*)
   17743              : {
   17744         2433 :   Map_type* mt = this->type_->map_type();
   17745            0 :   go_assert(mt != NULL);
   17746         2433 :   Type_context key_context(mt->key_type(), false);
   17747         2433 :   Type_context val_context(mt->val_type(), false);
   17748         2433 :   if (this->vals_ != NULL)
   17749              :     {
   17750        29823 :       for (Expression_list::const_iterator pv = this->vals_->begin();
   17751        29823 :            pv != this->vals_->end();
   17752        27748 :            ++pv)
   17753              :         {
   17754        27748 :           (*pv)->determine_type(gogo, &key_context);
   17755        27748 :           ++pv;
   17756        27748 :           (*pv)->determine_type(gogo, &val_context);
   17757              :         }
   17758              :     }
   17759         2433 : }
   17760              : 
   17761              : void
   17762            0 : Map_construction_expression::do_check_types(Gogo*)
   17763              : {
   17764              :   // Types should have been checked before this was created, so this
   17765              :   // will probably never be called.  Check it anyhow to be sure.
   17766              : 
   17767            0 :   if (this->vals_ == NULL)
   17768              :     return;
   17769              : 
   17770            0 :   Map_type* mt = this->type_->map_type();
   17771            0 :   go_assert(mt != NULL);
   17772            0 :   Type* key_type = mt->key_type();
   17773            0 :   Type* val_type = mt->val_type();
   17774            0 :   for (Expression_list::const_iterator pv = this->vals_->begin();
   17775            0 :        pv != this->vals_->end();
   17776            0 :        ++pv)
   17777              :     {
   17778            0 :       if (!Type::are_assignable(key_type, (*pv)->type(), NULL))
   17779              :         {
   17780            0 :           go_error_at((*pv)->location(),
   17781              :                       "incompatible type for key in map composite literal");
   17782            0 :           this->set_is_error();
   17783              :         }
   17784            0 :       ++pv;
   17785            0 :       if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
   17786              :         {
   17787            0 :           go_error_at((*pv)->location(),
   17788              :                       "incompatible type for value in map composite literal");
   17789            0 :           this->set_is_error();
   17790              :         }
   17791              :     }
   17792              : }
   17793              : 
   17794              : // Flatten constructor initializer into a temporary variable since
   17795              : // we need to take its address for __go_construct_map.
   17796              : 
   17797              : Expression*
   17798         3534 : Map_construction_expression::do_flatten(Gogo* gogo, Named_object*,
   17799              :                                         Statement_inserter* inserter)
   17800              : {
   17801         3534 :   if (!this->is_error_expression()
   17802         3534 :       && this->vals_ != NULL
   17803         2672 :       && !this->vals_->empty()
   17804         6206 :       && this->constructor_temp_ == NULL)
   17805              :     {
   17806         2638 :       Map_type* mt = this->type_->map_type();
   17807         2638 :       Type* key_type = mt->key_type();
   17808         2638 :       Type* val_type = mt->val_type();
   17809         2638 :       this->element_type_ = Type::make_builtin_struct_type(2,
   17810              :                                                            "__key", key_type,
   17811              :                                                            "__val", val_type);
   17812              : 
   17813         2638 :       Expression_list* value_pairs = new Expression_list();
   17814         2638 :       Location loc = this->location();
   17815              : 
   17816         2638 :       size_t i = 0;
   17817         2638 :       for (Expression_list::const_iterator pv = this->vals_->begin();
   17818        32491 :            pv != this->vals_->end();
   17819        29853 :            ++pv, ++i)
   17820              :         {
   17821        29853 :           Expression_list* key_value_pair = new Expression_list();
   17822        29853 :           Expression* key = *pv;
   17823        59706 :           if (key->is_error_expression() || key->type()->is_error_type())
   17824              :             {
   17825            0 :               go_assert(saw_errors());
   17826            0 :               return Expression::make_error(loc);
   17827              :             }
   17828        29853 :           if (key->type()->interface_type() != NULL
   17829          148 :               && !key->is_multi_eval_safe())
   17830              :             {
   17831           44 :               Temporary_statement* temp =
   17832           44 :                 Statement::make_temporary(NULL, key, loc);
   17833           44 :               inserter->insert(temp);
   17834           44 :               key = Expression::make_temporary_reference(temp, loc);
   17835              :             }
   17836        29853 :           key = Expression::convert_for_assignment(gogo, key_type, key, loc);
   17837              : 
   17838        29853 :           ++pv;
   17839        29853 :           Expression* val = *pv;
   17840        59706 :           if (val->is_error_expression() || val->type()->is_error_type())
   17841              :             {
   17842            0 :               go_assert(saw_errors());
   17843            0 :               return Expression::make_error(loc);
   17844              :             }
   17845        29853 :           if (val->type()->interface_type() != NULL
   17846          501 :               && !val->is_multi_eval_safe())
   17847              :             {
   17848          497 :               Temporary_statement* temp =
   17849          497 :                 Statement::make_temporary(NULL, val, loc);
   17850          497 :               inserter->insert(temp);
   17851          497 :               val = Expression::make_temporary_reference(temp, loc);
   17852              :             }
   17853        29853 :           val = Expression::convert_for_assignment(gogo, val_type, val, loc);
   17854              : 
   17855        29853 :           key_value_pair->push_back(key);
   17856        29853 :           key_value_pair->push_back(val);
   17857        29853 :           value_pairs->push_back(
   17858        29853 :               Expression::make_struct_composite_literal(this->element_type_,
   17859              :                                                         key_value_pair, loc));
   17860              :         }
   17861              : 
   17862         2638 :       Expression* element_count = Expression::make_integer_ul(i, NULL, loc);
   17863         2638 :       Array_type* ctor_type =
   17864         2638 :           Type::make_array_type(this->element_type_, element_count);
   17865         2638 :       ctor_type->set_is_array_incomparable();
   17866         2638 :       Expression* constructor =
   17867              :           new Fixed_array_construction_expression(ctor_type, NULL,
   17868         2638 :                                                   value_pairs, loc);
   17869              : 
   17870         5276 :       this->constructor_temp_ =
   17871         2638 :           Statement::make_temporary(NULL, constructor, loc);
   17872         2638 :       constructor->issue_nil_check();
   17873         2638 :       this->constructor_temp_->set_is_address_taken();
   17874         2638 :       this->constructor_temp_->determine_types(gogo);
   17875         2638 :       inserter->insert(this->constructor_temp_);
   17876              :     }
   17877              : 
   17878         3534 :   return this;
   17879              : }
   17880              : 
   17881              : // Copy.
   17882              : 
   17883              : Expression*
   17884            0 : Map_construction_expression::do_copy()
   17885              : {
   17886            0 :   return new Map_construction_expression(this->type_->copy_expressions(),
   17887            0 :                                          (this->vals_ == NULL
   17888              :                                           ? NULL
   17889            0 :                                           : this->vals_->copy()),
   17890            0 :                                          this->location());
   17891              : }
   17892              : 
   17893              : // Make implicit type conversions explicit.
   17894              : 
   17895              : void
   17896         3481 : Map_construction_expression::do_add_conversions()
   17897              : {
   17898         3481 :   if (this->vals_ == NULL || this->vals_->empty())
   17899         3336 :     return;
   17900              : 
   17901         2638 :   Map_type* mt = this->type_->map_type();
   17902         2638 :   Type* kt = mt->key_type();
   17903         2638 :   Type* vt = mt->val_type();
   17904         2638 :   bool key_is_interface = (kt->interface_type() != NULL);
   17905         2638 :   bool val_is_interface = (vt->interface_type() != NULL);
   17906         2638 :   if (!key_is_interface && !val_is_interface)
   17907              :     return;
   17908              : 
   17909          145 :   Location loc = this->location();
   17910          790 :   for (Expression_list::iterator pv = this->vals_->begin();
   17911          790 :        pv != this->vals_->end();
   17912          645 :        ++pv)
   17913              :     {
   17914          793 :       if (key_is_interface &&
   17915          148 :           !Type::are_identical(kt, (*pv)->type(), 0, NULL))
   17916           44 :         *pv = Expression::make_cast(kt, *pv, loc);
   17917          645 :       ++pv;
   17918         1146 :       if (val_is_interface &&
   17919          501 :           !Type::are_identical(vt, (*pv)->type(), 0, NULL))
   17920          493 :         *pv = Expression::make_cast(vt, *pv, loc);
   17921              :     }
   17922              : }
   17923              : 
   17924              : // Return the backend representation for constructing a map.
   17925              : 
   17926              : Bexpression*
   17927         3481 : Map_construction_expression::do_get_backend(Translate_context* context)
   17928              : {
   17929         3481 :   if (this->is_error_expression())
   17930            0 :     return context->backend()->error_expression();
   17931         3481 :   Location loc = this->location();
   17932              : 
   17933         3481 :   size_t i = 0;
   17934         3481 :   Expression* ventries;
   17935         3481 :   if (this->vals_ == NULL || this->vals_->empty())
   17936          843 :     ventries = Expression::make_nil(loc);
   17937              :   else
   17938              :     {
   17939         2638 :       go_assert(this->constructor_temp_ != NULL);
   17940         2638 :       i = this->vals_->size() / 2;
   17941              : 
   17942         2638 :       Expression* ctor_ref =
   17943         2638 :           Expression::make_temporary_reference(this->constructor_temp_, loc);
   17944         2638 :       ventries = Expression::make_unary(OPERATOR_AND, ctor_ref, loc);
   17945              :     }
   17946              : 
   17947         3481 :   Map_type* mt = this->type_->map_type();
   17948         3481 :   if (this->element_type_ == NULL)
   17949          843 :       this->element_type_ =
   17950          843 :           Type::make_builtin_struct_type(2,
   17951              :                                          "__key", mt->key_type(),
   17952              :                                          "__val", mt->val_type());
   17953         3481 :   Expression* descriptor = Expression::make_type_descriptor(mt, loc);
   17954              : 
   17955         3481 :   Type* uintptr_t = Type::lookup_integer_type("uintptr");
   17956         3481 :   Expression* count = Expression::make_integer_ul(i, uintptr_t, loc);
   17957              : 
   17958         3481 :   Expression* entry_size =
   17959         3481 :       Expression::make_type_info(this->element_type_, TYPE_INFO_SIZE);
   17960              : 
   17961         3481 :   unsigned int field_index;
   17962         3481 :   const Struct_field* valfield =
   17963         3481 :       this->element_type_->find_local_field("__val", &field_index);
   17964         3481 :   Expression* val_offset =
   17965         3481 :       Expression::make_struct_field_offset(this->element_type_, valfield);
   17966              : 
   17967         3481 :   Gogo* gogo = context->gogo();
   17968         3481 :   Expression* map_ctor =
   17969         3481 :     Runtime::make_call(gogo, Runtime::CONSTRUCT_MAP, loc, 5,
   17970              :                        descriptor, count, entry_size, val_offset, ventries);
   17971         3481 :   map_ctor->determine_type_no_context(gogo);
   17972         3481 :   return map_ctor->get_backend(context);
   17973              : }
   17974              : 
   17975              : // Export an array construction.
   17976              : 
   17977              : void
   17978            0 : Map_construction_expression::do_export(Export_function_body* efb) const
   17979              : {
   17980            0 :   efb->write_c_string("$convert(");
   17981            0 :   efb->write_type(this->type_);
   17982            0 :   for (Expression_list::const_iterator pv = this->vals_->begin();
   17983            0 :        pv != this->vals_->end();
   17984            0 :        ++pv)
   17985              :     {
   17986            0 :       efb->write_c_string(", ");
   17987            0 :       (*pv)->export_expression(efb);
   17988              :     }
   17989            0 :   efb->write_c_string(")");
   17990            0 : }
   17991              : 
   17992              : // Dump ast representation for a map construction expression.
   17993              : 
   17994              : void
   17995            0 : Map_construction_expression::do_dump_expression(
   17996              :     Ast_dump_context* ast_dump_context) const
   17997              : {
   17998            0 :   ast_dump_context->ostream() << "{" ;
   17999            0 :   ast_dump_context->dump_expression_list(this->vals_, true);
   18000            0 :   ast_dump_context->ostream() << "}";
   18001            0 : }
   18002              : 
   18003              : // A composite literal key.  This is seen during parsing, but is not
   18004              : // resolved to a named_object in case this is a composite literal of
   18005              : // struct type.
   18006              : 
   18007              : class Composite_literal_key_expression : public Parser_expression
   18008              : {
   18009              :  public:
   18010       115537 :   Composite_literal_key_expression(const std::string& name, Location location)
   18011       115537 :     : Parser_expression(EXPRESSION_COMPOSITE_LITERAL_KEY, location),
   18012       115537 :       name_(name), expr_(NULL)
   18013       115537 :   { }
   18014              : 
   18015              :   const std::string&
   18016       114998 :   name() const
   18017       114998 :   { return this->name_; }
   18018              : 
   18019              :  protected:
   18020              :   Type*
   18021              :   do_type();
   18022              : 
   18023              :   void
   18024              :   do_determine_type(Gogo*, const Type_context*);
   18025              : 
   18026              :   Expression*
   18027              :   do_lower(Gogo*, Named_object*, Statement_inserter*);
   18028              : 
   18029              :   Expression*
   18030            0 :   do_copy()
   18031              :   {
   18032            0 :     return new Composite_literal_key_expression(this->name_, this->location());
   18033              :   }
   18034              : 
   18035              :   void
   18036              :   do_dump_expression(Ast_dump_context*) const;
   18037              : 
   18038              :  private:
   18039              :   // The name.
   18040              :   std::string name_;
   18041              :   // After we look up the name, a corresponding expression.
   18042              :   Expression* expr_;
   18043              : };
   18044              : 
   18045              : // Determine the type of a composite literal key.  We will never get
   18046              : // here for keys in composite literals of struct types, because they
   18047              : // will be handled by Composite_literal_expression::do_determine_type.
   18048              : // So if we get here, this must be a regular name reference after all.
   18049              : 
   18050              : void
   18051          529 : Composite_literal_key_expression::do_determine_type(
   18052              :     Gogo* gogo,
   18053              :     const Type_context* context)
   18054              : {
   18055          529 :   if (this->expr_ != NULL)
   18056              :     {
   18057              :       // Already resolved.
   18058              :       return;
   18059              :     }
   18060              : 
   18061          529 :   Named_object* no = gogo->lookup(this->name_, NULL);
   18062          529 :   if (no == NULL)
   18063              :     {
   18064              :       // Gogo::lookup doesn't look in the global namespace, and names
   18065              :       // used in composite literal keys aren't seen by
   18066              :       // Gogo::define_global_names, so we have to look in the global
   18067              :       // namespace ourselves.
   18068            9 :       no = gogo->lookup_global(Gogo::unpack_hidden_name(this->name_).c_str());
   18069            9 :       if (no == NULL)
   18070              :         {
   18071            1 :           go_error_at(this->location(), "reference to undefined name %qs",
   18072            1 :                       Gogo::message_name(this->name_).c_str());
   18073            1 :           this->set_is_error();
   18074            1 :           return;
   18075              :         }
   18076              :     }
   18077              : 
   18078          528 :   this->expr_ = Expression::make_unknown_reference(no, this->location());
   18079          528 :   this->expr_->determine_type(gogo, context);
   18080              : }
   18081              : 
   18082              : Type*
   18083          369 : Composite_literal_key_expression::do_type()
   18084              : {
   18085          369 :   if (this->is_error_expression())
   18086            0 :     return Type::make_error_type();
   18087          369 :   go_assert(this->expr_ != NULL);
   18088          369 :   return this->expr_->type();
   18089              : }
   18090              : 
   18091              : Expression*
   18092          529 : Composite_literal_key_expression::do_lower(Gogo*, Named_object*,
   18093              :                                            Statement_inserter*)
   18094              : {
   18095          529 :   if (this->is_error_expression())
   18096            1 :     return Expression::make_error(this->location());
   18097          528 :   go_assert(this->expr_ != NULL);
   18098              :   return this->expr_;
   18099              : }
   18100              : 
   18101              : // Dump a composite literal key.
   18102              : 
   18103              : void
   18104            0 : Composite_literal_key_expression::do_dump_expression(
   18105              :     Ast_dump_context* ast_dump_context) const
   18106              : {
   18107            0 :   ast_dump_context->ostream() << "_UnknownName_(" << this->name_ << ")";
   18108            0 : }
   18109              : 
   18110              : // Make a composite literal key.
   18111              : 
   18112              : Expression*
   18113       115537 : Expression::make_composite_literal_key(const std::string& name,
   18114              :                                        Location location)
   18115              : {
   18116       115537 :   return new Composite_literal_key_expression(name, location);
   18117              : }
   18118              : 
   18119              : // Class Composite_literal_expression.
   18120              : 
   18121              : // Traversal.
   18122              : 
   18123              : int
   18124      1146569 : Composite_literal_expression::do_traverse(Traverse* traverse)
   18125              : {
   18126      1146569 :   if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
   18127              :     return TRAVERSE_EXIT;
   18128              : 
   18129              :   // If this is a struct composite literal with keys, then the keys
   18130              :   // are field names, not expressions.  We don't want to traverse them
   18131              :   // in that case.  If we do, we can give an erroneous error "variable
   18132              :   // initializer refers to itself."  See bug482.go in the testsuite.
   18133      1146569 :   if (this->has_keys_ && this->vals_ != NULL)
   18134              :     {
   18135              :       // The type may not be resolvable at this point.
   18136       108128 :       Type* type = this->type_;
   18137              : 
   18138       158074 :       for (int depth = 0; depth < this->depth_; ++depth)
   18139              :         {
   18140        49951 :           type = type->deref();
   18141        49951 :           if (type->array_type() != NULL)
   18142        96928 :             type = type->array_type()->element_type();
   18143       159689 :           else if (type->map_type() != NULL)
   18144              :             {
   18145         1482 :               if (this->key_path_[depth])
   18146           12 :                 type = type->map_type()->key_type();
   18147              :               else
   18148         2952 :                 type = type->map_type()->val_type();
   18149              :             }
   18150              :           else
   18151              :             {
   18152              :               // This error will be reported during lowering.
   18153              :               return TRAVERSE_CONTINUE;
   18154              :             }
   18155              :         }
   18156       108123 :       type = type->deref();
   18157              : 
   18158       239712 :       while (true)
   18159              :         {
   18160       239712 :           if (type->classification() == Type::TYPE_NAMED)
   18161        86409 :             type = type->named_type()->real_type();
   18162       153303 :           else if (type->classification() == Type::TYPE_FORWARD)
   18163              :             {
   18164        45180 :               Type* t = type->forwarded();
   18165        45180 :               if (t == type)
   18166              :                 break;
   18167              :               type = t;
   18168              :             }
   18169              :           else
   18170              :             break;
   18171              :         }
   18172              : 
   18173       108123 :       if (type->classification() == Type::TYPE_STRUCT)
   18174              :         {
   18175        92452 :           Expression_list::iterator p = this->vals_->begin();
   18176       346970 :           while (p != this->vals_->end())
   18177              :             {
   18178              :               // Skip key.
   18179       254518 :               ++p;
   18180       254518 :               go_assert(p != this->vals_->end());
   18181       254518 :               if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
   18182              :                 return TRAVERSE_EXIT;
   18183       254518 :               ++p;
   18184              :             }
   18185              :           return TRAVERSE_CONTINUE;
   18186              :         }
   18187              :     }
   18188              : 
   18189      1054112 :   if (this->vals_ != NULL)
   18190       988367 :     return this->vals_->traverse(traverse);
   18191              : 
   18192              :   return TRAVERSE_CONTINUE;
   18193              : }
   18194              : 
   18195              : void
   18196       233460 : Composite_literal_expression::do_determine_type(Gogo* gogo,
   18197              :                                                 const Type_context*)
   18198              : {
   18199              :   // Resolve the type if this composite literal is within another
   18200              :   // composite literal and has omitted the type.  The DEPTH_ field
   18201              :   // tells us how deeply this one is embedded.
   18202       233460 :   Type* type = this->type_;
   18203       412341 :   for (int depth = 0; depth < this->depth_; ++depth)
   18204              :     {
   18205       178885 :       type = type->deref();
   18206       178885 :       if (type->array_type() != NULL)
   18207       349558 :         type = type->array_type()->element_type();
   18208         4106 :       else if (type->map_type() != NULL)
   18209              :         {
   18210         4102 :           if (this->key_path_[depth])
   18211           70 :             type = type->map_type()->key_type();
   18212              :           else
   18213         8134 :             type = type->map_type()->val_type();
   18214              :         }
   18215              :       else
   18216              :         {
   18217            4 :           if (!type->is_error())
   18218            4 :             this->report_error(_("may only omit types within composite "
   18219              :                                  "literals of slice, array, or map type"));
   18220              :           else
   18221              :             {
   18222            0 :               go_assert(saw_errors());
   18223            0 :               this->set_is_error();
   18224              :             }
   18225            4 :           return;
   18226              :         }
   18227              :     }
   18228              : 
   18229       233456 :   this->type_ = type;
   18230       233456 :   this->depth_ = 0;
   18231              : 
   18232       233456 :   type = type->deref();
   18233              : 
   18234       233456 :   if (this->vals_ == NULL || this->vals_->empty())
   18235              :     {
   18236              :       // No value types to determine.
   18237        17677 :       if (type->array_type() != NULL
   18238         4059 :           && type->array_type()->length() != NULL
   18239          577 :           && type->array_type()->length()->is_nil_expression())
   18240            2 :         this->resolve_array_length(type);
   18241        13618 :       return;
   18242              :     }
   18243              : 
   18244       390165 :   if (type->struct_type() != NULL && this->has_keys_)
   18245              :     {
   18246              :       // Rewrite the value list by removing the struct field keys.  We
   18247              :       // do this now rather than during lowering because handling
   18248              :       // struct keys is painful.  We don't need to do this for
   18249              :       // slice/array/map literals, because it's easy to determine
   18250              :       // their types with or without the keys.
   18251        45900 :       if (!this->resolve_struct_keys(gogo, type))
   18252              :         {
   18253           19 :           this->set_is_error();
   18254           38 :           delete this->vals_;
   18255           19 :           this->vals_ = NULL;
   18256           19 :           this->has_keys_ = false;
   18257           19 :           return;
   18258              :         }
   18259              :     }
   18260              : 
   18261       219819 :   if (type->struct_type() != NULL)
   18262              :     {
   18263       340616 :       const Struct_field_list* fields = type->struct_type()->fields();
   18264       170308 :       Expression_list::const_iterator pv = this->vals_->begin();
   18265       170308 :       for (Struct_field_list::const_iterator pf = fields->begin();
   18266       747385 :            pf != fields->end();
   18267       577077 :            ++pf, ++pv)
   18268              :         {
   18269       577080 :           if (pv == this->vals_->end())
   18270       233460 :             return;
   18271       577077 :           if (*pv != NULL)
   18272              :             {
   18273       480410 :               Type_context subcontext(pf->type(), false);
   18274       480410 :               (*pv)->determine_type(gogo, &subcontext);
   18275              :             }
   18276              :         }
   18277              :       // Extra values are an error we will report in the check_types
   18278              :       // pass; we still want to determine the type to avoid knockon
   18279              :       // errors.
   18280       170313 :       for (; pv != this->vals_->end(); ++pv)
   18281            8 :         (*pv)->determine_type_no_context(gogo);
   18282              :     }
   18283        49511 :   else if (type->array_type() != NULL)
   18284              :     {
   18285        46824 :       Array_type* at = type->array_type();
   18286        46824 :       Type_context intcontext(Type::lookup_integer_type("int"), false);
   18287        46824 :       Type_context subcontext(at->element_type(), false);
   18288       652101 :       for (Expression_list::const_iterator pv = this->vals_->begin();
   18289       652101 :            pv != this->vals_->end();
   18290       605277 :            ++pv)
   18291              :         {
   18292       605277 :           if (this->has_keys_)
   18293              :             {
   18294       110423 :               if (*pv != NULL)
   18295       110400 :                 (*pv)->determine_type(gogo, &intcontext);
   18296       110423 :               ++pv;
   18297       110423 :               if (pv == this->vals_->end())
   18298              :                 break;
   18299              :             }
   18300              : 
   18301       605277 :           if (*pv != NULL)
   18302       605277 :             (*pv)->determine_type(gogo, &subcontext);
   18303              :         }
   18304              : 
   18305        46824 :       if (at->length() != NULL && at->length()->is_nil_expression())
   18306          867 :         this->resolve_array_length(type);
   18307              :     }
   18308         2687 :   else if (type->map_type() != NULL)
   18309              :     {
   18310         2685 :       if (!this->has_keys_)
   18311              :         {
   18312            0 :           this->report_error(_("map composite literal must have keys"));
   18313            0 :           return;
   18314              :         }
   18315              : 
   18316         2685 :       Map_type* mt = type->map_type();
   18317         2685 :       Type_context key_context(mt->key_type(), false);
   18318         2685 :       Type_context val_context(mt->val_type(), false);
   18319        32763 :       for (Expression_list::const_iterator pv = this->vals_->begin();
   18320        32763 :            pv != this->vals_->end();
   18321        30078 :            ++pv)
   18322              :         {
   18323        30078 :           if (*pv != NULL)
   18324        30076 :             (*pv)->determine_type(gogo, &key_context);
   18325        30078 :           ++pv;
   18326        30078 :           if (*pv != NULL)
   18327        30078 :             (*pv)->determine_type(gogo, &val_context);
   18328              :         }
   18329              :     }
   18330              :   else
   18331              :     {
   18332              :       // We'll report this as an error in the check_types pass.
   18333              :       // Determine types to avoid knockon errors.
   18334            6 :       for (Expression_list::const_iterator pv = this->vals_->begin();
   18335            6 :            pv != this->vals_->end();
   18336            4 :            ++pv)
   18337              :         {
   18338            4 :           if (*pv != NULL)
   18339            4 :             (*pv)->determine_type_no_context(gogo);
   18340              :         }
   18341              :     }
   18342              : }
   18343              : 
   18344              : Type*
   18345       257216 : Composite_literal_expression::do_type()
   18346              : {
   18347       257216 :   if (this->is_error_expression())
   18348           38 :     return Type::make_error_type();
   18349       257178 :   go_assert(this->depth_ == 0);
   18350       257178 :   return this->type_;
   18351              : }
   18352              : 
   18353              : // Resolve the field keys of a struct composite literal.
   18354              : 
   18355              : bool
   18356        45900 : Composite_literal_expression::resolve_struct_keys(Gogo* gogo, Type* type)
   18357              : {
   18358        45900 :   Struct_type* st = type->struct_type();
   18359        45900 :   size_t field_count = st->field_count();
   18360        45900 :   std::vector<Expression*> vals(field_count);
   18361        45900 :   std::vector<unsigned long>* traverse_order = new(std::vector<unsigned long>);
   18362        45900 :   Expression_list::const_iterator p = this->vals_->begin();
   18363        45900 :   Expression* external_expr = NULL;
   18364        45900 :   const Named_object* external_no = NULL;
   18365       171836 :   while (p != this->vals_->end())
   18366              :     {
   18367       125954 :       Expression* name_expr = *p;
   18368              : 
   18369       125954 :       ++p;
   18370       125954 :       go_assert(p != this->vals_->end());
   18371       125954 :       Expression* val = *p;
   18372              : 
   18373       125954 :       ++p;
   18374              : 
   18375       125954 :       if (name_expr == NULL)
   18376              :         {
   18377            1 :           go_error_at(val->location(),
   18378              :                       "mixture of field and value initializers");
   18379           18 :           return false;
   18380              :         }
   18381              : 
   18382       125953 :       bool bad_key = false;
   18383       125953 :       std::string name;
   18384       125953 :       const Named_object* no = NULL;
   18385       125953 :       switch (name_expr->classification())
   18386              :         {
   18387       114998 :         case EXPRESSION_COMPOSITE_LITERAL_KEY:
   18388       114998 :           name =
   18389       114998 :             static_cast<Composite_literal_key_expression*>(name_expr)->name();
   18390       114998 :           break;
   18391              : 
   18392         5232 :         case EXPRESSION_UNKNOWN_REFERENCE:
   18393         5232 :           name = name_expr->unknown_expression()->name();
   18394         5232 :           if (type->named_type() != NULL)
   18395              :             {
   18396              :               // If the named object found for this field name comes from a
   18397              :               // different package than the struct it is a part of, do not count
   18398              :               // this incorrect lookup as a usage of the object's package.
   18399         5042 :               no = name_expr->unknown_expression()->named_object();
   18400         5042 :               if (no->package() != NULL
   18401         5419 :                   && (no->package()
   18402          377 :                       != type->named_type()->named_object()->package()))
   18403           39 :                 no->package()->forget_usage(name_expr);
   18404              :             }
   18405              :           break;
   18406              : 
   18407          111 :         case EXPRESSION_CONST_REFERENCE:
   18408          111 :           no = static_cast<Const_expression*>(name_expr)->named_object();
   18409          111 :           break;
   18410              : 
   18411            1 :         case EXPRESSION_TYPE:
   18412            1 :           {
   18413            1 :             Type* t = name_expr->type();
   18414            1 :             Named_type* nt = t->named_type();
   18415            1 :             if (nt == NULL)
   18416              :               bad_key = true;
   18417              :             else
   18418            1 :               no = nt->named_object();
   18419              :           }
   18420              :           break;
   18421              : 
   18422         5185 :         case EXPRESSION_VAR_REFERENCE:
   18423         5185 :           no = name_expr->var_expression()->named_object();
   18424         5185 :           break;
   18425              : 
   18426           91 :         case EXPRESSION_ENCLOSED_VAR_REFERENCE:
   18427           91 :           no = name_expr->enclosed_var_expression()->variable();
   18428           91 :           break;
   18429              : 
   18430          331 :         case EXPRESSION_FUNC_REFERENCE:
   18431          331 :           no = name_expr->func_expression()->named_object();
   18432          331 :           break;
   18433              : 
   18434              :         default:
   18435              :           bad_key = true;
   18436              :           break;
   18437              :         }
   18438       120756 :       if (bad_key)
   18439              :         {
   18440            4 :           go_error_at(name_expr->location(), "expected struct field name");
   18441            4 :           return false;
   18442              :         }
   18443              : 
   18444       125949 :       if (no != NULL)
   18445              :         {
   18446        10761 :           if (no->package() != NULL && external_expr == NULL)
   18447              :             {
   18448        10761 :               external_expr = name_expr;
   18449        10761 :               external_no = no;
   18450              :             }
   18451              : 
   18452        10761 :           name = no->name();
   18453              : 
   18454              :           // A predefined name won't be packed.  If it starts with a
   18455              :           // lower case letter we need to check for that case, because
   18456              :           // the field name will be packed.  FIXME.
   18457        10761 :           if (!Gogo::is_hidden_name(name)
   18458         4447 :               && name[0] >= 'a'
   18459        10761 :               && name[0] <= 'z')
   18460              :             {
   18461            0 :               Named_object* gno = gogo->lookup_global(name.c_str());
   18462            0 :               if (gno == no)
   18463            0 :                 name = gogo->pack_hidden_name(name, false);
   18464              :             }
   18465              :         }
   18466              : 
   18467       125949 :       unsigned int index;
   18468       125949 :       const Struct_field* sf = st->find_local_field(name, &index);
   18469       125949 :       if (sf == NULL)
   18470              :         {
   18471           35 :           go_error_at(name_expr->location(), "unknown field %qs in %qs",
   18472           12 :                       Gogo::message_name(name).c_str(),
   18473           12 :                       (type->named_type() != NULL
   18474           34 :                        ? type->named_type()->message_name().c_str()
   18475              :                        : "unnamed struct"));
   18476           12 :           return false;
   18477              :         }
   18478       125937 :       if (vals[index] != NULL)
   18479              :         {
   18480            3 :           go_error_at(name_expr->location(),
   18481              :                       "duplicate value for field %qs in %qs",
   18482            1 :                       Gogo::message_name(name).c_str(),
   18483            1 :                       (type->named_type() != NULL
   18484            3 :                        ? type->named_type()->message_name().c_str()
   18485              :                        : "unnamed struct"));
   18486            1 :           return false;
   18487              :         }
   18488              : 
   18489       125936 :       vals[index] = val;
   18490       125936 :       traverse_order->push_back(static_cast<unsigned long>(index));
   18491       125953 :     }
   18492              : 
   18493        45882 :   if (!this->all_are_names_)
   18494              :     {
   18495              :       // This is a weird case like bug462 in the testsuite.
   18496            1 :       if (external_expr == NULL)
   18497            0 :         go_error_at(this->location(), "unknown field in %qs literal",
   18498            0 :                     (type->named_type() != NULL
   18499            0 :                      ? type->named_type()->message_name().c_str()
   18500              :                      : "unnamed struct"));
   18501              :       else
   18502            3 :         go_error_at(external_expr->location(), "unknown field %qs in %qs",
   18503            1 :                     external_no->message_name().c_str(),
   18504            1 :                     (type->named_type() != NULL
   18505            3 :                      ? type->named_type()->message_name().c_str()
   18506              :                      : "unnamed struct"));
   18507            1 :       return false;
   18508              :     }
   18509              : 
   18510        45881 :   Expression_list* list = new Expression_list;
   18511        45881 :   list->reserve(field_count);
   18512       267738 :   for (size_t i = 0; i < field_count; ++i)
   18513       221857 :     list->push_back(vals[i]);
   18514              : 
   18515        45881 :   this->vals_ = list;
   18516        45881 :   this->traverse_order_ = traverse_order;
   18517        45881 :   this->has_keys_ = false;
   18518              : 
   18519        45881 :   return true;
   18520        45900 : }
   18521              : 
   18522              : // Handle [...]{...}
   18523              : 
   18524              : void
   18525          869 : Composite_literal_expression::resolve_array_length(Type* type)
   18526              : {
   18527          869 :   size_t size;
   18528          869 :   if (this->vals_ == NULL || this->vals_->empty())
   18529              :     size = 0;
   18530          867 :   else if (!this->has_keys_)
   18531          690 :     size = this->vals_->size();
   18532              :   else
   18533              :     {
   18534              :       unsigned long index = 0;
   18535              :       size = 0;
   18536         2588 :       for (Expression_list::const_iterator pv = this->vals_->begin();
   18537         2765 :            pv != this->vals_->end();
   18538         2588 :            pv += 2)
   18539              :         {
   18540         2590 :           Expression* index_expr = *pv;
   18541         2590 :           if (index_expr != NULL)
   18542              :             {
   18543         2583 :               Numeric_constant nc;
   18544         2583 :               unsigned long iv;
   18545         2583 :               if (!index_expr->numeric_constant_value(&nc)
   18546         2583 :                   || nc.to_unsigned_long(&iv) != Numeric_constant::NC_UL_VALID)
   18547              :                 {
   18548              :                   // We will report an error when lowering.
   18549              :                   break;
   18550              :                 }
   18551         2581 :               index = iv;
   18552         2583 :             }
   18553              : 
   18554         2588 :           if (index >= size)
   18555         2553 :             size = index + 1;
   18556              : 
   18557         2588 :           ++index;
   18558              :         }
   18559              :     }
   18560              : 
   18561          869 :   Expression* elen = Expression::make_integer_ul(size, NULL, this->location());
   18562         1738 :   this->type_ = Type::make_array_type(type->array_type()->element_type(),
   18563              :                                       elen);
   18564          869 : }
   18565              : 
   18566              : void
   18567       226843 : Composite_literal_expression::do_check_types(Gogo* gogo)
   18568              : {
   18569       226843 :   if (this->is_error_expression() || this->type_->is_error())
   18570              :     {
   18571           28 :       go_assert(saw_errors());
   18572              :       return;
   18573              :     }
   18574       226815 :   go_assert(this->depth_ == 0);
   18575              : 
   18576       226815 :   Type* type = this->type_->deref();
   18577       226815 :   if (type->struct_type() != NULL)
   18578              :     {
   18579       173959 :       go_assert(!this->has_keys_);
   18580       173959 :       if (!Struct_construction_expression::check_value_types(gogo, type,
   18581              :                                                              this->vals_,
   18582              :                                                              this->location()))
   18583           12 :         this->set_is_error();
   18584              :     }
   18585        52856 :   else if (type->array_type() != NULL)
   18586              :     {
   18587        98714 :       Type* element_type = type->array_type()->element_type();
   18588        49357 :       if (element_type->is_error())
   18589              :         {
   18590            1 :           go_assert(saw_errors());
   18591              :           return;
   18592              :         }
   18593        49356 :       if (this->vals_ == NULL || this->vals_->empty())
   18594              :         return;
   18595              :       int i = 0;
   18596              :       for (Expression_list::const_iterator pv = this->vals_->begin();
   18597       641084 :            pv != this->vals_->end();
   18598       595670 :            ++pv, ++i)
   18599              :         {
   18600       595670 :           if (this->has_keys_)
   18601              :             {
   18602              :               // We check the key type in the lowering pass.
   18603       110423 :               ++pv;
   18604       110423 :               if (pv == this->vals_->end())
   18605              :                 break;
   18606              :             }
   18607       595670 :           if (*pv != NULL
   18608       595670 :               && !Type::are_assignable(element_type, (*pv)->type(), NULL))
   18609              :             {
   18610           10 :               go_error_at((*pv)->location(),
   18611              :                           ("incompatible type for element %d "
   18612              :                            "in composite literal"),
   18613              :                           i + 1);
   18614           10 :               this->set_is_error();
   18615              :             }
   18616              :         }
   18617              :     }
   18618         3499 :   else if (type->map_type() != NULL)
   18619              :     {
   18620         3496 :       if (this->vals_ == NULL || this->vals_->empty())
   18621              :         return;
   18622         2653 :       if (!this->has_keys_)
   18623              :         {
   18624            0 :           this->report_error(_("map composite literal must have keys"));
   18625            0 :           return;
   18626              :         }
   18627         2653 :       int i = 0;
   18628         2653 :       Map_type* mt = type->map_type();
   18629         2653 :       Type* key_type = mt->key_type();
   18630         2653 :       Type* val_type = mt->val_type();
   18631         2653 :       for (Expression_list::const_iterator pv = this->vals_->begin();
   18632        32543 :            pv != this->vals_->end();
   18633        29890 :            ++pv, ++i)
   18634              :         {
   18635        29890 :           if (*pv != NULL
   18636        29890 :               && !Type::are_assignable(key_type, (*pv)->type(), NULL))
   18637              :             {
   18638            1 :               go_error_at((*pv)->location(),
   18639              :                           ("incompatible type for element %d key "
   18640              :                            "in map construction"),
   18641              :                           i + 1);
   18642            1 :               this->set_is_error();
   18643              :             }
   18644        29890 :           ++pv;
   18645        29890 :           if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
   18646              :             {
   18647            0 :               go_error_at((*pv)->location(),
   18648              :                           ("incompatible type for element %d value "
   18649              :                            "in map construction"),
   18650              :                           i + 1);
   18651            0 :               this->set_is_error();
   18652              :             }
   18653              :         }
   18654              :     }
   18655              :   else
   18656              :     {
   18657            3 :       this->report_error(_("expected struct, slice, array, or map type "
   18658              :                            "for composite literal"));
   18659              :     }
   18660              : }
   18661              : 
   18662              : // Lower a generic composite literal into a specific version based on
   18663              : // the type.
   18664              : 
   18665              : Expression*
   18666       227356 : Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
   18667              :                                        Statement_inserter* inserter)
   18668              : {
   18669       227356 :   if (this->is_error_expression() || this->type_->is_error())
   18670           50 :     return Expression::make_error(this->location());
   18671       227306 :   go_assert(this->depth_ == 0);
   18672              : 
   18673       227306 :   Type* type = this->type_;
   18674       227306 :   Type *pt = type->points_to();
   18675       227306 :   bool is_pointer = false;
   18676       227306 :   if (pt != NULL)
   18677              :     {
   18678         2001 :       is_pointer = true;
   18679         2001 :       type = pt;
   18680              :     }
   18681              : 
   18682       227306 :   Expression* ret;
   18683       227306 :   if (type->is_error())
   18684            0 :     return Expression::make_error(this->location());
   18685       227306 :   else if (type->struct_type() != NULL)
   18686       174460 :     ret = this->lower_struct(type);
   18687        52846 :   else if (type->array_type() != NULL)
   18688        49351 :     ret = this->lower_array(type);
   18689         3495 :   else if (type->map_type() != NULL)
   18690         3495 :     ret = this->lower_map(gogo, function, inserter, type);
   18691              :   else
   18692            0 :     go_unreachable();
   18693              : 
   18694       227306 :   if (is_pointer)
   18695         2001 :     ret = Expression::make_heap_expression(ret, this->location());
   18696              : 
   18697              :   return ret;
   18698              : }
   18699              : 
   18700              : // Lower a struct composite literal.
   18701              : 
   18702              : Expression*
   18703       174460 : Composite_literal_expression::lower_struct(Type* type)
   18704              : {
   18705       174460 :   go_assert(!this->has_keys_);
   18706       174460 :   Struct_construction_expression* ret =
   18707       174460 :     new Struct_construction_expression(type, this->vals_, this->location());
   18708       174460 :   ret->set_traverse_order(this->traverse_order_);
   18709       174460 :   return ret;
   18710              : }
   18711              : 
   18712              : // Index/value/traversal-order triple.
   18713              : 
   18714              : struct IVT_triple {
   18715              :   unsigned long index;
   18716              :   unsigned long traversal_order;
   18717              :   Expression* expr;
   18718         1881 :   IVT_triple(unsigned long i, unsigned long to, Expression *e)
   18719         1881 :       : index(i), traversal_order(to), expr(e) { }
   18720        10509 :   bool operator<(const IVT_triple& other) const
   18721        10337 :   { return this->index < other.index; }
   18722              : };
   18723              : 
   18724              : // Lower an array composite literal.
   18725              : 
   18726              : Expression*
   18727        49351 : Composite_literal_expression::lower_array(Type* type)
   18728              : {
   18729        49351 :   Location location = this->location();
   18730        49351 :   if (this->vals_ == NULL || !this->has_keys_)
   18731        48884 :     return this->make_array(type, NULL, this->vals_);
   18732              : 
   18733          467 :   std::vector<unsigned long>* indexes = new std::vector<unsigned long>;
   18734          467 :   indexes->reserve(this->vals_->size());
   18735          467 :   bool indexes_out_of_order = false;
   18736          467 :   Expression_list* vals = new Expression_list();
   18737          467 :   vals->reserve(this->vals_->size());
   18738          467 :   unsigned long index = 0;
   18739          467 :   Expression_list::const_iterator p = this->vals_->begin();
   18740       110874 :   while (p != this->vals_->end())
   18741              :     {
   18742       110420 :       Expression* index_expr = *p;
   18743              : 
   18744       110420 :       ++p;
   18745       110420 :       go_assert(p != this->vals_->end());
   18746       110420 :       Expression* val = *p;
   18747              : 
   18748       110420 :       ++p;
   18749              : 
   18750       110420 :       if (index_expr == NULL)
   18751              :         {
   18752           22 :           if (std::find(indexes->begin(), indexes->end(), index)
   18753           44 :               != indexes->end())
   18754              :             {
   18755            0 :               go_error_at(val->location(),
   18756              :                           "duplicate value for index %lu", index);
   18757            0 :               return Expression::make_error(location);
   18758              :             }
   18759           22 :           if (!indexes->empty())
   18760           16 :             indexes->push_back(index);
   18761              :         }
   18762              :       else
   18763              :         {
   18764       110398 :           if (indexes->empty() && !vals->empty())
   18765              :             {
   18766           10 :               for (size_t i = 0; i < vals->size(); ++i)
   18767            6 :                 indexes->push_back(i);
   18768              :             }
   18769              : 
   18770       110398 :           Numeric_constant nc;
   18771       110398 :           if (!index_expr->numeric_constant_value(&nc))
   18772              :             {
   18773            4 :               go_error_at(index_expr->location(),
   18774              :                           "index expression is not integer constant");
   18775            4 :               return Expression::make_error(location);
   18776              :             }
   18777              : 
   18778       110394 :           switch (nc.to_unsigned_long(&index))
   18779              :             {
   18780       110387 :             case Numeric_constant::NC_UL_VALID:
   18781       110387 :               break;
   18782            1 :             case Numeric_constant::NC_UL_NOTINT:
   18783            1 :               go_error_at(index_expr->location(),
   18784              :                           "index expression is not integer constant");
   18785            1 :               return Expression::make_error(location);
   18786            6 :             case Numeric_constant::NC_UL_NEGATIVE:
   18787            6 :               go_error_at(index_expr->location(),
   18788              :                           "index expression is negative");
   18789            6 :               return Expression::make_error(location);
   18790            0 :             case Numeric_constant::NC_UL_BIG:
   18791            0 :               go_error_at(index_expr->location(), "index value overflow");
   18792            0 :               return Expression::make_error(location);
   18793            0 :             default:
   18794            0 :               go_unreachable();
   18795              :             }
   18796              : 
   18797       110387 :           Named_type* ntype = Type::lookup_integer_type("int");
   18798       110387 :           Integer_type* inttype = ntype->integer_type();
   18799       110387 :           if (sizeof(index) >= static_cast<size_t>(inttype->bits() / 8)
   18800       110387 :               && index >> (inttype->bits() - 1) != 0)
   18801              :             {
   18802            0 :               go_error_at(index_expr->location(), "index value overflow");
   18803            0 :               return Expression::make_error(location);
   18804              :             }
   18805              : 
   18806       110387 :           if (std::find(indexes->begin(), indexes->end(), index)
   18807       220774 :               != indexes->end())
   18808              :             {
   18809            2 :               go_error_at(index_expr->location(),
   18810              :                           "duplicate value for index %lu",
   18811              :                           index);
   18812            2 :               return Expression::make_error(location);
   18813              :             }
   18814              : 
   18815       110385 :           if (!indexes->empty() && index < indexes->back())
   18816              :             indexes_out_of_order = true;
   18817              : 
   18818       110385 :           indexes->push_back(index);
   18819       110398 :         }
   18820              : 
   18821       110407 :       vals->push_back(val);
   18822              : 
   18823       110407 :       ++index;
   18824              :     }
   18825              : 
   18826          454 :   if (indexes->empty())
   18827              :     {
   18828            0 :       delete indexes;
   18829            0 :       indexes = NULL;
   18830              :     }
   18831              : 
   18832          454 :   std::vector<unsigned long>* traverse_order = NULL;
   18833          454 :   if (indexes_out_of_order)
   18834              :     {
   18835           62 :       typedef std::vector<IVT_triple> V;
   18836              : 
   18837           62 :       V v;
   18838           62 :       v.reserve(indexes->size());
   18839           62 :       std::vector<unsigned long>::const_iterator pi = indexes->begin();
   18840           62 :       unsigned long torder = 0;
   18841           62 :       for (Expression_list::const_iterator pe = vals->begin();
   18842         1943 :            pe != vals->end();
   18843         1881 :            ++pe, ++pi, ++torder)
   18844         1881 :         v.push_back(IVT_triple(*pi, torder, *pe));
   18845              : 
   18846           62 :       std::sort(v.begin(), v.end());
   18847              : 
   18848           62 :       delete indexes;
   18849           62 :       delete vals;
   18850              : 
   18851           62 :       indexes = new std::vector<unsigned long>();
   18852           62 :       indexes->reserve(v.size());
   18853           62 :       vals = new Expression_list();
   18854           62 :       vals->reserve(v.size());
   18855           62 :       traverse_order = new std::vector<unsigned long>();
   18856           62 :       traverse_order->reserve(v.size());
   18857              : 
   18858         1943 :       for (V::const_iterator pv = v.begin(); pv != v.end(); ++pv)
   18859              :         {
   18860         1881 :           indexes->push_back(pv->index);
   18861         1881 :           vals->push_back(pv->expr);
   18862         1881 :           traverse_order->push_back(pv->traversal_order);
   18863              :         }
   18864           62 :     }
   18865              : 
   18866          454 :   Expression* ret = this->make_array(type, indexes, vals);
   18867          454 :   Array_construction_expression* ace = ret->array_literal();
   18868          454 :   if (ace != NULL && traverse_order != NULL)
   18869           55 :     ace->set_traverse_order(traverse_order);
   18870              :   return ret;
   18871              : }
   18872              : 
   18873              : // Actually build the array composite literal. This handles
   18874              : // [...]{...}.
   18875              : 
   18876              : Expression*
   18877        49338 : Composite_literal_expression::make_array(
   18878              :     Type* type,
   18879              :     const std::vector<unsigned long>* indexes,
   18880              :     Expression_list* vals)
   18881              : {
   18882        49338 :   Location location = this->location();
   18883        49338 :   Array_type* at = type->array_type();
   18884              : 
   18885        49338 :   if (at->length() != NULL
   18886        18043 :       && !at->length()->is_error_expression()
   18887        67381 :       && this->vals_ != NULL)
   18888              :     {
   18889        17491 :       Numeric_constant nc;
   18890        17491 :       unsigned long val;
   18891        17491 :       if (at->length()->numeric_constant_value(&nc)
   18892        17491 :           && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID)
   18893              :         {
   18894        17491 :           if (indexes == NULL)
   18895              :             {
   18896        17167 :               if (this->vals_->size() > val)
   18897              :                 {
   18898            1 :                   go_error_at(location,
   18899              :                               "too many elements in composite literal");
   18900            1 :                   return Expression::make_error(location);
   18901              :                 }
   18902              :             }
   18903              :           else
   18904              :             {
   18905          324 :               unsigned long max = indexes->back();
   18906          324 :               if (max >= val)
   18907              :                 {
   18908            5 :                   go_error_at(location,
   18909              :                               ("some element keys in composite literal "
   18910              :                                "are out of range"));
   18911            5 :                   return Expression::make_error(location);
   18912              :                 }
   18913              :             }
   18914              :         }
   18915        17491 :     }
   18916              : 
   18917        49332 :   if (at->length() != NULL)
   18918        18037 :     return new Fixed_array_construction_expression(type, indexes, vals,
   18919        18037 :                                                    location);
   18920              :   else
   18921        31295 :     return new Slice_construction_expression(type, indexes, vals, location);
   18922              : }
   18923              : 
   18924              : // Lower a map composite literal.
   18925              : 
   18926              : Expression*
   18927         3495 : Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
   18928              :                                         Statement_inserter* inserter,
   18929              :                                         Type* type)
   18930              : {
   18931         3495 :   Location location = this->location();
   18932         3495 :   Unordered_map(unsigned int, std::vector<Expression*>) st;
   18933         3495 :   Unordered_map(unsigned int, std::vector<Expression*>) nt;
   18934         3495 :   bool saw_false = false;
   18935         3495 :   bool saw_true = false;
   18936         3495 :   if (this->vals_ != NULL)
   18937              :     {
   18938         2652 :       go_assert(this->has_keys_);
   18939              : 
   18940        32535 :       for (Expression_list::iterator p = this->vals_->begin();
   18941        32535 :            p != this->vals_->end();
   18942        29883 :            p += 2)
   18943              :         {
   18944        29885 :           if (*p == NULL)
   18945              :             {
   18946            1 :               ++p;
   18947            1 :               go_error_at((*p)->location(),
   18948              :                           ("map composite literal must "
   18949              :                            "have keys for every value"));
   18950            2 :               return Expression::make_error(location);
   18951              :             }
   18952              :           // Make sure we have lowered the key; it may not have been
   18953              :           // lowered in order to handle keys for struct composite
   18954              :           // literals.  Lower it now to get the right error message.
   18955        29884 :           if ((*p)->unknown_expression() != NULL)
   18956              :             {
   18957            0 :               gogo->lower_expression(function, inserter, &*p);
   18958            0 :               go_assert((*p)->is_error_expression());
   18959            0 :               return Expression::make_error(location);
   18960              :             }
   18961              :           // Check if there are duplicate constant keys.
   18962        29884 :           if (!(*p)->is_constant())
   18963         1169 :             continue;
   18964        28715 :           std::string sval;
   18965        28715 :           Numeric_constant nval;
   18966        28715 :           bool bval;
   18967        28715 :           if ((*p)->string_constant_value(&sval)) // Check string keys.
   18968              :             {
   18969        25028 :               unsigned int h = Gogo::hash_string(sval, 0);
   18970              :               // Search the index h in the hash map.
   18971        25028 :               Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
   18972        25028 :               mit = st.find(h);
   18973        25028 :               if (mit == st.end())
   18974              :                 {
   18975              :                   // No duplicate since h is a new index.
   18976              :                   // Create a new vector indexed by h and add it to the hash map.
   18977        25027 :                   std::vector<Expression*> l;
   18978        25027 :                   l.push_back(*p);
   18979        25027 :                   std::pair<unsigned int, std::vector<Expression*> > val(h, l);
   18980        25027 :                   st.insert(val);
   18981        25027 :                 }
   18982              :               else
   18983              :                 {
   18984              :                   // Do further check since index h already exists.
   18985            1 :                   for (std::vector<Expression*>::iterator lit =
   18986            1 :                            mit->second.begin();
   18987            1 :                        lit != mit->second.end();
   18988            0 :                        lit++)
   18989              :                     {
   18990            1 :                       std::string s;
   18991            1 :                       bool ok = (*lit)->string_constant_value(&s);
   18992            1 :                       go_assert(ok);
   18993            1 :                       if (s == sval)
   18994              :                         {
   18995            1 :                           go_error_at((*p)->location(), ("duplicate key "
   18996              :                                       "in map literal"));
   18997            1 :                           return Expression::make_error(location);
   18998              :                         }
   18999            1 :                     }
   19000              :                   // Add this new string key to the vector indexed by h.
   19001            0 :                   mit->second.push_back(*p);
   19002              :                 }
   19003              :             }
   19004         3687 :           else if ((*p)->numeric_constant_value(&nval))
   19005              :             {
   19006              :               // Check numeric keys.
   19007         3663 :               unsigned int h = nval.hash(0);
   19008         3663 :               Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
   19009         3663 :               mit = nt.find(h);
   19010         3663 :               if (mit == nt.end())
   19011              :                 {
   19012              :                   // No duplicate since h is a new code.
   19013              :                   // Create a new vector indexed by h and add it to the hash map.
   19014         3659 :                   std::vector<Expression*> l;
   19015         3659 :                   l.push_back(*p);
   19016         3659 :                   std::pair<unsigned int, std::vector<Expression*> > val(h, l);
   19017         3659 :                   nt.insert(val);
   19018         3659 :                 }
   19019              :               else
   19020              :                 {
   19021              :                   // Do further check since h already exists.
   19022            8 :                   for (std::vector<Expression*>::iterator lit =
   19023            4 :                            mit->second.begin();
   19024            8 :                        lit != mit->second.end();
   19025            4 :                        lit++)
   19026              :                     {
   19027            4 :                       Numeric_constant rval;
   19028            4 :                       bool ok = (*lit)->numeric_constant_value(&rval);
   19029            4 :                       go_assert(ok);
   19030            4 :                       if (nval.equals(rval))
   19031              :                         {
   19032            0 :                           go_error_at((*p)->location(),
   19033              :                                       "duplicate key in map literal");
   19034            0 :                           return Expression::make_error(location);
   19035              :                         }
   19036            4 :                     }
   19037              :                   // Add this new numeric key to the vector indexed by h.
   19038            4 :                   mit->second.push_back(*p);
   19039              :                 }
   19040              :             }
   19041           24 :           else if ((*p)->boolean_constant_value(&bval))
   19042              :             {
   19043           17 :               if ((bval && saw_true) || (!bval && saw_false))
   19044              :                 {
   19045            0 :                   go_error_at((*p)->location(),
   19046              :                               "duplicate key in map literal");
   19047            0 :                   return Expression::make_error(location);
   19048              :                 }
   19049           17 :               if (bval)
   19050              :                 saw_true = true;
   19051              :               else
   19052            7 :                 saw_false = true;
   19053              :             }
   19054        28715 :         }
   19055              :     }
   19056              : 
   19057         3493 :   return new Map_construction_expression(type, this->vals_, location);
   19058         3495 : }
   19059              : 
   19060              : // Copy.
   19061              : 
   19062              : Expression*
   19063            3 : Composite_literal_expression::do_copy()
   19064              : {
   19065            3 :   Composite_literal_expression* ret =
   19066            3 :     new Composite_literal_expression(this->type_->copy_expressions(),
   19067            3 :                                      this->depth_, this->has_keys_,
   19068            3 :                                      (this->vals_ == NULL
   19069              :                                       ? NULL
   19070            0 :                                       : this->vals_->copy()),
   19071            3 :                                      this->all_are_names_,
   19072            3 :                                      this->location());
   19073            3 :   ret->key_path_ = this->key_path_;
   19074            3 :   return ret;
   19075              : }
   19076              : 
   19077              : // Dump ast representation for a composite literal expression.
   19078              : 
   19079              : void
   19080            0 : Composite_literal_expression::do_dump_expression(
   19081              :                                Ast_dump_context* ast_dump_context) const
   19082              : {
   19083            0 :   ast_dump_context->ostream() << "composite(";
   19084            0 :   ast_dump_context->dump_type(this->type_);
   19085            0 :   ast_dump_context->ostream() << ", {";
   19086            0 :   ast_dump_context->dump_expression_list(this->vals_, this->has_keys_);
   19087            0 :   ast_dump_context->ostream() << "})";
   19088            0 : }
   19089              : 
   19090              : // Make a composite literal expression.
   19091              : 
   19092              : Expression*
   19093       226854 : Expression::make_composite_literal(Type* type, int depth, bool has_keys,
   19094              :                                    Expression_list* vals, bool all_are_names,
   19095              :                                    Location location)
   19096              : {
   19097       226854 :   return new Composite_literal_expression(type, depth, has_keys, vals,
   19098       226854 :                                           all_are_names, location);
   19099              : }
   19100              : 
   19101              : // Return whether this expression is a composite literal.
   19102              : 
   19103              : bool
   19104      4399637 : Expression::is_composite_literal() const
   19105              : {
   19106      4399637 :   switch (this->classification_)
   19107              :     {
   19108              :     case EXPRESSION_COMPOSITE_LITERAL:
   19109              :     case EXPRESSION_STRUCT_CONSTRUCTION:
   19110              :     case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
   19111              :     case EXPRESSION_SLICE_CONSTRUCTION:
   19112              :     case EXPRESSION_MAP_CONSTRUCTION:
   19113              :       return true;
   19114      3979256 :     default:
   19115      3979256 :       return false;
   19116              :     }
   19117              : }
   19118              : 
   19119              : // Return whether this expression is a composite literal which is not
   19120              : // constant.
   19121              : 
   19122              : bool
   19123         1079 : Expression::is_nonconstant_composite_literal() const
   19124              : {
   19125         1079 :   switch (this->classification_)
   19126              :     {
   19127            0 :     case EXPRESSION_STRUCT_CONSTRUCTION:
   19128            0 :       {
   19129            0 :         const Struct_construction_expression *psce =
   19130              :           static_cast<const Struct_construction_expression*>(this);
   19131            0 :         return !psce->is_constant_struct();
   19132              :       }
   19133            0 :     case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
   19134            0 :       {
   19135            0 :         const Fixed_array_construction_expression *pace =
   19136              :           static_cast<const Fixed_array_construction_expression*>(this);
   19137            0 :         return !pace->is_constant_array();
   19138              :       }
   19139            0 :     case EXPRESSION_SLICE_CONSTRUCTION:
   19140            0 :       {
   19141            0 :         const Slice_construction_expression *pace =
   19142              :           static_cast<const Slice_construction_expression*>(this);
   19143            0 :         return !pace->is_constant_array();
   19144              :       }
   19145              :     case EXPRESSION_MAP_CONSTRUCTION:
   19146              :       return true;
   19147         1079 :     default:
   19148         1079 :       return false;
   19149              :     }
   19150              : }
   19151              : 
   19152              : // Return true if this is a variable or temporary_variable.
   19153              : 
   19154              : bool
   19155            0 : Expression::is_variable() const
   19156              : {
   19157            0 :   switch (this->classification_)
   19158              :     {
   19159              :     case EXPRESSION_VAR_REFERENCE:
   19160              :     case EXPRESSION_TEMPORARY_REFERENCE:
   19161              :     case EXPRESSION_SET_AND_USE_TEMPORARY:
   19162              :     case EXPRESSION_ENCLOSED_VAR_REFERENCE:
   19163              :       return true;
   19164            0 :     default:
   19165            0 :       return false;
   19166              :     }
   19167              : }
   19168              : 
   19169              : // Return true if this is a reference to a local variable.
   19170              : 
   19171              : bool
   19172            0 : Expression::is_local_variable() const
   19173              : {
   19174            0 :   const Var_expression* ve = this->var_expression();
   19175            0 :   if (ve == NULL)
   19176              :     return false;
   19177            0 :   const Named_object* no = ve->named_object();
   19178            0 :   return (no->is_result_variable()
   19179            0 :           || (no->is_variable() && !no->var_value()->is_global()));
   19180              : }
   19181              : 
   19182              : // Return true if multiple evaluations are OK.
   19183              : 
   19184              : bool
   19185      2787582 : Expression::is_multi_eval_safe()
   19186              : {
   19187      2787582 :   switch (this->classification_)
   19188              :     {
   19189      1050133 :     case EXPRESSION_VAR_REFERENCE:
   19190      1050133 :       {
   19191              :         // A variable is a simple reference if not stored in the heap.
   19192      1050133 :         const Named_object* no = this->var_expression()->named_object();
   19193      1050133 :         if (no->is_variable())
   19194      2085286 :           return !no->var_value()->is_in_heap();
   19195         7490 :         else if (no->is_result_variable())
   19196         7490 :           return !no->result_var_value()->is_in_heap();
   19197              :         else
   19198            0 :           go_unreachable();
   19199              :       }
   19200              : 
   19201              :     case EXPRESSION_TEMPORARY_REFERENCE:
   19202              :       return true;
   19203              : 
   19204       837375 :     default:
   19205       837375 :       break;
   19206              :     }
   19207              : 
   19208       837375 :   if (!this->is_constant())
   19209              :     return false;
   19210              : 
   19211              :   // Only numeric and boolean constants are really multi-evaluation
   19212              :   // safe.  We don't want multiple copies of string constants.
   19213       425230 :   Type* type = this->type();
   19214       496611 :   return type->is_numeric_type() || type->is_boolean_type();
   19215              : }
   19216              : 
   19217              : const Named_object*
   19218       348206 : Expression::named_constant() const
   19219              : {
   19220       348206 :   if (this->classification() != EXPRESSION_CONST_REFERENCE)
   19221              :     return NULL;
   19222        38611 :   const Const_expression* ce = static_cast<const Const_expression*>(this);
   19223        38611 :   return ce->named_object();
   19224              : }
   19225              : 
   19226              : // Class Type_guard_expression.
   19227              : 
   19228              : // Traversal.
   19229              : 
   19230              : int
   19231       247595 : Type_guard_expression::do_traverse(Traverse* traverse)
   19232              : {
   19233       247595 :   if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
   19234       247595 :       || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
   19235         4659 :     return TRAVERSE_EXIT;
   19236              :   return TRAVERSE_CONTINUE;
   19237              : }
   19238              : 
   19239              : Expression*
   19240        13894 : Type_guard_expression::do_flatten(Gogo*, Named_object*,
   19241              :                                   Statement_inserter* inserter)
   19242              : {
   19243        13894 :   if (this->expr_->is_error_expression()
   19244        13894 :       || this->expr_->type()->is_error_type())
   19245              :     {
   19246            0 :       go_assert(saw_errors());
   19247            0 :       return Expression::make_error(this->location());
   19248              :     }
   19249              : 
   19250        13894 :   if (!this->expr_->is_multi_eval_safe())
   19251              :     {
   19252         1608 :       Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_,
   19253              :                                                             this->location());
   19254         1608 :       inserter->insert(temp);
   19255         1608 :       this->expr_ =
   19256         1608 :           Expression::make_temporary_reference(temp, this->location());
   19257              :     }
   19258        13894 :   return this;
   19259              : }
   19260              : 
   19261              : // Check types of a type guard expression.  The expression must have
   19262              : // an interface type, but the actual type conversion is checked at run
   19263              : // time.
   19264              : 
   19265              : void
   19266        13803 : Type_guard_expression::do_check_types(Gogo*)
   19267              : {
   19268        13803 :   Type* expr_type = this->expr_->type();
   19269        13803 :   if (expr_type->interface_type() == NULL)
   19270              :     {
   19271            1 :       if (!expr_type->is_error() && !this->type_->is_error())
   19272            1 :         this->report_error(_("type assertion only valid for interface types"));
   19273            1 :       this->set_is_error();
   19274              :     }
   19275        13802 :   else if (this->type_->interface_type() == NULL)
   19276              :     {
   19277        12780 :       std::string reason;
   19278        25560 :       if (!expr_type->interface_type()->implements_interface(this->type_,
   19279              :                                                              &reason))
   19280              :         {
   19281            3 :           if (!this->type_->is_error())
   19282              :             {
   19283            3 :               if (reason.empty())
   19284            0 :                 this->report_error(_("impossible type assertion: "
   19285              :                                      "type does not implement interface"));
   19286              :               else
   19287            3 :                 go_error_at(this->location(),
   19288              :                             ("impossible type assertion: "
   19289              :                              "type does not implement interface (%s)"),
   19290              :                             reason.c_str());
   19291              :             }
   19292            3 :           this->set_is_error();
   19293              :         }
   19294        12780 :     }
   19295        13803 : }
   19296              : 
   19297              : // Copy.
   19298              : 
   19299              : Expression*
   19300            0 : Type_guard_expression::do_copy()
   19301              : {
   19302            0 :   return new Type_guard_expression(this->expr_->copy(),
   19303            0 :                                    this->type_->copy_expressions(),
   19304            0 :                                    this->location());
   19305              : }
   19306              : 
   19307              : // Return the backend representation for a type guard expression.
   19308              : 
   19309              : Bexpression*
   19310        13541 : Type_guard_expression::do_get_backend(Translate_context* context)
   19311              : {
   19312        13541 :   Expression* conversion;
   19313        13541 :   if (this->type_->interface_type() != NULL)
   19314         1016 :     conversion = Expression::convert_interface_to_interface(context->gogo(),
   19315              :                                                             this->type_,
   19316              :                                                             this->expr_,
   19317              :                                                             true,
   19318              :                                                             this->location());
   19319              :   else
   19320        12525 :     conversion = Expression::convert_for_assignment(context->gogo(),
   19321              :                                                     this->type_,
   19322              :                                                     this->expr_,
   19323              :                                                     this->location());
   19324              : 
   19325        13541 :   Gogo* gogo = context->gogo();
   19326        13541 :   Btype* bt = this->type_->get_backend(gogo);
   19327        13541 :   Bexpression* bexpr = conversion->get_backend(context);
   19328        13541 :   return gogo->backend()->convert_expression(bt, bexpr, this->location());
   19329              : }
   19330              : 
   19331              : // Dump ast representation for a type guard expression.
   19332              : 
   19333              : void
   19334            0 : Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
   19335              :     const
   19336              : {
   19337            0 :   this->expr_->dump_expression(ast_dump_context);
   19338            0 :   ast_dump_context->ostream() <<  ".";
   19339            0 :   ast_dump_context->dump_type(this->type_);
   19340            0 : }
   19341              : 
   19342              : // Make a type guard expression.
   19343              : 
   19344              : Expression*
   19345        20347 : Expression::make_type_guard(Expression* expr, Type* type,
   19346              :                             Location location)
   19347              : {
   19348        20347 :   return new Type_guard_expression(expr, type, location);
   19349              : }
   19350              : 
   19351              : // Class Heap_expression.
   19352              : 
   19353              : // Return the type of the expression stored on the heap.
   19354              : 
   19355              : Type*
   19356       693954 : Heap_expression::do_type()
   19357       693954 : { return Type::make_pointer_type(this->expr_->type()); }
   19358              : 
   19359              : // Return the backend representation for allocating an expression on the heap.
   19360              : 
   19361              : Bexpression*
   19362       204189 : Heap_expression::do_get_backend(Translate_context* context)
   19363              : {
   19364       204189 :   Type* etype = this->expr_->type();
   19365       204189 :   if (this->expr_->is_error_expression() || etype->is_error())
   19366            5 :     return context->backend()->error_expression();
   19367              : 
   19368       204184 :   Location loc = this->location();
   19369       204184 :   Gogo* gogo = context->gogo();
   19370       204184 :   Btype* btype = this->type()->get_backend(gogo);
   19371              : 
   19372       204184 :   Expression* alloc = Expression::make_allocation(etype, loc);
   19373       204184 :   if (this->allocate_on_stack_)
   19374        19415 :     alloc->allocation_expression()->set_allocate_on_stack();
   19375       204184 :   Bexpression* space = alloc->get_backend(context);
   19376              : 
   19377       204184 :   Bstatement* decl;
   19378       204184 :   Named_object* fn = context->function();
   19379       204184 :   go_assert(fn != NULL);
   19380       204184 :   Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
   19381       204184 :   Bvariable* space_temp =
   19382       204184 :     gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
   19383              :                                         space,
   19384              :                                         Backend::variable_address_is_taken,
   19385              :                                         loc, &decl);
   19386       204184 :   Btype* expr_btype = etype->get_backend(gogo);
   19387              : 
   19388       204184 :   Bexpression* bexpr = this->expr_->get_backend(context);
   19389              : 
   19390              :   // If this assignment needs a write barrier, call typedmemmove.  We
   19391              :   // don't do this in the write barrier pass because in some cases
   19392              :   // backend conversion can introduce new Heap_expression values.
   19393       204184 :   Bstatement* assn;
   19394       204184 :   if (!etype->has_pointer() || this->allocate_on_stack_)
   19395              :     {
   19396        74124 :       space = gogo->backend()->var_expression(space_temp, loc);
   19397        74124 :       Bexpression* ref =
   19398        74124 :         gogo->backend()->indirect_expression(expr_btype, space, true, loc);
   19399        74124 :       assn = gogo->backend()->assignment_statement(fndecl, ref, bexpr, loc);
   19400              :     }
   19401              :   else
   19402              :     {
   19403       130060 :       Bstatement* edecl;
   19404       130060 :       Bvariable* btemp =
   19405       130060 :         gogo->backend()->temporary_variable(fndecl, context->bblock(),
   19406              :                                             expr_btype, bexpr,
   19407              :                                             Backend::variable_address_is_taken,
   19408              :                                             loc, &edecl);
   19409       130060 :       Bexpression* btempref = gogo->backend()->var_expression(btemp,
   19410              :                                                               loc);
   19411       130060 :       space = gogo->backend()->var_expression(space_temp, loc);
   19412       130060 :       Type* etype_ptr = Type::make_pointer_type(etype);
   19413       130060 :       Expression* elhs = Expression::make_backend(space, etype_ptr, loc);
   19414       130060 :       Expression* erhs;
   19415       130060 :       Expression* call;
   19416       130060 :       if (etype->is_direct_iface_type())
   19417              :         {
   19418              :           // Single pointer.
   19419         4672 :           Type* uintptr_type = Type::lookup_integer_type("uintptr");
   19420         4672 :           erhs = Expression::make_backend(btempref, etype, loc);
   19421         4672 :           erhs = Expression::unpack_direct_iface(erhs, loc);
   19422         4672 :           erhs = Expression::make_unsafe_cast(uintptr_type, erhs, loc);
   19423         4672 :           call = Runtime::make_call(gogo, Runtime::GCWRITEBARRIER, loc, 2,
   19424              :                                     elhs, erhs);
   19425              :         }
   19426              :       else
   19427              :         {
   19428       125388 :           Expression* td = Expression::make_type_descriptor(etype, loc);
   19429       125388 :           Bexpression* addr =
   19430       125388 :             gogo->backend()->address_expression(btempref, loc);
   19431       125388 :           erhs = Expression::make_backend(addr, etype_ptr, loc);
   19432       125388 :           call = Runtime::make_call(gogo, Runtime::TYPEDMEMMOVE, loc, 3,
   19433              :                                     td, elhs, erhs);
   19434              :         }
   19435       130060 :       Statement* cs = Statement::make_statement(call, false);
   19436              : 
   19437       130060 :       space = gogo->backend()->var_expression(space_temp, loc);
   19438       130060 :       Bexpression* ref =
   19439       130060 :         gogo->backend()->indirect_expression(expr_btype, space, true, loc);
   19440       130060 :       Expression* eref = Expression::make_backend(ref, etype, loc);
   19441       130060 :       btempref = gogo->backend()->var_expression(btemp, loc);
   19442       130060 :       erhs = Expression::make_backend(btempref, etype, loc);
   19443       130060 :       Statement* as = Statement::make_assignment(eref, erhs, loc);
   19444              : 
   19445       130060 :       as = gogo->check_write_barrier(context->block(), as, cs);
   19446       130060 :       Bstatement* s = as->get_backend(context);
   19447              : 
   19448       130060 :       assn = gogo->backend()->compound_statement(edecl, s);
   19449              :     }
   19450       204184 :   decl = gogo->backend()->compound_statement(decl, assn);
   19451       204184 :   space = gogo->backend()->var_expression(space_temp, loc);
   19452       204184 :   return gogo->backend()->compound_expression(decl, space, loc);
   19453              : }
   19454              : 
   19455              : // Dump ast representation for a heap expression.
   19456              : 
   19457              : void
   19458            0 : Heap_expression::do_dump_expression(
   19459              :     Ast_dump_context* ast_dump_context) const
   19460              : {
   19461            0 :   ast_dump_context->ostream() << "&(";
   19462            0 :   ast_dump_context->dump_expression(this->expr_);
   19463            0 :   ast_dump_context->ostream() << ")";
   19464            0 : }
   19465              : 
   19466              : // Allocate an expression on the heap.
   19467              : 
   19468              : Expression*
   19469       204263 : Expression::make_heap_expression(Expression* expr, Location location)
   19470              : {
   19471       204263 :   return new Heap_expression(expr, location);
   19472              : }
   19473              : 
   19474              : // Class Receive_expression.
   19475              : 
   19476              : // Return the type of a receive expression.
   19477              : 
   19478              : Type*
   19479         9704 : Receive_expression::do_type()
   19480              : {
   19481         9704 :   if (this->is_error_expression())
   19482            2 :     return Type::make_error_type();
   19483         9702 :   Channel_type* channel_type = this->channel_->type()->channel_type();
   19484         9702 :   if (channel_type == NULL)
   19485              :     {
   19486            0 :       this->report_error(_("expected channel"));
   19487            0 :       return Type::make_error_type();
   19488              :     }
   19489         9702 :   return channel_type->element_type();
   19490              : }
   19491              : 
   19492              : // Check types for a receive expression.
   19493              : 
   19494              : void
   19495         1986 : Receive_expression::do_check_types(Gogo*)
   19496              : {
   19497         1986 :   Type* type = this->channel_->type();
   19498         1986 :   if (type->is_error())
   19499              :     {
   19500            0 :       go_assert(saw_errors());
   19501            0 :       this->set_is_error();
   19502            0 :       return;
   19503              :     }
   19504         1986 :   if (type->channel_type() == NULL)
   19505              :     {
   19506            1 :       this->report_error(_("expected channel"));
   19507            1 :       return;
   19508              :     }
   19509         3970 :   if (!type->channel_type()->may_receive())
   19510              :     {
   19511            1 :       this->report_error(_("invalid receive on send-only channel"));
   19512            1 :       return;
   19513              :     }
   19514              : }
   19515              : 
   19516              : // Flattening for receive expressions creates a temporary variable to store
   19517              : // received data in for receives.
   19518              : 
   19519              : Expression*
   19520         2042 : Receive_expression::do_flatten(Gogo*, Named_object*,
   19521              :                                Statement_inserter* inserter)
   19522              : {
   19523         2042 :   Channel_type* channel_type = this->channel_->type()->channel_type();
   19524         2042 :   if (channel_type == NULL)
   19525              :     {
   19526            1 :       go_assert(saw_errors());
   19527            1 :       return this;
   19528              :     }
   19529         2041 :   else if (this->channel_->is_error_expression())
   19530              :    {
   19531            0 :      go_assert(saw_errors());
   19532            0 :      return Expression::make_error(this->location());
   19533              :    }
   19534              : 
   19535         2041 :   Type* element_type = channel_type->element_type();
   19536         2041 :   if (this->temp_receiver_ == NULL)
   19537              :     {
   19538         2033 :       this->temp_receiver_ = Statement::make_temporary(element_type, NULL,
   19539              :                                                        this->location());
   19540         2033 :       this->temp_receiver_->set_is_address_taken();
   19541         2033 :       inserter->insert(this->temp_receiver_);
   19542              :     }
   19543              : 
   19544         2041 :   return this;
   19545              : }
   19546              : 
   19547              : // Get the backend representation for a receive expression.
   19548              : 
   19549              : Bexpression*
   19550         2021 : Receive_expression::do_get_backend(Translate_context* context)
   19551              : {
   19552         2021 :   Location loc = this->location();
   19553              : 
   19554         2021 :   Channel_type* channel_type = this->channel_->type()->channel_type();
   19555         2021 :   if (channel_type == NULL)
   19556              :     {
   19557            0 :       go_assert(this->channel_->type()->is_error());
   19558            0 :       return context->backend()->error_expression();
   19559              :     }
   19560              : 
   19561         2021 :   Gogo* gogo = context->gogo();
   19562         2021 :   Expression* recv_ref =
   19563         2021 :     Expression::make_temporary_reference(this->temp_receiver_, loc);
   19564         2021 :   Expression* recv_addr =
   19565         2021 :     Expression::make_temporary_reference(this->temp_receiver_, loc);
   19566         2021 :   recv_addr = Expression::make_unary(OPERATOR_AND, recv_addr, loc);
   19567         2021 :   Expression* recv = Runtime::make_call(gogo, Runtime::CHANRECV1, loc, 2,
   19568              :                                         this->channel_, recv_addr);
   19569         2021 :   Expression* ret = Expression::make_compound(recv, recv_ref, loc);
   19570         2021 :   ret->determine_type_no_context(gogo);
   19571         2021 :   return ret->get_backend(context);
   19572              : }
   19573              : 
   19574              : // Export a receive expression.
   19575              : 
   19576              : void
   19577           17 : Receive_expression::do_export(Export_function_body* efb) const
   19578              : {
   19579           17 :   efb->write_c_string("<-");
   19580           17 :   this->channel_->export_expression(efb);
   19581           17 : }
   19582              : 
   19583              : // Dump ast representation for a receive expression.
   19584              : 
   19585              : void
   19586            0 : Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
   19587              : {
   19588            0 :   ast_dump_context->ostream() << " <- " ;
   19589            0 :   ast_dump_context->dump_expression(channel_);
   19590            0 : }
   19591              : 
   19592              : // Import a receive expression.
   19593              : 
   19594              : Expression*
   19595            0 : Receive_expression::do_import(Import_expression* imp, Location loc)
   19596              : {
   19597            0 :   imp->require_c_string("<-");
   19598            0 :   Expression* expr = Expression::import_expression(imp, loc);
   19599            0 :   return Expression::make_receive(expr, loc);
   19600              : }
   19601              : 
   19602              : // Make a receive expression.
   19603              : 
   19604              : Receive_expression*
   19605         4139 : Expression::make_receive(Expression* channel, Location location)
   19606              : {
   19607         4139 :   return new Receive_expression(channel, location);
   19608              : }
   19609              : 
   19610              : // An expression which evaluates to a pointer to the type descriptor
   19611              : // of a type.
   19612              : 
   19613              : class Type_descriptor_expression : public Expression
   19614              : {
   19615              :  public:
   19616      1914692 :   Type_descriptor_expression(Type* type, Location location)
   19617      1914692 :     : Expression(EXPRESSION_TYPE_DESCRIPTOR, location),
   19618      3829384 :       type_(type)
   19619              :   { }
   19620              : 
   19621              :  protected:
   19622              :   int
   19623              :   do_traverse(Traverse*);
   19624              : 
   19625              :   Type*
   19626      2181911 :   do_type()
   19627      2181911 :   { return Type::make_type_descriptor_ptr_type(); }
   19628              : 
   19629              :   bool
   19630      1392074 :   do_is_static_initializer() const
   19631      1392074 :   { return true; }
   19632              : 
   19633              :   void
   19634      2068040 :   do_determine_type(Gogo*, const Type_context*)
   19635      2068040 :   { }
   19636              : 
   19637              :   Expression*
   19638        12525 :   do_copy()
   19639        12525 :   { return this; }
   19640              : 
   19641              :   Bexpression*
   19642      1327815 :   do_get_backend(Translate_context* context)
   19643              :   {
   19644      1327815 :     return this->type_->type_descriptor_pointer(context->gogo(),
   19645      1327815 :                                                 this->location());
   19646              :   }
   19647              : 
   19648              :   void
   19649              :   do_dump_expression(Ast_dump_context*) const;
   19650              : 
   19651              :  private:
   19652              :   // The type for which this is the descriptor.
   19653              :   Type* type_;
   19654              : };
   19655              : 
   19656              : int
   19657       683098 : Type_descriptor_expression::do_traverse(Traverse* traverse)
   19658              : {
   19659       683098 :   if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
   19660            0 :     return TRAVERSE_EXIT;
   19661              :   return TRAVERSE_CONTINUE;
   19662              : }
   19663              : 
   19664              : // Dump ast representation for a type descriptor expression.
   19665              : 
   19666              : void
   19667            0 : Type_descriptor_expression::do_dump_expression(
   19668              :     Ast_dump_context* ast_dump_context) const
   19669              : {
   19670            0 :   ast_dump_context->dump_type(this->type_);
   19671            0 : }
   19672              : 
   19673              : // Make a type descriptor expression.
   19674              : 
   19675              : Expression*
   19676      1914692 : Expression::make_type_descriptor(Type* type, Location location)
   19677              : {
   19678      1914692 :   return new Type_descriptor_expression(type, location);
   19679              : }
   19680              : 
   19681              : // An expression which evaluates to a pointer to the Garbage Collection symbol
   19682              : // of a type.
   19683              : 
   19684              : class GC_symbol_expression : public Expression
   19685              : {
   19686              :  public:
   19687       243677 :   GC_symbol_expression(Type* type)
   19688       243677 :     : Expression(EXPRESSION_GC_SYMBOL, Linemap::predeclared_location()),
   19689       243677 :       type_(type)
   19690       243677 :   {}
   19691              : 
   19692              :  protected:
   19693              :   Type*
   19694       212643 :   do_type()
   19695       212643 :   { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
   19696              : 
   19697              :   bool
   19698            0 :   do_is_static_initializer() const
   19699            0 :   { return true; }
   19700              : 
   19701              :   void
   19702       278070 :   do_determine_type(Gogo*, const Type_context*)
   19703       278070 :   { }
   19704              : 
   19705              :   Expression*
   19706            0 :   do_copy()
   19707            0 :   { return this; }
   19708              : 
   19709              :   Bexpression*
   19710       212643 :   do_get_backend(Translate_context* context)
   19711       212643 :   { return this->type_->gc_symbol_pointer(context->gogo()); }
   19712              : 
   19713              :   void
   19714              :   do_dump_expression(Ast_dump_context*) const;
   19715              : 
   19716              :  private:
   19717              :   // The type which this gc symbol describes.
   19718              :   Type* type_;
   19719              : };
   19720              : 
   19721              : // Dump ast representation for a gc symbol expression.
   19722              : 
   19723              : void
   19724            0 : GC_symbol_expression::do_dump_expression(
   19725              :     Ast_dump_context* ast_dump_context) const
   19726              : {
   19727            0 :   ast_dump_context->ostream() << "gcdata(";
   19728            0 :   ast_dump_context->dump_type(this->type_);
   19729            0 :   ast_dump_context->ostream() << ")";
   19730            0 : }
   19731              : 
   19732              : // Make a gc symbol expression.
   19733              : 
   19734              : Expression*
   19735       243677 : Expression::make_gc_symbol(Type* type)
   19736              : {
   19737       243677 :   return new GC_symbol_expression(type);
   19738              : }
   19739              : 
   19740              : // An expression that evaluates to a pointer to a symbol holding the
   19741              : // ptrmask data of a type.
   19742              : 
   19743              : class Ptrmask_symbol_expression : public Expression
   19744              : {
   19745              :  public:
   19746        22049 :   Ptrmask_symbol_expression(Type* type)
   19747        22049 :     : Expression(EXPRESSION_PTRMASK_SYMBOL, Linemap::predeclared_location()),
   19748        22049 :       type_(type)
   19749        22049 :   {}
   19750              : 
   19751              :  protected:
   19752              :   Type*
   19753        44098 :   do_type()
   19754        44098 :   { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
   19755              : 
   19756              :   bool
   19757        22049 :   do_is_static_initializer() const
   19758        22049 :   { return true; }
   19759              : 
   19760              :   void
   19761        22049 :   do_determine_type(Gogo*, const Type_context*)
   19762        22049 :   { }
   19763              : 
   19764              :   Expression*
   19765            0 :   do_copy()
   19766            0 :   { return this; }
   19767              : 
   19768              :   Bexpression*
   19769              :   do_get_backend(Translate_context*);
   19770              : 
   19771              :   void
   19772              :   do_dump_expression(Ast_dump_context*) const;
   19773              : 
   19774              :  private:
   19775              :   // The type that this ptrmask symbol describes.
   19776              :   Type* type_;
   19777              : };
   19778              : 
   19779              : // Return the ptrmask variable.
   19780              : 
   19781              : Bexpression*
   19782        22049 : Ptrmask_symbol_expression::do_get_backend(Translate_context* context)
   19783              : {
   19784        22049 :   Gogo* gogo = context->gogo();
   19785              : 
   19786              :   // If this type does not need a gcprog, then we can use the standard
   19787              :   // GC symbol.
   19788        22049 :   int64_t ptrsize, ptrdata;
   19789        22049 :   if (!this->type_->needs_gcprog(gogo, &ptrsize, &ptrdata))
   19790        22036 :     return this->type_->gc_symbol_pointer(gogo);
   19791              : 
   19792              :   // Otherwise we have to build a ptrmask variable, and return a
   19793              :   // pointer to it.
   19794              : 
   19795           13 :   Bvariable* bvar = this->type_->gc_ptrmask_var(gogo, ptrsize, ptrdata);
   19796           13 :   Location bloc = Linemap::predeclared_location();
   19797           13 :   Bexpression* bref = gogo->backend()->var_expression(bvar, bloc);
   19798           13 :   Bexpression* baddr = gogo->backend()->address_expression(bref, bloc);
   19799              : 
   19800           13 :   Type* uint8_type = Type::lookup_integer_type("uint8");
   19801           13 :   Type* pointer_uint8_type = Type::make_pointer_type(uint8_type);
   19802           13 :   Btype* ubtype = pointer_uint8_type->get_backend(gogo);
   19803           13 :   return gogo->backend()->convert_expression(ubtype, baddr, bloc);
   19804              : }
   19805              : 
   19806              : // Dump AST for a ptrmask symbol expression.
   19807              : 
   19808              : void
   19809            0 : Ptrmask_symbol_expression::do_dump_expression(
   19810              :     Ast_dump_context* ast_dump_context) const
   19811              : {
   19812            0 :   ast_dump_context->ostream() << "ptrmask(";
   19813            0 :   ast_dump_context->dump_type(this->type_);
   19814            0 :   ast_dump_context->ostream() << ")";
   19815            0 : }
   19816              : 
   19817              : // Make a ptrmask symbol expression.
   19818              : 
   19819              : Expression*
   19820        22049 : Expression::make_ptrmask_symbol(Type* type)
   19821              : {
   19822        22049 :   return new Ptrmask_symbol_expression(type);
   19823              : }
   19824              : 
   19825              : // An expression which evaluates to some characteristic of a type.
   19826              : // This is only used to initialize fields of a type descriptor.  Using
   19827              : // a new expression class is slightly inefficient but gives us a good
   19828              : // separation between the frontend and the middle-end with regard to
   19829              : // how types are laid out.
   19830              : 
   19831              : class Type_info_expression : public Expression
   19832              : {
   19833              :  public:
   19834      1155709 :   Type_info_expression(Type* type, Type_info type_info)
   19835      1155709 :     : Expression(EXPRESSION_TYPE_INFO, Linemap::predeclared_location()),
   19836      1155709 :       type_(type), type_info_(type_info)
   19837      1155709 :   { }
   19838              : 
   19839              :  protected:
   19840              :   bool
   19841        44098 :   do_is_static_initializer() const
   19842        44098 :   { return true; }
   19843              : 
   19844              :   Type*
   19845              :   do_type();
   19846              : 
   19847              :   void
   19848      1434377 :   do_determine_type(Gogo*, const Type_context*)
   19849      1434377 :   { }
   19850              : 
   19851              :   Expression*
   19852            0 :   do_copy()
   19853            0 :   { return this; }
   19854              : 
   19855              :   Bexpression*
   19856              :   do_get_backend(Translate_context* context);
   19857              : 
   19858              :   void
   19859              :   do_dump_expression(Ast_dump_context*) const;
   19860              : 
   19861              :  private:
   19862              :   // The type for which we are getting information.
   19863              :   Type* type_;
   19864              :   // What information we want.
   19865              :   Type_info type_info_;
   19866              : };
   19867              : 
   19868              : // The type is chosen to match what the type descriptor struct
   19869              : // expects.
   19870              : 
   19871              : Type*
   19872      2102869 : Type_info_expression::do_type()
   19873              : {
   19874      2102869 :   switch (this->type_info_)
   19875              :     {
   19876      1119053 :     case TYPE_INFO_SIZE:
   19877      1119053 :     case TYPE_INFO_BACKEND_PTRDATA:
   19878      1119053 :     case TYPE_INFO_DESCRIPTOR_PTRDATA:
   19879      1119053 :       return Type::lookup_integer_type("uintptr");
   19880       983816 :     case TYPE_INFO_ALIGNMENT:
   19881       983816 :     case TYPE_INFO_FIELD_ALIGNMENT:
   19882       983816 :       return Type::lookup_integer_type("uint8");
   19883            0 :     default:
   19884            0 :       go_unreachable();
   19885              :     }
   19886              : }
   19887              : 
   19888              : // Return the backend representation for type information.
   19889              : 
   19890              : Bexpression*
   19891      1011701 : Type_info_expression::do_get_backend(Translate_context* context)
   19892              : {
   19893      1011701 :   Gogo* gogo = context->gogo();
   19894      1011701 :   bool ok = true;
   19895      1011701 :   int64_t val;
   19896      1011701 :   switch (this->type_info_)
   19897              :     {
   19898       285101 :     case TYPE_INFO_SIZE:
   19899       285101 :       ok = this->type_->backend_type_size(gogo, &val);
   19900       285101 :       break;
   19901       245954 :     case TYPE_INFO_ALIGNMENT:
   19902       245954 :       ok = this->type_->backend_type_align(gogo, &val);
   19903       245954 :       break;
   19904       245954 :     case TYPE_INFO_FIELD_ALIGNMENT:
   19905       245954 :       ok = this->type_->backend_type_field_align(gogo, &val);
   19906       245954 :       break;
   19907        22049 :     case TYPE_INFO_BACKEND_PTRDATA:
   19908        22049 :       ok = this->type_->backend_type_ptrdata(gogo, &val);
   19909        22049 :       break;
   19910       212643 :     case TYPE_INFO_DESCRIPTOR_PTRDATA:
   19911       212643 :       ok = this->type_->descriptor_ptrdata(gogo, &val);
   19912       212643 :       break;
   19913            0 :     default:
   19914            0 :       go_unreachable();
   19915              :     }
   19916      1011701 :   if (!ok)
   19917              :     {
   19918            3 :       go_assert(saw_errors());
   19919            3 :       return gogo->backend()->error_expression();
   19920              :     }
   19921      1011698 :   Expression* e = Expression::make_integer_int64(val, this->type(),
   19922              :                                                  this->location());
   19923      1011698 :   return e->get_backend(context);
   19924              : }
   19925              : 
   19926              : // Dump ast representation for a type info expression.
   19927              : 
   19928              : void
   19929            0 : Type_info_expression::do_dump_expression(
   19930              :     Ast_dump_context* ast_dump_context) const
   19931              : {
   19932            0 :   ast_dump_context->ostream() << "typeinfo(";
   19933            0 :   ast_dump_context->dump_type(this->type_);
   19934            0 :   ast_dump_context->ostream() << ",";
   19935            0 :   ast_dump_context->ostream() <<
   19936            0 :     (this->type_info_ == TYPE_INFO_ALIGNMENT ? "alignment"
   19937            0 :     : this->type_info_ == TYPE_INFO_FIELD_ALIGNMENT ? "field alignment"
   19938            0 :     : this->type_info_ == TYPE_INFO_SIZE ? "size"
   19939            0 :     : this->type_info_ == TYPE_INFO_BACKEND_PTRDATA ? "backend_ptrdata"
   19940            0 :     : this->type_info_ == TYPE_INFO_DESCRIPTOR_PTRDATA ? "descriptor_ptrdata"
   19941            0 :     : "unknown");
   19942            0 :   ast_dump_context->ostream() << ")";
   19943            0 : }
   19944              : 
   19945              : // Make a type info expression.
   19946              : 
   19947              : Expression*
   19948      1155709 : Expression::make_type_info(Type* type, Type_info type_info)
   19949              : {
   19950      1155709 :   return new Type_info_expression(type, type_info);
   19951              : }
   19952              : 
   19953              : // Slice_info_expression.
   19954              : 
   19955              : // Return the type of the slice info.
   19956              : 
   19957              : Type*
   19958      1101756 : Slice_info_expression::do_type()
   19959              : {
   19960      1101756 :   switch (this->slice_info_)
   19961              :     {
   19962       367207 :     case SLICE_INFO_VALUE_POINTER:
   19963       734414 :       return Type::make_pointer_type(
   19964       734414 :           this->slice_->type()->array_type()->element_type());
   19965       734549 :     case SLICE_INFO_LENGTH:
   19966       734549 :     case SLICE_INFO_CAPACITY:
   19967       734549 :         return Type::lookup_integer_type("int");
   19968            0 :     default:
   19969            0 :       go_unreachable();
   19970              :     }
   19971              : }
   19972              : 
   19973              : // Return the backend information for slice information.
   19974              : 
   19975              : Bexpression*
   19976       723602 : Slice_info_expression::do_get_backend(Translate_context* context)
   19977              : {
   19978       723602 :   Gogo* gogo = context->gogo();
   19979       723602 :   Bexpression* bslice = this->slice_->get_backend(context);
   19980       723602 :   switch (this->slice_info_)
   19981              :     {
   19982       723602 :     case SLICE_INFO_VALUE_POINTER:
   19983       723602 :     case SLICE_INFO_LENGTH:
   19984       723602 :     case SLICE_INFO_CAPACITY:
   19985       723602 :       return gogo->backend()->struct_field_expression(bslice, this->slice_info_,
   19986       723602 :                                                       this->location());
   19987            0 :       break;
   19988            0 :     default:
   19989            0 :       go_unreachable();
   19990              :     }
   19991              : }
   19992              : 
   19993              : // Dump ast representation for a type info expression.
   19994              : 
   19995              : void
   19996            0 : Slice_info_expression::do_dump_expression(
   19997              :     Ast_dump_context* ast_dump_context) const
   19998              : {
   19999            0 :   ast_dump_context->ostream() << "sliceinfo(";
   20000            0 :   this->slice_->dump_expression(ast_dump_context);
   20001            0 :   ast_dump_context->ostream() << ",";
   20002            0 :   ast_dump_context->ostream() <<
   20003            0 :       (this->slice_info_ == SLICE_INFO_VALUE_POINTER ? "values"
   20004            0 :     : this->slice_info_ == SLICE_INFO_LENGTH ? "length"
   20005            0 :     : this->slice_info_ == SLICE_INFO_CAPACITY ? "capacity "
   20006            0 :     : "unknown");
   20007            0 :   ast_dump_context->ostream() << ")";
   20008            0 : }
   20009              : 
   20010              : // Make a slice info expression.
   20011              : 
   20012              : Expression*
   20013       692526 : Expression::make_slice_info(Expression* slice, Slice_info slice_info,
   20014              :                             Location location)
   20015              : {
   20016       692526 :   return new Slice_info_expression(slice, slice_info, location);
   20017              : }
   20018              : 
   20019              : // Class Slice_value_expression.
   20020              : 
   20021              : int
   20022       126120 : Slice_value_expression::do_traverse(Traverse* traverse)
   20023              : {
   20024       126120 :   if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT
   20025       126120 :       || Expression::traverse(&this->valmem_, traverse) == TRAVERSE_EXIT
   20026       126120 :       || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT
   20027       252240 :       || Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
   20028            0 :     return TRAVERSE_EXIT;
   20029              :   return TRAVERSE_CONTINUE;
   20030              : }
   20031              : 
   20032              : // Determine type of a slice value.
   20033              : 
   20034              : void
   20035        31327 : Slice_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
   20036              : {
   20037        31327 :   this->valmem_->determine_type_no_context(gogo);
   20038        31327 :   this->len_->determine_type_no_context(gogo);
   20039        31327 :   this->cap_->determine_type_no_context(gogo);
   20040        31327 : }
   20041              : 
   20042              : Expression*
   20043            0 : Slice_value_expression::do_copy()
   20044              : {
   20045            0 :   return new Slice_value_expression(this->type_->copy_expressions(),
   20046            0 :                                     this->valmem_->copy(),
   20047            0 :                                     this->len_->copy(), this->cap_->copy(),
   20048            0 :                                     this->location());
   20049              : }
   20050              : 
   20051              : Bexpression*
   20052       405130 : Slice_value_expression::do_get_backend(Translate_context* context)
   20053              : {
   20054       405130 :   std::vector<Bexpression*> vals(3);
   20055       405130 :   vals[0] = this->valmem_->get_backend(context);
   20056       405130 :   vals[1] = this->len_->get_backend(context);
   20057       405130 :   vals[2] = this->cap_->get_backend(context);
   20058              : 
   20059       405130 :   Gogo* gogo = context->gogo();
   20060       405130 :   Btype* btype = this->type_->get_backend(gogo);
   20061       405130 :   return gogo->backend()->constructor_expression(btype, vals, this->location());
   20062       405130 : }
   20063              : 
   20064              : void
   20065            0 : Slice_value_expression::do_dump_expression(
   20066              :     Ast_dump_context* ast_dump_context) const
   20067              : {
   20068            0 :   ast_dump_context->ostream() << "slicevalue(";
   20069            0 :   ast_dump_context->ostream() << "values: ";
   20070            0 :   this->valmem_->dump_expression(ast_dump_context);
   20071            0 :   ast_dump_context->ostream() << ", length: ";
   20072            0 :   this->len_->dump_expression(ast_dump_context);
   20073            0 :   ast_dump_context->ostream() << ", capacity: ";
   20074            0 :   this->cap_->dump_expression(ast_dump_context);
   20075            0 :   ast_dump_context->ostream() << ")";
   20076            0 : }
   20077              : 
   20078              : Expression*
   20079       405750 : Expression::make_slice_value(Type* at, Expression* valmem, Expression* len,
   20080              :                              Expression* cap, Location location)
   20081              : {
   20082       405750 :   go_assert(at->is_slice_type());
   20083       792334 :   go_assert(valmem->is_nil_expression()
   20084              :             || (at->array_type()->element_type()
   20085              :                 == valmem->type()->points_to()));
   20086       405750 :   return new Slice_value_expression(at, valmem, len, cap, location);
   20087              : }
   20088              : 
   20089              : // Look through the expression of a Slice_value_expression's valmem to
   20090              : // find an call to makeslice.  If found, return the call expression and
   20091              : // the containing temporary statement (if any).
   20092              : 
   20093              : std::pair<Call_expression*, Temporary_statement*>
   20094        12132 : Expression::find_makeslice_call(Expression* expr)
   20095              : {
   20096        12132 :   Unsafe_type_conversion_expression* utce =
   20097        12159 :     expr->unsafe_conversion_expression();
   20098           27 :   if (utce != NULL)
   20099           27 :     expr = utce->expr();
   20100              : 
   20101        12132 :   Slice_value_expression* sve = expr->slice_value_expression();
   20102        12132 :   if (sve == NULL)
   20103         3529 :     return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
   20104         8603 :   expr = sve->valmem();
   20105              : 
   20106         8603 :   utce = expr->unsafe_conversion_expression();
   20107         8594 :   if (utce != NULL)
   20108         8594 :     expr = utce->expr();
   20109              : 
   20110         8603 :   Temporary_reference_expression* tre = expr->temporary_reference_expression();
   20111         2797 :   Temporary_statement* ts = (tre != NULL ? tre->statement() : NULL);
   20112         2797 :   if (ts != NULL && ts->init() != NULL && !ts->assigned()
   20113         5594 :       && !ts->is_address_taken())
   20114              :     expr = ts->init();
   20115              : 
   20116         8603 :   Call_expression* call = expr->call_expression();
   20117         8603 :   if (call == NULL)
   20118           27 :     return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
   20119              : 
   20120         8576 :   Func_expression* fe = call->fn()->func_expression();
   20121         8576 :   if (fe != NULL
   20122         8576 :       && fe->runtime_code() == Runtime::MAKESLICE)
   20123         8456 :     return std::make_pair(call, ts);
   20124              : 
   20125          120 :   return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
   20126              : }
   20127              : 
   20128              : // An expression that evaluates to some characteristic of a non-empty interface.
   20129              : // This is used to access the method table or underlying object of an interface.
   20130              : 
   20131              : class Interface_info_expression : public Expression
   20132              : {
   20133              :  public:
   20134       210141 :   Interface_info_expression(Expression* iface, Interface_info iface_info,
   20135              :                             Location location)
   20136       210141 :     : Expression(EXPRESSION_INTERFACE_INFO, location),
   20137       420282 :       iface_(iface), iface_info_(iface_info)
   20138              :   { }
   20139              : 
   20140              :  protected:
   20141              :   Type*
   20142              :   do_type();
   20143              : 
   20144              :   void
   20145       398772 :   do_determine_type(Gogo*, const Type_context*)
   20146       398772 :   { }
   20147              : 
   20148              :   Expression*
   20149            0 :   do_copy()
   20150              :   {
   20151            0 :     return new Interface_info_expression(this->iface_->copy(),
   20152            0 :                                          this->iface_info_, this->location());
   20153              :   }
   20154              : 
   20155              :   Bexpression*
   20156              :   do_get_backend(Translate_context* context);
   20157              : 
   20158              :   void
   20159              :   do_dump_expression(Ast_dump_context*) const;
   20160              : 
   20161              :   void
   20162            0 :   do_issue_nil_check()
   20163            0 :   { this->iface_->issue_nil_check(); }
   20164              : 
   20165              :  private:
   20166              :   // The interface for which we are getting information.
   20167              :   Expression* iface_;
   20168              :   // What information we want.
   20169              :   Interface_info iface_info_;
   20170              : };
   20171              : 
   20172              : // Return the type of the interface info.
   20173              : 
   20174              : Type*
   20175      1108952 : Interface_info_expression::do_type()
   20176              : {
   20177      1108952 :   switch (this->iface_info_)
   20178              :     {
   20179       867135 :     case INTERFACE_INFO_METHODS:
   20180       867135 :       {
   20181       867135 :         typedef Unordered_map(Interface_type*, Type*) Hashtable;
   20182       867135 :         static Hashtable result_types;
   20183              : 
   20184       867135 :         Interface_type* itype = this->iface_->type()->interface_type();
   20185              : 
   20186       867135 :         Hashtable::const_iterator pr = result_types.find(itype);
   20187       867135 :         if (pr != result_types.end())
   20188       859918 :           return pr->second;
   20189              : 
   20190         7217 :         Type* pdt = Type::make_type_descriptor_ptr_type();
   20191         7217 :         if (itype->is_empty())
   20192              :           {
   20193          811 :             result_types[itype] = pdt;
   20194          811 :             return pdt;
   20195              :           }
   20196              : 
   20197         6406 :         Location loc = this->location();
   20198         6406 :         Struct_field_list* sfl = new Struct_field_list();
   20199         6406 :         sfl->push_back(
   20200        19218 :             Struct_field(Typed_identifier("__type_descriptor", pdt, loc)));
   20201              : 
   20202         6406 :         for (Typed_identifier_list::const_iterator p = itype->methods()->begin();
   20203        28162 :              p != itype->methods()->end();
   20204        21756 :              ++p)
   20205              :           {
   20206        21756 :             Function_type* ft = p->type()->function_type();
   20207        21756 :             go_assert(ft->receiver() == NULL);
   20208              : 
   20209        21756 :             const Typed_identifier_list* params = ft->parameters();
   20210        21756 :             Typed_identifier_list* mparams = new Typed_identifier_list();
   20211        21756 :             if (params != NULL)
   20212         7984 :               mparams->reserve(params->size() + 1);
   20213        21756 :             Type* vt = Type::make_pointer_type(Type::make_void_type());
   20214        43512 :             mparams->push_back(Typed_identifier("", vt, ft->location()));
   20215        21756 :             if (params != NULL)
   20216              :               {
   20217         7984 :                 for (Typed_identifier_list::const_iterator pp = params->begin();
   20218        18017 :                      pp != params->end();
   20219        10033 :                      ++pp)
   20220        10033 :                   mparams->push_back(*pp);
   20221              :               }
   20222              : 
   20223        21756 :             Typed_identifier_list* mresults = (ft->results() == NULL
   20224        21756 :                                                ? NULL
   20225        19407 :                                                : ft->results()->copy());
   20226        21756 :             Backend_function_type* mft =
   20227        21756 :                 Type::make_backend_function_type(NULL, mparams, mresults,
   20228              :                                                  ft->location());
   20229              : 
   20230        21756 :             std::string fname = Gogo::unpack_hidden_name(p->name());
   20231        43512 :             sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc)));
   20232        21756 :           }
   20233              : 
   20234         6406 :         Struct_type* st = Type::make_struct_type(sfl, loc);
   20235         6406 :         st->set_is_struct_incomparable();
   20236         6406 :         Pointer_type *pt = Type::make_pointer_type(st);
   20237         6406 :         result_types[itype] = pt;
   20238         6406 :         return pt;
   20239              :       }
   20240       241817 :     case INTERFACE_INFO_OBJECT:
   20241       241817 :       return Type::make_pointer_type(Type::make_void_type());
   20242            0 :     default:
   20243            0 :       go_unreachable();
   20244              :     }
   20245              : }
   20246              : 
   20247              : // Return the backend representation for interface information.
   20248              : 
   20249              : Bexpression*
   20250       281884 : Interface_info_expression::do_get_backend(Translate_context* context)
   20251              : {
   20252       281884 :   Gogo* gogo = context->gogo();
   20253       281884 :   Bexpression* biface = this->iface_->get_backend(context);
   20254       281884 :   switch (this->iface_info_)
   20255              :     {
   20256       281884 :     case INTERFACE_INFO_METHODS:
   20257       281884 :     case INTERFACE_INFO_OBJECT:
   20258       281884 :       return gogo->backend()->struct_field_expression(biface, this->iface_info_,
   20259       281884 :                                                       this->location());
   20260            0 :       break;
   20261            0 :     default:
   20262            0 :       go_unreachable();
   20263              :     }
   20264              : }
   20265              : 
   20266              : // Dump ast representation for an interface info expression.
   20267              : 
   20268              : void
   20269            0 : Interface_info_expression::do_dump_expression(
   20270              :     Ast_dump_context* ast_dump_context) const
   20271              : {
   20272            0 :   bool is_empty = this->iface_->type()->interface_type()->is_empty();
   20273            0 :   ast_dump_context->ostream() << "interfaceinfo(";
   20274            0 :   this->iface_->dump_expression(ast_dump_context);
   20275            0 :   ast_dump_context->ostream() << ",";
   20276            0 :   ast_dump_context->ostream() <<
   20277            0 :       (this->iface_info_ == INTERFACE_INFO_METHODS && !is_empty ? "methods"
   20278            0 :     : this->iface_info_ == INTERFACE_INFO_TYPE_DESCRIPTOR ? "type_descriptor"
   20279            0 :     : this->iface_info_ == INTERFACE_INFO_OBJECT ? "object"
   20280            0 :     : "unknown");
   20281            0 :   ast_dump_context->ostream() << ")";
   20282            0 : }
   20283              : 
   20284              : // Make an interface info expression.
   20285              : 
   20286              : Expression*
   20287       210141 : Expression::make_interface_info(Expression* iface, Interface_info iface_info,
   20288              :                                 Location location)
   20289              : {
   20290       210141 :   return new Interface_info_expression(iface, iface_info, location);
   20291              : }
   20292              : 
   20293              : // An expression that represents an interface value.  The first field is either
   20294              : // a type descriptor for an empty interface or a pointer to the interface method
   20295              : // table for a non-empty interface.  The second field is always the object.
   20296              : 
   20297              : class Interface_value_expression : public Expression
   20298              : {
   20299              :  public:
   20300       229082 :   Interface_value_expression(Type* type, Expression* first_field,
   20301              :                              Expression* obj, Location location)
   20302       229082 :       : Expression(EXPRESSION_INTERFACE_VALUE, location),
   20303       458164 :         type_(type), first_field_(first_field), obj_(obj)
   20304              :   { }
   20305              : 
   20306              :  protected:
   20307              :   int
   20308              :   do_traverse(Traverse*);
   20309              : 
   20310              :   Type*
   20311          847 :   do_type()
   20312          847 :   { return this->type_; }
   20313              : 
   20314              :   void
   20315              :   do_determine_type(Gogo*, const Type_context*);
   20316              : 
   20317              :   Expression*
   20318            0 :   do_copy()
   20319              :   {
   20320            0 :     return new Interface_value_expression(this->type_->copy_expressions(),
   20321            0 :                                           this->first_field_->copy(),
   20322            0 :                                           this->obj_->copy(), this->location());
   20323              :   }
   20324              : 
   20325              :   Bexpression*
   20326              :   do_get_backend(Translate_context* context);
   20327              : 
   20328              :   void
   20329              :   do_dump_expression(Ast_dump_context*) const;
   20330              : 
   20331              :  private:
   20332              :   // The type of the interface value.
   20333              :   Type* type_;
   20334              :   // The first field of the interface (either a type descriptor or a pointer
   20335              :   // to the method table.
   20336              :   Expression* first_field_;
   20337              :   // The underlying object of the interface.
   20338              :   Expression* obj_;
   20339              : };
   20340              : 
   20341              : int
   20342            0 : Interface_value_expression::do_traverse(Traverse* traverse)
   20343              : {
   20344            0 :   if (Expression::traverse(&this->first_field_, traverse) == TRAVERSE_EXIT
   20345            0 :       || Expression::traverse(&this->obj_, traverse) == TRAVERSE_EXIT)
   20346            0 :     return TRAVERSE_EXIT;
   20347              :   return TRAVERSE_CONTINUE;
   20348              : }
   20349              : 
   20350              : void
   20351       281130 : Interface_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
   20352              : {
   20353       281130 :   this->first_field_->determine_type_no_context(gogo);
   20354       281130 :   this->obj_->determine_type_no_context(gogo);
   20355       281130 : }
   20356              : 
   20357              : Bexpression*
   20358       229082 : Interface_value_expression::do_get_backend(Translate_context* context)
   20359              : {
   20360       229082 :   std::vector<Bexpression*> vals(2);
   20361       229082 :   vals[0] = this->first_field_->get_backend(context);
   20362       229082 :   vals[1] = this->obj_->get_backend(context);
   20363              : 
   20364       229082 :   Gogo* gogo = context->gogo();
   20365       229082 :   Btype* btype = this->type_->get_backend(gogo);
   20366       229082 :   return gogo->backend()->constructor_expression(btype, vals, this->location());
   20367       229082 : }
   20368              : 
   20369              : void
   20370            0 : Interface_value_expression::do_dump_expression(
   20371              :     Ast_dump_context* ast_dump_context) const
   20372              : {
   20373            0 :   ast_dump_context->ostream() << "interfacevalue(";
   20374            0 :   ast_dump_context->ostream() <<
   20375            0 :       (this->type_->interface_type()->is_empty()
   20376              :        ? "type_descriptor: "
   20377            0 :        : "methods: ");
   20378            0 :   this->first_field_->dump_expression(ast_dump_context);
   20379            0 :   ast_dump_context->ostream() << ", object: ";
   20380            0 :   this->obj_->dump_expression(ast_dump_context);
   20381            0 :   ast_dump_context->ostream() << ")";
   20382            0 : }
   20383              : 
   20384              : Expression*
   20385       229082 : Expression::make_interface_value(Type* type, Expression* first_value,
   20386              :                                  Expression* object, Location location)
   20387              : {
   20388       229082 :   return new Interface_value_expression(type, first_value, object, location);
   20389              : }
   20390              : 
   20391              : // An interface method table for a pair of types: an interface type and a type
   20392              : // that implements that interface.
   20393              : 
   20394              : class Interface_mtable_expression : public Expression
   20395              : {
   20396              :  public:
   20397        66004 :   Interface_mtable_expression(Interface_type* itype, Type* type,
   20398              :                               bool is_pointer, Location location)
   20399        66004 :       : Expression(EXPRESSION_INTERFACE_MTABLE, location),
   20400        66004 :         itype_(itype), type_(type), is_pointer_(is_pointer),
   20401       132008 :         method_table_type_(NULL), bvar_(NULL)
   20402              :   { }
   20403              : 
   20404              :  protected:
   20405              :   int
   20406              :   do_traverse(Traverse*);
   20407              : 
   20408              :   Type*
   20409              :   do_type();
   20410              : 
   20411              :   bool
   20412            0 :   do_is_static_initializer() const
   20413            0 :   { return true; }
   20414              : 
   20415              :   void
   20416        43409 :   do_determine_type(Gogo*, const Type_context*)
   20417        43409 :   { }
   20418              : 
   20419              :   Expression*
   20420            0 :   do_copy()
   20421              :   {
   20422            0 :     Interface_type* itype = this->itype_->copy_expressions()->interface_type();
   20423            0 :     return new Interface_mtable_expression(itype,
   20424            0 :                                            this->type_->copy_expressions(),
   20425            0 :                                            this->is_pointer_, this->location());
   20426              :   }
   20427              : 
   20428              :   bool
   20429            0 :   do_is_addressable() const
   20430            0 :   { return true; }
   20431              : 
   20432              :   Bexpression*
   20433              :   do_get_backend(Translate_context* context);
   20434              : 
   20435              :   void
   20436              :   do_dump_expression(Ast_dump_context*) const;
   20437              : 
   20438              :  private:
   20439              :   // The interface type for which the methods are defined.
   20440              :   Interface_type* itype_;
   20441              :   // The type to construct the interface method table for.
   20442              :   Type* type_;
   20443              :   // Whether this table contains the method set for the receiver type or the
   20444              :   // pointer receiver type.
   20445              :   bool is_pointer_;
   20446              :   // The type of the method table.
   20447              :   Type* method_table_type_;
   20448              :   // The backend variable that refers to the interface method table.
   20449              :   Bvariable* bvar_;
   20450              : };
   20451              : 
   20452              : int
   20453            0 : Interface_mtable_expression::do_traverse(Traverse* traverse)
   20454              : {
   20455            0 :   if (Type::traverse(this->itype_, traverse) == TRAVERSE_EXIT
   20456            0 :       || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
   20457            0 :     return TRAVERSE_EXIT;
   20458              :   return TRAVERSE_CONTINUE;
   20459              : }
   20460              : 
   20461              : Type*
   20462       217370 : Interface_mtable_expression::do_type()
   20463              : {
   20464       217370 :   if (this->method_table_type_ != NULL)
   20465              :     return this->method_table_type_;
   20466              : 
   20467        66004 :   const Typed_identifier_list* interface_methods = this->itype_->methods();
   20468        66004 :   go_assert(!interface_methods->empty());
   20469              : 
   20470        66004 :   Struct_field_list* sfl = new Struct_field_list;
   20471        66004 :   Typed_identifier tid("__type_descriptor", Type::make_type_descriptor_ptr_type(),
   20472       132008 :                        this->location());
   20473        66004 :   sfl->push_back(Struct_field(tid));
   20474        66004 :   Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
   20475        66004 :   for (Typed_identifier_list::const_iterator p = interface_methods->begin();
   20476       510485 :        p != interface_methods->end();
   20477       444481 :        ++p)
   20478              :     {
   20479              :       // We want C function pointers here, not func descriptors; model
   20480              :       // using void* pointers.
   20481       444481 :       Typed_identifier method(p->name(), unsafe_ptr_type, p->location());
   20482       444481 :       sfl->push_back(Struct_field(method));
   20483       444481 :     }
   20484        66004 :   Struct_type* st = Type::make_struct_type(sfl, this->location());
   20485        66004 :   st->set_is_struct_incomparable();
   20486        66004 :   this->method_table_type_ = st;
   20487        66004 :   return this->method_table_type_;
   20488        66004 : }
   20489              : 
   20490              : Bexpression*
   20491       182999 : Interface_mtable_expression::do_get_backend(Translate_context* context)
   20492              : {
   20493       182999 :   Gogo* gogo = context->gogo();
   20494       182999 :   Location loc = Linemap::predeclared_location();
   20495       182999 :   if (this->bvar_ != NULL)
   20496       116995 :     return gogo->backend()->var_expression(this->bvar_, this->location());
   20497              : 
   20498        66004 :   const Typed_identifier_list* interface_methods = this->itype_->methods();
   20499        66004 :   go_assert(!interface_methods->empty());
   20500              : 
   20501        66004 :   std::string mangled_name =
   20502              :     gogo->interface_method_table_name(this->itype_, this->type_,
   20503        66004 :                                       this->is_pointer_);
   20504              : 
   20505              :   // Set is_public if we are converting a named type to an interface
   20506              :   // type that is defined in the same package as the named type, and
   20507              :   // the interface has hidden methods.  In that case the interface
   20508              :   // method table will be defined by the package that defines the
   20509              :   // types.
   20510        66004 :   bool is_public = false;
   20511        66004 :   if (this->type_->named_type() != NULL
   20512        66004 :       && (this->type_->named_type()->named_object()->package()
   20513        65903 :           == this->itype_->package()))
   20514              :     {
   20515       259537 :       for (Typed_identifier_list::const_iterator p = interface_methods->begin();
   20516       259537 :            p != interface_methods->end();
   20517       217227 :            ++p)
   20518              :         {
   20519       254987 :           if (Gogo::is_hidden_name(p->name()))
   20520              :             {
   20521              :               is_public = true;
   20522              :               break;
   20523              :             }
   20524              :         }
   20525              :     }
   20526              : 
   20527        42310 :   if (is_public
   20528        42310 :       && this->type_->named_type()->named_object()->package() != NULL)
   20529              :     {
   20530              :       // The interface conversion table is defined elsewhere.
   20531        34371 :       Btype* btype = this->type()->get_backend(gogo);
   20532        68742 :       this->bvar_ =
   20533        34371 :           gogo->backend()->immutable_struct_reference(mangled_name, "",
   20534              :                                                       btype, loc);
   20535        34371 :       return gogo->backend()->var_expression(this->bvar_, this->location());
   20536              :     }
   20537              : 
   20538              :   // The first element is the type descriptor.
   20539        31633 :   Type* td_type;
   20540        31633 :   if (!this->is_pointer_)
   20541        13998 :     td_type = this->type_;
   20542              :   else
   20543        17635 :     td_type = Type::make_pointer_type(this->type_);
   20544              : 
   20545        31633 :   std::vector<Backend::Btyped_identifier> bstructfields;
   20546              : 
   20547              :   // Build an interface method table for a type: a type descriptor followed by a
   20548              :   // list of function pointers, one for each interface method.  This is used for
   20549              :   // interfaces.
   20550        31633 :   Expression_list* svals = new Expression_list();
   20551        31633 :   Expression* tdescriptor = Expression::make_type_descriptor(td_type, loc);
   20552        31633 :   svals->push_back(tdescriptor);
   20553              : 
   20554        31633 :   Btype* tdesc_btype = tdescriptor->type()->get_backend(gogo);
   20555        63266 :   Backend::Btyped_identifier btd("_type", tdesc_btype, loc);
   20556        31633 :   bstructfields.push_back(btd);
   20557              : 
   20558        31633 :   Named_type* nt = this->type_->named_type();
   20559        31633 :   Struct_type* st = this->type_->struct_type();
   20560        31633 :   go_assert(nt != NULL || st != NULL);
   20561              : 
   20562        31633 :   for (Typed_identifier_list::const_iterator p = interface_methods->begin();
   20563       217683 :        p != interface_methods->end();
   20564       186050 :        ++p)
   20565              :     {
   20566       186050 :       bool is_ambiguous;
   20567       186050 :       Method* m;
   20568       186050 :       if (nt != NULL)
   20569       185878 :         m = nt->method_function(p->name(), &is_ambiguous);
   20570              :       else
   20571          172 :         m = st->method_function(p->name(), &is_ambiguous);
   20572       186050 :       go_assert(m != NULL);
   20573              : 
   20574              :       // See the comment in Type::method_constructor.
   20575       186050 :       bool use_direct_iface_stub = false;
   20576       186050 :       if (m->is_value_method()
   20577        22460 :           && this->is_pointer_
   20578       191919 :           && this->type_->is_direct_iface_type())
   20579              :         use_direct_iface_stub = true;
   20580       186050 :       if (!m->is_value_method()
   20581       163590 :           && this->is_pointer_
   20582       273696 :           && !this->type_->in_heap())
   20583              :         use_direct_iface_stub = true;
   20584       186050 :       Named_object* no = (use_direct_iface_stub
   20585       186050 :                           ? m->iface_stub_object()
   20586       185876 :                           : m->named_object());
   20587              : 
   20588       186050 :       go_assert(no->is_function() || no->is_function_declaration());
   20589              : 
   20590       186050 :       Function_type* fcn_type = (no->is_function()
   20591       186050 :                                  ? no->func_value()->type()
   20592       158248 :                                  : no->func_declaration_value()->type());
   20593       186050 :       Btype* fcn_btype = fcn_type->get_backend_fntype(gogo);
   20594       186050 :       Backend::Btyped_identifier bmtype(p->name(), fcn_btype, loc);
   20595       186050 :       bstructfields.push_back(bmtype);
   20596              : 
   20597       186050 :       svals->push_back(Expression::make_func_code_reference(no, loc));
   20598       186050 :     }
   20599              : 
   20600        31633 :   Btype *btype = gogo->backend()->struct_type(bstructfields);
   20601        31633 :   std::vector<Bexpression*> ctor_bexprs;
   20602        31633 :   for (Expression_list::const_iterator pe = svals->begin();
   20603       249316 :        pe != svals->end();
   20604       217683 :        ++pe)
   20605              :     {
   20606       217683 :       ctor_bexprs.push_back((*pe)->get_backend(context));
   20607              :     }
   20608        31633 :   Bexpression* ctor =
   20609        31633 :       gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
   20610              : 
   20611        31633 :   unsigned int flags = 0;
   20612        31633 :   if (!is_public)
   20613        28244 :     flags |= Backend::variable_is_hidden;
   20614        31633 :   this->bvar_ = gogo->backend()->immutable_struct(mangled_name, "", flags,
   20615              :                                                   btype, loc);
   20616        31633 :   gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, flags,
   20617              :                                              btype, loc, ctor);
   20618        31633 :   return gogo->backend()->var_expression(this->bvar_, loc);
   20619        97637 : }
   20620              : 
   20621              : void
   20622            0 : Interface_mtable_expression::do_dump_expression(
   20623              :     Ast_dump_context* ast_dump_context) const
   20624              : {
   20625            0 :   ast_dump_context->ostream() << "__go_"
   20626            0 :                               << (this->is_pointer_ ? "pimt__" : "imt_");
   20627            0 :   ast_dump_context->dump_type(this->itype_);
   20628            0 :   ast_dump_context->ostream() << "__";
   20629            0 :   ast_dump_context->dump_type(this->type_);
   20630            0 : }
   20631              : 
   20632              : Expression*
   20633        66004 : Expression::make_interface_mtable_ref(Interface_type* itype, Type* type,
   20634              :                                       bool is_pointer, Location location)
   20635              : {
   20636        66004 :   return new Interface_mtable_expression(itype, type, is_pointer, location);
   20637              : }
   20638              : 
   20639              : // An expression which evaluates to the offset of a field within a
   20640              : // struct.  This, like Type_info_expression, q.v., is only used to
   20641              : // initialize fields of a type descriptor.
   20642              : 
   20643              : class Struct_field_offset_expression : public Expression
   20644              : {
   20645              :  public:
   20646       188891 :   Struct_field_offset_expression(Struct_type* type, const Struct_field* field)
   20647       188891 :     : Expression(EXPRESSION_STRUCT_FIELD_OFFSET,
   20648              :                  Linemap::predeclared_location()),
   20649       188891 :       type_(type), field_(field)
   20650       188891 :   { }
   20651              : 
   20652              :  protected:
   20653              :   bool
   20654       236552 :   do_is_static_initializer() const
   20655       236552 :   { return true; }
   20656              : 
   20657              :   Type*
   20658       311911 :   do_type()
   20659       311911 :   { return Type::lookup_integer_type("uintptr"); }
   20660              : 
   20661              :   void
   20662       192372 :   do_determine_type(Gogo*, const Type_context*)
   20663       192372 :   { }
   20664              : 
   20665              :   Expression*
   20666            0 :   do_copy()
   20667            0 :   { return this; }
   20668              : 
   20669              :   Bexpression*
   20670              :   do_get_backend(Translate_context* context);
   20671              : 
   20672              :   void
   20673              :   do_dump_expression(Ast_dump_context*) const;
   20674              : 
   20675              :  private:
   20676              :   // The type of the struct.
   20677              :   Struct_type* type_;
   20678              :   // The field.
   20679              :   const Struct_field* field_;
   20680              : };
   20681              : 
   20682              : // Return the backend representation for a struct field offset.
   20683              : 
   20684              : Bexpression*
   20685       122178 : Struct_field_offset_expression::do_get_backend(Translate_context* context)
   20686              : {
   20687       122178 :   const Struct_field_list* fields = this->type_->fields();
   20688       122178 :   Struct_field_list::const_iterator p;
   20689       122178 :   unsigned i = 0;
   20690       122178 :   for (p = fields->begin();
   20691       570349 :        p != fields->end();
   20692       448171 :        ++p, ++i)
   20693       570349 :     if (&*p == this->field_)
   20694              :       break;
   20695       122178 :   go_assert(&*p == this->field_);
   20696              : 
   20697       122178 :   Gogo* gogo = context->gogo();
   20698       122178 :   Btype* btype = this->type_->get_backend(gogo);
   20699              : 
   20700       122178 :   int64_t offset = gogo->backend()->type_field_offset(btype, i);
   20701       122178 :   Type* uptr_type = Type::lookup_integer_type("uintptr");
   20702       122178 :   Expression* ret =
   20703       122178 :     Expression::make_integer_int64(offset, uptr_type,
   20704              :                                    Linemap::predeclared_location());
   20705       122178 :   return ret->get_backend(context);
   20706              : }
   20707              : 
   20708              : // Dump ast representation for a struct field offset expression.
   20709              : 
   20710              : void
   20711            0 : Struct_field_offset_expression::do_dump_expression(
   20712              :     Ast_dump_context* ast_dump_context) const
   20713              : {
   20714            0 :   ast_dump_context->ostream() <<  "unsafe.Offsetof(";
   20715            0 :   ast_dump_context->dump_type(this->type_);
   20716            0 :   ast_dump_context->ostream() << '.';
   20717            0 :   ast_dump_context->ostream() <<
   20718            0 :     Gogo::message_name(this->field_->field_name());
   20719            0 :   ast_dump_context->ostream() << ")";
   20720            0 : }
   20721              : 
   20722              : // Make an expression for a struct field offset.
   20723              : 
   20724              : Expression*
   20725       188891 : Expression::make_struct_field_offset(Struct_type* type,
   20726              :                                      const Struct_field* field)
   20727              : {
   20728       188891 :   return new Struct_field_offset_expression(type, field);
   20729              : }
   20730              : 
   20731              : // An expression which evaluates to the address of an unnamed label.
   20732              : 
   20733              : class Label_addr_expression : public Expression
   20734              : {
   20735              :  public:
   20736         8840 :   Label_addr_expression(Label* label, Location location)
   20737         8840 :     : Expression(EXPRESSION_LABEL_ADDR, location),
   20738            0 :       label_(label)
   20739              :   { }
   20740              : 
   20741              :  protected:
   20742              :   Type*
   20743        61880 :   do_type()
   20744        61880 :   { return Type::make_pointer_type(Type::make_void_type()); }
   20745              : 
   20746              :   void
   20747        17680 :   do_determine_type(Gogo*, const Type_context*)
   20748        17680 :   { }
   20749              : 
   20750              :   Expression*
   20751            0 :   do_copy()
   20752            0 :   { return new Label_addr_expression(this->label_, this->location()); }
   20753              : 
   20754              :   Bexpression*
   20755         8840 :   do_get_backend(Translate_context* context)
   20756         8840 :   { return this->label_->get_addr(context, this->location()); }
   20757              : 
   20758              :   void
   20759            0 :   do_dump_expression(Ast_dump_context* ast_dump_context) const
   20760            0 :   { ast_dump_context->ostream() << this->label_->name(); }
   20761              : 
   20762              :  private:
   20763              :   // The label whose address we are taking.
   20764              :   Label* label_;
   20765              : };
   20766              : 
   20767              : // Make an expression for the address of an unnamed label.
   20768              : 
   20769              : Expression*
   20770         8840 : Expression::make_label_addr(Label* label, Location location)
   20771              : {
   20772         8840 :   return new Label_addr_expression(label, location);
   20773              : }
   20774              : 
   20775              : // Class Conditional_expression.
   20776              : 
   20777              : // Traversal.
   20778              : 
   20779              : int
   20780       217442 : Conditional_expression::do_traverse(Traverse* traverse)
   20781              : {
   20782       217442 :   if (Expression::traverse(&this->cond_, traverse) == TRAVERSE_EXIT
   20783       206217 :       || Expression::traverse(&this->then_, traverse) == TRAVERSE_EXIT
   20784       423659 :       || Expression::traverse(&this->else_, traverse) == TRAVERSE_EXIT)
   20785        11225 :     return TRAVERSE_EXIT;
   20786              :   return TRAVERSE_CONTINUE;
   20787              : }
   20788              : 
   20789              : // Return the type of the conditional expression.
   20790              : 
   20791              : Type*
   20792       548757 : Conditional_expression::do_type()
   20793              : {
   20794       548757 :   Type* result_type = Type::make_void_type();
   20795       548757 :   if (Type::are_identical(this->then_->type(), this->else_->type(),
   20796              :                           Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
   20797              :                           NULL))
   20798       201266 :     result_type = this->then_->type();
   20799       347491 :   else if (this->then_->is_nil_expression()
   20800       347491 :            || this->else_->is_nil_expression())
   20801       124904 :     result_type = (!this->then_->is_nil_expression()
   20802       124904 :                    ? this->then_->type()
   20803       122984 :                    : this->else_->type());
   20804       548757 :   return result_type;
   20805              : }
   20806              : 
   20807              : // Determine type for a conditional expression.
   20808              : 
   20809              : void
   20810       439882 : Conditional_expression::do_determine_type(Gogo* gogo,
   20811              :                                           const Type_context* context)
   20812              : {
   20813       439882 :   this->cond_->determine_type_no_context(gogo);
   20814       439882 :   this->then_->determine_type(gogo, context);
   20815       439882 :   this->else_->determine_type(gogo, context);
   20816       439882 : }
   20817              : 
   20818              : // Get the backend representation of a conditional expression.
   20819              : 
   20820              : Bexpression*
   20821       380064 : Conditional_expression::do_get_backend(Translate_context* context)
   20822              : {
   20823       380064 :   Gogo* gogo = context->gogo();
   20824       380064 :   Btype* result_btype = this->type()->get_backend(gogo);
   20825       380064 :   Bexpression* cond = this->cond_->get_backend(context);
   20826       380064 :   Bexpression* then = this->then_->get_backend(context);
   20827       380064 :   Bexpression* belse = this->else_->get_backend(context);
   20828       380064 :   Bfunction* bfn = context->function()->func_value()->get_decl();
   20829       380064 :   return gogo->backend()->conditional_expression(bfn, result_btype, cond, then,
   20830       380064 :                                                  belse, this->location());
   20831              : }
   20832              : 
   20833              : // Dump ast representation of a conditional expression.
   20834              : 
   20835              : void
   20836            0 : Conditional_expression::do_dump_expression(
   20837              :     Ast_dump_context* ast_dump_context) const
   20838              : {
   20839            0 :   ast_dump_context->ostream() << "(";
   20840            0 :   ast_dump_context->dump_expression(this->cond_);
   20841            0 :   ast_dump_context->ostream() << " ? ";
   20842            0 :   ast_dump_context->dump_expression(this->then_);
   20843            0 :   ast_dump_context->ostream() << " : ";
   20844            0 :   ast_dump_context->dump_expression(this->else_);
   20845            0 :   ast_dump_context->ostream() << ") ";
   20846            0 : }
   20847              : 
   20848              : // Make a conditional expression.
   20849              : 
   20850              : Expression*
   20851       381973 : Expression::make_conditional(Expression* cond, Expression* then,
   20852              :                              Expression* else_expr, Location location)
   20853              : {
   20854       381973 :   return new Conditional_expression(cond, then, else_expr, location);
   20855              : }
   20856              : 
   20857              : // Class Compound_expression.
   20858              : 
   20859              : // Traversal.
   20860              : 
   20861              : int
   20862        14468 : Compound_expression::do_traverse(Traverse* traverse)
   20863              : {
   20864        14468 :   if (Expression::traverse(&this->init_, traverse) == TRAVERSE_EXIT
   20865        14468 :       || Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT)
   20866            0 :     return TRAVERSE_EXIT;
   20867              :   return TRAVERSE_CONTINUE;
   20868              : }
   20869              : 
   20870              : // Return the type of the compound expression.
   20871              : 
   20872              : Type*
   20873        14131 : Compound_expression::do_type()
   20874              : {
   20875        14131 :   return this->expr_->type();
   20876              : }
   20877              : 
   20878              : // Determine type for a compound expression.
   20879              : 
   20880              : void
   20881       103569 : Compound_expression::do_determine_type(Gogo* gogo, const Type_context* context)
   20882              : {
   20883       103569 :   this->init_->determine_type_no_context(gogo);
   20884       103569 :   this->expr_->determine_type(gogo, context);
   20885       103569 : }
   20886              : 
   20887              : // Get the backend representation of a compound expression.
   20888              : 
   20889              : Bexpression*
   20890       100032 : Compound_expression::do_get_backend(Translate_context* context)
   20891              : {
   20892       100032 :   Gogo* gogo = context->gogo();
   20893       100032 :   Bexpression* binit = this->init_->get_backend(context);
   20894       100032 :   Bfunction* bfunction = context->function()->func_value()->get_decl();
   20895       100032 :   Bstatement* init_stmt = gogo->backend()->expression_statement(bfunction,
   20896              :                                                                 binit);
   20897       100032 :   Bexpression* bexpr = this->expr_->get_backend(context);
   20898       100032 :   return gogo->backend()->compound_expression(init_stmt, bexpr,
   20899       100032 :                                               this->location());
   20900              : }
   20901              : 
   20902              : // Dump ast representation of a conditional expression.
   20903              : 
   20904              : void
   20905            0 : Compound_expression::do_dump_expression(
   20906              :     Ast_dump_context* ast_dump_context) const
   20907              : {
   20908            0 :   ast_dump_context->ostream() << "(";
   20909            0 :   ast_dump_context->dump_expression(this->init_);
   20910            0 :   ast_dump_context->ostream() << ",";
   20911            0 :   ast_dump_context->dump_expression(this->expr_);
   20912            0 :   ast_dump_context->ostream() << ") ";
   20913            0 : }
   20914              : 
   20915              : // Make a compound expression.
   20916              : 
   20917              : Expression*
   20918       100033 : Expression::make_compound(Expression* init, Expression* expr, Location location)
   20919              : {
   20920       100033 :   return new Compound_expression(init, expr, location);
   20921              : }
   20922              : 
   20923              : // Class Backend_expression.
   20924              : 
   20925              : int
   20926            0 : Backend_expression::do_traverse(Traverse*)
   20927              : {
   20928            0 :   return TRAVERSE_CONTINUE;
   20929              : }
   20930              : 
   20931              : Expression*
   20932            0 : Backend_expression::do_copy()
   20933              : {
   20934            0 :   return new Backend_expression(this->bexpr_, this->type_->copy_expressions(),
   20935            0 :                                 this->location());
   20936              : }
   20937              : 
   20938              : void
   20939            0 : Backend_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
   20940              : {
   20941            0 :   ast_dump_context->ostream() << "backend_expression<";
   20942            0 :   ast_dump_context->dump_type(this->type_);
   20943            0 :   ast_dump_context->ostream() << ">";
   20944            0 : }
   20945              : 
   20946              : Expression*
   20947       769407 : Expression::make_backend(Bexpression* bexpr, Type* type, Location location)
   20948              : {
   20949       769407 :   return new Backend_expression(bexpr, type, location);
   20950              : }
   20951              : 
   20952              : // Import an expression.  This comes at the end in order to see the
   20953              : // various class definitions.
   20954              : 
   20955              : Expression*
   20956      1140540 : Expression::import_expression(Import_expression* imp, Location loc)
   20957              : {
   20958      1140540 :   Expression* expr = Expression::import_expression_without_suffix(imp, loc);
   20959      1162461 :   while (true)
   20960              :     {
   20961      1162461 :       if (imp->match_c_string("("))
   20962              :         {
   20963        18194 :           imp->advance(1);
   20964        18194 :           Expression_list* args = new Expression_list();
   20965        18194 :           bool is_varargs = false;
   20966        26443 :           while (!imp->match_c_string(")"))
   20967              :             {
   20968        23597 :               Expression* arg = Expression::import_expression(imp, loc);
   20969        23597 :               if (arg->is_error_expression())
   20970              :                 return arg;
   20971        23597 :               args->push_back(arg);
   20972        23597 :               if (imp->match_c_string(")"))
   20973              :                 break;
   20974         8571 :               else if (imp->match_c_string("...)"))
   20975              :                 {
   20976          322 :                   imp->advance(3);
   20977          322 :                   is_varargs = true;
   20978          322 :                   break;
   20979              :                 }
   20980         8249 :               imp->require_c_string(", ");
   20981              :             }
   20982        18194 :           imp->require_c_string(")");
   20983        18194 :           expr = Expression::make_call(expr, args, is_varargs, loc);
   20984        18194 :           expr->call_expression()->set_varargs_are_lowered();
   20985              :         }
   20986      1144267 :       else if (imp->match_c_string("["))
   20987              :         {
   20988         3727 :           imp->advance(1);
   20989         3727 :           Expression* start = Expression::import_expression(imp, loc);
   20990         3727 :           Expression* end = NULL;
   20991         3727 :           Expression* cap = NULL;
   20992         3727 :           if (imp->match_c_string(":"))
   20993              :             {
   20994         2119 :               imp->advance(1);
   20995         2119 :               int c = imp->peek_char();
   20996         2119 :               if (c == ':' || c == ']')
   20997          898 :                 end = Expression::make_nil(loc);
   20998              :               else
   20999         1221 :                 end = Expression::import_expression(imp, loc);
   21000         2119 :               if (imp->match_c_string(":"))
   21001              :                 {
   21002            0 :                   imp->advance(1);
   21003            0 :                   cap = Expression::import_expression(imp, loc);
   21004              :                 }
   21005              :             }
   21006         3727 :           imp->require_c_string("]");
   21007         3727 :           expr = Expression::make_index(expr, start, end, cap, loc);
   21008              :         }
   21009              :       else
   21010              :         break;
   21011              :     }
   21012              : 
   21013              :   return expr;
   21014              : }
   21015              : 
   21016              : // Import an expression without considering a suffix (function
   21017              : // arguments, index operations, etc.).
   21018              : 
   21019              : Expression*
   21020      1140540 : Expression::import_expression_without_suffix(Import_expression* imp,
   21021              :                                              Location loc)
   21022              : {
   21023      1140540 :   int c = imp->peek_char();
   21024      1140540 :   if (c == '+' || c == '-' || c == '!' || c == '^' || c == '&' || c == '*')
   21025         9449 :     return Unary_expression::do_import(imp, loc);
   21026              :   else if (c == '(')
   21027        22026 :     return Binary_expression::do_import(imp, loc);
   21028      1109065 :   else if (imp->match_c_string("$true")
   21029      1107695 :            || imp->match_c_string("$false")
   21030      2215271 :            || (imp->version() < EXPORT_FORMAT_V3
   21031            0 :                && (imp->match_c_string("true")
   21032            0 :                    || imp->match_c_string("false"))))
   21033         2859 :     return Boolean_expression::do_import(imp, loc);
   21034      1106206 :   else if (c == '"')
   21035        31862 :     return String_expression::do_import(imp, loc);
   21036      1074344 :   else if (c == '-' || (c >= '0' && c <= '9'))
   21037              :     {
   21038              :       // This handles integers, floats and complex constants.
   21039       979371 :       return Integer_expression::do_import(imp, loc);
   21040              :     }
   21041        94973 :   else if (imp->match_c_string("<-"))
   21042            0 :     return Receive_expression::do_import(imp, loc);
   21043        94973 :   else if (imp->match_c_string("$nil")
   21044        94973 :            || (imp->version() < EXPORT_FORMAT_V3
   21045            0 :                && imp->match_c_string("nil")))
   21046          621 :     return Nil_expression::do_import(imp, loc);
   21047        94352 :   else if (imp->match_c_string("$convert")
   21048        94352 :            || (imp->version() < EXPORT_FORMAT_V3
   21049            0 :                && imp->match_c_string("convert")))
   21050        18058 :     return Type_conversion_expression::do_import(imp, loc);
   21051              : 
   21052        76294 :   Import_function_body* ifb = imp->ifb();
   21053        76294 :   if (ifb == NULL)
   21054              :     {
   21055            0 :       go_error_at(imp->location(), "import error: expected expression");
   21056            0 :       return Expression::make_error(loc);
   21057              :     }
   21058        76294 :   if (ifb->saw_error())
   21059            0 :     return Expression::make_error(loc);
   21060              : 
   21061        76294 :   if (ifb->match_c_string("$t"))
   21062         3923 :     return Temporary_reference_expression::do_import(ifb, loc);
   21063              : 
   21064        72371 :   return Expression::import_identifier(ifb, loc);
   21065              : }
   21066              : 
   21067              : // Import an identifier in an expression.  This is a reference to a
   21068              : // variable or function.
   21069              : 
   21070              : Expression*
   21071        72371 : Expression::import_identifier(Import_function_body* ifb, Location loc)
   21072              : {
   21073        72371 :   std::string id;
   21074        72371 :   Package* pkg;
   21075        72371 :   bool is_exported;
   21076        72371 :   if (!Import::read_qualified_identifier(ifb, &id, &pkg, &is_exported))
   21077              :     {
   21078            0 :       if (!ifb->saw_error())
   21079            0 :         go_error_at(ifb->location(),
   21080              :                     "import error for %qs: bad qualified identifier at %lu",
   21081            0 :                     ifb->name().c_str(),
   21082            0 :                     static_cast<unsigned long>(ifb->off()));
   21083            0 :       ifb->set_saw_error();
   21084            0 :       return Expression::make_error(loc);
   21085              :     }
   21086              : 
   21087        72371 :   Named_object* no = NULL;
   21088        72371 :   if (pkg == NULL && is_exported)
   21089        63256 :     no = ifb->block()->bindings()->lookup(id);
   21090        63256 :   if (no == NULL)
   21091              :     {
   21092        20060 :       const Package* ipkg = pkg;
   21093        20060 :       if (ipkg == NULL)
   21094        16186 :         ipkg = ifb->function()->package();
   21095        20060 :       if (!is_exported)
   21096         5631 :         id = '.' + ipkg->pkgpath() + '.' + id;
   21097        20060 :       no = ipkg->bindings()->lookup(id);
   21098              :     }
   21099        20060 :   if (no == NULL)
   21100         6503 :     no = ifb->gogo()->lookup_global(id.c_str());
   21101              : 
   21102         6503 :   if (no == NULL)
   21103              :     {
   21104            0 :       if (!ifb->saw_error())
   21105            0 :         go_error_at(ifb->location(),
   21106              :                     "import error for %qs: lookup of %qs failed",
   21107            0 :                     ifb->name().c_str(), id.c_str());
   21108            0 :       ifb->set_saw_error();
   21109            0 :       return Expression::make_error(loc);
   21110              :     }
   21111              : 
   21112        72371 :   if (no->is_variable() || no->is_result_variable())
   21113        54239 :     return Expression::make_var_reference(no, loc);
   21114        18132 :   else if (no->is_function() || no->is_function_declaration())
   21115        18132 :     return Expression::make_func_reference(no, NULL, loc);
   21116              :   else
   21117              :     {
   21118            0 :       if (!ifb->saw_error())
   21119            0 :         go_error_at(ifb->location(),
   21120              :                     ("import error for %qs: "
   21121              :                      "unexpected type of identifier %qs (%d)"),
   21122            0 :                     ifb->name().c_str(),
   21123            0 :                     id.c_str(), no->classification());
   21124            0 :       ifb->set_saw_error();
   21125            0 :       return Expression::make_error(loc);
   21126              :     }
   21127        72371 : }
   21128              : 
   21129              : // Class Expression_list.
   21130              : 
   21131              : // Traverse the list.
   21132              : 
   21133              : int
   21134     22945259 : Expression_list::traverse(Traverse* traverse)
   21135              : {
   21136     83410968 :   for (Expression_list::iterator p = this->begin();
   21137     83410968 :        p != this->end();
   21138     60465709 :        ++p)
   21139              :     {
   21140     60670549 :       if (*p != NULL)
   21141              :         {
   21142     60381594 :           if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
   21143     22945259 :             return TRAVERSE_EXIT;
   21144              :         }
   21145              :     }
   21146              :   return TRAVERSE_CONTINUE;
   21147              : }
   21148              : 
   21149              : // Copy the list.
   21150              : 
   21151              : Expression_list*
   21152           11 : Expression_list::copy()
   21153              : {
   21154           11 :   Expression_list* ret = new Expression_list();
   21155           22 :   for (Expression_list::iterator p = this->begin();
   21156           22 :        p != this->end();
   21157           11 :        ++p)
   21158              :     {
   21159           11 :       if (*p == NULL)
   21160            0 :         ret->push_back(NULL);
   21161              :       else
   21162           11 :         ret->push_back((*p)->copy());
   21163              :     }
   21164           11 :   return ret;
   21165              : }
   21166              : 
   21167              : // Return whether an expression list has an error expression.
   21168              : 
   21169              : bool
   21170            0 : Expression_list::contains_error() const
   21171              : {
   21172            0 :   for (Expression_list::const_iterator p = this->begin();
   21173            0 :        p != this->end();
   21174            0 :        ++p)
   21175            0 :     if (*p != NULL && (*p)->is_error_expression())
   21176            0 :       return true;
   21177              :   return false;
   21178              : }
   21179              : 
   21180              : // Class Numeric_constant.
   21181              : 
   21182              : // Destructor.
   21183              : 
   21184     41303532 : Numeric_constant::~Numeric_constant()
   21185              : {
   21186     41303532 :   this->clear();
   21187     41303532 : }
   21188              : 
   21189              : // Copy constructor.
   21190              : 
   21191            0 : Numeric_constant::Numeric_constant(const Numeric_constant& a)
   21192            0 :   : classification_(a.classification_), type_(a.type_)
   21193              : {
   21194            0 :   switch (a.classification_)
   21195              :     {
   21196              :     case NC_INVALID:
   21197              :       break;
   21198            0 :     case NC_INT:
   21199            0 :     case NC_RUNE:
   21200            0 :       mpz_init_set(this->u_.int_val, a.u_.int_val);
   21201            0 :       break;
   21202            0 :     case NC_FLOAT:
   21203            0 :       mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
   21204            0 :       break;
   21205            0 :     case NC_COMPLEX:
   21206            0 :       mpc_init2(this->u_.complex_val, mpc_precision);
   21207            0 :       mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
   21208            0 :       break;
   21209            0 :     default:
   21210            0 :       go_unreachable();
   21211              :     }
   21212            0 : }
   21213              : 
   21214              : // Assignment operator.
   21215              : 
   21216              : Numeric_constant&
   21217         1029 : Numeric_constant::operator=(const Numeric_constant& a)
   21218              : {
   21219         1029 :   this->clear();
   21220         1029 :   this->classification_ = a.classification_;
   21221         1029 :   this->type_ = a.type_;
   21222         1029 :   switch (a.classification_)
   21223              :     {
   21224              :     case NC_INVALID:
   21225              :       break;
   21226          868 :     case NC_INT:
   21227          868 :     case NC_RUNE:
   21228          868 :       mpz_init_set(this->u_.int_val, a.u_.int_val);
   21229          868 :       break;
   21230          161 :     case NC_FLOAT:
   21231          161 :       mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
   21232          161 :       break;
   21233            0 :     case NC_COMPLEX:
   21234            0 :       mpc_init2(this->u_.complex_val, mpc_precision);
   21235            0 :       mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
   21236            0 :       break;
   21237            0 :     default:
   21238            0 :       go_unreachable();
   21239              :     }
   21240         1029 :   return *this;
   21241              : }
   21242              : 
   21243              : // Check equality with another numeric constant.
   21244              : 
   21245              : bool
   21246           32 : Numeric_constant::equals(const Numeric_constant& a) const
   21247              : {
   21248           32 :   if (this->classification_ != a.classification_)
   21249              :     return false;
   21250              : 
   21251           32 :   if (this->type_ != NULL && a.type_ != NULL
   21252           64 :       && !Type::are_identical(this->type_, a.type_,
   21253              :                               Type::COMPARE_ALIASES, NULL))
   21254              :     return false;
   21255              : 
   21256           32 :   switch (a.classification_)
   21257              :     {
   21258              :     case NC_INVALID:
   21259              :       break;
   21260           30 :     case NC_INT:
   21261           30 :     case NC_RUNE:
   21262           30 :       return mpz_cmp(this->u_.int_val, a.u_.int_val) == 0;
   21263            0 :     case NC_FLOAT:
   21264            0 :       return mpfr_cmp(this->u_.float_val, a.u_.float_val) == 0;
   21265            2 :     case NC_COMPLEX:
   21266            2 :       return mpc_cmp(this->u_.complex_val, a.u_.complex_val) == 0;
   21267            0 :     default:
   21268            0 :       go_unreachable();
   21269              :     }
   21270              :   return false;
   21271              : }
   21272              : 
   21273              : // Clear the contents.
   21274              : 
   21275              : void
   21276     76896795 : Numeric_constant::clear()
   21277              : {
   21278     76896795 :   switch (this->classification_)
   21279              :     {
   21280              :     case NC_INVALID:
   21281              :       break;
   21282     35470057 :     case NC_INT:
   21283     35470057 :     case NC_RUNE:
   21284     35470057 :       mpz_clear(this->u_.int_val);
   21285     35470057 :       break;
   21286       112146 :     case NC_FLOAT:
   21287       112146 :       mpfr_clear(this->u_.float_val);
   21288       112146 :       break;
   21289        10069 :     case NC_COMPLEX:
   21290        10069 :       mpc_clear(this->u_.complex_val);
   21291        10069 :       break;
   21292            0 :     default:
   21293            0 :       go_unreachable();
   21294              :     }
   21295     76896795 :   this->classification_ = NC_INVALID;
   21296     76896795 : }
   21297              : 
   21298              : // Set to an unsigned long value.
   21299              : 
   21300              : void
   21301        67214 : Numeric_constant::set_unsigned_long(Type* type, unsigned long val)
   21302              : {
   21303        67214 :   this->clear();
   21304        67214 :   this->classification_ = NC_INT;
   21305        67214 :   this->type_ = type;
   21306        67214 :   mpz_init_set_ui(this->u_.int_val, val);
   21307        67214 : }
   21308              : 
   21309              : // Set to an integer value.
   21310              : 
   21311              : void
   21312     35308719 : Numeric_constant::set_int(Type* type, const mpz_t val)
   21313              : {
   21314     35308719 :   this->clear();
   21315     35308719 :   this->classification_ = NC_INT;
   21316     35308719 :   this->type_ = type;
   21317     35308719 :   mpz_init_set(this->u_.int_val, val);
   21318     35308719 : }
   21319              : 
   21320              : // Set to a rune value.
   21321              : 
   21322              : void
   21323        93735 : Numeric_constant::set_rune(Type* type, const mpz_t val)
   21324              : {
   21325        93735 :   this->clear();
   21326        93735 :   this->classification_ = NC_RUNE;
   21327        93735 :   this->type_ = type;
   21328        93735 :   mpz_init_set(this->u_.int_val, val);
   21329        93735 : }
   21330              : 
   21331              : // Set to a floating point value.
   21332              : 
   21333              : void
   21334       112486 : Numeric_constant::set_float(Type* type, const mpfr_t val)
   21335              : {
   21336       112486 :   this->clear();
   21337       112486 :   this->classification_ = NC_FLOAT;
   21338       112486 :   this->type_ = type;
   21339              : 
   21340              :   // Numeric constants do not have negative zero values, so remove
   21341              :   // them here.  They also don't have infinity or NaN values, but we
   21342              :   // should never see them here.
   21343       112486 :   int bits = 0;
   21344       112486 :   if (type != NULL
   21345        79463 :       && type->float_type() != NULL
   21346       191949 :       && !type->float_type()->is_abstract())
   21347       118728 :     bits = type->float_type()->bits();
   21348       112486 :   if (Numeric_constant::is_float_neg_zero(val, bits))
   21349           29 :     mpfr_init_set_ui(this->u_.float_val, 0, MPFR_RNDN);
   21350              :   else
   21351       112457 :     mpfr_init_set(this->u_.float_val, val, MPFR_RNDN);
   21352       112486 : }
   21353              : 
   21354              : // Set to a complex value.
   21355              : 
   21356              : void
   21357        10080 : Numeric_constant::set_complex(Type* type, const mpc_t val)
   21358              : {
   21359        10080 :   this->clear();
   21360        10080 :   this->classification_ = NC_COMPLEX;
   21361        10080 :   this->type_ = type;
   21362              : 
   21363              :   // Avoid negative zero as in set_float.
   21364        10080 :   int bits = 0;
   21365        10080 :   if (type != NULL
   21366         7143 :       && type->complex_type() != NULL
   21367        17223 :       && !type->complex_type()->is_abstract())
   21368        12102 :     bits = type->complex_type()->bits() / 2;
   21369              : 
   21370        10080 :   mpfr_t real;
   21371        10080 :   mpfr_init_set(real, mpc_realref(val), MPFR_RNDN);
   21372        10080 :   if (Numeric_constant::is_float_neg_zero(real, bits))
   21373            3 :     mpfr_set_ui(real, 0, MPFR_RNDN);
   21374              : 
   21375        10080 :   mpfr_t imag;
   21376        10080 :   mpfr_init_set(imag, mpc_imagref(val), MPFR_RNDN);
   21377        10080 :   if (Numeric_constant::is_float_neg_zero(imag, bits))
   21378            0 :     mpfr_set_ui(imag, 0, MPFR_RNDN);
   21379              : 
   21380        10080 :   mpc_init2(this->u_.complex_val, mpc_precision);
   21381        10080 :   mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN);
   21382              : 
   21383        10080 :   mpfr_clear(real);
   21384        10080 :   mpfr_clear(imag);
   21385        10080 : }
   21386              : 
   21387              : // Return whether VAL, at a precision of BITS, is a negative zero.
   21388              : // BITS may be zero in which case it is ignored.
   21389              : 
   21390              : bool
   21391       132646 : Numeric_constant::is_float_neg_zero(const mpfr_t val, int bits)
   21392              : {
   21393       132646 :   if (!mpfr_signbit(val))
   21394              :     return false;
   21395        21171 :   if (mpfr_zero_p(val))
   21396              :     return true;
   21397        21141 :   mpfr_exp_t min_exp;
   21398        21141 :   switch (bits)
   21399              :     {
   21400              :     case 0:
   21401              :       return false;
   21402              :     case 32:
   21403              :       // In a denormalized float32 the exponent is -126, and there are
   21404              :       // 24 bits of which at least the last must be 1, so the smallest
   21405              :       // representable non-zero exponent is -126 - (24 - 1) == -149.
   21406              :       min_exp = -149;
   21407              :       break;
   21408        11794 :     case 64:
   21409              :       // Minimum exponent is -1022, there are 53 bits.
   21410        11794 :       min_exp = -1074;
   21411        11794 :       break;
   21412            0 :     default:
   21413            0 :       go_unreachable();
   21414              :     }
   21415        12000 :   return mpfr_get_exp(val) < min_exp;
   21416              : }
   21417              : 
   21418              : // Get an int value.
   21419              : 
   21420              : void
   21421        76497 : Numeric_constant::get_int(mpz_t* val) const
   21422              : {
   21423        76497 :   go_assert(this->is_int());
   21424        76497 :   mpz_init_set(*val, this->u_.int_val);
   21425        76497 : }
   21426              : 
   21427              : // Get a rune value.
   21428              : 
   21429              : void
   21430            0 : Numeric_constant::get_rune(mpz_t* val) const
   21431              : {
   21432            0 :   go_assert(this->is_rune());
   21433            0 :   mpz_init_set(*val, this->u_.int_val);
   21434            0 : }
   21435              : 
   21436              : // Get a floating point value.
   21437              : 
   21438              : void
   21439         4051 : Numeric_constant::get_float(mpfr_t* val) const
   21440              : {
   21441         4051 :   go_assert(this->is_float());
   21442         4051 :   mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
   21443         4051 : }
   21444              : 
   21445              : // Get a complex value.
   21446              : 
   21447              : void
   21448           10 : Numeric_constant::get_complex(mpc_t* val) const
   21449              : {
   21450           10 :   go_assert(this->is_complex());
   21451           10 :   mpc_init2(*val, mpc_precision);
   21452           10 :   mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
   21453           10 : }
   21454              : 
   21455              : // Express value as unsigned long if possible.
   21456              : 
   21457              : Numeric_constant::To_unsigned_long
   21458       773455 : Numeric_constant::to_unsigned_long(unsigned long* val) const
   21459              : {
   21460       773455 :   switch (this->classification_)
   21461              :     {
   21462       773158 :     case NC_INT:
   21463       773158 :     case NC_RUNE:
   21464       773158 :       return this->mpz_to_unsigned_long(this->u_.int_val, val);
   21465          284 :     case NC_FLOAT:
   21466          284 :       return this->mpfr_to_unsigned_long(this->u_.float_val, val);
   21467           13 :     case NC_COMPLEX:
   21468           13 :       if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
   21469              :         return NC_UL_NOTINT;
   21470           12 :       return this->mpfr_to_unsigned_long(mpc_realref(this->u_.complex_val),
   21471           12 :                                          val);
   21472            0 :     default:
   21473            0 :       go_unreachable();
   21474              :     }
   21475              : }
   21476              : 
   21477              : // Express integer value as unsigned long if possible.
   21478              : 
   21479              : Numeric_constant::To_unsigned_long
   21480       773452 : Numeric_constant::mpz_to_unsigned_long(const mpz_t ival,
   21481              :                                        unsigned long *val) const
   21482              : {
   21483       773452 :   if (mpz_sgn(ival) < 0)
   21484              :     return NC_UL_NEGATIVE;
   21485       773029 :   unsigned long ui = mpz_get_ui(ival);
   21486       773029 :   if (mpz_cmp_ui(ival, ui) != 0)
   21487              :     return NC_UL_BIG;
   21488       773018 :   *val = ui;
   21489       773018 :   return NC_UL_VALID;
   21490              : }
   21491              : 
   21492              : // Express floating point value as unsigned long if possible.
   21493              : 
   21494              : Numeric_constant::To_unsigned_long
   21495          296 : Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval,
   21496              :                                         unsigned long *val) const
   21497              : {
   21498          296 :   if (!mpfr_integer_p(fval))
   21499              :     return NC_UL_NOTINT;
   21500          294 :   mpz_t ival;
   21501          294 :   mpz_init(ival);
   21502          294 :   mpfr_get_z(ival, fval, MPFR_RNDN);
   21503          294 :   To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val);
   21504          294 :   mpz_clear(ival);
   21505          294 :   return ret;
   21506              : }
   21507              : 
   21508              : // Express value as memory size if possible.
   21509              : 
   21510              : bool
   21511       194238 : Numeric_constant::to_memory_size(int64_t* val) const
   21512              : {
   21513       194238 :   switch (this->classification_)
   21514              :     {
   21515       194233 :     case NC_INT:
   21516       194233 :     case NC_RUNE:
   21517       194233 :       return this->mpz_to_memory_size(this->u_.int_val, val);
   21518            5 :     case NC_FLOAT:
   21519            5 :       return this->mpfr_to_memory_size(this->u_.float_val, val);
   21520            0 :     case NC_COMPLEX:
   21521            0 :       if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
   21522              :         return false;
   21523            0 :       return this->mpfr_to_memory_size(mpc_realref(this->u_.complex_val), val);
   21524            0 :     default:
   21525            0 :       go_unreachable();
   21526              :     }
   21527              : }
   21528              : 
   21529              : // Express integer as memory size if possible.
   21530              : 
   21531              : bool
   21532       194238 : Numeric_constant::mpz_to_memory_size(const mpz_t ival, int64_t* val) const
   21533              : {
   21534       194238 :   if (mpz_sgn(ival) < 0)
   21535              :     return false;
   21536       194238 :   if (mpz_fits_slong_p(ival))
   21537              :     {
   21538       194238 :       *val = static_cast<int64_t>(mpz_get_si(ival));
   21539       194238 :       return true;
   21540              :     }
   21541              : 
   21542              :   // Test >= 64, not > 64, because an int64_t can hold 63 bits of a
   21543              :   // positive value.
   21544            0 :   if (mpz_sizeinbase(ival, 2) >= 64)
   21545              :     return false;
   21546              : 
   21547            0 :   mpz_t q, r;
   21548            0 :   mpz_init(q);
   21549            0 :   mpz_init(r);
   21550            0 :   mpz_tdiv_q_2exp(q, ival, 32);
   21551            0 :   mpz_tdiv_r_2exp(r, ival, 32);
   21552            0 :   go_assert(mpz_fits_ulong_p(q) && mpz_fits_ulong_p(r));
   21553            0 :   *val = ((static_cast<int64_t>(mpz_get_ui(q)) << 32)
   21554            0 :           + static_cast<int64_t>(mpz_get_ui(r)));
   21555            0 :   mpz_clear(r);
   21556            0 :   mpz_clear(q);
   21557            0 :   return true;
   21558              : }
   21559              : 
   21560              : // Express floating point value as memory size if possible.
   21561              : 
   21562              : bool
   21563            5 : Numeric_constant::mpfr_to_memory_size(const mpfr_t fval, int64_t* val) const
   21564              : {
   21565            5 :   if (!mpfr_integer_p(fval))
   21566              :     return false;
   21567            5 :   mpz_t ival;
   21568            5 :   mpz_init(ival);
   21569            5 :   mpfr_get_z(ival, fval, MPFR_RNDN);
   21570            5 :   bool ret = this->mpz_to_memory_size(ival, val);
   21571            5 :   mpz_clear(ival);
   21572            5 :   return ret;
   21573              : }
   21574              : 
   21575              : // Convert value to integer if possible.
   21576              : 
   21577              : bool
   21578     31457569 : Numeric_constant::to_int(mpz_t* val) const
   21579              : {
   21580     31457569 :   switch (this->classification_)
   21581              :     {
   21582     31453402 :     case NC_INT:
   21583     31453402 :     case NC_RUNE:
   21584     31453402 :       mpz_init_set(*val, this->u_.int_val);
   21585     31453402 :       return true;
   21586         4128 :     case NC_FLOAT:
   21587         4128 :       if (!mpfr_integer_p(this->u_.float_val))
   21588              :         return false;
   21589         4128 :       mpz_init(*val);
   21590         4128 :       mpfr_get_z(*val, this->u_.float_val, MPFR_RNDN);
   21591         4128 :       return true;
   21592           39 :     case NC_COMPLEX:
   21593           39 :       if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val))
   21594           39 :           || !mpfr_integer_p(mpc_realref(this->u_.complex_val)))
   21595            0 :         return false;
   21596           39 :       mpz_init(*val);
   21597           39 :       mpfr_get_z(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
   21598           39 :       return true;
   21599            0 :     default:
   21600            0 :       go_unreachable();
   21601              :     }
   21602              : }
   21603              : 
   21604              : // Convert value to floating point if possible.
   21605              : 
   21606              : bool
   21607        40198 : Numeric_constant::to_float(mpfr_t* val) const
   21608              : {
   21609        40198 :   switch (this->classification_)
   21610              :     {
   21611        19927 :     case NC_INT:
   21612        19927 :     case NC_RUNE:
   21613        19927 :       mpfr_init_set_z(*val, this->u_.int_val, MPFR_RNDN);
   21614        19927 :       return true;
   21615        20267 :     case NC_FLOAT:
   21616        20267 :       mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
   21617        20267 :       return true;
   21618            4 :     case NC_COMPLEX:
   21619            4 :       if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
   21620              :         return false;
   21621            4 :       mpfr_init_set(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
   21622            4 :       return true;
   21623            0 :     default:
   21624            0 :       go_unreachable();
   21625              :     }
   21626              : }
   21627              : 
   21628              : // Convert value to complex.
   21629              : 
   21630              : bool
   21631         5034 : Numeric_constant::to_complex(mpc_t* val) const
   21632              : {
   21633         5034 :   mpc_init2(*val, mpc_precision);
   21634         5034 :   switch (this->classification_)
   21635              :     {
   21636          801 :     case NC_INT:
   21637          801 :     case NC_RUNE:
   21638          801 :       mpc_set_z(*val, this->u_.int_val, MPC_RNDNN);
   21639          801 :       return true;
   21640          600 :     case NC_FLOAT:
   21641          600 :       mpc_set_fr(*val, this->u_.float_val, MPC_RNDNN);
   21642          600 :       return true;
   21643         3633 :     case NC_COMPLEX:
   21644         3633 :       mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
   21645         3633 :       return true;
   21646            0 :     default:
   21647            0 :       go_unreachable();
   21648              :     }
   21649              : }
   21650              : 
   21651              : // Get the type.
   21652              : 
   21653              : Type*
   21654      6993811 : Numeric_constant::type() const
   21655              : {
   21656      6993811 :   if (this->type_ != NULL)
   21657              :     return this->type_;
   21658        28813 :   switch (this->classification_)
   21659              :     {
   21660        28813 :     case NC_INT:
   21661        28813 :       return Type::make_abstract_integer_type();
   21662            0 :     case NC_RUNE:
   21663            0 :       return Type::make_abstract_character_type();
   21664            0 :     case NC_FLOAT:
   21665            0 :       return Type::make_abstract_float_type();
   21666            0 :     case NC_COMPLEX:
   21667            0 :       return Type::make_abstract_complex_type();
   21668            0 :     default:
   21669            0 :       go_unreachable();
   21670              :     }
   21671              : }
   21672              : 
   21673              : // If the constant can be expressed in TYPE, then set the type of the
   21674              : // constant to TYPE and return true.  Otherwise return false, and, if
   21675              : // ISSUE_ERROR is true, report an appropriate error message.
   21676              : 
   21677              : bool
   21678      4163931 : Numeric_constant::set_type(Type* type, bool issue_error, Location loc)
   21679              : {
   21680      4163931 :   bool ret;
   21681      4163931 :   if (type == NULL || type->is_error())
   21682              :     ret = true;
   21683      4163931 :   else if (type->integer_type() != NULL)
   21684      8192844 :     ret = this->check_int_type(type->integer_type(), issue_error, loc);
   21685        67509 :   else if (type->float_type() != NULL)
   21686       121476 :     ret = this->check_float_type(type->float_type(), issue_error, loc);
   21687         6771 :   else if (type->complex_type() != NULL)
   21688        13542 :     ret = this->check_complex_type(type->complex_type(), issue_error, loc);
   21689              :   else
   21690              :     {
   21691            0 :       ret = false;
   21692            0 :       if (issue_error)
   21693            0 :         go_assert(saw_errors());
   21694              :     }
   21695      4163931 :   if (ret)
   21696      4162069 :     this->type_ = type;
   21697      4163931 :   return ret;
   21698              : }
   21699              : 
   21700              : // Check whether the constant can be expressed in an integer type.
   21701              : 
   21702              : bool
   21703      4096422 : Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
   21704              :                                  Location location)
   21705              : {
   21706      4096422 :   mpz_t val;
   21707      4096422 :   switch (this->classification_)
   21708              :     {
   21709      4090930 :     case NC_INT:
   21710      4090930 :     case NC_RUNE:
   21711      4090930 :       mpz_init_set(val, this->u_.int_val);
   21712      4090930 :       break;
   21713              : 
   21714         5443 :     case NC_FLOAT:
   21715         5443 :       if (!mpfr_integer_p(this->u_.float_val))
   21716              :         {
   21717          924 :           if (issue_error)
   21718              :             {
   21719          489 :               go_error_at(location,
   21720              :                           "floating-point constant truncated to integer");
   21721          489 :               this->set_invalid();
   21722              :             }
   21723          924 :           return false;
   21724              :         }
   21725         4519 :       mpz_init(val);
   21726         4519 :       mpfr_get_z(val, this->u_.float_val, MPFR_RNDN);
   21727         4519 :       break;
   21728              : 
   21729           49 :     case NC_COMPLEX:
   21730           49 :       if (!mpfr_integer_p(mpc_realref(this->u_.complex_val))
   21731           49 :           || !mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
   21732              :         {
   21733           11 :           if (issue_error)
   21734              :             {
   21735            8 :               go_error_at(location, "complex constant truncated to integer");
   21736            8 :               this->set_invalid();
   21737              :             }
   21738           11 :           return false;
   21739              :         }
   21740           38 :       mpz_init(val);
   21741           38 :       mpfr_get_z(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
   21742           38 :       break;
   21743              : 
   21744            0 :     default:
   21745            0 :       go_unreachable();
   21746              :     }
   21747              : 
   21748      4095487 :   bool ret;
   21749      4095487 :   if (type->is_abstract())
   21750              :     ret = true;
   21751              :   else
   21752              :     {
   21753      2250783 :       int bits = mpz_sizeinbase(val, 2);
   21754      2250783 :       if (type->is_unsigned())
   21755              :         {
   21756              :           // For an unsigned type we can only accept a nonnegative
   21757              :           // number, and we must be able to represents at least BITS.
   21758       967273 :           ret = mpz_sgn(val) >= 0 && bits <= type->bits();
   21759              :         }
   21760              :       else
   21761              :         {
   21762              :           // For a signed type we need an extra bit to indicate the
   21763              :           // sign.  We have to handle the most negative integer
   21764              :           // specially.
   21765      1283510 :           ret = (bits + 1 <= type->bits()
   21766      1283510 :                  || (bits <= type->bits()
   21767         1756 :                      && mpz_sgn(val) < 0
   21768         1752 :                      && (mpz_scan1(val, 0)
   21769         1752 :                          == static_cast<unsigned long>(type->bits() - 1))
   21770         1752 :                      && mpz_scan0(val, type->bits()) == ULONG_MAX));
   21771              :         }
   21772              :     }
   21773              : 
   21774      4095487 :   if (!ret && issue_error)
   21775              :     {
   21776          484 :       go_error_at(location, "integer constant overflow");
   21777          484 :       this->set_invalid();
   21778              :     }
   21779              : 
   21780              :   return ret;
   21781              : }
   21782              : 
   21783              : // Check whether the constant can be expressed in a floating point
   21784              : // type.
   21785              : 
   21786              : bool
   21787        60738 : Numeric_constant::check_float_type(Float_type* type, bool issue_error,
   21788              :                                    Location location)
   21789              : {
   21790        60738 :   mpfr_t val;
   21791        60738 :   switch (this->classification_)
   21792              :     {
   21793        22177 :     case NC_INT:
   21794        22177 :     case NC_RUNE:
   21795        22177 :       mpfr_init_set_z(val, this->u_.int_val, MPFR_RNDN);
   21796        22177 :       break;
   21797              : 
   21798        38554 :     case NC_FLOAT:
   21799        38554 :       mpfr_init_set(val, this->u_.float_val, MPFR_RNDN);
   21800        38554 :       break;
   21801              : 
   21802            7 :     case NC_COMPLEX:
   21803            7 :       if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
   21804              :         {
   21805            2 :           if (issue_error)
   21806              :             {
   21807            2 :               this->set_invalid();
   21808            2 :               go_error_at(location,
   21809              :                           "complex constant truncated to floating-point");
   21810              :             }
   21811            2 :           return false;
   21812              :         }
   21813            5 :       mpfr_init_set(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
   21814            5 :       break;
   21815              : 
   21816            0 :     default:
   21817            0 :       go_unreachable();
   21818              :     }
   21819              : 
   21820        60736 :   bool ret;
   21821        60736 :   if (type->is_abstract())
   21822              :     ret = true;
   21823        43297 :   else if (mpfr_nan_p(val) || mpfr_inf_p(val) || mpfr_zero_p(val))
   21824              :     {
   21825              :       // A NaN or Infinity always fits in the range of the type.
   21826              :       ret = true;
   21827              :     }
   21828              :   else
   21829              :     {
   21830        39455 :       mpfr_exp_t exp = mpfr_get_exp(val);
   21831        39455 :       mpfr_exp_t max_exp;
   21832        39455 :       switch (type->bits())
   21833              :         {
   21834              :         case 32:
   21835              :           max_exp = 128;
   21836              :           break;
   21837        30431 :         case 64:
   21838        30431 :           max_exp = 1024;
   21839        30431 :           break;
   21840            0 :         default:
   21841            0 :           go_unreachable();
   21842              :         }
   21843              : 
   21844        39455 :       ret = exp <= max_exp;
   21845              : 
   21846        39455 :       if (ret)
   21847              :         {
   21848              :           // Round the constant to the desired type.
   21849        39449 :           mpfr_t t;
   21850        39449 :           mpfr_init(t);
   21851        39449 :           switch (type->bits())
   21852              :             {
   21853         9021 :             case 32:
   21854         9021 :               mpfr_set_prec(t, 24);
   21855         9021 :               break;
   21856        30428 :             case 64:
   21857        30428 :               mpfr_set_prec(t, 53);
   21858        30428 :               break;
   21859            0 :             default:
   21860            0 :               go_unreachable();
   21861              :             }
   21862        39449 :           mpfr_set(t, val, MPFR_RNDN);
   21863        39449 :           mpfr_set(val, t, MPFR_RNDN);
   21864        39449 :           mpfr_clear(t);
   21865              : 
   21866        39449 :           this->set_float(type, val);
   21867              :         }
   21868              :     }
   21869              : 
   21870        60736 :   mpfr_clear(val);
   21871              : 
   21872        60736 :   if (!ret && issue_error)
   21873              :     {
   21874            6 :       go_error_at(location, "floating-point constant overflow");
   21875            6 :       this->set_invalid();
   21876              :     }
   21877              : 
   21878              :   return ret;
   21879              : }
   21880              : 
   21881              : // Check whether the constant can be expressed in a complex type.
   21882              : 
   21883              : bool
   21884         6771 : Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
   21885              :                                      Location location)
   21886              : {
   21887         6771 :   if (type->is_abstract())
   21888              :     return true;
   21889              : 
   21890         1894 :   mpfr_exp_t max_exp;
   21891         1894 :   switch (type->bits())
   21892              :     {
   21893              :     case 64:
   21894              :       max_exp = 128;
   21895              :       break;
   21896         1542 :     case 128:
   21897         1542 :       max_exp = 1024;
   21898         1542 :       break;
   21899            0 :     default:
   21900            0 :       go_unreachable();
   21901              :     }
   21902              : 
   21903         1894 :   mpc_t val;
   21904         1894 :   mpc_init2(val, mpc_precision);
   21905         1894 :   switch (this->classification_)
   21906              :     {
   21907          539 :     case NC_INT:
   21908          539 :     case NC_RUNE:
   21909          539 :       mpc_set_z(val, this->u_.int_val, MPC_RNDNN);
   21910          539 :       break;
   21911              : 
   21912          100 :     case NC_FLOAT:
   21913          100 :       mpc_set_fr(val, this->u_.float_val, MPC_RNDNN);
   21914          100 :       break;
   21915              : 
   21916         1255 :     case NC_COMPLEX:
   21917         1255 :       mpc_set(val, this->u_.complex_val, MPC_RNDNN);
   21918         1255 :       break;
   21919              : 
   21920            0 :     default:
   21921            0 :       go_unreachable();
   21922              :     }
   21923              : 
   21924         1894 :   bool ret = true;
   21925         1894 :   if (!mpfr_nan_p(mpc_realref(val))
   21926         1894 :       && !mpfr_inf_p(mpc_realref(val))
   21927         1894 :       && !mpfr_zero_p(mpc_realref(val))
   21928         1212 :       && mpfr_get_exp(mpc_realref(val)) > max_exp)
   21929              :     {
   21930            2 :       if (issue_error)
   21931              :         {
   21932            2 :           go_error_at(location, "complex real part overflow");
   21933            2 :           this->set_invalid();
   21934              :         }
   21935              :       ret = false;
   21936              :     }
   21937              : 
   21938         1894 :   if (!mpfr_nan_p(mpc_imagref(val))
   21939         1894 :       && !mpfr_inf_p(mpc_imagref(val))
   21940         1894 :       && !mpfr_zero_p(mpc_imagref(val))
   21941         1032 :       && mpfr_get_exp(mpc_imagref(val)) > max_exp)
   21942              :     {
   21943            0 :       if (issue_error)
   21944              :         {
   21945            0 :           go_error_at(location, "complex imaginary part overflow");
   21946            0 :           this->set_invalid();
   21947              :         }
   21948              :       ret = false;
   21949              :     }
   21950              : 
   21951         1894 :   if (ret)
   21952              :     {
   21953              :       // Round the constant to the desired type.
   21954         1892 :       mpc_t t;
   21955         1892 :       switch (type->bits())
   21956              :         {
   21957          351 :         case 64:
   21958          351 :           mpc_init2(t, 24);
   21959          351 :           break;
   21960         1541 :         case 128:
   21961         1541 :           mpc_init2(t, 53);
   21962         1541 :           break;
   21963            0 :         default:
   21964            0 :           go_unreachable();
   21965              :         }
   21966         1892 :       mpc_set(t, val, MPC_RNDNN);
   21967         1892 :       mpc_set(val, t, MPC_RNDNN);
   21968         1892 :       mpc_clear(t);
   21969              : 
   21970         1892 :       this->set_complex(type, val);
   21971              :     }
   21972              : 
   21973         1894 :   mpc_clear(val);
   21974              : 
   21975         1894 :   return ret;
   21976              : }
   21977              : 
   21978              : // Return an Expression for this value.
   21979              : 
   21980              : Expression*
   21981       235215 : Numeric_constant::expression(Location loc) const
   21982              : {
   21983       235215 :   switch (this->classification_)
   21984              :     {
   21985       219035 :     case NC_INT:
   21986       219035 :       return Expression::make_integer_z(&this->u_.int_val, this->type_, loc);
   21987         4382 :     case NC_RUNE:
   21988         4382 :       return Expression::make_character(&this->u_.int_val, this->type_, loc);
   21989         9205 :     case NC_FLOAT:
   21990         9205 :       return Expression::make_float(&this->u_.float_val, this->type_, loc);
   21991         2593 :     case NC_COMPLEX:
   21992         2593 :       return Expression::make_complex(&this->u_.complex_val, this->type_, loc);
   21993            0 :     case NC_INVALID:
   21994            0 :       go_assert(saw_errors());
   21995            0 :       return Expression::make_error(loc);
   21996            0 :     default:
   21997            0 :       go_unreachable();
   21998              :     }
   21999              : }
   22000              : 
   22001              : // Calculate a hash code with a given seed.
   22002              : 
   22003              : unsigned int
   22004         3663 : Numeric_constant::hash(unsigned int seed) const
   22005              : {
   22006         3663 :   unsigned long val;
   22007         3663 :   const unsigned int PRIME = 97;
   22008         3663 :   long e = 0;
   22009         3663 :   double f = 1.0;
   22010         3663 :   mpfr_t m;
   22011              : 
   22012         3663 :   switch (this->classification_)
   22013              :     {
   22014              :     case NC_INVALID:
   22015              :       return PRIME;
   22016         3653 :     case NC_INT:
   22017         3653 :     case NC_RUNE:
   22018         3653 :       val = mpz_get_ui(this->u_.int_val);
   22019              :       break;
   22020            4 :     case NC_COMPLEX:
   22021            4 :       mpfr_init(m);
   22022            4 :       mpc_abs(m, this->u_.complex_val, MPFR_RNDN);
   22023            4 :       val = mpfr_get_ui(m, MPFR_RNDN);
   22024            4 :       mpfr_clear(m);
   22025            4 :       break;
   22026            6 :     case NC_FLOAT:
   22027            6 :       f = mpfr_get_d_2exp(&e, this->u_.float_val, MPFR_RNDN) * 4294967295.0;
   22028            6 :       val = static_cast<unsigned long>(e + static_cast<long>(f));
   22029            6 :       break;
   22030            0 :     default:
   22031            0 :       go_unreachable();
   22032              :     }
   22033              : 
   22034         3663 :   return (static_cast<unsigned int>(val) + seed) * PRIME;
   22035              : }
        

Generated by: LCOV version 2.4-beta

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