]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/go/gofrontend/expressions.cc
compiler, runtime: implement shifts by signed amounts
[thirdparty/gcc.git] / gcc / go / gofrontend / expressions.cc
CommitLineData
e440a328 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
ffe743ca 9#include <algorithm>
10
e440a328 11#include "go-c.h"
12#include "gogo.h"
631d5788 13#include "go-diagnostics.h"
438b4bec 14#include "go-encode-id.h"
e440a328 15#include "types.h"
16#include "export.h"
17#include "import.h"
18#include "statements.h"
19#include "lex.h"
a9182619 20#include "runtime.h"
6e193e6f 21#include "backend.h"
e440a328 22#include "expressions.h"
d751bb78 23#include "ast-dump.h"
e440a328 24
25// Class Expression.
26
27Expression::Expression(Expression_classification classification,
b13c66cd 28 Location location)
e440a328 29 : classification_(classification), location_(location)
30{
31}
32
33Expression::~Expression()
34{
35}
36
e440a328 37// Traverse the expressions.
38
39int
40Expression::traverse(Expression** pexpr, Traverse* traverse)
41{
42 Expression* expr = *pexpr;
43 if ((traverse->traverse_mask() & Traverse::traverse_expressions) != 0)
44 {
45 int t = traverse->expression(pexpr);
46 if (t == TRAVERSE_EXIT)
47 return TRAVERSE_EXIT;
48 else if (t == TRAVERSE_SKIP_COMPONENTS)
49 return TRAVERSE_CONTINUE;
50 }
51 return expr->do_traverse(traverse);
52}
53
54// Traverse subexpressions of this expression.
55
56int
57Expression::traverse_subexpressions(Traverse* traverse)
58{
59 return this->do_traverse(traverse);
60}
61
62// Default implementation for do_traverse for child classes.
63
64int
65Expression::do_traverse(Traverse*)
66{
67 return TRAVERSE_CONTINUE;
68}
69
70// This virtual function is called by the parser if the value of this
a7549a6a 71// expression is being discarded. By default, we give an error.
72// Expressions with side effects override.
e440a328 73
4f2138d7 74bool
e440a328 75Expression::do_discarding_value()
76{
a7549a6a 77 this->unused_value_error();
4f2138d7 78 return false;
e440a328 79}
80
81// This virtual function is called to export expressions. This will
82// only be used by expressions which may be constant.
83
84void
548be246 85Expression::do_export(Export_function_body*) const
e440a328 86{
c3e6f413 87 go_unreachable();
e440a328 88}
89
015399f9 90// Write a name to the export data.
91
92void
93Expression::export_name(Export_function_body* efb, const Named_object* no)
94{
95 if (no->package() != NULL)
96 {
97 char buf[50];
98 snprintf(buf, sizeof buf, "<p%d>", efb->package_index(no->package()));
99 efb->write_c_string(buf);
100 }
101
102 if (!Gogo::is_hidden_name(no->name()))
103 efb->write_string(no->name());
104 else
105 {
106 efb->write_c_string(".");
107 efb->write_string(Gogo::unpack_hidden_name(no->name()));
108 }
109}
110
a7549a6a 111// Give an error saying that the value of the expression is not used.
e440a328 112
113void
a7549a6a 114Expression::unused_value_error()
e440a328 115{
4f2138d7 116 this->report_error(_("value computed is not used"));
e440a328 117}
118
119// Note that this expression is an error. This is called by children
120// when they discover an error.
121
122void
123Expression::set_is_error()
124{
125 this->classification_ = EXPRESSION_ERROR;
126}
127
128// For children to call to report an error conveniently.
129
130void
131Expression::report_error(const char* msg)
132{
631d5788 133 go_error_at(this->location_, "%s", msg);
e440a328 134 this->set_is_error();
135}
136
137// Set types of variables and constants. This is implemented by the
138// child class.
139
140void
141Expression::determine_type(const Type_context* context)
142{
143 this->do_determine_type(context);
144}
145
146// Set types when there is no context.
147
148void
149Expression::determine_type_no_context()
150{
151 Type_context context;
152 this->do_determine_type(&context);
153}
154
d3c55148 155// Return true if two expressions refer to the same variable or struct
156// field. This can only be true when there are no side effects.
157
158bool
159Expression::is_same_variable(Expression* a, Expression* b)
160{
161 if (a->classification() != b->classification())
162 return false;
163
164 Var_expression* av = a->var_expression();
165 if (av != NULL)
166 return av->named_object() == b->var_expression()->named_object();
167
168 Field_reference_expression* af = a->field_reference_expression();
169 if (af != NULL)
170 {
171 Field_reference_expression* bf = b->field_reference_expression();
172 return (af->field_index() == bf->field_index()
173 && Expression::is_same_variable(af->expr(), bf->expr()));
174 }
175
176 Unary_expression* au = a->unary_expression();
177 if (au != NULL)
178 {
179 Unary_expression* bu = b->unary_expression();
180 return (au->op() == OPERATOR_MULT
181 && bu->op() == OPERATOR_MULT
182 && Expression::is_same_variable(au->operand(),
183 bu->operand()));
184 }
185
186 return false;
187}
188
2c809f8f 189// Return an expression handling any conversions which must be done during
e440a328 190// assignment.
191
2c809f8f 192Expression*
b4a33049 193Expression::convert_for_assignment(Gogo*, Type* lhs_type,
2c809f8f 194 Expression* rhs, Location location)
e440a328 195{
2c809f8f 196 Type* rhs_type = rhs->type();
197 if (lhs_type->is_error()
198 || rhs_type->is_error()
199 || rhs->is_error_expression())
200 return Expression::make_error(location);
e440a328 201
3a522dcc 202 bool are_identical = Type::are_identical(lhs_type, rhs_type,
203 (Type::COMPARE_ERRORS
204 | Type::COMPARE_TAGS),
205 NULL);
22984631 206 if (!are_identical && lhs_type->interface_type() != NULL)
e440a328 207 {
e007b1eb 208 // Type to interface conversions have been made explicit early.
209 go_assert(rhs_type->interface_type() != NULL);
210 return Expression::convert_interface_to_interface(lhs_type, rhs, false,
211 location);
e440a328 212 }
22984631 213 else if (!are_identical && rhs_type->interface_type() != NULL)
2c809f8f 214 return Expression::convert_interface_to_type(lhs_type, rhs, location);
411eb89e 215 else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
e440a328 216 {
2c809f8f 217 // Assigning nil to a slice.
2c809f8f 218 Expression* nil = Expression::make_nil(location);
e67508fa 219 Expression* zero = Expression::make_integer_ul(0, NULL, location);
2c809f8f 220 return Expression::make_slice_value(lhs_type, nil, zero, zero, location);
e440a328 221 }
222 else if (rhs_type->is_nil_type())
2c809f8f 223 return Expression::make_nil(location);
22984631 224 else if (are_identical)
e440a328 225 {
22984631 226 if (lhs_type->forwarded() != rhs_type->forwarded())
227 {
228 // Different but identical types require an explicit
229 // conversion. This happens with type aliases.
230 return Expression::make_cast(lhs_type, rhs, location);
231 }
232
e440a328 233 // No conversion is needed.
2c809f8f 234 return rhs;
235 }
236 else if (lhs_type->points_to() != NULL)
237 return Expression::make_unsafe_cast(lhs_type, rhs, location);
238 else if (lhs_type->is_numeric_type())
239 return Expression::make_cast(lhs_type, rhs, location);
240 else if ((lhs_type->struct_type() != NULL
241 && rhs_type->struct_type() != NULL)
242 || (lhs_type->array_type() != NULL
243 && rhs_type->array_type() != NULL))
e440a328 244 {
245 // This conversion must be permitted by Go, or we wouldn't have
246 // gotten here.
2c809f8f 247 return Expression::make_unsafe_cast(lhs_type, rhs, location);
e440a328 248 }
249 else
2c809f8f 250 return rhs;
e440a328 251}
252
2c809f8f 253// Return an expression for a conversion from a non-interface type to an
e007b1eb 254// interface type. If ON_STACK is true, it can allocate the storage on
255// stack.
e440a328 256
2c809f8f 257Expression*
258Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
e007b1eb 259 bool on_stack, Location location)
e440a328 260{
e440a328 261 Interface_type* lhs_interface_type = lhs_type->interface_type();
262 bool lhs_is_empty = lhs_interface_type->is_empty();
263
264 // Since RHS_TYPE is a static type, we can create the interface
265 // method table at compile time.
266
267 // When setting an interface to nil, we just set both fields to
268 // NULL.
2c809f8f 269 Type* rhs_type = rhs->type();
e440a328 270 if (rhs_type->is_nil_type())
63697958 271 {
2c809f8f 272 Expression* nil = Expression::make_nil(location);
273 return Expression::make_interface_value(lhs_type, nil, nil, location);
63697958 274 }
e440a328 275
276 // This should have been checked already.
2b8629dd 277 if (!lhs_interface_type->implements_interface(rhs_type, NULL))
278 {
279 go_assert(saw_errors());
280 return Expression::make_error(location);
281 }
e440a328 282
e440a328 283 // An interface is a tuple. If LHS_TYPE is an empty interface type,
284 // then the first field is the type descriptor for RHS_TYPE.
285 // Otherwise it is the interface method table for RHS_TYPE.
2c809f8f 286 Expression* first_field;
e440a328 287 if (lhs_is_empty)
2c809f8f 288 first_field = Expression::make_type_descriptor(rhs_type, location);
e440a328 289 else
290 {
291 // Build the interface method table for this interface and this
292 // object type: a list of function pointers for each interface
293 // method.
294 Named_type* rhs_named_type = rhs_type->named_type();
c0cab2ec 295 Struct_type* rhs_struct_type = rhs_type->struct_type();
e440a328 296 bool is_pointer = false;
c0cab2ec 297 if (rhs_named_type == NULL && rhs_struct_type == NULL)
e440a328 298 {
299 rhs_named_type = rhs_type->deref()->named_type();
c0cab2ec 300 rhs_struct_type = rhs_type->deref()->struct_type();
e440a328 301 is_pointer = true;
302 }
c0cab2ec 303 if (rhs_named_type != NULL)
2c809f8f 304 first_field =
305 rhs_named_type->interface_method_table(lhs_interface_type,
306 is_pointer);
c0cab2ec 307 else if (rhs_struct_type != NULL)
2c809f8f 308 first_field =
309 rhs_struct_type->interface_method_table(lhs_interface_type,
310 is_pointer);
c0cab2ec 311 else
2c809f8f 312 first_field = Expression::make_nil(location);
e440a328 313 }
e440a328 314
2c809f8f 315 Expression* obj;
5b665222 316 if (rhs_type->is_direct_iface_type())
e440a328 317 {
2c809f8f 318 // We are assigning a pointer to the interface; the interface
e440a328 319 // holds the pointer itself.
5b665222 320 obj = unpack_direct_iface(rhs, location);
2c809f8f 321 }
322 else
323 {
324 // We are assigning a non-pointer value to the interface; the
45ff893b 325 // interface gets a copy of the value in the heap if it escapes.
e47edcf7 326 if (rhs->is_constant())
327 obj = Expression::make_unary(OPERATOR_AND, rhs, location);
328 else
329 {
330 obj = Expression::make_heap_expression(rhs, location);
331 if (on_stack)
332 obj->heap_expression()->set_allocate_on_stack();
333 }
e440a328 334 }
335
2c809f8f 336 return Expression::make_interface_value(lhs_type, first_field, obj, location);
337}
e440a328 338
5b665222 339// Return an expression for the pointer-typed value of a direct interface
340// type. Specifically, for single field struct or array, get the single
341// field, and do this recursively. The reason for this is that we don't
342// want to assign a struct or an array to a pointer-typed field. The
343// backend may not like that.
344
345Expression*
346Expression::unpack_direct_iface(Expression* rhs, Location loc)
347{
348 Struct_type* st = rhs->type()->struct_type();
349 if (st != NULL)
350 {
351 go_assert(st->field_count() == 1);
352 Expression* field = Expression::make_field_reference(rhs, 0, loc);
353 return unpack_direct_iface(field, loc);
354 }
355 Array_type* at = rhs->type()->array_type();
356 if (at != NULL)
357 {
358 int64_t len;
359 bool ok = at->int_length(&len);
360 go_assert(ok && len == 1);
361 Type* int_type = Type::lookup_integer_type("int");
362 Expression* index = Expression::make_integer_ul(0, int_type, loc);
363 Expression* elem = Expression::make_array_index(rhs, index, NULL, NULL, loc);
364 return unpack_direct_iface(elem, loc);
365 }
366 return rhs;
367}
368
369// The opposite of unpack_direct_iface.
370
371Expression*
372Expression::pack_direct_iface(Type* t, Expression* rhs, Location loc)
373{
374 if (rhs->type() == t)
375 return rhs;
376 Struct_type* st = t->struct_type();
377 if (st != NULL)
378 {
379 Expression_list* vals = new Expression_list();
380 vals->push_back(pack_direct_iface(st->field(0)->type(), rhs, loc));
381 return Expression::make_struct_composite_literal(t, vals, loc);
382 }
383 Array_type* at = t->array_type();
384 if (at != NULL)
385 {
386 Expression_list* vals = new Expression_list();
387 vals->push_back(pack_direct_iface(at->element_type(), rhs, loc));
388 return Expression::make_array_composite_literal(t, vals, loc);
389 }
390 return Expression::make_unsafe_cast(t, rhs, loc);
391}
392
2c809f8f 393// Return an expression for the type descriptor of RHS.
e440a328 394
2c809f8f 395Expression*
396Expression::get_interface_type_descriptor(Expression* rhs)
397{
398 go_assert(rhs->type()->interface_type() != NULL);
399 Location location = rhs->location();
e440a328 400
2c809f8f 401 // The type descriptor is the first field of an empty interface.
402 if (rhs->type()->interface_type()->is_empty())
403 return Expression::make_interface_info(rhs, INTERFACE_INFO_TYPE_DESCRIPTOR,
404 location);
405
406 Expression* mtable =
407 Expression::make_interface_info(rhs, INTERFACE_INFO_METHODS, location);
e440a328 408
2c809f8f 409 Expression* descriptor =
f614ea8b 410 Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, location);
2c809f8f 411 descriptor = Expression::make_field_reference(descriptor, 0, location);
412 Expression* nil = Expression::make_nil(location);
e440a328 413
2c809f8f 414 Expression* eq =
415 Expression::make_binary(OPERATOR_EQEQ, mtable, nil, location);
416 return Expression::make_conditional(eq, nil, descriptor, location);
e440a328 417}
418
2c809f8f 419// Return an expression for the conversion of an interface type to an
e440a328 420// interface type.
421
2c809f8f 422Expression*
423Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
424 bool for_type_guard,
425 Location location)
e440a328 426{
3a522dcc 427 if (Type::are_identical(lhs_type, rhs->type(),
428 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
429 NULL))
8ba8cc87 430 return rhs;
431
e440a328 432 Interface_type* lhs_interface_type = lhs_type->interface_type();
433 bool lhs_is_empty = lhs_interface_type->is_empty();
434
e440a328 435 // In the general case this requires runtime examination of the type
436 // method table to match it up with the interface methods.
437
438 // FIXME: If all of the methods in the right hand side interface
439 // also appear in the left hand side interface, then we don't need
440 // to do a runtime check, although we still need to build a new
441 // method table.
442
8ba8cc87 443 // We are going to evaluate RHS multiple times.
444 go_assert(rhs->is_variable());
445
e440a328 446 // Get the type descriptor for the right hand side. This will be
447 // NULL for a nil interface.
2c809f8f 448 Expression* rhs_type_expr = Expression::get_interface_type_descriptor(rhs);
449 Expression* lhs_type_expr =
450 Expression::make_type_descriptor(lhs_type, location);
e440a328 451
2c809f8f 452 Expression* first_field;
e440a328 453 if (for_type_guard)
454 {
455 // A type assertion fails when converting a nil interface.
6098d6cb 456 first_field = Runtime::make_call(Runtime::ASSERTITAB, location, 2,
457 lhs_type_expr, rhs_type_expr);
e440a328 458 }
459 else if (lhs_is_empty)
460 {
2c809f8f 461 // A conversion to an empty interface always succeeds, and the
e440a328 462 // first field is just the type descriptor of the object.
2c809f8f 463 first_field = rhs_type_expr;
e440a328 464 }
465 else
466 {
467 // A conversion to a non-empty interface may fail, but unlike a
468 // type assertion converting nil will always succeed.
6098d6cb 469 first_field = Runtime::make_call(Runtime::REQUIREITAB, location, 2,
470 lhs_type_expr, rhs_type_expr);
e440a328 471 }
472
473 // The second field is simply the object pointer.
2c809f8f 474 Expression* obj =
475 Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT, location);
476 return Expression::make_interface_value(lhs_type, first_field, obj, location);
e440a328 477}
478
2c809f8f 479// Return an expression for the conversion of an interface type to a
e440a328 480// non-interface type.
481
2c809f8f 482Expression*
483Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs,
484 Location location)
e440a328 485{
8ba8cc87 486 // We are going to evaluate RHS multiple times.
487 go_assert(rhs->is_variable());
488
ff736f11 489 // Build an expression to check that the type is valid. It will
490 // panic with an appropriate runtime type error if the type is not
491 // valid.
492 // (lhs_type != rhs_type ? panicdottype(lhs_type, rhs_type, inter_type) :
493 // nil /*dummy*/)
2c809f8f 494 Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type,
495 location);
496 Expression* rhs_descriptor =
497 Expression::get_interface_type_descriptor(rhs);
498
499 Type* rhs_type = rhs->type();
500 Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
501 location);
502
ff736f11 503 Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, lhs_type_expr,
504 rhs_descriptor, location);
505 rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
506 Expression* panic = Runtime::make_call(Runtime::PANICDOTTYPE, location,
507 3, lhs_type_expr->copy(),
508 rhs_descriptor,
509 rhs_inter_expr);
510 Expression* nil = Expression::make_nil(location);
511 Expression* check = Expression::make_conditional(cond, panic, nil,
512 location);
e440a328 513
ff736f11 514 // If the conversion succeeds, pull out the value.
2c809f8f 515 Expression* obj = Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT,
516 location);
e440a328 517
5b665222 518 // If the value is a direct interface, then it is the value we want.
e440a328 519 // Otherwise it points to the value.
5b665222 520 if (lhs_type->is_direct_iface_type())
521 obj = Expression::pack_direct_iface(lhs_type, obj, location);
522 else
e440a328 523 {
2c809f8f 524 obj = Expression::make_unsafe_cast(Type::make_pointer_type(lhs_type), obj,
525 location);
f614ea8b 526 obj = Expression::make_dereference(obj, NIL_CHECK_NOT_NEEDED,
527 location);
e440a328 528 }
ff736f11 529 return Expression::make_compound(check, obj, location);
e440a328 530}
531
ea664253 532// Convert an expression to its backend representation. This is implemented by
533// the child class. Not that it is not in general safe to call this multiple
e440a328 534// times for a single expression, but that we don't catch such errors.
535
ea664253 536Bexpression*
537Expression::get_backend(Translate_context* context)
e440a328 538{
539 // The child may have marked this expression as having an error.
540 if (this->classification_ == EXPRESSION_ERROR)
ea664253 541 return context->backend()->error_expression();
e440a328 542
ea664253 543 return this->do_get_backend(context);
e440a328 544}
545
48c2a53a 546// Return a backend expression for VAL.
547Bexpression*
548Expression::backend_numeric_constant_expression(Translate_context* context,
549 Numeric_constant* val)
e440a328 550{
48c2a53a 551 Gogo* gogo = context->gogo();
552 Type* type = val->type();
553 if (type == NULL)
554 return gogo->backend()->error_expression();
e440a328 555
48c2a53a 556 Btype* btype = type->get_backend(gogo);
557 Bexpression* ret;
558 if (type->integer_type() != NULL)
e440a328 559 {
560 mpz_t ival;
48c2a53a 561 if (!val->to_int(&ival))
562 {
563 go_assert(saw_errors());
564 return gogo->backend()->error_expression();
565 }
566 ret = gogo->backend()->integer_constant_expression(btype, ival);
e440a328 567 mpz_clear(ival);
e440a328 568 }
48c2a53a 569 else if (type->float_type() != NULL)
e440a328 570 {
48c2a53a 571 mpfr_t fval;
572 if (!val->to_float(&fval))
573 {
574 go_assert(saw_errors());
575 return gogo->backend()->error_expression();
576 }
577 ret = gogo->backend()->float_constant_expression(btype, fval);
578 mpfr_clear(fval);
e440a328 579 }
48c2a53a 580 else if (type->complex_type() != NULL)
e440a328 581 {
fcbea5e4 582 mpc_t cval;
583 if (!val->to_complex(&cval))
48c2a53a 584 {
585 go_assert(saw_errors());
586 return gogo->backend()->error_expression();
587 }
fcbea5e4 588 ret = gogo->backend()->complex_constant_expression(btype, cval);
589 mpc_clear(cval);
e440a328 590 }
591 else
c3e6f413 592 go_unreachable();
e440a328 593
48c2a53a 594 return ret;
e440a328 595}
596
2c809f8f 597// Return an expression which evaluates to true if VAL, of arbitrary integer
598// type, is negative or is more than the maximum value of the Go type "int".
e440a328 599
2c809f8f 600Expression*
601Expression::check_bounds(Expression* val, Location loc)
e440a328 602{
2c809f8f 603 Type* val_type = val->type();
604 Type* bound_type = Type::lookup_integer_type("int");
605
606 int val_type_size;
607 bool val_is_unsigned = false;
608 if (val_type->integer_type() != NULL)
609 {
610 val_type_size = val_type->integer_type()->bits();
611 val_is_unsigned = val_type->integer_type()->is_unsigned();
612 }
613 else
614 {
615 if (!val_type->is_numeric_type()
616 || !Type::are_convertible(bound_type, val_type, NULL))
617 {
618 go_assert(saw_errors());
619 return Expression::make_boolean(true, loc);
620 }
e440a328 621
2c809f8f 622 if (val_type->complex_type() != NULL)
623 val_type_size = val_type->complex_type()->bits();
624 else
625 val_type_size = val_type->float_type()->bits();
626 }
627
628 Expression* negative_index = Expression::make_boolean(false, loc);
629 Expression* index_overflows = Expression::make_boolean(false, loc);
630 if (!val_is_unsigned)
e440a328 631 {
e67508fa 632 Expression* zero = Expression::make_integer_ul(0, val_type, loc);
2c809f8f 633 negative_index = Expression::make_binary(OPERATOR_LT, val, zero, loc);
e440a328 634 }
635
2c809f8f 636 int bound_type_size = bound_type->integer_type()->bits();
c3068ac0 637 if (val_type_size > bound_type_size
638 || (val_type_size == bound_type_size
2c809f8f 639 && val_is_unsigned))
640 {
641 mpz_t one;
642 mpz_init_set_ui(one, 1UL);
643
644 // maxval = 2^(bound_type_size - 1) - 1
645 mpz_t maxval;
646 mpz_init(maxval);
647 mpz_mul_2exp(maxval, one, bound_type_size - 1);
648 mpz_sub_ui(maxval, maxval, 1);
e67508fa 649 Expression* max = Expression::make_integer_z(&maxval, val_type, loc);
2c809f8f 650 mpz_clear(one);
651 mpz_clear(maxval);
652
653 index_overflows = Expression::make_binary(OPERATOR_GT, val, max, loc);
e440a328 654 }
655
2c809f8f 656 return Expression::make_binary(OPERATOR_OROR, negative_index, index_overflows,
657 loc);
e440a328 658}
659
d751bb78 660void
661Expression::dump_expression(Ast_dump_context* ast_dump_context) const
662{
663 this->do_dump_expression(ast_dump_context);
664}
665
e440a328 666// Error expressions. This are used to avoid cascading errors.
667
668class Error_expression : public Expression
669{
670 public:
b13c66cd 671 Error_expression(Location location)
e440a328 672 : Expression(EXPRESSION_ERROR, location)
673 { }
674
675 protected:
676 bool
677 do_is_constant() const
678 { return true; }
679
680 bool
0c77715b 681 do_numeric_constant_value(Numeric_constant* nc) const
e440a328 682 {
0c77715b 683 nc->set_unsigned_long(NULL, 0);
e440a328 684 return true;
685 }
686
4f2138d7 687 bool
e440a328 688 do_discarding_value()
4f2138d7 689 { return true; }
e440a328 690
691 Type*
692 do_type()
693 { return Type::make_error_type(); }
694
695 void
696 do_determine_type(const Type_context*)
697 { }
698
699 Expression*
700 do_copy()
701 { return this; }
702
703 bool
704 do_is_addressable() const
705 { return true; }
706
ea664253 707 Bexpression*
708 do_get_backend(Translate_context* context)
709 { return context->backend()->error_expression(); }
d751bb78 710
711 void
712 do_dump_expression(Ast_dump_context*) const;
e440a328 713};
714
d751bb78 715// Dump the ast representation for an error expression to a dump context.
716
717void
718Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
719{
720 ast_dump_context->ostream() << "_Error_" ;
721}
722
e440a328 723Expression*
b13c66cd 724Expression::make_error(Location location)
e440a328 725{
726 return new Error_expression(location);
727}
728
729// An expression which is really a type. This is used during parsing.
730// It is an error if these survive after lowering.
731
732class
733Type_expression : public Expression
734{
735 public:
b13c66cd 736 Type_expression(Type* type, Location location)
e440a328 737 : Expression(EXPRESSION_TYPE, location),
738 type_(type)
739 { }
740
741 protected:
742 int
743 do_traverse(Traverse* traverse)
744 { return Type::traverse(this->type_, traverse); }
745
746 Type*
747 do_type()
748 { return this->type_; }
749
750 void
751 do_determine_type(const Type_context*)
752 { }
753
754 void
755 do_check_types(Gogo*)
756 { this->report_error(_("invalid use of type")); }
757
758 Expression*
759 do_copy()
760 { return this; }
761
ea664253 762 Bexpression*
763 do_get_backend(Translate_context*)
c3e6f413 764 { go_unreachable(); }
e440a328 765
d751bb78 766 void do_dump_expression(Ast_dump_context*) const;
f03a9fbf 767
e440a328 768 private:
769 // The type which we are representing as an expression.
770 Type* type_;
771};
772
d751bb78 773void
774Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
775{
776 ast_dump_context->dump_type(this->type_);
777}
778
e440a328 779Expression*
b13c66cd 780Expression::make_type(Type* type, Location location)
e440a328 781{
782 return new Type_expression(type, location);
783}
784
e03bdf36 785// Class Parser_expression.
786
787Type*
788Parser_expression::do_type()
789{
790 // We should never really ask for the type of a Parser_expression.
791 // However, it can happen, at least when we have an invalid const
792 // whose initializer refers to the const itself. In that case we
793 // may ask for the type when lowering the const itself.
c484d925 794 go_assert(saw_errors());
e03bdf36 795 return Type::make_error_type();
796}
797
e440a328 798// Class Var_expression.
799
800// Lower a variable expression. Here we just make sure that the
801// initialization expression of the variable has been lowered. This
802// ensures that we will be able to determine the type of the variable
803// if necessary.
804
805Expression*
ceeb4318 806Var_expression::do_lower(Gogo* gogo, Named_object* function,
807 Statement_inserter* inserter, int)
e440a328 808{
809 if (this->variable_->is_variable())
810 {
811 Variable* var = this->variable_->var_value();
812 // This is either a local variable or a global variable. A
813 // reference to a variable which is local to an enclosing
814 // function will be a reference to a field in a closure.
815 if (var->is_global())
ceeb4318 816 {
817 function = NULL;
818 inserter = NULL;
819 }
820 var->lower_init_expression(gogo, function, inserter);
e440a328 821 }
822 return this;
823}
824
e440a328 825// Return the type of a reference to a variable.
826
827Type*
828Var_expression::do_type()
829{
830 if (this->variable_->is_variable())
831 return this->variable_->var_value()->type();
832 else if (this->variable_->is_result_variable())
833 return this->variable_->result_var_value()->type();
834 else
c3e6f413 835 go_unreachable();
e440a328 836}
837
0ab09e06 838// Determine the type of a reference to a variable.
839
840void
841Var_expression::do_determine_type(const Type_context*)
842{
843 if (this->variable_->is_variable())
844 this->variable_->var_value()->determine_type();
845}
846
e440a328 847// Something takes the address of this variable. This means that we
848// may want to move the variable onto the heap.
849
850void
851Var_expression::do_address_taken(bool escapes)
852{
853 if (!escapes)
f325319b 854 {
855 if (this->variable_->is_variable())
856 this->variable_->var_value()->set_non_escaping_address_taken();
857 else if (this->variable_->is_result_variable())
858 this->variable_->result_var_value()->set_non_escaping_address_taken();
859 else
860 go_unreachable();
861 }
e440a328 862 else
f325319b 863 {
864 if (this->variable_->is_variable())
865 this->variable_->var_value()->set_address_taken();
866 else if (this->variable_->is_result_variable())
867 this->variable_->result_var_value()->set_address_taken();
868 else
869 go_unreachable();
870 }
45ff893b 871
872 if (this->variable_->is_variable()
873 && this->variable_->var_value()->is_in_heap())
874 {
875 Node::make_node(this)->set_encoding(Node::ESCAPE_HEAP);
876 Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
877 }
e440a328 878}
879
5f6f5357 880// Export a reference to a variable.
881
882void
883Var_expression::do_export(Export_function_body* efb) const
884{
015399f9 885 Named_object* no = this->variable_;
886 if (no->is_result_variable() || !no->var_value()->is_global())
887 efb->write_string(Gogo::unpack_hidden_name(no->name()));
888 else
889 Expression::export_name(efb, no);
5f6f5357 890}
891
ea664253 892// Get the backend representation for a reference to a variable.
e440a328 893
ea664253 894Bexpression*
895Var_expression::do_get_backend(Translate_context* context)
e440a328 896{
fe2f84cf 897 Bvariable* bvar = this->variable_->get_backend_variable(context->gogo(),
898 context->function());
fe2f84cf 899 bool is_in_heap;
c6777780 900 Location loc = this->location();
9b27b43c 901 Btype* btype;
902 Gogo* gogo = context->gogo();
fe2f84cf 903 if (this->variable_->is_variable())
9b27b43c 904 {
905 is_in_heap = this->variable_->var_value()->is_in_heap();
906 btype = this->variable_->var_value()->type()->get_backend(gogo);
907 }
fe2f84cf 908 else if (this->variable_->is_result_variable())
9b27b43c 909 {
910 is_in_heap = this->variable_->result_var_value()->is_in_heap();
911 btype = this->variable_->result_var_value()->type()->get_backend(gogo);
912 }
fe2f84cf 913 else
c3e6f413 914 go_unreachable();
c6777780 915
d4e6573e 916 Bexpression* ret =
7af8e400 917 context->backend()->var_expression(bvar, loc);
fe2f84cf 918 if (is_in_heap)
9b27b43c 919 ret = context->backend()->indirect_expression(btype, ret, true, loc);
ea664253 920 return ret;
e440a328 921}
922
d751bb78 923// Ast dump for variable expression.
924
925void
926Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
927{
cd5e24c1 928 ast_dump_context->ostream() << this->variable_->message_name() ;
d751bb78 929}
930
e440a328 931// Make a reference to a variable in an expression.
932
933Expression*
b13c66cd 934Expression::make_var_reference(Named_object* var, Location location)
e440a328 935{
936 if (var->is_sink())
937 return Expression::make_sink(location);
938
939 // FIXME: Creating a new object for each reference to a variable is
940 // wasteful.
941 return new Var_expression(var, location);
942}
943
b0c09712 944// Class Enclosed_var_expression.
945
946int
947Enclosed_var_expression::do_traverse(Traverse*)
948{
949 return TRAVERSE_CONTINUE;
950}
951
952// Lower the reference to the enclosed variable.
953
954Expression*
955Enclosed_var_expression::do_lower(Gogo* gogo, Named_object* function,
956 Statement_inserter* inserter, int)
957{
958 gogo->lower_expression(function, inserter, &this->reference_);
959 return this;
960}
961
962// Flatten the reference to the enclosed variable.
963
964Expression*
965Enclosed_var_expression::do_flatten(Gogo* gogo, Named_object* function,
966 Statement_inserter* inserter)
967{
968 gogo->flatten_expression(function, inserter, &this->reference_);
969 return this;
970}
971
972void
973Enclosed_var_expression::do_address_taken(bool escapes)
974{
975 if (!escapes)
976 {
977 if (this->variable_->is_variable())
978 this->variable_->var_value()->set_non_escaping_address_taken();
979 else if (this->variable_->is_result_variable())
980 this->variable_->result_var_value()->set_non_escaping_address_taken();
981 else
982 go_unreachable();
983 }
984 else
985 {
986 if (this->variable_->is_variable())
987 this->variable_->var_value()->set_address_taken();
988 else if (this->variable_->is_result_variable())
989 this->variable_->result_var_value()->set_address_taken();
990 else
991 go_unreachable();
992 }
45ff893b 993
994 if (this->variable_->is_variable()
995 && this->variable_->var_value()->is_in_heap())
996 Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
b0c09712 997}
998
999// Ast dump for enclosed variable expression.
1000
1001void
1002Enclosed_var_expression::do_dump_expression(Ast_dump_context* adc) const
1003{
cd5e24c1 1004 adc->ostream() << this->variable_->message_name();
b0c09712 1005}
1006
1007// Make a reference to a variable within an enclosing function.
1008
1009Expression*
1010Expression::make_enclosing_var_reference(Expression* reference,
1011 Named_object* var, Location location)
1012{
1013 return new Enclosed_var_expression(reference, var, location);
1014}
1015
e440a328 1016// Class Temporary_reference_expression.
1017
1018// The type.
1019
1020Type*
1021Temporary_reference_expression::do_type()
1022{
1023 return this->statement_->type();
1024}
1025
1026// Called if something takes the address of this temporary variable.
1027// We never have to move temporary variables to the heap, but we do
1028// need to know that they must live in the stack rather than in a
1029// register.
1030
1031void
1032Temporary_reference_expression::do_address_taken(bool)
1033{
1034 this->statement_->set_is_address_taken();
1035}
1036
f6492beb 1037// Export a reference to a temporary.
1038
1039void
1040Temporary_reference_expression::do_export(Export_function_body* efb) const
1041{
1042 unsigned int idx = efb->temporary_index(this->statement_);
1043 char buf[50];
1044 snprintf(buf, sizeof buf, "$t%u", idx);
1045 efb->write_c_string(buf);
1046}
1047
1048// Import a reference to a temporary.
1049
1050Expression*
1051Temporary_reference_expression::do_import(Import_function_body* ifb,
1052 Location loc)
1053{
1054 std::string id = ifb->read_identifier();
1055 go_assert(id[0] == '$' && id[1] == 't');
1056 const char *p = id.c_str();
1057 char *end;
1058 long idx = strtol(p + 2, &end, 10);
1059 if (*end != '\0' || idx > 0x7fffffff)
1060 {
1061 if (!ifb->saw_error())
1062 go_error_at(loc,
1063 ("invalid export data for %qs: "
1064 "invalid temporary reference index at %lu"),
1065 ifb->name().c_str(),
1066 static_cast<unsigned long>(ifb->off()));
1067 ifb->set_saw_error();
1068 return Expression::make_error(loc);
1069 }
1070
1071 Temporary_statement* temp =
1072 ifb->temporary_statement(static_cast<unsigned int>(idx));
1073 if (temp == NULL)
1074 {
1075 if (!ifb->saw_error())
1076 go_error_at(loc,
1077 ("invalid export data for %qs: "
1078 "undefined temporary reference index at %lu"),
1079 ifb->name().c_str(),
1080 static_cast<unsigned long>(ifb->off()));
1081 ifb->set_saw_error();
1082 return Expression::make_error(loc);
1083 }
1084
1085 return Expression::make_temporary_reference(temp, loc);
1086}
1087
ea664253 1088// Get a backend expression referring to the variable.
e440a328 1089
ea664253 1090Bexpression*
1091Temporary_reference_expression::do_get_backend(Translate_context* context)
e440a328 1092{
cd440cff 1093 Gogo* gogo = context->gogo();
eefc1ed3 1094 Bvariable* bvar = this->statement_->get_backend_variable(context);
7af8e400 1095 Bexpression* ret = gogo->backend()->var_expression(bvar, this->location());
eefc1ed3 1096
cd440cff 1097 // The backend can't always represent the same set of recursive types
eefc1ed3 1098 // that the Go frontend can. In some cases this means that a
1099 // temporary variable won't have the right backend type. Correct
1100 // that here by adding a type cast. We need to use base() to push
1101 // the circularity down one level.
cd440cff 1102 Type* stype = this->statement_->type();
ceeb4318 1103 if (!this->is_lvalue_
03118c21 1104 && stype->points_to() != NULL
1105 && stype->points_to()->is_void_type())
eefc1ed3 1106 {
cd440cff 1107 Btype* btype = this->type()->base()->get_backend(gogo);
1108 ret = gogo->backend()->convert_expression(btype, ret, this->location());
eefc1ed3 1109 }
ea664253 1110 return ret;
e440a328 1111}
1112
d751bb78 1113// Ast dump for temporary reference.
1114
1115void
1116Temporary_reference_expression::do_dump_expression(
1117 Ast_dump_context* ast_dump_context) const
1118{
1119 ast_dump_context->dump_temp_variable_name(this->statement_);
1120}
1121
e440a328 1122// Make a reference to a temporary variable.
1123
ceeb4318 1124Temporary_reference_expression*
e440a328 1125Expression::make_temporary_reference(Temporary_statement* statement,
b13c66cd 1126 Location location)
e440a328 1127{
38ba9eec 1128 statement->add_use();
e440a328 1129 return new Temporary_reference_expression(statement, location);
1130}
1131
e9d3367e 1132// Class Set_and_use_temporary_expression.
1133
1134// Return the type.
1135
1136Type*
1137Set_and_use_temporary_expression::do_type()
1138{
1139 return this->statement_->type();
1140}
1141
0afbb937 1142// Determine the type of the expression.
1143
1144void
1145Set_and_use_temporary_expression::do_determine_type(
1146 const Type_context* context)
1147{
1148 this->expr_->determine_type(context);
1149}
1150
e9d3367e 1151// Take the address.
1152
1153void
1154Set_and_use_temporary_expression::do_address_taken(bool)
1155{
1156 this->statement_->set_is_address_taken();
1157}
1158
1159// Return the backend representation.
1160
ea664253 1161Bexpression*
1162Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
e9d3367e 1163{
e9d3367e 1164 Location loc = this->location();
a302c105 1165 Gogo* gogo = context->gogo();
1166 Bvariable* bvar = this->statement_->get_backend_variable(context);
7af8e400 1167 Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, loc);
a302c105 1168
0ab48656 1169 Named_object* fn = context->function();
1170 go_assert(fn != NULL);
1171 Bfunction* bfn = fn->func_value()->get_or_make_decl(gogo, fn);
ea664253 1172 Bexpression* bexpr = this->expr_->get_backend(context);
0ab48656 1173 Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref,
1174 bexpr, loc);
7af8e400 1175 Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc);
a302c105 1176 Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
ea664253 1177 return ret;
e9d3367e 1178}
1179
1180// Dump.
1181
1182void
1183Set_and_use_temporary_expression::do_dump_expression(
1184 Ast_dump_context* ast_dump_context) const
1185{
1186 ast_dump_context->ostream() << '(';
1187 ast_dump_context->dump_temp_variable_name(this->statement_);
1188 ast_dump_context->ostream() << " = ";
1189 this->expr_->dump_expression(ast_dump_context);
1190 ast_dump_context->ostream() << ')';
1191}
1192
1193// Make a set-and-use temporary.
1194
1195Set_and_use_temporary_expression*
1196Expression::make_set_and_use_temporary(Temporary_statement* statement,
1197 Expression* expr, Location location)
1198{
1199 return new Set_and_use_temporary_expression(statement, expr, location);
1200}
1201
e440a328 1202// A sink expression--a use of the blank identifier _.
1203
1204class Sink_expression : public Expression
1205{
1206 public:
b13c66cd 1207 Sink_expression(Location location)
e440a328 1208 : Expression(EXPRESSION_SINK, location),
aa93217a 1209 type_(NULL), bvar_(NULL)
e440a328 1210 { }
1211
1212 protected:
4f2138d7 1213 bool
e440a328 1214 do_discarding_value()
4f2138d7 1215 { return true; }
e440a328 1216
1217 Type*
1218 do_type();
1219
1220 void
1221 do_determine_type(const Type_context*);
1222
1223 Expression*
1224 do_copy()
1225 { return new Sink_expression(this->location()); }
1226
ea664253 1227 Bexpression*
1228 do_get_backend(Translate_context*);
e440a328 1229
d751bb78 1230 void
1231 do_dump_expression(Ast_dump_context*) const;
1232
e440a328 1233 private:
1234 // The type of this sink variable.
1235 Type* type_;
1236 // The temporary variable we generate.
aa93217a 1237 Bvariable* bvar_;
e440a328 1238};
1239
1240// Return the type of a sink expression.
1241
1242Type*
1243Sink_expression::do_type()
1244{
1245 if (this->type_ == NULL)
1246 return Type::make_sink_type();
1247 return this->type_;
1248}
1249
1250// Determine the type of a sink expression.
1251
1252void
1253Sink_expression::do_determine_type(const Type_context* context)
1254{
1255 if (context->type != NULL)
1256 this->type_ = context->type;
1257}
1258
1259// Return a temporary variable for a sink expression. This will
1260// presumably be a write-only variable which the middle-end will drop.
1261
ea664253 1262Bexpression*
1263Sink_expression::do_get_backend(Translate_context* context)
e440a328 1264{
aa93217a 1265 Location loc = this->location();
1266 Gogo* gogo = context->gogo();
1267 if (this->bvar_ == NULL)
e440a328 1268 {
c484d925 1269 go_assert(this->type_ != NULL && !this->type_->is_sink_type());
aa93217a 1270 Named_object* fn = context->function();
1271 go_assert(fn != NULL);
1272 Bfunction* fn_ctx = fn->func_value()->get_or_make_decl(gogo, fn);
9f0e0513 1273 Btype* bt = this->type_->get_backend(context->gogo());
aa93217a 1274 Bstatement* decl;
1275 this->bvar_ =
1276 gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL,
1277 false, loc, &decl);
d4e6573e 1278 Bexpression* var_ref =
7af8e400 1279 gogo->backend()->var_expression(this->bvar_, loc);
aa93217a 1280 var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
ea664253 1281 return var_ref;
e440a328 1282 }
7af8e400 1283 return gogo->backend()->var_expression(this->bvar_, loc);
e440a328 1284}
1285
d751bb78 1286// Ast dump for sink expression.
1287
1288void
1289Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1290{
1291 ast_dump_context->ostream() << "_" ;
1292}
1293
e440a328 1294// Make a sink expression.
1295
1296Expression*
b13c66cd 1297Expression::make_sink(Location location)
e440a328 1298{
1299 return new Sink_expression(location);
1300}
1301
1302// Class Func_expression.
1303
1304// FIXME: Can a function expression appear in a constant expression?
1305// The value is unchanging. Initializing a constant to the address of
1306// a function seems like it could work, though there might be little
1307// point to it.
1308
e440a328 1309// Traversal.
1310
1311int
1312Func_expression::do_traverse(Traverse* traverse)
1313{
1314 return (this->closure_ == NULL
1315 ? TRAVERSE_CONTINUE
1316 : Expression::traverse(&this->closure_, traverse));
1317}
1318
1319// Return the type of a function expression.
1320
1321Type*
1322Func_expression::do_type()
1323{
1324 if (this->function_->is_function())
1325 return this->function_->func_value()->type();
1326 else if (this->function_->is_function_declaration())
1327 return this->function_->func_declaration_value()->type();
1328 else
c3e6f413 1329 go_unreachable();
e440a328 1330}
1331
ea664253 1332// Get the backend representation for the code of a function expression.
e440a328 1333
97267c39 1334Bexpression*
8381eda7 1335Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc)
e440a328 1336{
1337 Function_type* fntype;
8381eda7 1338 if (no->is_function())
1339 fntype = no->func_value()->type();
1340 else if (no->is_function_declaration())
1341 fntype = no->func_declaration_value()->type();
e440a328 1342 else
c3e6f413 1343 go_unreachable();
e440a328 1344
1345 // Builtin functions are handled specially by Call_expression. We
1346 // can't take their address.
1347 if (fntype->is_builtin())
1348 {
631d5788 1349 go_error_at(loc,
37423a84 1350 ("invalid use of special built-in function %qs; "
1351 "must be called"),
631d5788 1352 no->message_name().c_str());
97267c39 1353 return gogo->backend()->error_expression();
e440a328 1354 }
1355
97267c39 1356 Bfunction* fndecl;
e440a328 1357 if (no->is_function())
cf3cae55 1358 fndecl = no->func_value()->get_or_make_decl(gogo, no);
e440a328 1359 else if (no->is_function_declaration())
cf3cae55 1360 fndecl = no->func_declaration_value()->get_or_make_decl(gogo, no);
e440a328 1361 else
c3e6f413 1362 go_unreachable();
e440a328 1363
97267c39 1364 return gogo->backend()->function_code_expression(fndecl, loc);
e440a328 1365}
1366
ea664253 1367// Get the backend representation for a function expression. This is used when
1368// we take the address of a function rather than simply calling it. A func
8381eda7 1369// value is represented as a pointer to a block of memory. The first
1370// word of that memory is a pointer to the function code. The
1371// remaining parts of that memory are the addresses of variables that
1372// the function closes over.
e440a328 1373
ea664253 1374Bexpression*
1375Func_expression::do_get_backend(Translate_context* context)
e440a328 1376{
8381eda7 1377 // If there is no closure, just use the function descriptor.
2010c17a 1378 if (this->closure_ == NULL)
8381eda7 1379 {
1380 Gogo* gogo = context->gogo();
1381 Named_object* no = this->function_;
1382 Expression* descriptor;
1383 if (no->is_function())
1384 descriptor = no->func_value()->descriptor(gogo, no);
1385 else if (no->is_function_declaration())
1386 {
1387 if (no->func_declaration_value()->type()->is_builtin())
1388 {
631d5788 1389 go_error_at(this->location(),
37423a84 1390 ("invalid use of special built-in function %qs; "
631d5788 1391 "must be called"),
1392 no->message_name().c_str());
ea664253 1393 return gogo->backend()->error_expression();
8381eda7 1394 }
1395 descriptor = no->func_declaration_value()->descriptor(gogo, no);
1396 }
1397 else
1398 go_unreachable();
2010c17a 1399
ea664253 1400 Bexpression* bdesc = descriptor->get_backend(context);
1401 return gogo->backend()->address_expression(bdesc, this->location());
8381eda7 1402 }
e440a328 1403
8381eda7 1404 go_assert(this->function_->func_value()->enclosing() != NULL);
e440a328 1405
8381eda7 1406 // If there is a closure, then the closure is itself the function
1407 // expression. It is a pointer to a struct whose first field points
1408 // to the function code and whose remaining fields are the addresses
1409 // of the closed-over variables.
76818e19 1410 Bexpression *bexpr = this->closure_->get_backend(context);
1411
1412 // Introduce a backend type conversion, to account for any differences
1413 // between the argument type (function descriptor, struct with a
1414 // single field) and the closure (struct with multiple fields).
1415 Gogo* gogo = context->gogo();
1416 Btype *btype = this->type()->get_backend(gogo);
1417 return gogo->backend()->convert_expression(btype, bexpr, this->location());
e440a328 1418}
1419
e3d09834 1420// The cost of inlining a function reference.
1421
1422int
1423Func_expression::do_inlining_cost() const
1424{
1425 // FIXME: We don't inline references to nested functions.
1426 if (this->closure_ != NULL)
1427 return 0x100000;
1428 if (this->function_->is_function()
1429 && this->function_->func_value()->enclosing() != NULL)
1430 return 0x100000;
1431
1432 return 1;
1433}
1434
1435// Export a reference to a function.
1436
1437void
1438Func_expression::do_export(Export_function_body* efb) const
1439{
1440 Expression::export_name(efb, this->function_);
1441}
1442
d751bb78 1443// Ast dump for function.
1444
1445void
1446Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1447{
8b1c301d 1448 ast_dump_context->ostream() << this->function_->name();
1449 if (this->closure_ != NULL)
1450 {
1451 ast_dump_context->ostream() << " {closure = ";
1452 this->closure_->dump_expression(ast_dump_context);
1453 ast_dump_context->ostream() << "}";
1454 }
d751bb78 1455}
1456
e440a328 1457// Make a reference to a function in an expression.
1458
1459Expression*
1460Expression::make_func_reference(Named_object* function, Expression* closure,
b13c66cd 1461 Location location)
e440a328 1462{
b1d7ecfa 1463 Func_expression* fe = new Func_expression(function, closure, location);
1464
1465 // Detect references to builtin functions and set the runtime code if
1466 // appropriate.
1467 if (function->is_function_declaration())
1468 fe->set_runtime_code(Runtime::name_to_code(function->name()));
1469 return fe;
e440a328 1470}
1471
c6837989 1472// Class Func_descriptor_expression.
8381eda7 1473
c6837989 1474// Constructor.
8381eda7 1475
c6837989 1476Func_descriptor_expression::Func_descriptor_expression(Named_object* fn)
1477 : Expression(EXPRESSION_FUNC_DESCRIPTOR, fn->location()),
f8bdf81a 1478 fn_(fn), dvar_(NULL)
c6837989 1479{
1480 go_assert(!fn->is_function() || !fn->func_value()->needs_closure());
1481}
8381eda7 1482
c6837989 1483// Traversal.
8381eda7 1484
c6837989 1485int
1486Func_descriptor_expression::do_traverse(Traverse*)
1487{
1488 return TRAVERSE_CONTINUE;
1489}
8381eda7 1490
1491// All function descriptors have the same type.
1492
1493Type* Func_descriptor_expression::descriptor_type;
1494
1495void
1496Func_descriptor_expression::make_func_descriptor_type()
1497{
1498 if (Func_descriptor_expression::descriptor_type != NULL)
1499 return;
1500 Type* uintptr_type = Type::lookup_integer_type("uintptr");
81487fff 1501 Type* struct_type = Type::make_builtin_struct_type(1, "fn", uintptr_type);
8381eda7 1502 Func_descriptor_expression::descriptor_type =
1503 Type::make_builtin_named_type("functionDescriptor", struct_type);
1504}
1505
1506Type*
1507Func_descriptor_expression::do_type()
1508{
1509 Func_descriptor_expression::make_func_descriptor_type();
1510 return Func_descriptor_expression::descriptor_type;
1511}
1512
ea664253 1513// The backend representation for a function descriptor.
8381eda7 1514
ea664253 1515Bexpression*
1516Func_descriptor_expression::do_get_backend(Translate_context* context)
8381eda7 1517{
8381eda7 1518 Named_object* no = this->fn_;
1519 Location loc = no->location();
ea664253 1520 if (this->dvar_ != NULL)
7af8e400 1521 return context->backend()->var_expression(this->dvar_, loc);
8381eda7 1522
ea664253 1523 Gogo* gogo = context->gogo();
19272321 1524 std::string var_name(gogo->function_descriptor_name(no));
09e57698 1525 bool is_descriptor = false;
1526 if (no->is_function_declaration()
1527 && !no->func_declaration_value()->asm_name().empty()
1528 && Linemap::is_predeclared_location(no->location()))
19272321 1529 is_descriptor = true;
8381eda7 1530
13f2fdb8 1531 // The runtime package implements some functions defined in the
1532 // syscall package. Let the syscall package define the descriptor
1533 // in this case.
1534 if (gogo->compiling_runtime()
1535 && gogo->package_name() == "runtime"
1536 && no->is_function()
1537 && !no->func_value()->asm_name().empty()
1538 && no->func_value()->asm_name().compare(0, 8, "syscall.") == 0)
1539 is_descriptor = true;
1540
8381eda7 1541 Btype* btype = this->type()->get_backend(gogo);
1542
1543 Bvariable* bvar;
438b4bec 1544 std::string asm_name(go_selectively_encode_id(var_name));
09e57698 1545 if (no->package() != NULL || is_descriptor)
438b4bec 1546 bvar = context->backend()->immutable_struct_reference(var_name, asm_name,
1547 btype, loc);
8381eda7 1548 else
1549 {
1550 Location bloc = Linemap::predeclared_location();
80efb81d 1551
1552 // The runtime package has hash/equality functions that are
1553 // referenced by type descriptors outside of the runtime, so the
1554 // function descriptors must be visible even though they are not
1555 // exported.
1556 bool is_exported_runtime = false;
1557 if (gogo->compiling_runtime()
1558 && gogo->package_name() == "runtime"
1559 && (no->name().find("hash") != std::string::npos
1560 || no->name().find("equal") != std::string::npos))
1561 is_exported_runtime = true;
1562
8381eda7 1563 bool is_hidden = ((no->is_function()
1564 && no->func_value()->enclosing() != NULL)
80efb81d 1565 || (Gogo::is_hidden_name(no->name())
1566 && !is_exported_runtime)
8381eda7 1567 || Gogo::is_thunk(no));
80efb81d 1568
438b4bec 1569 bvar = context->backend()->immutable_struct(var_name, asm_name,
1570 is_hidden, false,
8381eda7 1571 btype, bloc);
1572 Expression_list* vals = new Expression_list();
f8bdf81a 1573 vals->push_back(Expression::make_func_code_reference(this->fn_, bloc));
8381eda7 1574 Expression* init =
1575 Expression::make_struct_composite_literal(this->type(), vals, bloc);
1576 Translate_context bcontext(gogo, NULL, NULL, NULL);
1577 bcontext.set_is_const();
ea664253 1578 Bexpression* binit = init->get_backend(&bcontext);
8381eda7 1579 context->backend()->immutable_struct_set_init(bvar, var_name, is_hidden,
1580 false, btype, bloc, binit);
1581 }
1582
1583 this->dvar_ = bvar;
7af8e400 1584 return gogo->backend()->var_expression(bvar, loc);
8381eda7 1585}
1586
c6837989 1587// Print a function descriptor expression.
1588
1589void
1590Func_descriptor_expression::do_dump_expression(Ast_dump_context* context) const
1591{
1592 context->ostream() << "[descriptor " << this->fn_->name() << "]";
1593}
1594
8381eda7 1595// Make a function descriptor expression.
1596
c6837989 1597Func_descriptor_expression*
1598Expression::make_func_descriptor(Named_object* fn)
8381eda7 1599{
c6837989 1600 return new Func_descriptor_expression(fn);
8381eda7 1601}
1602
1603// Make the function descriptor type, so that it can be converted.
1604
1605void
1606Expression::make_func_descriptor_type()
1607{
1608 Func_descriptor_expression::make_func_descriptor_type();
1609}
1610
1611// A reference to just the code of a function.
1612
1613class Func_code_reference_expression : public Expression
1614{
1615 public:
1616 Func_code_reference_expression(Named_object* function, Location location)
1617 : Expression(EXPRESSION_FUNC_CODE_REFERENCE, location),
1618 function_(function)
1619 { }
1620
1621 protected:
1622 int
1623 do_traverse(Traverse*)
1624 { return TRAVERSE_CONTINUE; }
1625
f9ca30f9 1626 bool
3ae06f68 1627 do_is_static_initializer() const
f9ca30f9 1628 { return true; }
1629
8381eda7 1630 Type*
1631 do_type()
1632 { return Type::make_pointer_type(Type::make_void_type()); }
1633
1634 void
1635 do_determine_type(const Type_context*)
1636 { }
1637
1638 Expression*
1639 do_copy()
1640 {
1641 return Expression::make_func_code_reference(this->function_,
1642 this->location());
1643 }
1644
ea664253 1645 Bexpression*
1646 do_get_backend(Translate_context*);
8381eda7 1647
1648 void
1649 do_dump_expression(Ast_dump_context* context) const
1650 { context->ostream() << "[raw " << this->function_->name() << "]" ; }
1651
1652 private:
1653 // The function.
1654 Named_object* function_;
1655};
1656
ea664253 1657// Get the backend representation for a reference to function code.
8381eda7 1658
ea664253 1659Bexpression*
1660Func_code_reference_expression::do_get_backend(Translate_context* context)
8381eda7 1661{
ea664253 1662 return Func_expression::get_code_pointer(context->gogo(), this->function_,
1663 this->location());
8381eda7 1664}
1665
1666// Make a reference to the code of a function.
1667
1668Expression*
1669Expression::make_func_code_reference(Named_object* function, Location location)
1670{
1671 return new Func_code_reference_expression(function, location);
1672}
1673
e440a328 1674// Class Unknown_expression.
1675
1676// Return the name of an unknown expression.
1677
1678const std::string&
1679Unknown_expression::name() const
1680{
1681 return this->named_object_->name();
1682}
1683
1684// Lower a reference to an unknown name.
1685
1686Expression*
ceeb4318 1687Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
e440a328 1688{
b13c66cd 1689 Location location = this->location();
e440a328 1690 Named_object* no = this->named_object_;
deded542 1691 Named_object* real;
1692 if (!no->is_unknown())
1693 real = no;
1694 else
e440a328 1695 {
deded542 1696 real = no->unknown_value()->real_named_object();
1697 if (real == NULL)
1698 {
1699 if (this->is_composite_literal_key_)
1700 return this;
acf8e158 1701 if (!this->no_error_message_)
631d5788 1702 go_error_at(location, "reference to undefined name %qs",
1703 this->named_object_->message_name().c_str());
deded542 1704 return Expression::make_error(location);
1705 }
e440a328 1706 }
1707 switch (real->classification())
1708 {
1709 case Named_object::NAMED_OBJECT_CONST:
1710 return Expression::make_const_reference(real, location);
1711 case Named_object::NAMED_OBJECT_TYPE:
1712 return Expression::make_type(real->type_value(), location);
1713 case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
1714 if (this->is_composite_literal_key_)
1715 return this;
acf8e158 1716 if (!this->no_error_message_)
631d5788 1717 go_error_at(location, "reference to undefined type %qs",
1718 real->message_name().c_str());
e440a328 1719 return Expression::make_error(location);
1720 case Named_object::NAMED_OBJECT_VAR:
7d834090 1721 real->var_value()->set_is_used();
e440a328 1722 return Expression::make_var_reference(real, location);
1723 case Named_object::NAMED_OBJECT_FUNC:
1724 case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
1725 return Expression::make_func_reference(real, NULL, location);
1726 case Named_object::NAMED_OBJECT_PACKAGE:
1727 if (this->is_composite_literal_key_)
1728 return this;
acf8e158 1729 if (!this->no_error_message_)
631d5788 1730 go_error_at(location, "unexpected reference to package");
e440a328 1731 return Expression::make_error(location);
1732 default:
c3e6f413 1733 go_unreachable();
e440a328 1734 }
1735}
1736
d751bb78 1737// Dump the ast representation for an unknown expression to a dump context.
1738
1739void
1740Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1741{
1742 ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
1743 << ")";
d751bb78 1744}
1745
e440a328 1746// Make a reference to an unknown name.
1747
acf8e158 1748Unknown_expression*
b13c66cd 1749Expression::make_unknown_reference(Named_object* no, Location location)
e440a328 1750{
e440a328 1751 return new Unknown_expression(no, location);
1752}
1753
1754// A boolean expression.
1755
1756class Boolean_expression : public Expression
1757{
1758 public:
b13c66cd 1759 Boolean_expression(bool val, Location location)
e440a328 1760 : Expression(EXPRESSION_BOOLEAN, location),
1761 val_(val), type_(NULL)
1762 { }
1763
1764 static Expression*
bc8e2ef4 1765 do_import(Import_expression*, Location);
e440a328 1766
1767 protected:
1768 bool
1769 do_is_constant() const
1770 { return true; }
1771
d2199dbc 1772 bool
1773 do_is_zero_value() const
1774 { return this->val_ == false; }
1775
ac7ef97d 1776 bool
1777 do_boolean_constant_value(bool* val) const
1778 {
1779 *val = this->val_;
1780 return true;
1781 }
1782
0e168074 1783 bool
3ae06f68 1784 do_is_static_initializer() const
0e168074 1785 { return true; }
1786
e440a328 1787 Type*
1788 do_type();
1789
1790 void
1791 do_determine_type(const Type_context*);
1792
1793 Expression*
1794 do_copy()
1795 { return this; }
1796
ea664253 1797 Bexpression*
1798 do_get_backend(Translate_context* context)
1799 { return context->backend()->boolean_constant_expression(this->val_); }
e440a328 1800
5f6f5357 1801 int
1802 do_inlining_cost() const
1803 { return 1; }
1804
e440a328 1805 void
548be246 1806 do_export(Export_function_body* efb) const
204d4af4 1807 { efb->write_c_string(this->val_ ? "$true" : "$false"); }
e440a328 1808
d751bb78 1809 void
1810 do_dump_expression(Ast_dump_context* ast_dump_context) const
1811 { ast_dump_context->ostream() << (this->val_ ? "true" : "false"); }
66b1ea95 1812
e440a328 1813 private:
1814 // The constant.
1815 bool val_;
1816 // The type as determined by context.
1817 Type* type_;
1818};
1819
1820// Get the type.
1821
1822Type*
1823Boolean_expression::do_type()
1824{
1825 if (this->type_ == NULL)
1826 this->type_ = Type::make_boolean_type();
1827 return this->type_;
1828}
1829
1830// Set the type from the context.
1831
1832void
1833Boolean_expression::do_determine_type(const Type_context* context)
1834{
1835 if (this->type_ != NULL && !this->type_->is_abstract())
1836 ;
1837 else if (context->type != NULL && context->type->is_boolean_type())
1838 this->type_ = context->type;
1839 else if (!context->may_be_abstract)
1840 this->type_ = Type::lookup_bool_type();
1841}
1842
1843// Import a boolean constant.
1844
1845Expression*
bc8e2ef4 1846Boolean_expression::do_import(Import_expression* imp, Location loc)
e440a328 1847{
204d4af4 1848 if (imp->version() >= EXPORT_FORMAT_V3)
1849 imp->require_c_string("$");
e440a328 1850 if (imp->peek_char() == 't')
1851 {
1852 imp->require_c_string("true");
9b92780c 1853 return Expression::make_boolean(true, loc);
e440a328 1854 }
1855 else
1856 {
1857 imp->require_c_string("false");
9b92780c 1858 return Expression::make_boolean(false, loc);
e440a328 1859 }
1860}
1861
1862// Make a boolean expression.
1863
1864Expression*
b13c66cd 1865Expression::make_boolean(bool val, Location location)
e440a328 1866{
1867 return new Boolean_expression(val, location);
1868}
1869
1870// Class String_expression.
1871
1872// Get the type.
1873
1874Type*
1875String_expression::do_type()
1876{
1877 if (this->type_ == NULL)
1878 this->type_ = Type::make_string_type();
1879 return this->type_;
1880}
1881
1882// Set the type from the context.
1883
1884void
1885String_expression::do_determine_type(const Type_context* context)
1886{
1887 if (this->type_ != NULL && !this->type_->is_abstract())
1888 ;
1889 else if (context->type != NULL && context->type->is_string_type())
1890 this->type_ = context->type;
1891 else if (!context->may_be_abstract)
1892 this->type_ = Type::lookup_string_type();
1893}
1894
1895// Build a string constant.
1896
ea664253 1897Bexpression*
1898String_expression::do_get_backend(Translate_context* context)
e440a328 1899{
2c809f8f 1900 Gogo* gogo = context->gogo();
1901 Btype* btype = Type::make_string_type()->get_backend(gogo);
1902
1903 Location loc = this->location();
1904 std::vector<Bexpression*> init(2);
1905 Bexpression* str_cst =
1906 gogo->backend()->string_constant_expression(this->val_);
1907 init[0] = gogo->backend()->address_expression(str_cst, loc);
1908
1909 Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo);
1910 mpz_t lenval;
1911 mpz_init_set_ui(lenval, this->val_.length());
1912 init[1] = gogo->backend()->integer_constant_expression(int_btype, lenval);
1913 mpz_clear(lenval);
1914
ea664253 1915 return gogo->backend()->constructor_expression(btype, init, loc);
e440a328 1916}
1917
8b1c301d 1918 // Write string literal to string dump.
e440a328 1919
1920void
8b1c301d 1921String_expression::export_string(String_dump* exp,
1922 const String_expression* str)
e440a328 1923{
1924 std::string s;
8b1c301d 1925 s.reserve(str->val_.length() * 4 + 2);
e440a328 1926 s += '"';
8b1c301d 1927 for (std::string::const_iterator p = str->val_.begin();
1928 p != str->val_.end();
e440a328 1929 ++p)
1930 {
1931 if (*p == '\\' || *p == '"')
1932 {
1933 s += '\\';
1934 s += *p;
1935 }
1936 else if (*p >= 0x20 && *p < 0x7f)
1937 s += *p;
1938 else if (*p == '\n')
1939 s += "\\n";
1940 else if (*p == '\t')
1941 s += "\\t";
1942 else
1943 {
1944 s += "\\x";
1945 unsigned char c = *p;
1946 unsigned int dig = c >> 4;
1947 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
1948 dig = c & 0xf;
1949 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
1950 }
1951 }
1952 s += '"';
1953 exp->write_string(s);
1954}
1955
8b1c301d 1956// Export a string expression.
1957
1958void
548be246 1959String_expression::do_export(Export_function_body* efb) const
8b1c301d 1960{
548be246 1961 String_expression::export_string(efb, this);
8b1c301d 1962}
1963
e440a328 1964// Import a string expression.
1965
1966Expression*
bc8e2ef4 1967String_expression::do_import(Import_expression* imp, Location loc)
e440a328 1968{
1969 imp->require_c_string("\"");
1970 std::string val;
1971 while (true)
1972 {
1973 int c = imp->get_char();
1974 if (c == '"' || c == -1)
1975 break;
1976 if (c != '\\')
1977 val += static_cast<char>(c);
1978 else
1979 {
1980 c = imp->get_char();
1981 if (c == '\\' || c == '"')
1982 val += static_cast<char>(c);
1983 else if (c == 'n')
1984 val += '\n';
1985 else if (c == 't')
1986 val += '\t';
1987 else if (c == 'x')
1988 {
1989 c = imp->get_char();
1990 unsigned int vh = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
1991 c = imp->get_char();
1992 unsigned int vl = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
1993 char v = (vh << 4) | vl;
1994 val += v;
1995 }
1996 else
1997 {
631d5788 1998 go_error_at(imp->location(), "bad string constant");
9b92780c 1999 return Expression::make_error(loc);
e440a328 2000 }
2001 }
2002 }
9b92780c 2003 return Expression::make_string(val, loc);
e440a328 2004}
2005
d751bb78 2006// Ast dump for string expression.
2007
2008void
2009String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2010{
8b1c301d 2011 String_expression::export_string(ast_dump_context, this);
d751bb78 2012}
2013
4713b5b9 2014// Make a string expression with abstract string type (common case).
e440a328 2015
2016Expression*
b13c66cd 2017Expression::make_string(const std::string& val, Location location)
e440a328 2018{
4713b5b9 2019 return new String_expression(val, NULL, location);
2020}
2021
2022// Make a string expression with a specific string type.
2023
2024Expression*
2025Expression::make_string_typed(const std::string& val, Type* type, Location location)
2026{
2027 return new String_expression(val, type, location);
e440a328 2028}
2029
2c809f8f 2030// An expression that evaluates to some characteristic of a string.
2031// This is used when indexing, bound-checking, or nil checking a string.
2032
2033class String_info_expression : public Expression
2034{
2035 public:
2036 String_info_expression(Expression* string, String_info string_info,
2037 Location location)
2038 : Expression(EXPRESSION_STRING_INFO, location),
2039 string_(string), string_info_(string_info)
2040 { }
2041
2042 protected:
2043 Type*
2044 do_type();
2045
2046 void
2047 do_determine_type(const Type_context*)
2048 { go_unreachable(); }
2049
2050 Expression*
2051 do_copy()
2052 {
2053 return new String_info_expression(this->string_->copy(), this->string_info_,
2054 this->location());
2055 }
2056
ea664253 2057 Bexpression*
2058 do_get_backend(Translate_context* context);
2c809f8f 2059
2060 void
2061 do_dump_expression(Ast_dump_context*) const;
2062
2063 void
2064 do_issue_nil_check()
2065 { this->string_->issue_nil_check(); }
2066
2067 private:
2068 // The string for which we are getting information.
2069 Expression* string_;
2070 // What information we want.
2071 String_info string_info_;
2072};
2073
2074// Return the type of the string info.
2075
2076Type*
2077String_info_expression::do_type()
2078{
2079 switch (this->string_info_)
2080 {
2081 case STRING_INFO_DATA:
2082 {
2083 Type* byte_type = Type::lookup_integer_type("uint8");
2084 return Type::make_pointer_type(byte_type);
2085 }
2086 case STRING_INFO_LENGTH:
2087 return Type::lookup_integer_type("int");
2088 default:
2089 go_unreachable();
2090 }
2091}
2092
2093// Return string information in GENERIC.
2094
ea664253 2095Bexpression*
2096String_info_expression::do_get_backend(Translate_context* context)
2c809f8f 2097{
2098 Gogo* gogo = context->gogo();
2099
ea664253 2100 Bexpression* bstring = this->string_->get_backend(context);
2c809f8f 2101 switch (this->string_info_)
2102 {
2103 case STRING_INFO_DATA:
2104 case STRING_INFO_LENGTH:
ea664253 2105 return gogo->backend()->struct_field_expression(bstring,
2106 this->string_info_,
2107 this->location());
2c809f8f 2108 break;
2109 default:
2110 go_unreachable();
2111 }
2c809f8f 2112}
2113
2114// Dump ast representation for a type info expression.
2115
2116void
2117String_info_expression::do_dump_expression(
2118 Ast_dump_context* ast_dump_context) const
2119{
2120 ast_dump_context->ostream() << "stringinfo(";
2121 this->string_->dump_expression(ast_dump_context);
2122 ast_dump_context->ostream() << ",";
66b1ea95 2123 ast_dump_context->ostream() <<
2124 (this->string_info_ == STRING_INFO_DATA ? "data"
2c809f8f 2125 : this->string_info_ == STRING_INFO_LENGTH ? "length"
2126 : "unknown");
2127 ast_dump_context->ostream() << ")";
2128}
2129
2130// Make a string info expression.
2131
2132Expression*
2133Expression::make_string_info(Expression* string, String_info string_info,
2134 Location location)
2135{
2136 return new String_info_expression(string, string_info, location);
2137}
2138
ae77af58 2139// An expression that represents an string value: a struct with value pointer
2140// and length fields.
2141
2142class String_value_expression : public Expression
2143{
2144 public:
2145 String_value_expression(Expression* valptr, Expression* len, Location location)
2146 : Expression(EXPRESSION_STRING_VALUE, location),
2147 valptr_(valptr), len_(len)
2148 { }
2149
2150 protected:
2151 int
2152 do_traverse(Traverse*);
2153
2154 Type*
2155 do_type()
2156 { return Type::make_string_type(); }
2157
2158 void
2159 do_determine_type(const Type_context*)
2160 { go_unreachable(); }
2161
2162 Expression*
2163 do_copy()
2164 {
2165 return new String_value_expression(this->valptr_->copy(),
2166 this->len_->copy(),
2167 this->location());
2168 }
2169
2170 Bexpression*
2171 do_get_backend(Translate_context* context);
2172
2173 void
2174 do_dump_expression(Ast_dump_context*) const;
2175
2176 private:
2177 // The value pointer.
2178 Expression* valptr_;
2179 // The length.
2180 Expression* len_;
2181};
2182
2183int
2184String_value_expression::do_traverse(Traverse* traverse)
2185{
2186 if (Expression::traverse(&this->valptr_, traverse) == TRAVERSE_EXIT
2187 || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT)
2188 return TRAVERSE_EXIT;
2189 return TRAVERSE_CONTINUE;
2190}
2191
2192Bexpression*
2193String_value_expression::do_get_backend(Translate_context* context)
2194{
2195 std::vector<Bexpression*> vals(2);
2196 vals[0] = this->valptr_->get_backend(context);
2197 vals[1] = this->len_->get_backend(context);
2198
2199 Gogo* gogo = context->gogo();
2200 Btype* btype = Type::make_string_type()->get_backend(gogo);
2201 return gogo->backend()->constructor_expression(btype, vals, this->location());
2202}
2203
2204void
2205String_value_expression::do_dump_expression(
2206 Ast_dump_context* ast_dump_context) const
2207{
2208 ast_dump_context->ostream() << "stringvalue(";
2209 ast_dump_context->ostream() << "value: ";
2210 this->valptr_->dump_expression(ast_dump_context);
2211 ast_dump_context->ostream() << ", length: ";
2212 this->len_->dump_expression(ast_dump_context);
2213 ast_dump_context->ostream() << ")";
2214}
2215
2216Expression*
2217Expression::make_string_value(Expression* valptr, Expression* len,
2218 Location location)
2219{
2220 return new String_value_expression(valptr, len, location);
2221}
2222
e440a328 2223// Make an integer expression.
2224
2225class Integer_expression : public Expression
2226{
2227 public:
5d4b8566 2228 Integer_expression(const mpz_t* val, Type* type, bool is_character_constant,
2229 Location location)
e440a328 2230 : Expression(EXPRESSION_INTEGER, location),
5d4b8566 2231 type_(type), is_character_constant_(is_character_constant)
e440a328 2232 { mpz_init_set(this->val_, *val); }
2233
2234 static Expression*
bc8e2ef4 2235 do_import(Import_expression*, Location);
e440a328 2236
8b1c301d 2237 // Write VAL to string dump.
e440a328 2238 static void
8b1c301d 2239 export_integer(String_dump* exp, const mpz_t val);
e440a328 2240
d751bb78 2241 // Write VAL to dump context.
2242 static void
2243 dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val);
2244
e440a328 2245 protected:
2246 bool
2247 do_is_constant() const
2248 { return true; }
2249
d2199dbc 2250 bool
2251 do_is_zero_value() const
2252 { return mpz_sgn(this->val_) == 0; }
2253
0e168074 2254 bool
3ae06f68 2255 do_is_static_initializer() const
0e168074 2256 { return true; }
2257
e440a328 2258 bool
0c77715b 2259 do_numeric_constant_value(Numeric_constant* nc) const;
e440a328 2260
2261 Type*
2262 do_type();
2263
2264 void
2265 do_determine_type(const Type_context* context);
2266
2267 void
2268 do_check_types(Gogo*);
2269
ea664253 2270 Bexpression*
2271 do_get_backend(Translate_context*);
e440a328 2272
2273 Expression*
2274 do_copy()
5d4b8566 2275 {
2276 if (this->is_character_constant_)
de590a61 2277 return Expression::make_character(&this->val_,
2278 (this->type_ == NULL
2279 ? NULL
2280 : this->type_->copy_expressions()),
5d4b8566 2281 this->location());
2282 else
de590a61 2283 return Expression::make_integer_z(&this->val_,
2284 (this->type_ == NULL
2285 ? NULL
2286 : this->type_->copy_expressions()),
e67508fa 2287 this->location());
5d4b8566 2288 }
e440a328 2289
5f6f5357 2290 int
2291 do_inlining_cost() const
2292 { return 1; }
2293
e440a328 2294 void
548be246 2295 do_export(Export_function_body*) const;
e440a328 2296
d751bb78 2297 void
2298 do_dump_expression(Ast_dump_context*) const;
2299
e440a328 2300 private:
2301 // The integer value.
2302 mpz_t val_;
2303 // The type so far.
2304 Type* type_;
5d4b8566 2305 // Whether this is a character constant.
2306 bool is_character_constant_;
e440a328 2307};
2308
0c77715b 2309// Return a numeric constant for this expression. We have to mark
2310// this as a character when appropriate.
e440a328 2311
2312bool
0c77715b 2313Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 2314{
0c77715b 2315 if (this->is_character_constant_)
2316 nc->set_rune(this->type_, this->val_);
2317 else
2318 nc->set_int(this->type_, this->val_);
e440a328 2319 return true;
2320}
2321
2322// Return the current type. If we haven't set the type yet, we return
2323// an abstract integer type.
2324
2325Type*
2326Integer_expression::do_type()
2327{
2328 if (this->type_ == NULL)
5d4b8566 2329 {
2330 if (this->is_character_constant_)
2331 this->type_ = Type::make_abstract_character_type();
2332 else
2333 this->type_ = Type::make_abstract_integer_type();
2334 }
e440a328 2335 return this->type_;
2336}
2337
2338// Set the type of the integer value. Here we may switch from an
2339// abstract type to a real type.
2340
2341void
2342Integer_expression::do_determine_type(const Type_context* context)
2343{
2344 if (this->type_ != NULL && !this->type_->is_abstract())
2345 ;
0c77715b 2346 else if (context->type != NULL && context->type->is_numeric_type())
e440a328 2347 this->type_ = context->type;
2348 else if (!context->may_be_abstract)
5d4b8566 2349 {
2350 if (this->is_character_constant_)
2351 this->type_ = Type::lookup_integer_type("int32");
2352 else
2353 this->type_ = Type::lookup_integer_type("int");
2354 }
e440a328 2355}
2356
e440a328 2357// Check the type of an integer constant.
2358
2359void
2360Integer_expression::do_check_types(Gogo*)
2361{
0c77715b 2362 Type* type = this->type_;
2363 if (type == NULL)
e440a328 2364 return;
0c77715b 2365 Numeric_constant nc;
2366 if (this->is_character_constant_)
2367 nc.set_rune(NULL, this->val_);
2368 else
2369 nc.set_int(NULL, this->val_);
2370 if (!nc.set_type(type, true, this->location()))
e440a328 2371 this->set_is_error();
2372}
2373
ea664253 2374// Get the backend representation for an integer constant.
e440a328 2375
ea664253 2376Bexpression*
2377Integer_expression::do_get_backend(Translate_context* context)
e440a328 2378{
12373dd5 2379 if (this->is_error_expression()
2380 || (this->type_ != NULL && this->type_->is_error_type()))
2381 {
2382 go_assert(saw_errors());
2383 return context->gogo()->backend()->error_expression();
2384 }
2385
48c2a53a 2386 Type* resolved_type = NULL;
e440a328 2387 if (this->type_ != NULL && !this->type_->is_abstract())
48c2a53a 2388 resolved_type = this->type_;
e440a328 2389 else if (this->type_ != NULL && this->type_->float_type() != NULL)
2390 {
2391 // We are converting to an abstract floating point type.
48c2a53a 2392 resolved_type = Type::lookup_float_type("float64");
e440a328 2393 }
2394 else if (this->type_ != NULL && this->type_->complex_type() != NULL)
2395 {
2396 // We are converting to an abstract complex type.
48c2a53a 2397 resolved_type = Type::lookup_complex_type("complex128");
e440a328 2398 }
2399 else
2400 {
2401 // If we still have an abstract type here, then this is being
2402 // used in a constant expression which didn't get reduced for
2403 // some reason. Use a type which will fit the value. We use <,
2404 // not <=, because we need an extra bit for the sign bit.
2405 int bits = mpz_sizeinbase(this->val_, 2);
1b1f2abf 2406 Type* int_type = Type::lookup_integer_type("int");
2407 if (bits < int_type->integer_type()->bits())
48c2a53a 2408 resolved_type = int_type;
e440a328 2409 else if (bits < 64)
48c2a53a 2410 resolved_type = Type::lookup_integer_type("int64");
e440a328 2411 else
48c2a53a 2412 {
2413 if (!saw_errors())
631d5788 2414 go_error_at(this->location(),
2415 "unknown type for large integer constant");
ea664253 2416 return context->gogo()->backend()->error_expression();
48c2a53a 2417 }
e440a328 2418 }
48c2a53a 2419 Numeric_constant nc;
2420 nc.set_int(resolved_type, this->val_);
ea664253 2421 return Expression::backend_numeric_constant_expression(context, &nc);
e440a328 2422}
2423
2424// Write VAL to export data.
2425
2426void
8b1c301d 2427Integer_expression::export_integer(String_dump* exp, const mpz_t val)
e440a328 2428{
2429 char* s = mpz_get_str(NULL, 10, val);
2430 exp->write_c_string(s);
2431 free(s);
2432}
2433
2434// Export an integer in a constant expression.
2435
2436void
548be246 2437Integer_expression::do_export(Export_function_body* efb) const
e440a328 2438{
69f634cc 2439 bool added_type = false;
2440 if (this->type_ != NULL
2441 && !this->type_->is_abstract()
2442 && this->type_ != efb->type_context())
2443 {
2444 efb->write_c_string("$convert(");
2445 efb->write_type(this->type_);
2446 efb->write_c_string(", ");
2447 added_type = true;
2448 }
2449
548be246 2450 Integer_expression::export_integer(efb, this->val_);
5d4b8566 2451 if (this->is_character_constant_)
548be246 2452 efb->write_c_string("'");
e440a328 2453 // A trailing space lets us reliably identify the end of the number.
548be246 2454 efb->write_c_string(" ");
69f634cc 2455
2456 if (added_type)
2457 efb->write_c_string(")");
e440a328 2458}
2459
2460// Import an integer, floating point, or complex value. This handles
2461// all these types because they all start with digits.
2462
2463Expression*
bc8e2ef4 2464Integer_expression::do_import(Import_expression* imp, Location loc)
e440a328 2465{
2466 std::string num = imp->read_identifier();
2467 imp->require_c_string(" ");
2468 if (!num.empty() && num[num.length() - 1] == 'i')
2469 {
2470 mpfr_t real;
2471 size_t plus_pos = num.find('+', 1);
2472 size_t minus_pos = num.find('-', 1);
2473 size_t pos;
2474 if (plus_pos == std::string::npos)
2475 pos = minus_pos;
2476 else if (minus_pos == std::string::npos)
2477 pos = plus_pos;
2478 else
2479 {
631d5788 2480 go_error_at(imp->location(), "bad number in import data: %qs",
2481 num.c_str());
9b92780c 2482 return Expression::make_error(loc);
e440a328 2483 }
2484 if (pos == std::string::npos)
2485 mpfr_set_ui(real, 0, GMP_RNDN);
2486 else
2487 {
2488 std::string real_str = num.substr(0, pos);
2489 if (mpfr_init_set_str(real, real_str.c_str(), 10, GMP_RNDN) != 0)
2490 {
631d5788 2491 go_error_at(imp->location(), "bad number in import data: %qs",
2492 real_str.c_str());
9b92780c 2493 return Expression::make_error(loc);
e440a328 2494 }
2495 }
2496
2497 std::string imag_str;
2498 if (pos == std::string::npos)
2499 imag_str = num;
2500 else
2501 imag_str = num.substr(pos);
2502 imag_str = imag_str.substr(0, imag_str.size() - 1);
2503 mpfr_t imag;
2504 if (mpfr_init_set_str(imag, imag_str.c_str(), 10, GMP_RNDN) != 0)
2505 {
631d5788 2506 go_error_at(imp->location(), "bad number in import data: %qs",
2507 imag_str.c_str());
9b92780c 2508 return Expression::make_error(loc);
e440a328 2509 }
fcbea5e4 2510 mpc_t cval;
2511 mpc_init2(cval, mpc_precision);
2512 mpc_set_fr_fr(cval, real, imag, MPC_RNDNN);
e440a328 2513 mpfr_clear(real);
2514 mpfr_clear(imag);
9b92780c 2515 Expression* ret = Expression::make_complex(&cval, NULL, loc);
fcbea5e4 2516 mpc_clear(cval);
e440a328 2517 return ret;
2518 }
2519 else if (num.find('.') == std::string::npos
2520 && num.find('E') == std::string::npos)
2521 {
5d4b8566 2522 bool is_character_constant = (!num.empty()
2523 && num[num.length() - 1] == '\'');
2524 if (is_character_constant)
2525 num = num.substr(0, num.length() - 1);
e440a328 2526 mpz_t val;
2527 if (mpz_init_set_str(val, num.c_str(), 10) != 0)
2528 {
631d5788 2529 go_error_at(imp->location(), "bad number in import data: %qs",
2530 num.c_str());
9b92780c 2531 return Expression::make_error(loc);
e440a328 2532 }
5d4b8566 2533 Expression* ret;
2534 if (is_character_constant)
9b92780c 2535 ret = Expression::make_character(&val, NULL, loc);
5d4b8566 2536 else
9b92780c 2537 ret = Expression::make_integer_z(&val, NULL, loc);
e440a328 2538 mpz_clear(val);
2539 return ret;
2540 }
2541 else
2542 {
2543 mpfr_t val;
2544 if (mpfr_init_set_str(val, num.c_str(), 10, GMP_RNDN) != 0)
2545 {
631d5788 2546 go_error_at(imp->location(), "bad number in import data: %qs",
2547 num.c_str());
9b92780c 2548 return Expression::make_error(loc);
e440a328 2549 }
9b92780c 2550 Expression* ret = Expression::make_float(&val, NULL, loc);
e440a328 2551 mpfr_clear(val);
2552 return ret;
2553 }
2554}
d751bb78 2555// Ast dump for integer expression.
2556
2557void
2558Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2559{
5d4b8566 2560 if (this->is_character_constant_)
2561 ast_dump_context->ostream() << '\'';
8b1c301d 2562 Integer_expression::export_integer(ast_dump_context, this->val_);
5d4b8566 2563 if (this->is_character_constant_)
2564 ast_dump_context->ostream() << '\'';
d751bb78 2565}
2566
e67508fa 2567// Build a new integer value from a multi-precision integer.
e440a328 2568
2569Expression*
e67508fa 2570Expression::make_integer_z(const mpz_t* val, Type* type, Location location)
5d4b8566 2571{
2572 return new Integer_expression(val, type, false, location);
2573}
2574
e67508fa 2575// Build a new integer value from an unsigned long.
2576
2577Expression*
2578Expression::make_integer_ul(unsigned long val, Type *type, Location location)
2579{
2580 mpz_t zval;
2581 mpz_init_set_ui(zval, val);
2582 Expression* ret = Expression::make_integer_z(&zval, type, location);
2583 mpz_clear(zval);
2584 return ret;
2585}
2586
2587// Build a new integer value from a signed long.
2588
2589Expression*
2590Expression::make_integer_sl(long val, Type *type, Location location)
2591{
2592 mpz_t zval;
2593 mpz_init_set_si(zval, val);
2594 Expression* ret = Expression::make_integer_z(&zval, type, location);
2595 mpz_clear(zval);
2596 return ret;
2597}
2598
3f378015 2599// Store an int64_t in an uninitialized mpz_t.
2600
2601static void
2602set_mpz_from_int64(mpz_t* zval, int64_t val)
2603{
2604 if (val >= 0)
2605 {
2606 unsigned long ul = static_cast<unsigned long>(val);
2607 if (static_cast<int64_t>(ul) == val)
2608 {
2609 mpz_init_set_ui(*zval, ul);
2610 return;
2611 }
2612 }
2613 uint64_t uv;
2614 if (val >= 0)
2615 uv = static_cast<uint64_t>(val);
2616 else
2617 uv = static_cast<uint64_t>(- val);
2618 unsigned long ul = uv & 0xffffffffUL;
2619 mpz_init_set_ui(*zval, ul);
2620 mpz_t hval;
2621 mpz_init_set_ui(hval, static_cast<unsigned long>(uv >> 32));
2622 mpz_mul_2exp(hval, hval, 32);
2623 mpz_add(*zval, *zval, hval);
2624 mpz_clear(hval);
2625 if (val < 0)
2626 mpz_neg(*zval, *zval);
2627}
2628
2629// Build a new integer value from an int64_t.
2630
2631Expression*
2632Expression::make_integer_int64(int64_t val, Type* type, Location location)
2633{
2634 mpz_t zval;
2635 set_mpz_from_int64(&zval, val);
2636 Expression* ret = Expression::make_integer_z(&zval, type, location);
2637 mpz_clear(zval);
2638 return ret;
2639}
2640
5d4b8566 2641// Build a new character constant value.
2642
2643Expression*
2644Expression::make_character(const mpz_t* val, Type* type, Location location)
e440a328 2645{
5d4b8566 2646 return new Integer_expression(val, type, true, location);
e440a328 2647}
2648
2649// Floats.
2650
2651class Float_expression : public Expression
2652{
2653 public:
b13c66cd 2654 Float_expression(const mpfr_t* val, Type* type, Location location)
e440a328 2655 : Expression(EXPRESSION_FLOAT, location),
2656 type_(type)
2657 {
2658 mpfr_init_set(this->val_, *val, GMP_RNDN);
2659 }
2660
e440a328 2661 // Write VAL to export data.
2662 static void
8b1c301d 2663 export_float(String_dump* exp, const mpfr_t val);
2664
d751bb78 2665 // Write VAL to dump file.
2666 static void
2667 dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
e440a328 2668
2669 protected:
2670 bool
2671 do_is_constant() const
2672 { return true; }
2673
d2199dbc 2674 bool
2675 do_is_zero_value() const
2676 {
2677 return mpfr_zero_p(this->val_) != 0
2678 && mpfr_signbit(this->val_) == 0;
2679 }
2680
0e168074 2681 bool
3ae06f68 2682 do_is_static_initializer() const
0e168074 2683 { return true; }
2684
e440a328 2685 bool
0c77715b 2686 do_numeric_constant_value(Numeric_constant* nc) const
2687 {
2688 nc->set_float(this->type_, this->val_);
2689 return true;
2690 }
e440a328 2691
2692 Type*
2693 do_type();
2694
2695 void
2696 do_determine_type(const Type_context*);
2697
2698 void
2699 do_check_types(Gogo*);
2700
2701 Expression*
2702 do_copy()
de590a61 2703 { return Expression::make_float(&this->val_,
2704 (this->type_ == NULL
2705 ? NULL
2706 : this->type_->copy_expressions()),
e440a328 2707 this->location()); }
2708
ea664253 2709 Bexpression*
2710 do_get_backend(Translate_context*);
e440a328 2711
5f6f5357 2712 int
2713 do_inlining_cost() const
2714 { return 1; }
2715
e440a328 2716 void
548be246 2717 do_export(Export_function_body*) const;
e440a328 2718
d751bb78 2719 void
2720 do_dump_expression(Ast_dump_context*) const;
2721
e440a328 2722 private:
2723 // The floating point value.
2724 mpfr_t val_;
2725 // The type so far.
2726 Type* type_;
2727};
2728
e440a328 2729// Return the current type. If we haven't set the type yet, we return
2730// an abstract float type.
2731
2732Type*
2733Float_expression::do_type()
2734{
2735 if (this->type_ == NULL)
2736 this->type_ = Type::make_abstract_float_type();
2737 return this->type_;
2738}
2739
2740// Set the type of the float value. Here we may switch from an
2741// abstract type to a real type.
2742
2743void
2744Float_expression::do_determine_type(const Type_context* context)
2745{
2746 if (this->type_ != NULL && !this->type_->is_abstract())
2747 ;
2748 else if (context->type != NULL
2749 && (context->type->integer_type() != NULL
2750 || context->type->float_type() != NULL
2751 || context->type->complex_type() != NULL))
2752 this->type_ = context->type;
2753 else if (!context->may_be_abstract)
48080209 2754 this->type_ = Type::lookup_float_type("float64");
e440a328 2755}
2756
e440a328 2757// Check the type of a float value.
2758
2759void
2760Float_expression::do_check_types(Gogo*)
2761{
0c77715b 2762 Type* type = this->type_;
2763 if (type == NULL)
e440a328 2764 return;
0c77715b 2765 Numeric_constant nc;
2766 nc.set_float(NULL, this->val_);
2767 if (!nc.set_type(this->type_, true, this->location()))
e440a328 2768 this->set_is_error();
e440a328 2769}
2770
ea664253 2771// Get the backend representation for a float constant.
e440a328 2772
ea664253 2773Bexpression*
2774Float_expression::do_get_backend(Translate_context* context)
e440a328 2775{
12373dd5 2776 if (this->is_error_expression()
2777 || (this->type_ != NULL && this->type_->is_error_type()))
2778 {
2779 go_assert(saw_errors());
2780 return context->gogo()->backend()->error_expression();
2781 }
2782
48c2a53a 2783 Type* resolved_type;
e440a328 2784 if (this->type_ != NULL && !this->type_->is_abstract())
48c2a53a 2785 resolved_type = this->type_;
e440a328 2786 else if (this->type_ != NULL && this->type_->integer_type() != NULL)
2787 {
2788 // We have an abstract integer type. We just hope for the best.
48c2a53a 2789 resolved_type = Type::lookup_integer_type("int");
2790 }
2791 else if (this->type_ != NULL && this->type_->complex_type() != NULL)
2792 {
2793 // We are converting to an abstract complex type.
2794 resolved_type = Type::lookup_complex_type("complex128");
e440a328 2795 }
2796 else
2797 {
2798 // If we still have an abstract type here, then this is being
2799 // used in a constant expression which didn't get reduced. We
2800 // just use float64 and hope for the best.
48c2a53a 2801 resolved_type = Type::lookup_float_type("float64");
e440a328 2802 }
48c2a53a 2803
2804 Numeric_constant nc;
2805 nc.set_float(resolved_type, this->val_);
ea664253 2806 return Expression::backend_numeric_constant_expression(context, &nc);
e440a328 2807}
2808
8b1c301d 2809// Write a floating point number to a string dump.
e440a328 2810
2811void
8b1c301d 2812Float_expression::export_float(String_dump *exp, const mpfr_t val)
e440a328 2813{
2814 mp_exp_t exponent;
2815 char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
2816 if (*s == '-')
2817 exp->write_c_string("-");
2818 exp->write_c_string("0.");
2819 exp->write_c_string(*s == '-' ? s + 1 : s);
2820 mpfr_free_str(s);
2821 char buf[30];
2822 snprintf(buf, sizeof buf, "E%ld", exponent);
2823 exp->write_c_string(buf);
2824}
2825
2826// Export a floating point number in a constant expression.
2827
2828void
548be246 2829Float_expression::do_export(Export_function_body* efb) const
e440a328 2830{
69f634cc 2831 bool added_type = false;
2832 if (this->type_ != NULL
2833 && !this->type_->is_abstract()
2834 && this->type_ != efb->type_context())
2835 {
2836 efb->write_c_string("$convert(");
2837 efb->write_type(this->type_);
2838 efb->write_c_string(", ");
2839 added_type = true;
2840 }
2841
548be246 2842 Float_expression::export_float(efb, this->val_);
e440a328 2843 // A trailing space lets us reliably identify the end of the number.
548be246 2844 efb->write_c_string(" ");
69f634cc 2845
2846 if (added_type)
2847 efb->write_c_string(")");
e440a328 2848}
2849
d751bb78 2850// Dump a floating point number to the dump file.
2851
2852void
2853Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2854{
8b1c301d 2855 Float_expression::export_float(ast_dump_context, this->val_);
d751bb78 2856}
2857
e440a328 2858// Make a float expression.
2859
2860Expression*
b13c66cd 2861Expression::make_float(const mpfr_t* val, Type* type, Location location)
e440a328 2862{
2863 return new Float_expression(val, type, location);
2864}
2865
2866// Complex numbers.
2867
2868class Complex_expression : public Expression
2869{
2870 public:
fcbea5e4 2871 Complex_expression(const mpc_t* val, Type* type, Location location)
e440a328 2872 : Expression(EXPRESSION_COMPLEX, location),
2873 type_(type)
2874 {
fcbea5e4 2875 mpc_init2(this->val_, mpc_precision);
2876 mpc_set(this->val_, *val, MPC_RNDNN);
e440a328 2877 }
2878
fcbea5e4 2879 // Write VAL to string dump.
e440a328 2880 static void
fcbea5e4 2881 export_complex(String_dump* exp, const mpc_t val);
e440a328 2882
d751bb78 2883 // Write REAL/IMAG to dump context.
2884 static void
fcbea5e4 2885 dump_complex(Ast_dump_context* ast_dump_context, const mpc_t val);
66b1ea95 2886
e440a328 2887 protected:
2888 bool
2889 do_is_constant() const
2890 { return true; }
2891
d2199dbc 2892 bool
2893 do_is_zero_value() const
2894 {
2895 return mpfr_zero_p(mpc_realref(this->val_)) != 0
2896 && mpfr_signbit(mpc_realref(this->val_)) == 0
2897 && mpfr_zero_p(mpc_imagref(this->val_)) != 0
2898 && mpfr_signbit(mpc_imagref(this->val_)) == 0;
2899 }
2900
0e168074 2901 bool
3ae06f68 2902 do_is_static_initializer() const
0e168074 2903 { return true; }
2904
e440a328 2905 bool
0c77715b 2906 do_numeric_constant_value(Numeric_constant* nc) const
2907 {
fcbea5e4 2908 nc->set_complex(this->type_, this->val_);
0c77715b 2909 return true;
2910 }
e440a328 2911
2912 Type*
2913 do_type();
2914
2915 void
2916 do_determine_type(const Type_context*);
2917
2918 void
2919 do_check_types(Gogo*);
2920
2921 Expression*
2922 do_copy()
2923 {
de590a61 2924 return Expression::make_complex(&this->val_,
2925 (this->type_ == NULL
2926 ? NULL
2927 : this->type_->copy_expressions()),
e440a328 2928 this->location());
2929 }
2930
ea664253 2931 Bexpression*
2932 do_get_backend(Translate_context*);
e440a328 2933
5f6f5357 2934 int
2935 do_inlining_cost() const
2936 { return 2; }
2937
e440a328 2938 void
548be246 2939 do_export(Export_function_body*) const;
e440a328 2940
d751bb78 2941 void
2942 do_dump_expression(Ast_dump_context*) const;
abd26de0 2943
e440a328 2944 private:
fcbea5e4 2945 // The complex value.
2946 mpc_t val_;
e440a328 2947 // The type if known.
2948 Type* type_;
2949};
2950
e440a328 2951// Return the current type. If we haven't set the type yet, we return
2952// an abstract complex type.
2953
2954Type*
2955Complex_expression::do_type()
2956{
2957 if (this->type_ == NULL)
2958 this->type_ = Type::make_abstract_complex_type();
2959 return this->type_;
2960}
2961
2962// Set the type of the complex value. Here we may switch from an
2963// abstract type to a real type.
2964
2965void
2966Complex_expression::do_determine_type(const Type_context* context)
2967{
2968 if (this->type_ != NULL && !this->type_->is_abstract())
2969 ;
abd26de0 2970 else if (context->type != NULL && context->type->is_numeric_type())
e440a328 2971 this->type_ = context->type;
2972 else if (!context->may_be_abstract)
48080209 2973 this->type_ = Type::lookup_complex_type("complex128");
e440a328 2974}
2975
e440a328 2976// Check the type of a complex value.
2977
2978void
2979Complex_expression::do_check_types(Gogo*)
2980{
0c77715b 2981 Type* type = this->type_;
2982 if (type == NULL)
e440a328 2983 return;
0c77715b 2984 Numeric_constant nc;
fcbea5e4 2985 nc.set_complex(NULL, this->val_);
0c77715b 2986 if (!nc.set_type(this->type_, true, this->location()))
e440a328 2987 this->set_is_error();
2988}
2989
ea664253 2990// Get the backend representation for a complex constant.
e440a328 2991
ea664253 2992Bexpression*
2993Complex_expression::do_get_backend(Translate_context* context)
e440a328 2994{
12373dd5 2995 if (this->is_error_expression()
2996 || (this->type_ != NULL && this->type_->is_error_type()))
2997 {
2998 go_assert(saw_errors());
2999 return context->gogo()->backend()->error_expression();
3000 }
3001
48c2a53a 3002 Type* resolved_type;
e440a328 3003 if (this->type_ != NULL && !this->type_->is_abstract())
48c2a53a 3004 resolved_type = this->type_;
3005 else if (this->type_ != NULL && this->type_->integer_type() != NULL)
3006 {
3007 // We are converting to an abstract integer type.
3008 resolved_type = Type::lookup_integer_type("int");
3009 }
3010 else if (this->type_ != NULL && this->type_->float_type() != NULL)
3011 {
3012 // We are converting to an abstract float type.
3013 resolved_type = Type::lookup_float_type("float64");
3014 }
e440a328 3015 else
3016 {
47ae02b7 3017 // If we still have an abstract type here, this is being
e440a328 3018 // used in a constant expression which didn't get reduced. We
3019 // just use complex128 and hope for the best.
48c2a53a 3020 resolved_type = Type::lookup_complex_type("complex128");
e440a328 3021 }
48c2a53a 3022
3023 Numeric_constant nc;
fcbea5e4 3024 nc.set_complex(resolved_type, this->val_);
ea664253 3025 return Expression::backend_numeric_constant_expression(context, &nc);
e440a328 3026}
3027
3028// Write REAL/IMAG to export data.
3029
3030void
fcbea5e4 3031Complex_expression::export_complex(String_dump* exp, const mpc_t val)
e440a328 3032{
fcbea5e4 3033 if (!mpfr_zero_p(mpc_realref(val)))
e440a328 3034 {
fcbea5e4 3035 Float_expression::export_float(exp, mpc_realref(val));
d1db782d 3036 if (mpfr_sgn(mpc_imagref(val)) >= 0)
e440a328 3037 exp->write_c_string("+");
3038 }
fcbea5e4 3039 Float_expression::export_float(exp, mpc_imagref(val));
e440a328 3040 exp->write_c_string("i");
3041}
3042
3043// Export a complex number in a constant expression.
3044
3045void
548be246 3046Complex_expression::do_export(Export_function_body* efb) const
e440a328 3047{
69f634cc 3048 bool added_type = false;
3049 if (this->type_ != NULL
3050 && !this->type_->is_abstract()
3051 && this->type_ != efb->type_context())
3052 {
3053 efb->write_c_string("$convert(");
3054 efb->write_type(this->type_);
3055 efb->write_c_string(", ");
3056 added_type = true;
3057 }
3058
548be246 3059 Complex_expression::export_complex(efb, this->val_);
e440a328 3060 // A trailing space lets us reliably identify the end of the number.
548be246 3061 efb->write_c_string(" ");
69f634cc 3062
3063 if (added_type)
3064 efb->write_c_string(")");
e440a328 3065}
3066
d751bb78 3067// Dump a complex expression to the dump file.
3068
3069void
3070Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3071{
fcbea5e4 3072 Complex_expression::export_complex(ast_dump_context, this->val_);
d751bb78 3073}
3074
e440a328 3075// Make a complex expression.
3076
3077Expression*
fcbea5e4 3078Expression::make_complex(const mpc_t* val, Type* type, Location location)
e440a328 3079{
fcbea5e4 3080 return new Complex_expression(val, type, location);
e440a328 3081}
3082
d5b605df 3083// Find a named object in an expression.
3084
3085class Find_named_object : public Traverse
3086{
3087 public:
3088 Find_named_object(Named_object* no)
3089 : Traverse(traverse_expressions),
3090 no_(no), found_(false)
3091 { }
3092
3093 // Whether we found the object.
3094 bool
3095 found() const
3096 { return this->found_; }
3097
3098 protected:
3099 int
3100 expression(Expression**);
3101
3102 private:
3103 // The object we are looking for.
3104 Named_object* no_;
3105 // Whether we found it.
3106 bool found_;
3107};
3108
e440a328 3109// A reference to a const in an expression.
3110
3111class Const_expression : public Expression
3112{
3113 public:
b13c66cd 3114 Const_expression(Named_object* constant, Location location)
e440a328 3115 : Expression(EXPRESSION_CONST_REFERENCE, location),
13e818f5 3116 constant_(constant), type_(NULL), seen_(false)
e440a328 3117 { }
3118
d5b605df 3119 Named_object*
3120 named_object()
3121 { return this->constant_; }
3122
a7f064d5 3123 // Check that the initializer does not refer to the constant itself.
3124 void
3125 check_for_init_loop();
3126
e440a328 3127 protected:
ba4aedd4 3128 int
3129 do_traverse(Traverse*);
3130
e440a328 3131 Expression*
ceeb4318 3132 do_lower(Gogo*, Named_object*, Statement_inserter*, int);
e440a328 3133
3134 bool
3135 do_is_constant() const
3136 { return true; }
3137
d2199dbc 3138 bool
3139 do_is_zero_value() const
3140 { return this->constant_->const_value()->expr()->is_zero_value(); }
3141
0e168074 3142 bool
3ae06f68 3143 do_is_static_initializer() const
0e168074 3144 { return true; }
3145
e440a328 3146 bool
0c77715b 3147 do_numeric_constant_value(Numeric_constant* nc) const;
e440a328 3148
3149 bool
af6b489a 3150 do_string_constant_value(std::string* val) const;
e440a328 3151
ac7ef97d 3152 bool
3153 do_boolean_constant_value(bool* val) const;
3154
e440a328 3155 Type*
3156 do_type();
3157
3158 // The type of a const is set by the declaration, not the use.
3159 void
3160 do_determine_type(const Type_context*);
3161
3162 void
3163 do_check_types(Gogo*);
3164
3165 Expression*
3166 do_copy()
3167 { return this; }
3168
ea664253 3169 Bexpression*
3170 do_get_backend(Translate_context* context);
e440a328 3171
3172 // When exporting a reference to a const as part of a const
3173 // expression, we export the value. We ignore the fact that it has
3174 // a name.
3175 void
548be246 3176 do_export(Export_function_body* efb) const
3177 { this->constant_->const_value()->expr()->export_expression(efb); }
e440a328 3178
d751bb78 3179 void
3180 do_dump_expression(Ast_dump_context*) const;
3181
e440a328 3182 private:
3183 // The constant.
3184 Named_object* constant_;
3185 // The type of this reference. This is used if the constant has an
3186 // abstract type.
3187 Type* type_;
13e818f5 3188 // Used to prevent infinite recursion when a constant incorrectly
3189 // refers to itself.
3190 mutable bool seen_;
e440a328 3191};
3192
ba4aedd4 3193// Traversal.
3194
3195int
3196Const_expression::do_traverse(Traverse* traverse)
3197{
3198 if (this->type_ != NULL)
3199 return Type::traverse(this->type_, traverse);
3200 return TRAVERSE_CONTINUE;
3201}
3202
e440a328 3203// Lower a constant expression. This is where we convert the
3204// predeclared constant iota into an integer value.
3205
3206Expression*
ceeb4318 3207Const_expression::do_lower(Gogo* gogo, Named_object*,
3208 Statement_inserter*, int iota_value)
e440a328 3209{
3210 if (this->constant_->const_value()->expr()->classification()
3211 == EXPRESSION_IOTA)
3212 {
3213 if (iota_value == -1)
3214 {
631d5788 3215 go_error_at(this->location(),
3216 "iota is only defined in const declarations");
e440a328 3217 iota_value = 0;
3218 }
e67508fa 3219 return Expression::make_integer_ul(iota_value, NULL, this->location());
e440a328 3220 }
3221
3222 // Make sure that the constant itself has been lowered.
3223 gogo->lower_constant(this->constant_);
3224
3225 return this;
3226}
3227
0c77715b 3228// Return a numeric constant value.
e440a328 3229
3230bool
0c77715b 3231Const_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 3232{
13e818f5 3233 if (this->seen_)
3234 return false;
3235
e440a328 3236 Expression* e = this->constant_->const_value()->expr();
f03a9fbf 3237
13e818f5 3238 this->seen_ = true;
3239
0c77715b 3240 bool r = e->numeric_constant_value(nc);
e440a328 3241
13e818f5 3242 this->seen_ = false;
3243
e440a328 3244 Type* ctype;
3245 if (this->type_ != NULL)
3246 ctype = this->type_;
3247 else
3248 ctype = this->constant_->const_value()->type();
e440a328 3249 if (r && ctype != NULL)
3250 {
0c77715b 3251 if (!nc->set_type(ctype, false, this->location()))
e440a328 3252 return false;
e440a328 3253 }
e440a328 3254
e440a328 3255 return r;
3256}
3257
af6b489a 3258bool
3259Const_expression::do_string_constant_value(std::string* val) const
3260{
3261 if (this->seen_)
3262 return false;
3263
3264 Expression* e = this->constant_->const_value()->expr();
3265
3266 this->seen_ = true;
3267 bool ok = e->string_constant_value(val);
3268 this->seen_ = false;
3269
3270 return ok;
3271}
3272
ac7ef97d 3273bool
3274Const_expression::do_boolean_constant_value(bool* val) const
3275{
3276 if (this->seen_)
3277 return false;
3278
3279 Expression* e = this->constant_->const_value()->expr();
3280
3281 this->seen_ = true;
3282 bool ok = e->boolean_constant_value(val);
3283 this->seen_ = false;
3284
3285 return ok;
3286}
3287
e440a328 3288// Return the type of the const reference.
3289
3290Type*
3291Const_expression::do_type()
3292{
3293 if (this->type_ != NULL)
3294 return this->type_;
13e818f5 3295
2f78f012 3296 Named_constant* nc = this->constant_->const_value();
3297
3298 if (this->seen_ || nc->lowering())
13e818f5 3299 {
4b2ab536 3300 if (nc->type() == NULL || !nc->type()->is_error_type())
3301 {
3302 Location loc = this->location();
3303 if (!this->seen_)
3304 loc = nc->location();
3305 go_error_at(loc, "constant refers to itself");
3306 }
3307 this->set_is_error();
13e818f5 3308 this->type_ = Type::make_error_type();
4b2ab536 3309 nc->set_type(this->type_);
13e818f5 3310 return this->type_;
3311 }
3312
3313 this->seen_ = true;
3314
e440a328 3315 Type* ret = nc->type();
13e818f5 3316
e440a328 3317 if (ret != NULL)
13e818f5 3318 {
3319 this->seen_ = false;
3320 return ret;
3321 }
3322
e440a328 3323 // During parsing, a named constant may have a NULL type, but we
3324 // must not return a NULL type here.
13e818f5 3325 ret = nc->expr()->type();
3326
3327 this->seen_ = false;
3328
4b2ab536 3329 if (ret->is_error_type())
3330 nc->set_type(ret);
3331
13e818f5 3332 return ret;
e440a328 3333}
3334
3335// Set the type of the const reference.
3336
3337void
3338Const_expression::do_determine_type(const Type_context* context)
3339{
3340 Type* ctype = this->constant_->const_value()->type();
3341 Type* cetype = (ctype != NULL
3342 ? ctype
3343 : this->constant_->const_value()->expr()->type());
3344 if (ctype != NULL && !ctype->is_abstract())
3345 ;
3346 else if (context->type != NULL
0c77715b 3347 && context->type->is_numeric_type()
3348 && cetype->is_numeric_type())
e440a328 3349 this->type_ = context->type;
3350 else if (context->type != NULL
3351 && context->type->is_string_type()
3352 && cetype->is_string_type())
3353 this->type_ = context->type;
3354 else if (context->type != NULL
3355 && context->type->is_boolean_type()
3356 && cetype->is_boolean_type())
3357 this->type_ = context->type;
3358 else if (!context->may_be_abstract)
3359 {
3360 if (cetype->is_abstract())
3361 cetype = cetype->make_non_abstract_type();
3362 this->type_ = cetype;
3363 }
3364}
3365
a7f064d5 3366// Check for a loop in which the initializer of a constant refers to
3367// the constant itself.
e440a328 3368
3369void
a7f064d5 3370Const_expression::check_for_init_loop()
e440a328 3371{
5c13bd80 3372 if (this->type_ != NULL && this->type_->is_error())
d5b605df 3373 return;
3374
a7f064d5 3375 if (this->seen_)
3376 {
3377 this->report_error(_("constant refers to itself"));
3378 this->type_ = Type::make_error_type();
3379 return;
3380 }
3381
d5b605df 3382 Expression* init = this->constant_->const_value()->expr();
3383 Find_named_object find_named_object(this->constant_);
a7f064d5 3384
3385 this->seen_ = true;
d5b605df 3386 Expression::traverse(&init, &find_named_object);
a7f064d5 3387 this->seen_ = false;
3388
d5b605df 3389 if (find_named_object.found())
3390 {
5c13bd80 3391 if (this->type_ == NULL || !this->type_->is_error())
a7f064d5 3392 {
3393 this->report_error(_("constant refers to itself"));
3394 this->type_ = Type::make_error_type();
3395 }
d5b605df 3396 return;
3397 }
a7f064d5 3398}
3399
3400// Check types of a const reference.
3401
3402void
3403Const_expression::do_check_types(Gogo*)
3404{
5c13bd80 3405 if (this->type_ != NULL && this->type_->is_error())
a7f064d5 3406 return;
3407
3408 this->check_for_init_loop();
d5b605df 3409
0c77715b 3410 // Check that numeric constant fits in type.
3411 if (this->type_ != NULL && this->type_->is_numeric_type())
e440a328 3412 {
0c77715b 3413 Numeric_constant nc;
3414 if (this->constant_->const_value()->expr()->numeric_constant_value(&nc))
e440a328 3415 {
0c77715b 3416 if (!nc.set_type(this->type_, true, this->location()))
3417 this->set_is_error();
e440a328 3418 }
e440a328 3419 }
3420}
3421
ea664253 3422// Return the backend representation for a const reference.
e440a328 3423
ea664253 3424Bexpression*
3425Const_expression::do_get_backend(Translate_context* context)
e440a328 3426{
12373dd5 3427 if (this->is_error_expression()
3428 || (this->type_ != NULL && this->type_->is_error()))
3429 {
3430 go_assert(saw_errors());
3431 return context->backend()->error_expression();
3432 }
e440a328 3433
3434 // If the type has been set for this expression, but the underlying
3435 // object is an abstract int or float, we try to get the abstract
3436 // value. Otherwise we may lose something in the conversion.
f2de4532 3437 Expression* expr = this->constant_->const_value()->expr();
e440a328 3438 if (this->type_ != NULL
0c77715b 3439 && this->type_->is_numeric_type()
a68492b4 3440 && (this->constant_->const_value()->type() == NULL
3441 || this->constant_->const_value()->type()->is_abstract()))
e440a328 3442 {
0c77715b 3443 Numeric_constant nc;
3444 if (expr->numeric_constant_value(&nc)
3445 && nc.set_type(this->type_, false, this->location()))
e440a328 3446 {
0c77715b 3447 Expression* e = nc.expression(this->location());
ea664253 3448 return e->get_backend(context);
e440a328 3449 }
e440a328 3450 }
3451
2c809f8f 3452 if (this->type_ != NULL)
f2de4532 3453 expr = Expression::make_cast(this->type_, expr, this->location());
ea664253 3454 return expr->get_backend(context);
e440a328 3455}
3456
d751bb78 3457// Dump ast representation for constant expression.
3458
3459void
3460Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3461{
3462 ast_dump_context->ostream() << this->constant_->name();
3463}
3464
e440a328 3465// Make a reference to a constant in an expression.
3466
3467Expression*
3468Expression::make_const_reference(Named_object* constant,
b13c66cd 3469 Location location)
e440a328 3470{
3471 return new Const_expression(constant, location);
3472}
3473
d5b605df 3474// Find a named object in an expression.
3475
3476int
3477Find_named_object::expression(Expression** pexpr)
3478{
3479 switch ((*pexpr)->classification())
3480 {
3481 case Expression::EXPRESSION_CONST_REFERENCE:
a7f064d5 3482 {
3483 Const_expression* ce = static_cast<Const_expression*>(*pexpr);
3484 if (ce->named_object() == this->no_)
3485 break;
3486
3487 // We need to check a constant initializer explicitly, as
3488 // loops here will not be caught by the loop checking for
3489 // variable initializers.
3490 ce->check_for_init_loop();
3491
3492 return TRAVERSE_CONTINUE;
3493 }
3494
d5b605df 3495 case Expression::EXPRESSION_VAR_REFERENCE:
3496 if ((*pexpr)->var_expression()->named_object() == this->no_)
3497 break;
3498 return TRAVERSE_CONTINUE;
3499 case Expression::EXPRESSION_FUNC_REFERENCE:
3500 if ((*pexpr)->func_expression()->named_object() == this->no_)
3501 break;
3502 return TRAVERSE_CONTINUE;
3503 default:
3504 return TRAVERSE_CONTINUE;
3505 }
3506 this->found_ = true;
3507 return TRAVERSE_EXIT;
3508}
3509
e440a328 3510// The nil value.
3511
3512class Nil_expression : public Expression
3513{
3514 public:
b13c66cd 3515 Nil_expression(Location location)
e440a328 3516 : Expression(EXPRESSION_NIL, location)
3517 { }
3518
3519 static Expression*
bc8e2ef4 3520 do_import(Import_expression*, Location);
e440a328 3521
3522 protected:
3523 bool
3524 do_is_constant() const
3525 { return true; }
3526
d2199dbc 3527 bool
3528 do_is_zero_value() const
3529 { return true; }
3530
f9ca30f9 3531 bool
3ae06f68 3532 do_is_static_initializer() const
f9ca30f9 3533 { return true; }
3534
e440a328 3535 Type*
3536 do_type()
3537 { return Type::make_nil_type(); }
3538
3539 void
3540 do_determine_type(const Type_context*)
3541 { }
3542
3543 Expression*
3544 do_copy()
3545 { return this; }
3546
ea664253 3547 Bexpression*
3548 do_get_backend(Translate_context* context)
3549 { return context->backend()->nil_pointer_expression(); }
e440a328 3550
5f6f5357 3551 int
3552 do_inlining_cost() const
3553 { return 1; }
3554
e440a328 3555 void
548be246 3556 do_export(Export_function_body* efb) const
204d4af4 3557 { efb->write_c_string("$nil"); }
d751bb78 3558
3559 void
3560 do_dump_expression(Ast_dump_context* ast_dump_context) const
3561 { ast_dump_context->ostream() << "nil"; }
e440a328 3562};
3563
3564// Import a nil expression.
3565
3566Expression*
bc8e2ef4 3567Nil_expression::do_import(Import_expression* imp, Location loc)
e440a328 3568{
204d4af4 3569 if (imp->version() >= EXPORT_FORMAT_V3)
3570 imp->require_c_string("$");
e440a328 3571 imp->require_c_string("nil");
9b92780c 3572 return Expression::make_nil(loc);
e440a328 3573}
3574
3575// Make a nil expression.
3576
3577Expression*
b13c66cd 3578Expression::make_nil(Location location)
e440a328 3579{
3580 return new Nil_expression(location);
3581}
3582
3583// The value of the predeclared constant iota. This is little more
3584// than a marker. This will be lowered to an integer in
3585// Const_expression::do_lower, which is where we know the value that
3586// it should have.
3587
3588class Iota_expression : public Parser_expression
3589{
3590 public:
b13c66cd 3591 Iota_expression(Location location)
e440a328 3592 : Parser_expression(EXPRESSION_IOTA, location)
3593 { }
3594
3595 protected:
3596 Expression*
ceeb4318 3597 do_lower(Gogo*, Named_object*, Statement_inserter*, int)
c3e6f413 3598 { go_unreachable(); }
e440a328 3599
3600 // There should only ever be one of these.
3601 Expression*
3602 do_copy()
c3e6f413 3603 { go_unreachable(); }
f03a9fbf 3604
d751bb78 3605 void
3606 do_dump_expression(Ast_dump_context* ast_dump_context) const
f03a9fbf 3607 { ast_dump_context->ostream() << "iota"; }
e440a328 3608};
3609
3610// Make an iota expression. This is only called for one case: the
3611// value of the predeclared constant iota.
3612
3613Expression*
3614Expression::make_iota()
3615{
b13c66cd 3616 static Iota_expression iota_expression(Linemap::unknown_location());
e440a328 3617 return &iota_expression;
3618}
3619
da244e59 3620// Class Type_conversion_expression.
e440a328 3621
3622// Traversal.
3623
3624int
3625Type_conversion_expression::do_traverse(Traverse* traverse)
3626{
3627 if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
3628 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
3629 return TRAVERSE_EXIT;
3630 return TRAVERSE_CONTINUE;
3631}
3632
3633// Convert to a constant at lowering time.
3634
3635Expression*
ceeb4318 3636Type_conversion_expression::do_lower(Gogo*, Named_object*,
3637 Statement_inserter*, int)
e440a328 3638{
3639 Type* type = this->type_;
3640 Expression* val = this->expr_;
b13c66cd 3641 Location location = this->location();
e440a328 3642
0c77715b 3643 if (type->is_numeric_type())
e440a328 3644 {
0c77715b 3645 Numeric_constant nc;
3646 if (val->numeric_constant_value(&nc))
e440a328 3647 {
0c77715b 3648 if (!nc.set_type(type, true, location))
3649 return Expression::make_error(location);
3650 return nc.expression(location);
e440a328 3651 }
e440a328 3652 }
3653
d7739c9a 3654 // According to the language specification on string conversions
3655 // (http://golang.org/ref/spec#Conversions_to_and_from_a_string_type):
3656 // When converting an integer into a string, the string will be a UTF-8
3657 // representation of the integer and integers "outside the range of valid
3658 // Unicode code points are converted to '\uFFFD'."
3659 if (type->is_string_type())
3660 {
3661 Numeric_constant nc;
3662 if (val->numeric_constant_value(&nc) && nc.is_int())
3663 {
3664 // An integer value doesn't fit in the Unicode code point range if it
3665 // overflows the Go "int" type or is negative.
3666 unsigned long ul;
3667 if (!nc.set_type(Type::lookup_integer_type("int"), false, location)
3668 || nc.to_unsigned_long(&ul) == Numeric_constant::NC_UL_NEGATIVE)
3669 return Expression::make_string("\ufffd", location);
3670 }
3671 }
3672
55072f2b 3673 if (type->is_slice_type())
e440a328 3674 {
3675 Type* element_type = type->array_type()->element_type()->forwarded();
60963afd 3676 bool is_byte = (element_type->integer_type() != NULL
3677 && element_type->integer_type()->is_byte());
3678 bool is_rune = (element_type->integer_type() != NULL
3679 && element_type->integer_type()->is_rune());
3680 if (is_byte || is_rune)
e440a328 3681 {
3682 std::string s;
3683 if (val->string_constant_value(&s))
3684 {
3685 Expression_list* vals = new Expression_list();
3686 if (is_byte)
3687 {
3688 for (std::string::const_iterator p = s.begin();
3689 p != s.end();
3690 p++)
3691 {
e67508fa 3692 unsigned char c = static_cast<unsigned char>(*p);
3693 vals->push_back(Expression::make_integer_ul(c,
3694 element_type,
3695 location));
e440a328 3696 }
3697 }
3698 else
3699 {
3700 const char *p = s.data();
3701 const char *pend = s.data() + s.length();
3702 while (p < pend)
3703 {
3704 unsigned int c;
3705 int adv = Lex::fetch_char(p, &c);
3706 if (adv == 0)
3707 {
631d5788 3708 go_warning_at(this->location(), 0,
e440a328 3709 "invalid UTF-8 encoding");
3710 adv = 1;
3711 }
3712 p += adv;
e67508fa 3713 vals->push_back(Expression::make_integer_ul(c,
3714 element_type,
3715 location));
e440a328 3716 }
3717 }
3718
3719 return Expression::make_slice_composite_literal(type, vals,
3720 location);
3721 }
3722 }
3723 }
3724
3725 return this;
3726}
3727
35a54f17 3728// Flatten a type conversion by using a temporary variable for the slice
3729// in slice to string conversions.
3730
3731Expression*
3732Type_conversion_expression::do_flatten(Gogo*, Named_object*,
3733 Statement_inserter* inserter)
3734{
5bf8be8b 3735 if (this->type()->is_error_type() || this->expr_->is_error_expression())
3736 {
3737 go_assert(saw_errors());
3738 return Expression::make_error(this->location());
3739 }
3740
2c809f8f 3741 if (((this->type()->is_string_type()
3742 && this->expr_->type()->is_slice_type())
8ba8cc87 3743 || this->expr_->type()->interface_type() != NULL)
35a54f17 3744 && !this->expr_->is_variable())
3745 {
3746 Temporary_statement* temp =
3747 Statement::make_temporary(NULL, this->expr_, this->location());
3748 inserter->insert(temp);
3749 this->expr_ = Expression::make_temporary_reference(temp, this->location());
3750 }
e007b1eb 3751
20a381c4 3752 // For interface conversion and string to/from slice conversions,
3753 // decide if we can allocate on stack.
3754 if (this->type()->interface_type() != NULL
3755 || this->type()->is_string_type()
3756 || this->expr_->type()->is_string_type())
e007b1eb 3757 {
3758 Node* n = Node::make_node(this);
3759 if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
3760 this->no_escape_ = true;
3761 }
35a54f17 3762 return this;
3763}
3764
1ca01a59 3765// Return whether a type conversion is a constant.
3766
3767bool
3768Type_conversion_expression::do_is_constant() const
3769{
3770 if (!this->expr_->is_constant())
3771 return false;
3772
3773 // A conversion to a type that may not be used as a constant is not
3774 // a constant. For example, []byte(nil).
3775 Type* type = this->type_;
3776 if (type->integer_type() == NULL
3777 && type->float_type() == NULL
3778 && type->complex_type() == NULL
3779 && !type->is_boolean_type()
3780 && !type->is_string_type())
3781 return false;
3782
3783 return true;
3784}
3785
d2199dbc 3786// Return whether a type conversion is a zero value.
3787
3788bool
3789Type_conversion_expression::do_is_zero_value() const
3790{
3791 if (!this->expr_->is_zero_value())
3792 return false;
3793
3794 // Some type conversion from zero value is still not zero value.
3795 // For example, []byte("") or interface{}(0).
3796 // Conservatively, only report true if the RHS is nil.
3797 Type* type = this->type_;
3798 if (type->integer_type() == NULL
3799 && type->float_type() == NULL
3800 && type->complex_type() == NULL
3801 && !type->is_boolean_type()
3802 && !type->is_string_type())
3803 return this->expr_->is_nil_expression();
3804
3805 return true;
3806}
3807
3ae06f68 3808// Return whether a type conversion can be used in a constant
3809// initializer.
0e168074 3810
3811bool
3ae06f68 3812Type_conversion_expression::do_is_static_initializer() const
0e168074 3813{
3814 Type* type = this->type_;
3815 Type* expr_type = this->expr_->type();
3816
3817 if (type->interface_type() != NULL
3818 || expr_type->interface_type() != NULL)
3819 return false;
3820
3ae06f68 3821 if (!this->expr_->is_static_initializer())
0e168074 3822 return false;
3823
3a522dcc 3824 if (Type::are_identical(type, expr_type,
3825 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
3826 NULL))
0e168074 3827 return true;
3828
03118c21 3829 if (type->is_string_type() && expr_type->is_string_type())
3830 return true;
3831
3832 if ((type->is_numeric_type()
3833 || type->is_boolean_type()
3834 || type->points_to() != NULL)
3835 && (expr_type->is_numeric_type()
3836 || expr_type->is_boolean_type()
3837 || expr_type->points_to() != NULL))
3838 return true;
3839
3840 return false;
0e168074 3841}
3842
0c77715b 3843// Return the constant numeric value if there is one.
e440a328 3844
3845bool
0c77715b 3846Type_conversion_expression::do_numeric_constant_value(
3847 Numeric_constant* nc) const
e440a328 3848{
0c77715b 3849 if (!this->type_->is_numeric_type())
e440a328 3850 return false;
0c77715b 3851 if (!this->expr_->numeric_constant_value(nc))
e440a328 3852 return false;
0c77715b 3853 return nc->set_type(this->type_, false, this->location());
e440a328 3854}
3855
3856// Return the constant string value if there is one.
3857
3858bool
3859Type_conversion_expression::do_string_constant_value(std::string* val) const
3860{
3861 if (this->type_->is_string_type()
3862 && this->expr_->type()->integer_type() != NULL)
3863 {
0c77715b 3864 Numeric_constant nc;
3865 if (this->expr_->numeric_constant_value(&nc))
e440a328 3866 {
0c77715b 3867 unsigned long ival;
3868 if (nc.to_unsigned_long(&ival) == Numeric_constant::NC_UL_VALID)
e440a328 3869 {
0c77715b 3870 val->clear();
3871 Lex::append_char(ival, true, val, this->location());
e440a328 3872 return true;
3873 }
3874 }
e440a328 3875 }
3876
3877 // FIXME: Could handle conversion from const []int here.
3878
3879 return false;
3880}
3881
ac7ef97d 3882// Return the constant boolean value if there is one.
3883
3884bool
3885Type_conversion_expression::do_boolean_constant_value(bool* val) const
3886{
3887 if (!this->type_->is_boolean_type())
3888 return false;
3889 return this->expr_->boolean_constant_value(val);
3890}
3891
da244e59 3892// Determine the resulting type of the conversion.
3893
3894void
3895Type_conversion_expression::do_determine_type(const Type_context*)
3896{
3897 Type_context subcontext(this->type_, false);
3898 this->expr_->determine_type(&subcontext);
3899}
3900
e440a328 3901// Check that types are convertible.
3902
3903void
3904Type_conversion_expression::do_check_types(Gogo*)
3905{
3906 Type* type = this->type_;
3907 Type* expr_type = this->expr_->type();
3908 std::string reason;
3909
5c13bd80 3910 if (type->is_error() || expr_type->is_error())
842f6425 3911 {
842f6425 3912 this->set_is_error();
3913 return;
3914 }
3915
e440a328 3916 if (this->may_convert_function_types_
3917 && type->function_type() != NULL
3918 && expr_type->function_type() != NULL)
3919 return;
3920
3921 if (Type::are_convertible(type, expr_type, &reason))
3922 return;
3923
631d5788 3924 go_error_at(this->location(), "%s", reason.c_str());
e440a328 3925 this->set_is_error();
3926}
3927
de590a61 3928// Copy.
3929
3930Expression*
3931Type_conversion_expression::do_copy()
3932{
ae77af58 3933 Expression* ret = new Type_conversion_expression(this->type_->copy_expressions(),
3934 this->expr_->copy(),
3935 this->location());
3936 ret->conversion_expression()->set_no_copy(this->no_copy_);
3937 return ret;
de590a61 3938}
3939
ea664253 3940// Get the backend representation for a type conversion.
e440a328 3941
ea664253 3942Bexpression*
3943Type_conversion_expression::do_get_backend(Translate_context* context)
e440a328 3944{
e440a328 3945 Type* type = this->type_;
3946 Type* expr_type = this->expr_->type();
2c809f8f 3947
3948 Gogo* gogo = context->gogo();
3949 Btype* btype = type->get_backend(gogo);
2c809f8f 3950 Location loc = this->location();
3951
3a522dcc 3952 if (Type::are_identical(type, expr_type,
3953 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
3954 NULL))
859cdc93 3955 {
3956 Bexpression* bexpr = this->expr_->get_backend(context);
3957 return gogo->backend()->convert_expression(btype, bexpr, loc);
3958 }
e007b1eb 3959 else if (type->interface_type() != NULL
3960 && expr_type->interface_type() == NULL)
3961 {
3962 Expression* conversion =
3963 Expression::convert_type_to_interface(type, this->expr_,
3964 this->no_escape_, loc);
3965 return conversion->get_backend(context);
3966 }
2c809f8f 3967 else if (type->interface_type() != NULL
3968 || expr_type->interface_type() != NULL)
e440a328 3969 {
2c809f8f 3970 Expression* conversion =
3971 Expression::convert_for_assignment(gogo, type, this->expr_,
e007b1eb 3972 loc);
ea664253 3973 return conversion->get_backend(context);
e440a328 3974 }
3975 else if (type->is_string_type()
3976 && expr_type->integer_type() != NULL)
3977 {
2c809f8f 3978 mpz_t intval;
3979 Numeric_constant nc;
3980 if (this->expr_->numeric_constant_value(&nc)
9ee9df22 3981 && nc.to_int(&intval))
e440a328 3982 {
e440a328 3983 std::string s;
9ee9df22 3984 unsigned int x;
3985 if (mpz_fits_uint_p(intval))
3986 x = mpz_get_ui(intval);
3987 else
3988 {
3989 char* s = mpz_get_str(NULL, 16, intval);
3990 go_warning_at(loc, 0,
3991 "unicode code point 0x%s out of range in string", s);
3992 x = 0xfffd;
3993 }
3994 Lex::append_char(x, true, &s, loc);
2c809f8f 3995 mpz_clear(intval);
3996 Expression* se = Expression::make_string(s, loc);
ea664253 3997 return se->get_backend(context);
e440a328 3998 }
3999
20a381c4 4000 Expression* buf;
4001 if (this->no_escape_)
4002 {
4003 Type* byte_type = Type::lookup_integer_type("uint8");
4004 Expression* buflen =
4005 Expression::make_integer_ul(4, NULL, loc);
4006 Type* array_type = Type::make_array_type(byte_type, buflen);
4007 buf = Expression::make_allocation(array_type, loc);
4008 buf->allocation_expression()->set_allocate_on_stack();
4009 buf->allocation_expression()->set_no_zero();
4010 }
4011 else
4012 buf = Expression::make_nil(loc);
f16ab008 4013 Expression* i2s_expr =
20a381c4 4014 Runtime::make_call(Runtime::INTSTRING, loc, 2, buf, this->expr_);
ea664253 4015 return Expression::make_cast(type, i2s_expr, loc)->get_backend(context);
e440a328 4016 }
55072f2b 4017 else if (type->is_string_type() && expr_type->is_slice_type())
e440a328 4018 {
55072f2b 4019 Array_type* a = expr_type->array_type();
e440a328 4020 Type* e = a->element_type()->forwarded();
c484d925 4021 go_assert(e->integer_type() != NULL);
35a54f17 4022 go_assert(this->expr_->is_variable());
4023
4024 Runtime::Function code;
60963afd 4025 if (e->integer_type()->is_byte())
ae77af58 4026 {
4027 if (this->no_copy_)
4028 {
4029 if (gogo->debug_optimization())
37188bf9 4030 go_debug(loc, "no copy string([]byte)");
ae77af58 4031 Expression* ptr = Expression::make_slice_info(this->expr_,
4032 SLICE_INFO_VALUE_POINTER,
4033 loc);
4034 Expression* len = Expression::make_slice_info(this->expr_,
4035 SLICE_INFO_LENGTH,
4036 loc);
4037 Expression* str = Expression::make_string_value(ptr, len, loc);
4038 return str->get_backend(context);
4039 }
4040 code = Runtime::SLICEBYTETOSTRING;
4041 }
e440a328 4042 else
35a54f17 4043 {
4044 go_assert(e->integer_type()->is_rune());
736a16ba 4045 code = Runtime::SLICERUNETOSTRING;
35a54f17 4046 }
20a381c4 4047
4048 Expression* buf;
4049 if (this->no_escape_)
4050 {
4051 Type* byte_type = Type::lookup_integer_type("uint8");
4052 Expression* buflen =
4053 Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
4054 Type* array_type = Type::make_array_type(byte_type, buflen);
4055 buf = Expression::make_allocation(array_type, loc);
4056 buf->allocation_expression()->set_allocate_on_stack();
4057 buf->allocation_expression()->set_no_zero();
4058 }
4059 else
4060 buf = Expression::make_nil(loc);
4061 return Runtime::make_call(code, loc, 2, buf,
736a16ba 4062 this->expr_)->get_backend(context);
e440a328 4063 }
411eb89e 4064 else if (type->is_slice_type() && expr_type->is_string_type())
e440a328 4065 {
4066 Type* e = type->array_type()->element_type()->forwarded();
c484d925 4067 go_assert(e->integer_type() != NULL);
6c252e42 4068
2c809f8f 4069 Runtime::Function code;
60963afd 4070 if (e->integer_type()->is_byte())
736a16ba 4071 code = Runtime::STRINGTOSLICEBYTE;
e440a328 4072 else
4073 {
60963afd 4074 go_assert(e->integer_type()->is_rune());
736a16ba 4075 code = Runtime::STRINGTOSLICERUNE;
e440a328 4076 }
20a381c4 4077
4078 Expression* buf;
4079 if (this->no_escape_)
4080 {
4081 Expression* buflen =
4082 Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
4083 Type* array_type = Type::make_array_type(e, buflen);
4084 buf = Expression::make_allocation(array_type, loc);
4085 buf->allocation_expression()->set_allocate_on_stack();
4086 buf->allocation_expression()->set_no_zero();
4087 }
4088 else
4089 buf = Expression::make_nil(loc);
4090 Expression* s2a = Runtime::make_call(code, loc, 2, buf, this->expr_);
ea664253 4091 return Expression::make_unsafe_cast(type, s2a, loc)->get_backend(context);
2c809f8f 4092 }
4093 else if (type->is_numeric_type())
4094 {
4095 go_assert(Type::are_convertible(type, expr_type, NULL));
859cdc93 4096 Bexpression* bexpr = this->expr_->get_backend(context);
ea664253 4097 return gogo->backend()->convert_expression(btype, bexpr, loc);
e440a328 4098 }
4099 else if ((type->is_unsafe_pointer_type()
2c809f8f 4100 && (expr_type->points_to() != NULL
4101 || expr_type->integer_type()))
4102 || (expr_type->is_unsafe_pointer_type()
4103 && type->points_to() != NULL)
4104 || (this->may_convert_function_types_
4105 && type->function_type() != NULL
4106 && expr_type->function_type() != NULL))
859cdc93 4107 {
4108 Bexpression* bexpr = this->expr_->get_backend(context);
4109 return gogo->backend()->convert_expression(btype, bexpr, loc);
4110 }
e440a328 4111 else
2c809f8f 4112 {
4113 Expression* conversion =
4114 Expression::convert_for_assignment(gogo, type, this->expr_, loc);
ea664253 4115 return conversion->get_backend(context);
2c809f8f 4116 }
e440a328 4117}
4118
5f6f5357 4119// Cost of inlining a type conversion.
4120
4121int
4122Type_conversion_expression::do_inlining_cost() const
4123{
4124 Type* type = this->type_;
4125 Type* expr_type = this->expr_->type();
4126 if (type->interface_type() != NULL || expr_type->interface_type() != NULL)
4127 return 10;
4128 else if (type->is_string_type() && expr_type->integer_type() != NULL)
4129 return 10;
4130 else if (type->is_string_type() && expr_type->is_slice_type())
4131 return 10;
4132 else if (type->is_slice_type() && expr_type->is_string_type())
4133 return 10;
4134 else
4135 return 1;
4136}
4137
e440a328 4138// Output a type conversion in a constant expression.
4139
4140void
548be246 4141Type_conversion_expression::do_export(Export_function_body* efb) const
e440a328 4142{
204d4af4 4143 efb->write_c_string("$convert(");
548be246 4144 efb->write_type(this->type_);
4145 efb->write_c_string(", ");
69f634cc 4146
4147 Type* old_context = efb->type_context();
4148 efb->set_type_context(this->type_);
4149
548be246 4150 this->expr_->export_expression(efb);
69f634cc 4151
4152 efb->set_type_context(old_context);
4153
548be246 4154 efb->write_c_string(")");
e440a328 4155}
4156
4157// Import a type conversion or a struct construction.
4158
4159Expression*
bc8e2ef4 4160Type_conversion_expression::do_import(Import_expression* imp, Location loc)
e440a328 4161{
204d4af4 4162 imp->require_c_string("$convert(");
e440a328 4163 Type* type = imp->read_type();
4164 imp->require_c_string(", ");
9b92780c 4165 Expression* val = Expression::import_expression(imp, loc);
e440a328 4166 imp->require_c_string(")");
9b92780c 4167 return Expression::make_cast(type, val, loc);
e440a328 4168}
4169
d751bb78 4170// Dump ast representation for a type conversion expression.
4171
4172void
4173Type_conversion_expression::do_dump_expression(
4174 Ast_dump_context* ast_dump_context) const
4175{
4176 ast_dump_context->dump_type(this->type_);
4177 ast_dump_context->ostream() << "(";
4178 ast_dump_context->dump_expression(this->expr_);
4179 ast_dump_context->ostream() << ") ";
4180}
4181
e440a328 4182// Make a type cast expression.
4183
4184Expression*
b13c66cd 4185Expression::make_cast(Type* type, Expression* val, Location location)
e440a328 4186{
4187 if (type->is_error_type() || val->is_error_expression())
4188 return Expression::make_error(location);
4189 return new Type_conversion_expression(type, val, location);
4190}
4191
98f62f7a 4192// Class Unsafe_type_conversion_expression.
9581e91d 4193
4194// Traversal.
4195
4196int
4197Unsafe_type_conversion_expression::do_traverse(Traverse* traverse)
4198{
4199 if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
4200 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
4201 return TRAVERSE_EXIT;
4202 return TRAVERSE_CONTINUE;
4203}
4204
3ae06f68 4205// Return whether an unsafe type conversion can be used as a constant
4206// initializer.
aa5ae575 4207
4208bool
3ae06f68 4209Unsafe_type_conversion_expression::do_is_static_initializer() const
aa5ae575 4210{
4211 Type* type = this->type_;
4212 Type* expr_type = this->expr_->type();
4213
4214 if (type->interface_type() != NULL
4215 || expr_type->interface_type() != NULL)
4216 return false;
4217
3ae06f68 4218 if (!this->expr_->is_static_initializer())
aa5ae575 4219 return false;
4220
4221 if (Type::are_convertible(type, expr_type, NULL))
4222 return true;
4223
03118c21 4224 if (type->is_string_type() && expr_type->is_string_type())
4225 return true;
4226
4227 if ((type->is_numeric_type()
4228 || type->is_boolean_type()
4229 || type->points_to() != NULL)
4230 && (expr_type->is_numeric_type()
4231 || expr_type->is_boolean_type()
4232 || expr_type->points_to() != NULL))
4233 return true;
4234
4235 return false;
aa5ae575 4236}
4237
de590a61 4238// Copy.
4239
4240Expression*
4241Unsafe_type_conversion_expression::do_copy()
4242{
4243 return new Unsafe_type_conversion_expression(this->type_->copy_expressions(),
4244 this->expr_->copy(),
4245 this->location());
4246}
4247
9581e91d 4248// Convert to backend representation.
4249
ea664253 4250Bexpression*
4251Unsafe_type_conversion_expression::do_get_backend(Translate_context* context)
9581e91d 4252{
4253 // We are only called for a limited number of cases.
4254
4255 Type* t = this->type_;
4256 Type* et = this->expr_->type();
5c4802f1 4257
4258 if (t->is_error_type()
4259 || this->expr_->is_error_expression()
4260 || et->is_error_type())
4261 {
4262 go_assert(saw_errors());
4263 return context->backend()->error_expression();
4264 }
4265
2c809f8f 4266 if (t->array_type() != NULL)
4267 go_assert(et->array_type() != NULL
4268 && t->is_slice_type() == et->is_slice_type());
4269 else if (t->struct_type() != NULL)
9581e91d 4270 {
2c809f8f 4271 if (t->named_type() != NULL
4272 && et->named_type() != NULL
4273 && !Type::are_convertible(t, et, NULL))
4274 {
4275 go_assert(saw_errors());
ea664253 4276 return context->backend()->error_expression();
2c809f8f 4277 }
4278
4279 go_assert(et->struct_type() != NULL
4280 && Type::are_convertible(t, et, NULL));
4281 }
4282 else if (t->map_type() != NULL)
5b665222 4283 go_assert(et->map_type() != NULL || et->points_to() != NULL);
9581e91d 4284 else if (t->channel_type() != NULL)
5b665222 4285 go_assert(et->channel_type() != NULL || et->points_to() != NULL);
09ea332d 4286 else if (t->points_to() != NULL)
2c809f8f 4287 go_assert(et->points_to() != NULL
4288 || et->channel_type() != NULL
4289 || et->map_type() != NULL
4290 || et->function_type() != NULL
132ed071 4291 || et->integer_type() != NULL
2c809f8f 4292 || et->is_nil_type());
5b665222 4293 else if (t->function_type() != NULL)
4294 go_assert(et->points_to() != NULL);
9581e91d 4295 else if (et->is_unsafe_pointer_type())
81487fff 4296 go_assert(t->points_to() != NULL
4297 || (t->integer_type() != NULL
4298 && t->integer_type() == Type::lookup_integer_type("uintptr")->real_type()));
2c809f8f 4299 else if (t->interface_type() != NULL)
9581e91d 4300 {
2c809f8f 4301 bool empty_iface = t->interface_type()->is_empty();
c484d925 4302 go_assert(et->interface_type() != NULL
2c809f8f 4303 && et->interface_type()->is_empty() == empty_iface);
9581e91d 4304 }
588e3cf9 4305 else if (t->integer_type() != NULL)
2c809f8f 4306 go_assert(et->is_boolean_type()
4307 || et->integer_type() != NULL
4308 || et->function_type() != NULL
4309 || et->points_to() != NULL
4310 || et->map_type() != NULL
8ba8cc87 4311 || et->channel_type() != NULL
4312 || et->is_nil_type());
9581e91d 4313 else
c3e6f413 4314 go_unreachable();
9581e91d 4315
2c809f8f 4316 Gogo* gogo = context->gogo();
4317 Btype* btype = t->get_backend(gogo);
ea664253 4318 Bexpression* bexpr = this->expr_->get_backend(context);
2c809f8f 4319 Location loc = this->location();
ea664253 4320 return gogo->backend()->convert_expression(btype, bexpr, loc);
9581e91d 4321}
4322
d751bb78 4323// Dump ast representation for an unsafe type conversion expression.
4324
4325void
4326Unsafe_type_conversion_expression::do_dump_expression(
4327 Ast_dump_context* ast_dump_context) const
4328{
4329 ast_dump_context->dump_type(this->type_);
4330 ast_dump_context->ostream() << "(";
4331 ast_dump_context->dump_expression(this->expr_);
4332 ast_dump_context->ostream() << ") ";
4333}
4334
9581e91d 4335// Make an unsafe type conversion expression.
4336
4337Expression*
4338Expression::make_unsafe_cast(Type* type, Expression* expr,
b13c66cd 4339 Location location)
9581e91d 4340{
4341 return new Unsafe_type_conversion_expression(type, expr, location);
4342}
4343
76f85fd6 4344// Class Unary_expression.
e440a328 4345
03118c21 4346// Call the address_taken method of the operand if needed. This is
4347// called after escape analysis but before inserting write barriers.
4348
4349void
c1177ba4 4350Unary_expression::check_operand_address_taken(Gogo*)
03118c21 4351{
4352 if (this->op_ != OPERATOR_AND)
4353 return;
4354
4355 // If this->escapes_ is false at this point, then it was set to
4356 // false by an explicit call to set_does_not_escape, and the value
4357 // does not escape. If this->escapes_ is true, we may be able to
2f86af0a 4358 // set it to false based on the escape analysis pass.
4359 if (this->escapes_)
4360 {
4361 Node* n = Node::make_node(this);
4362 if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
4363 this->escapes_ = false;
03118c21 4364 }
4365
4366 this->expr_->address_taken(this->escapes_);
4367}
4368
e440a328 4369// If we are taking the address of a composite literal, and the
2c809f8f 4370// contents are not constant, then we want to make a heap expression
e440a328 4371// instead.
4372
4373Expression*
ceeb4318 4374Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
e440a328 4375{
b13c66cd 4376 Location loc = this->location();
e440a328 4377 Operator op = this->op_;
4378 Expression* expr = this->expr_;
4379
4380 if (op == OPERATOR_MULT && expr->is_type_expression())
4381 return Expression::make_type(Type::make_pointer_type(expr->type()), loc);
4382
4383 // *&x simplifies to x. *(*T)(unsafe.Pointer)(&x) does not require
4384 // moving x to the heap. FIXME: Is it worth doing a real escape
4385 // analysis here? This case is found in math/unsafe.go and is
4386 // therefore worth special casing.
4387 if (op == OPERATOR_MULT)
4388 {
4389 Expression* e = expr;
4390 while (e->classification() == EXPRESSION_CONVERSION)
4391 {
4392 Type_conversion_expression* te
4393 = static_cast<Type_conversion_expression*>(e);
4394 e = te->expr();
4395 }
4396
4397 if (e->classification() == EXPRESSION_UNARY)
4398 {
4399 Unary_expression* ue = static_cast<Unary_expression*>(e);
4400 if (ue->op_ == OPERATOR_AND)
4401 {
4402 if (e == expr)
4403 {
4404 // *&x == x.
f4dea966 4405 if (!ue->expr_->is_addressable() && !ue->create_temp_)
4406 {
631d5788 4407 go_error_at(ue->location(),
4408 "invalid operand for unary %<&%>");
f4dea966 4409 this->set_is_error();
4410 }
e440a328 4411 return ue->expr_;
4412 }
4413 ue->set_does_not_escape();
4414 }
4415 }
4416 }
4417
55661ce9 4418 // Catching an invalid indirection of unsafe.Pointer here avoid
4419 // having to deal with TYPE_VOID in other places.
4420 if (op == OPERATOR_MULT && expr->type()->is_unsafe_pointer_type())
4421 {
631d5788 4422 go_error_at(this->location(), "invalid indirect of %<unsafe.Pointer%>");
55661ce9 4423 return Expression::make_error(this->location());
4424 }
4425
d9f3743a 4426 // Check for an invalid pointer dereference. We need to do this
4427 // here because Unary_expression::do_type will return an error type
4428 // in this case. That can cause code to appear erroneous, and
4429 // therefore disappear at lowering time, without any error message.
4430 if (op == OPERATOR_MULT && expr->type()->points_to() == NULL)
4431 {
4432 this->report_error(_("expected pointer"));
4433 return Expression::make_error(this->location());
4434 }
4435
59a401fe 4436 if (op == OPERATOR_PLUS || op == OPERATOR_MINUS || op == OPERATOR_XOR)
e440a328 4437 {
0c77715b 4438 Numeric_constant nc;
4439 if (expr->numeric_constant_value(&nc))
e440a328 4440 {
0c77715b 4441 Numeric_constant result;
af7a5274 4442 bool issued_error;
4443 if (Unary_expression::eval_constant(op, &nc, loc, &result,
4444 &issued_error))
0c77715b 4445 return result.expression(loc);
af7a5274 4446 else if (issued_error)
4447 return Expression::make_error(this->location());
e440a328 4448 }
4449 }
4450
4451 return this;
4452}
4453
f9ca30f9 4454// Flatten expression if a nil check must be performed and create temporary
4455// variables if necessary.
4456
4457Expression*
4458Unary_expression::do_flatten(Gogo* gogo, Named_object*,
4459 Statement_inserter* inserter)
4460{
5bf8be8b 4461 if (this->is_error_expression()
4462 || this->expr_->is_error_expression()
4463 || this->expr_->type()->is_error_type())
4464 {
4465 go_assert(saw_errors());
4466 return Expression::make_error(this->location());
4467 }
f4dea966 4468
f9ca30f9 4469 Location location = this->location();
4470 if (this->op_ == OPERATOR_MULT
4471 && !this->expr_->is_variable())
4472 {
4473 go_assert(this->expr_->type()->points_to() != NULL);
f614ea8b 4474 switch (this->requires_nil_check(gogo))
f9ca30f9 4475 {
f614ea8b 4476 case NIL_CHECK_ERROR_ENCOUNTERED:
2a305b85 4477 {
4478 go_assert(saw_errors());
4479 return Expression::make_error(this->location());
4480 }
f614ea8b 4481 case NIL_CHECK_NOT_NEEDED:
4482 break;
4483 case NIL_CHECK_NEEDED:
4484 this->create_temp_ = true;
4485 break;
4486 case NIL_CHECK_DEFAULT:
4487 go_unreachable();
f9ca30f9 4488 }
4489 }
4490
4491 if (this->create_temp_ && !this->expr_->is_variable())
4492 {
4493 Temporary_statement* temp =
4494 Statement::make_temporary(NULL, this->expr_, location);
4495 inserter->insert(temp);
4496 this->expr_ = Expression::make_temporary_reference(temp, location);
4497 }
4498
4499 return this;
4500}
4501
e440a328 4502// Return whether a unary expression is a constant.
4503
4504bool
4505Unary_expression::do_is_constant() const
4506{
4507 if (this->op_ == OPERATOR_MULT)
4508 {
4509 // Indirecting through a pointer is only constant if the object
4510 // to which the expression points is constant, but we currently
4511 // have no way to determine that.
4512 return false;
4513 }
4514 else if (this->op_ == OPERATOR_AND)
4515 {
4516 // Taking the address of a variable is constant if it is a
f9ca30f9 4517 // global variable, not constant otherwise. In other cases taking the
4518 // address is probably not a constant.
e440a328 4519 Var_expression* ve = this->expr_->var_expression();
4520 if (ve != NULL)
4521 {
4522 Named_object* no = ve->named_object();
4523 return no->is_variable() && no->var_value()->is_global();
4524 }
4525 return false;
4526 }
4527 else
4528 return this->expr_->is_constant();
4529}
4530
3ae06f68 4531// Return whether a unary expression can be used as a constant
4532// initializer.
4533
4534bool
4535Unary_expression::do_is_static_initializer() const
4536{
4537 if (this->op_ == OPERATOR_MULT)
4538 return false;
4539 else if (this->op_ == OPERATOR_AND)
de048538 4540 return Unary_expression::base_is_static_initializer(this->expr_);
4541 else
4542 return this->expr_->is_static_initializer();
4543}
3ae06f68 4544
de048538 4545// Return whether the address of EXPR can be used as a static
4546// initializer.
3ae06f68 4547
de048538 4548bool
4549Unary_expression::base_is_static_initializer(Expression* expr)
4550{
4551 // The address of a field reference can be a static initializer if
4552 // the base can be a static initializer.
4553 Field_reference_expression* fre = expr->field_reference_expression();
4554 if (fre != NULL)
4555 return Unary_expression::base_is_static_initializer(fre->expr());
4556
4557 // The address of an index expression can be a static initializer if
4558 // the base can be a static initializer and the index is constant.
4559 Array_index_expression* aind = expr->array_index_expression();
4560 if (aind != NULL)
4561 return (aind->end() == NULL
4562 && aind->start()->is_constant()
4563 && Unary_expression::base_is_static_initializer(aind->array()));
4564
4565 // The address of a global variable can be a static initializer.
4566 Var_expression* ve = expr->var_expression();
4567 if (ve != NULL)
4568 {
4569 Named_object* no = ve->named_object();
4570 return no->is_variable() && no->var_value()->is_global();
4571 }
4572
4573 // The address of a composite literal can be used as a static
4574 // initializer if the composite literal is itself usable as a
4575 // static initializer.
4576 if (expr->is_composite_literal() && expr->is_static_initializer())
4577 return true;
3ae06f68 4578
de048538 4579 // The address of a string constant can be used as a static
4580 // initializer. This can not be written in Go itself but this is
4581 // used when building a type descriptor.
4582 if (expr->string_expression() != NULL)
4583 return true;
4584
4585 return false;
3ae06f68 4586}
4587
f614ea8b 4588// Return whether this dereference expression requires an explicit nil
4589// check. If we are dereferencing the pointer to a large struct
4590// (greater than the specified size threshold), we need to check for
4591// nil. We don't bother to check for small structs because we expect
4592// the system to crash on a nil pointer dereference. However, if we
4593// know the address of this expression is being taken, we must always
4594// check for nil.
4595Unary_expression::Nil_check_classification
f03a9fbf 4596Unary_expression::requires_nil_check(Gogo* gogo)
f614ea8b 4597{
4598 go_assert(this->op_ == OPERATOR_MULT);
4599 go_assert(this->expr_->type()->points_to() != NULL);
4600
4601 if (this->issue_nil_check_ == NIL_CHECK_NEEDED)
4602 return NIL_CHECK_NEEDED;
4603 else if (this->issue_nil_check_ == NIL_CHECK_NOT_NEEDED)
4604 return NIL_CHECK_NOT_NEEDED;
4605
4606 Type* ptype = this->expr_->type()->points_to();
4607 int64_t type_size = -1;
4608 if (!ptype->is_void_type())
4609 {
4610 bool ok = ptype->backend_type_size(gogo, &type_size);
4611 if (!ok)
4612 return NIL_CHECK_ERROR_ENCOUNTERED;
4613 }
4614
4615 int64_t size_cutoff = gogo->nil_check_size_threshold();
4616 if (size_cutoff == -1 || (type_size != -1 && type_size >= size_cutoff))
4617 this->issue_nil_check_ = NIL_CHECK_NEEDED;
4618 else
4619 this->issue_nil_check_ = NIL_CHECK_NOT_NEEDED;
4620 return this->issue_nil_check_;
4621}
4622
0c77715b 4623// Apply unary opcode OP to UNC, setting NC. Return true if this
af7a5274 4624// could be done, false if not. On overflow, issues an error and sets
4625// *ISSUED_ERROR.
e440a328 4626
4627bool
0c77715b 4628Unary_expression::eval_constant(Operator op, const Numeric_constant* unc,
af7a5274 4629 Location location, Numeric_constant* nc,
4630 bool* issued_error)
e440a328 4631{
af7a5274 4632 *issued_error = false;
e440a328 4633 switch (op)
4634 {
4635 case OPERATOR_PLUS:
0c77715b 4636 *nc = *unc;
e440a328 4637 return true;
0c77715b 4638
e440a328 4639 case OPERATOR_MINUS:
0c77715b 4640 if (unc->is_int() || unc->is_rune())
4641 break;
4642 else if (unc->is_float())
4643 {
4644 mpfr_t uval;
4645 unc->get_float(&uval);
4646 mpfr_t val;
4647 mpfr_init(val);
4648 mpfr_neg(val, uval, GMP_RNDN);
4649 nc->set_float(unc->type(), val);
4650 mpfr_clear(uval);
4651 mpfr_clear(val);
4652 return true;
4653 }
4654 else if (unc->is_complex())
4655 {
fcbea5e4 4656 mpc_t uval;
4657 unc->get_complex(&uval);
4658 mpc_t val;
4659 mpc_init2(val, mpc_precision);
4660 mpc_neg(val, uval, MPC_RNDNN);
4661 nc->set_complex(unc->type(), val);
4662 mpc_clear(uval);
4663 mpc_clear(val);
0c77715b 4664 return true;
4665 }
e440a328 4666 else
0c77715b 4667 go_unreachable();
e440a328 4668
0c77715b 4669 case OPERATOR_XOR:
4670 break;
68448d53 4671
59a401fe 4672 case OPERATOR_NOT:
e440a328 4673 case OPERATOR_AND:
4674 case OPERATOR_MULT:
4675 return false;
0c77715b 4676
e440a328 4677 default:
c3e6f413 4678 go_unreachable();
e440a328 4679 }
e440a328 4680
0c77715b 4681 if (!unc->is_int() && !unc->is_rune())
4682 return false;
4683
4684 mpz_t uval;
8387e1df 4685 if (unc->is_rune())
4686 unc->get_rune(&uval);
4687 else
4688 unc->get_int(&uval);
0c77715b 4689 mpz_t val;
4690 mpz_init(val);
e440a328 4691
e440a328 4692 switch (op)
4693 {
e440a328 4694 case OPERATOR_MINUS:
0c77715b 4695 mpz_neg(val, uval);
4696 break;
4697
e440a328 4698 case OPERATOR_NOT:
0c77715b 4699 mpz_set_ui(val, mpz_cmp_si(uval, 0) == 0 ? 1 : 0);
4700 break;
4701
e440a328 4702 case OPERATOR_XOR:
0c77715b 4703 {
4704 Type* utype = unc->type();
4705 if (utype->integer_type() == NULL
4706 || utype->integer_type()->is_abstract())
4707 mpz_com(val, uval);
4708 else
4709 {
4710 // The number of HOST_WIDE_INTs that it takes to represent
4711 // UVAL.
4712 size_t count = ((mpz_sizeinbase(uval, 2)
4713 + HOST_BITS_PER_WIDE_INT
4714 - 1)
4715 / HOST_BITS_PER_WIDE_INT);
e440a328 4716
0c77715b 4717 unsigned HOST_WIDE_INT* phwi = new unsigned HOST_WIDE_INT[count];
4718 memset(phwi, 0, count * sizeof(HOST_WIDE_INT));
4719
4720 size_t obits = utype->integer_type()->bits();
4721
4722 if (!utype->integer_type()->is_unsigned() && mpz_sgn(uval) < 0)
4723 {
4724 mpz_t adj;
4725 mpz_init_set_ui(adj, 1);
4726 mpz_mul_2exp(adj, adj, obits);
4727 mpz_add(uval, uval, adj);
4728 mpz_clear(adj);
4729 }
4730
4731 size_t ecount;
4732 mpz_export(phwi, &ecount, -1, sizeof(HOST_WIDE_INT), 0, 0, uval);
4733 go_assert(ecount <= count);
4734
4735 // Trim down to the number of words required by the type.
4736 size_t ocount = ((obits + HOST_BITS_PER_WIDE_INT - 1)
4737 / HOST_BITS_PER_WIDE_INT);
4738 go_assert(ocount <= count);
4739
4740 for (size_t i = 0; i < ocount; ++i)
4741 phwi[i] = ~phwi[i];
4742
4743 size_t clearbits = ocount * HOST_BITS_PER_WIDE_INT - obits;
4744 if (clearbits != 0)
4745 phwi[ocount - 1] &= (((unsigned HOST_WIDE_INT) (HOST_WIDE_INT) -1)
4746 >> clearbits);
4747
4748 mpz_import(val, ocount, -1, sizeof(HOST_WIDE_INT), 0, 0, phwi);
4749
4750 if (!utype->integer_type()->is_unsigned()
4751 && mpz_tstbit(val, obits - 1))
4752 {
4753 mpz_t adj;
4754 mpz_init_set_ui(adj, 1);
4755 mpz_mul_2exp(adj, adj, obits);
4756 mpz_sub(val, val, adj);
4757 mpz_clear(adj);
4758 }
4759
4760 delete[] phwi;
4761 }
4762 }
4763 break;
e440a328 4764
e440a328 4765 default:
c3e6f413 4766 go_unreachable();
e440a328 4767 }
e440a328 4768
0c77715b 4769 if (unc->is_rune())
4770 nc->set_rune(NULL, val);
e440a328 4771 else
0c77715b 4772 nc->set_int(NULL, val);
e440a328 4773
0c77715b 4774 mpz_clear(uval);
4775 mpz_clear(val);
e440a328 4776
af7a5274 4777 if (!nc->set_type(unc->type(), true, location))
4778 {
4779 *issued_error = true;
4780 return false;
4781 }
4782 return true;
e440a328 4783}
4784
0c77715b 4785// Return the integral constant value of a unary expression, if it has one.
e440a328 4786
4787bool
0c77715b 4788Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 4789{
0c77715b 4790 Numeric_constant unc;
4791 if (!this->expr_->numeric_constant_value(&unc))
4792 return false;
af7a5274 4793 bool issued_error;
0c77715b 4794 return Unary_expression::eval_constant(this->op_, &unc, this->location(),
af7a5274 4795 nc, &issued_error);
e440a328 4796}
4797
ac7ef97d 4798// Return the boolean constant value of a unary expression, if it has one.
4799
4800bool
4801Unary_expression::do_boolean_constant_value(bool* val) const
4802{
4803 if (this->op_ == OPERATOR_NOT
4804 && this->expr_->boolean_constant_value(val))
4805 {
4806 *val = !*val;
4807 return true;
4808 }
4809 return false;
4810}
4811
e440a328 4812// Return the type of a unary expression.
4813
4814Type*
4815Unary_expression::do_type()
4816{
4817 switch (this->op_)
4818 {
4819 case OPERATOR_PLUS:
4820 case OPERATOR_MINUS:
4821 case OPERATOR_NOT:
4822 case OPERATOR_XOR:
4823 return this->expr_->type();
4824
4825 case OPERATOR_AND:
4826 return Type::make_pointer_type(this->expr_->type());
4827
4828 case OPERATOR_MULT:
4829 {
4830 Type* subtype = this->expr_->type();
4831 Type* points_to = subtype->points_to();
4832 if (points_to == NULL)
4833 return Type::make_error_type();
4834 return points_to;
4835 }
4836
4837 default:
c3e6f413 4838 go_unreachable();
e440a328 4839 }
4840}
4841
4842// Determine abstract types for a unary expression.
4843
4844void
4845Unary_expression::do_determine_type(const Type_context* context)
4846{
4847 switch (this->op_)
4848 {
4849 case OPERATOR_PLUS:
4850 case OPERATOR_MINUS:
4851 case OPERATOR_NOT:
4852 case OPERATOR_XOR:
4853 this->expr_->determine_type(context);
4854 break;
4855
4856 case OPERATOR_AND:
4857 // Taking the address of something.
4858 {
4859 Type* subtype = (context->type == NULL
4860 ? NULL
4861 : context->type->points_to());
4862 Type_context subcontext(subtype, false);
4863 this->expr_->determine_type(&subcontext);
4864 }
4865 break;
4866
4867 case OPERATOR_MULT:
4868 // Indirecting through a pointer.
4869 {
4870 Type* subtype = (context->type == NULL
4871 ? NULL
4872 : Type::make_pointer_type(context->type));
4873 Type_context subcontext(subtype, false);
4874 this->expr_->determine_type(&subcontext);
4875 }
4876 break;
4877
4878 default:
c3e6f413 4879 go_unreachable();
e440a328 4880 }
4881}
4882
4883// Check types for a unary expression.
4884
4885void
4886Unary_expression::do_check_types(Gogo*)
4887{
9fe897ef 4888 Type* type = this->expr_->type();
5c13bd80 4889 if (type->is_error())
9fe897ef 4890 {
4891 this->set_is_error();
4892 return;
4893 }
4894
e440a328 4895 switch (this->op_)
4896 {
4897 case OPERATOR_PLUS:
4898 case OPERATOR_MINUS:
9fe897ef 4899 if (type->integer_type() == NULL
4900 && type->float_type() == NULL
4901 && type->complex_type() == NULL)
4902 this->report_error(_("expected numeric type"));
e440a328 4903 break;
4904
4905 case OPERATOR_NOT:
59a401fe 4906 if (!type->is_boolean_type())
4907 this->report_error(_("expected boolean type"));
4908 break;
4909
e440a328 4910 case OPERATOR_XOR:
b3b1474e 4911 if (type->integer_type() == NULL)
4912 this->report_error(_("expected integer"));
e440a328 4913 break;
4914
4915 case OPERATOR_AND:
4916 if (!this->expr_->is_addressable())
09ea332d 4917 {
4918 if (!this->create_temp_)
f4dea966 4919 {
631d5788 4920 go_error_at(this->location(), "invalid operand for unary %<&%>");
f4dea966 4921 this->set_is_error();
4922 }
09ea332d 4923 }
e440a328 4924 else
da244e59 4925 this->expr_->issue_nil_check();
e440a328 4926 break;
4927
4928 case OPERATOR_MULT:
4929 // Indirecting through a pointer.
9fe897ef 4930 if (type->points_to() == NULL)
4931 this->report_error(_("expected pointer"));
7661d702 4932 if (type->points_to()->is_error())
4933 this->set_is_error();
e440a328 4934 break;
4935
4936 default:
c3e6f413 4937 go_unreachable();
e440a328 4938 }
4939}
4940
ea664253 4941// Get the backend representation for a unary expression.
e440a328 4942
ea664253 4943Bexpression*
4944Unary_expression::do_get_backend(Translate_context* context)
e440a328 4945{
1b1f2abf 4946 Gogo* gogo = context->gogo();
e9d3367e 4947 Location loc = this->location();
4948
4949 // Taking the address of a set-and-use-temporary expression requires
4950 // setting the temporary and then taking the address.
4951 if (this->op_ == OPERATOR_AND)
4952 {
4953 Set_and_use_temporary_expression* sut =
4954 this->expr_->set_and_use_temporary_expression();
4955 if (sut != NULL)
4956 {
4957 Temporary_statement* temp = sut->temporary();
4958 Bvariable* bvar = temp->get_backend_variable(context);
d4e6573e 4959 Bexpression* bvar_expr =
7af8e400 4960 gogo->backend()->var_expression(bvar, loc);
ea664253 4961 Bexpression* bval = sut->expression()->get_backend(context);
f9ca30f9 4962
0ab48656 4963 Named_object* fn = context->function();
4964 go_assert(fn != NULL);
4965 Bfunction* bfn =
4966 fn->func_value()->get_or_make_decl(gogo, fn);
f9ca30f9 4967 Bstatement* bassign =
0ab48656 4968 gogo->backend()->assignment_statement(bfn, bvar_expr, bval, loc);
f9ca30f9 4969 Bexpression* bvar_addr =
4970 gogo->backend()->address_expression(bvar_expr, loc);
ea664253 4971 return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
e9d3367e 4972 }
4973 }
4974
f9ca30f9 4975 Bexpression* ret;
ea664253 4976 Bexpression* bexpr = this->expr_->get_backend(context);
f9ca30f9 4977 Btype* btype = this->expr_->type()->get_backend(gogo);
e440a328 4978 switch (this->op_)
4979 {
4980 case OPERATOR_PLUS:
f9ca30f9 4981 ret = bexpr;
4982 break;
e440a328 4983
4984 case OPERATOR_MINUS:
f9ca30f9 4985 ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
4986 ret = gogo->backend()->convert_expression(btype, ret, loc);
4987 break;
e440a328 4988
4989 case OPERATOR_NOT:
e440a328 4990 case OPERATOR_XOR:
f9ca30f9 4991 ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
4992 break;
e440a328 4993
4994 case OPERATOR_AND:
09ea332d 4995 if (!this->create_temp_)
4996 {
4997 // We should not see a non-constant constructor here; cases
4998 // where we would see one should have been moved onto the
4999 // heap at parse time. Taking the address of a nonconstant
5000 // constructor will not do what the programmer expects.
f9ca30f9 5001
5002 go_assert(!this->expr_->is_composite_literal()
3ae06f68 5003 || this->expr_->is_static_initializer());
24060bf9 5004 if (this->expr_->classification() == EXPRESSION_UNARY)
5005 {
5006 Unary_expression* ue =
5007 static_cast<Unary_expression*>(this->expr_);
5008 go_assert(ue->op() != OPERATOR_AND);
5009 }
09ea332d 5010 }
e440a328 5011
f23d7786 5012 if (this->is_gc_root_ || this->is_slice_init_)
76f85fd6 5013 {
19272321 5014 std::string var_name;
f23d7786 5015 bool copy_to_heap = false;
5016 if (this->is_gc_root_)
5017 {
5018 // Build a decl for a GC root variable. GC roots are mutable, so
5019 // they cannot be represented as an immutable_struct in the
5020 // backend.
19272321 5021 var_name = gogo->gc_root_name();
f23d7786 5022 }
5023 else
5024 {
5025 // Build a decl for a slice value initializer. An immutable slice
5026 // value initializer may have to be copied to the heap if it
5027 // contains pointers in a non-constant context.
19272321 5028 var_name = gogo->initializer_name();
f23d7786 5029
5030 Array_type* at = this->expr_->type()->array_type();
5031 go_assert(at != NULL);
5032
5033 // If we are not copying the value to the heap, we will only
5034 // initialize the value once, so we can use this directly
5035 // rather than copying it. In that case we can't make it
5036 // read-only, because the program is permitted to change it.
ee200713 5037 copy_to_heap = (context->function() != NULL
5038 || context->is_const());
f23d7786 5039 }
19272321 5040 std::string asm_name(go_selectively_encode_id(var_name));
f23d7786 5041 Bvariable* implicit =
19272321 5042 gogo->backend()->implicit_variable(var_name, asm_name,
438b4bec 5043 btype, true, copy_to_heap,
5044 false, 0);
19272321 5045 gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
aa5ae575 5046 true, copy_to_heap, false,
5047 bexpr);
7af8e400 5048 bexpr = gogo->backend()->var_expression(implicit, loc);
1b4fb1e0 5049
5050 // If we are not copying a slice initializer to the heap,
5051 // then it can be changed by the program, so if it can
5052 // contain pointers we must register it as a GC root.
5053 if (this->is_slice_init_
5054 && !copy_to_heap
5055 && this->expr_->type()->has_pointer())
5056 {
5057 Bexpression* root =
7af8e400 5058 gogo->backend()->var_expression(implicit, loc);
1b4fb1e0 5059 root = gogo->backend()->address_expression(root, loc);
5060 Type* type = Type::make_pointer_type(this->expr_->type());
5061 gogo->add_gc_root(Expression::make_backend(root, type, loc));
5062 }
76f85fd6 5063 }
5064 else if ((this->expr_->is_composite_literal()
3ae06f68 5065 || this->expr_->string_expression() != NULL)
5066 && this->expr_->is_static_initializer())
f9ca30f9 5067 {
19272321 5068 std::string var_name(gogo->initializer_name());
5069 std::string asm_name(go_selectively_encode_id(var_name));
f9ca30f9 5070 Bvariable* decl =
19272321 5071 gogo->backend()->immutable_struct(var_name, asm_name,
438b4bec 5072 true, false, btype, loc);
19272321 5073 gogo->backend()->immutable_struct_set_init(decl, var_name, true,
5074 false, btype, loc, bexpr);
7af8e400 5075 bexpr = gogo->backend()->var_expression(decl, loc);
f9ca30f9 5076 }
e47edcf7 5077 else if (this->expr_->is_constant())
5078 {
5079 std::string var_name(gogo->initializer_name());
5080 std::string asm_name(go_selectively_encode_id(var_name));
5081 Bvariable* decl =
5082 gogo->backend()->implicit_variable(var_name, asm_name, btype,
5083 true, true, false, 0);
5084 gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
5085 true, true, false,
5086 bexpr);
5087 bexpr = gogo->backend()->var_expression(decl, loc);
5088 }
09ea332d 5089
f9ca30f9 5090 go_assert(!this->create_temp_ || this->expr_->is_variable());
5091 ret = gogo->backend()->address_expression(bexpr, loc);
5092 break;
e440a328 5093
5094 case OPERATOR_MULT:
5095 {
f9ca30f9 5096 go_assert(this->expr_->type()->points_to() != NULL);
e440a328 5097
f614ea8b 5098 bool known_valid = false;
f9ca30f9 5099 Type* ptype = this->expr_->type()->points_to();
5100 Btype* pbtype = ptype->get_backend(gogo);
f614ea8b 5101 switch (this->requires_nil_check(gogo))
5102 {
5103 case NIL_CHECK_NOT_NEEDED:
5104 break;
5105 case NIL_CHECK_ERROR_ENCOUNTERED:
2a305b85 5106 {
5107 go_assert(saw_errors());
5108 return gogo->backend()->error_expression();
5109 }
f614ea8b 5110 case NIL_CHECK_NEEDED:
5111 {
f9ca30f9 5112 go_assert(this->expr_->is_variable());
2dd89704 5113
5114 // If we're nil-checking the result of a set-and-use-temporary
5115 // expression, then pick out the target temp and use that
5116 // for the final result of the conditional.
5117 Bexpression* tbexpr = bexpr;
5118 Bexpression* ubexpr = bexpr;
5119 Set_and_use_temporary_expression* sut =
5120 this->expr_->set_and_use_temporary_expression();
5121 if (sut != NULL) {
5122 Temporary_statement* temp = sut->temporary();
5123 Bvariable* bvar = temp->get_backend_variable(context);
5124 ubexpr = gogo->backend()->var_expression(bvar, loc);
5125 }
ea664253 5126 Bexpression* nil =
f614ea8b 5127 Expression::make_nil(loc)->get_backend(context);
f9ca30f9 5128 Bexpression* compare =
2dd89704 5129 gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr,
f9ca30f9 5130 nil, loc);
f9ca30f9 5131 Bexpression* crash =
f614ea8b 5132 gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
5133 loc)->get_backend(context);
93715b75 5134 Bfunction* bfn = context->function()->func_value()->get_decl();
5135 bexpr = gogo->backend()->conditional_expression(bfn, btype,
5136 compare,
2dd89704 5137 crash, ubexpr,
f9ca30f9 5138 loc);
f614ea8b 5139 known_valid = true;
5140 break;
5141 }
5142 case NIL_CHECK_DEFAULT:
5143 go_unreachable();
5144 }
5145 ret = gogo->backend()->indirect_expression(pbtype, bexpr,
5146 known_valid, loc);
e440a328 5147 }
f9ca30f9 5148 break;
e440a328 5149
5150 default:
c3e6f413 5151 go_unreachable();
e440a328 5152 }
f9ca30f9 5153
ea664253 5154 return ret;
e440a328 5155}
5156
5157// Export a unary expression.
5158
5159void
548be246 5160Unary_expression::do_export(Export_function_body* efb) const
e440a328 5161{
5162 switch (this->op_)
5163 {
5164 case OPERATOR_PLUS:
204d4af4 5165 efb->write_c_string("+");
e440a328 5166 break;
5167 case OPERATOR_MINUS:
204d4af4 5168 efb->write_c_string("-");
e440a328 5169 break;
5170 case OPERATOR_NOT:
204d4af4 5171 efb->write_c_string("!");
e440a328 5172 break;
5173 case OPERATOR_XOR:
204d4af4 5174 efb->write_c_string("^");
e440a328 5175 break;
5176 case OPERATOR_AND:
5f6f5357 5177 efb->write_c_string("&");
5178 break;
e440a328 5179 case OPERATOR_MULT:
5f6f5357 5180 efb->write_c_string("*");
5181 break;
e440a328 5182 default:
c3e6f413 5183 go_unreachable();
e440a328 5184 }
548be246 5185 this->expr_->export_expression(efb);
e440a328 5186}
5187
5188// Import a unary expression.
5189
5190Expression*
bc8e2ef4 5191Unary_expression::do_import(Import_expression* imp, Location loc)
e440a328 5192{
5193 Operator op;
5194 switch (imp->get_char())
5195 {
5196 case '+':
5197 op = OPERATOR_PLUS;
5198 break;
5199 case '-':
5200 op = OPERATOR_MINUS;
5201 break;
5202 case '!':
5203 op = OPERATOR_NOT;
5204 break;
5205 case '^':
5206 op = OPERATOR_XOR;
5207 break;
5f6f5357 5208 case '&':
5209 op = OPERATOR_AND;
5210 break;
5211 case '*':
5212 op = OPERATOR_MULT;
5213 break;
e440a328 5214 default:
c3e6f413 5215 go_unreachable();
e440a328 5216 }
204d4af4 5217 if (imp->version() < EXPORT_FORMAT_V3)
5218 imp->require_c_string(" ");
9b92780c 5219 Expression* expr = Expression::import_expression(imp, loc);
5220 return Expression::make_unary(op, expr, loc);
e440a328 5221}
5222
d751bb78 5223// Dump ast representation of an unary expression.
5224
5225void
5226Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
5227{
5228 ast_dump_context->dump_operator(this->op_);
5229 ast_dump_context->ostream() << "(";
5230 ast_dump_context->dump_expression(this->expr_);
5231 ast_dump_context->ostream() << ") ";
5232}
5233
e440a328 5234// Make a unary expression.
5235
5236Expression*
b13c66cd 5237Expression::make_unary(Operator op, Expression* expr, Location location)
e440a328 5238{
5239 return new Unary_expression(op, expr, location);
5240}
5241
f614ea8b 5242Expression*
5243Expression::make_dereference(Expression* ptr,
5244 Nil_check_classification docheck,
5245 Location location)
5246{
5247 Expression* deref = Expression::make_unary(OPERATOR_MULT, ptr, location);
5248 if (docheck == NIL_CHECK_NEEDED)
5249 deref->unary_expression()->set_requires_nil_check(true);
5250 else if (docheck == NIL_CHECK_NOT_NEEDED)
5251 deref->unary_expression()->set_requires_nil_check(false);
5252 return deref;
5253}
5254
e440a328 5255// If this is an indirection through a pointer, return the expression
5256// being pointed through. Otherwise return this.
5257
5258Expression*
5259Expression::deref()
5260{
5261 if (this->classification_ == EXPRESSION_UNARY)
5262 {
5263 Unary_expression* ue = static_cast<Unary_expression*>(this);
5264 if (ue->op() == OPERATOR_MULT)
5265 return ue->operand();
5266 }
5267 return this;
5268}
5269
5270// Class Binary_expression.
5271
5272// Traversal.
5273
5274int
5275Binary_expression::do_traverse(Traverse* traverse)
5276{
5277 int t = Expression::traverse(&this->left_, traverse);
5278 if (t == TRAVERSE_EXIT)
5279 return TRAVERSE_EXIT;
5280 return Expression::traverse(&this->right_, traverse);
5281}
5282
3ae06f68 5283// Return whether this expression may be used as a static initializer.
5284
5285bool
5286Binary_expression::do_is_static_initializer() const
5287{
5288 if (!this->left_->is_static_initializer()
5289 || !this->right_->is_static_initializer())
5290 return false;
5291
5292 // Addresses can be static initializers, but we can't implement
5293 // arbitray binary expressions of them.
5294 Unary_expression* lu = this->left_->unary_expression();
5295 Unary_expression* ru = this->right_->unary_expression();
5296 if (lu != NULL && lu->op() == OPERATOR_AND)
5297 {
5298 if (ru != NULL && ru->op() == OPERATOR_AND)
5299 return this->op_ == OPERATOR_MINUS;
5300 else
5301 return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
5302 }
5303 else if (ru != NULL && ru->op() == OPERATOR_AND)
5304 return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
5305
5306 // Other cases should resolve in the backend.
5307 return true;
5308}
5309
0c77715b 5310// Return the type to use for a binary operation on operands of
5311// LEFT_TYPE and RIGHT_TYPE. These are the types of constants and as
5312// such may be NULL or abstract.
5313
5314bool
5315Binary_expression::operation_type(Operator op, Type* left_type,
5316 Type* right_type, Type** result_type)
5317{
5318 if (left_type != right_type
5319 && !left_type->is_abstract()
5320 && !right_type->is_abstract()
5321 && left_type->base() != right_type->base()
5322 && op != OPERATOR_LSHIFT
5323 && op != OPERATOR_RSHIFT)
5324 {
5325 // May be a type error--let it be diagnosed elsewhere.
5326 return false;
5327 }
5328
5329 if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
5330 {
5331 if (left_type->integer_type() != NULL)
5332 *result_type = left_type;
5333 else
5334 *result_type = Type::make_abstract_integer_type();
5335 }
5336 else if (!left_type->is_abstract() && left_type->named_type() != NULL)
5337 *result_type = left_type;
5338 else if (!right_type->is_abstract() && right_type->named_type() != NULL)
5339 *result_type = right_type;
5340 else if (!left_type->is_abstract())
5341 *result_type = left_type;
5342 else if (!right_type->is_abstract())
5343 *result_type = right_type;
5344 else if (left_type->complex_type() != NULL)
5345 *result_type = left_type;
5346 else if (right_type->complex_type() != NULL)
5347 *result_type = right_type;
5348 else if (left_type->float_type() != NULL)
5349 *result_type = left_type;
5350 else if (right_type->float_type() != NULL)
5351 *result_type = right_type;
5352 else if (left_type->integer_type() != NULL
5353 && left_type->integer_type()->is_rune())
5354 *result_type = left_type;
5355 else if (right_type->integer_type() != NULL
5356 && right_type->integer_type()->is_rune())
5357 *result_type = right_type;
5358 else
5359 *result_type = left_type;
5360
5361 return true;
5362}
5363
5364// Convert an integer comparison code and an operator to a boolean
5365// value.
e440a328 5366
5367bool
0c77715b 5368Binary_expression::cmp_to_bool(Operator op, int cmp)
e440a328 5369{
e440a328 5370 switch (op)
5371 {
5372 case OPERATOR_EQEQ:
0c77715b 5373 return cmp == 0;
5374 break;
e440a328 5375 case OPERATOR_NOTEQ:
0c77715b 5376 return cmp != 0;
5377 break;
e440a328 5378 case OPERATOR_LT:
0c77715b 5379 return cmp < 0;
5380 break;
e440a328 5381 case OPERATOR_LE:
0c77715b 5382 return cmp <= 0;
e440a328 5383 case OPERATOR_GT:
0c77715b 5384 return cmp > 0;
e440a328 5385 case OPERATOR_GE:
0c77715b 5386 return cmp >= 0;
e440a328 5387 default:
c3e6f413 5388 go_unreachable();
e440a328 5389 }
5390}
5391
0c77715b 5392// Compare constants according to OP.
e440a328 5393
5394bool
0c77715b 5395Binary_expression::compare_constant(Operator op, Numeric_constant* left_nc,
5396 Numeric_constant* right_nc,
5397 Location location, bool* result)
e440a328 5398{
0c77715b 5399 Type* left_type = left_nc->type();
5400 Type* right_type = right_nc->type();
5401
5402 Type* type;
5403 if (!Binary_expression::operation_type(op, left_type, right_type, &type))
5404 return false;
5405
5406 // When comparing an untyped operand to a typed operand, we are
5407 // effectively coercing the untyped operand to the other operand's
5408 // type, so make sure that is valid.
5409 if (!left_nc->set_type(type, true, location)
5410 || !right_nc->set_type(type, true, location))
5411 return false;
5412
5413 bool ret;
5414 int cmp;
5415 if (type->complex_type() != NULL)
5416 {
5417 if (op != OPERATOR_EQEQ && op != OPERATOR_NOTEQ)
5418 return false;
5419 ret = Binary_expression::compare_complex(left_nc, right_nc, &cmp);
5420 }
5421 else if (type->float_type() != NULL)
5422 ret = Binary_expression::compare_float(left_nc, right_nc, &cmp);
e440a328 5423 else
0c77715b 5424 ret = Binary_expression::compare_integer(left_nc, right_nc, &cmp);
5425
5426 if (ret)
5427 *result = Binary_expression::cmp_to_bool(op, cmp);
5428
5429 return ret;
5430}
5431
5432// Compare integer constants.
5433
5434bool
5435Binary_expression::compare_integer(const Numeric_constant* left_nc,
5436 const Numeric_constant* right_nc,
5437 int* cmp)
5438{
5439 mpz_t left_val;
5440 if (!left_nc->to_int(&left_val))
5441 return false;
5442 mpz_t right_val;
5443 if (!right_nc->to_int(&right_val))
e440a328 5444 {
0c77715b 5445 mpz_clear(left_val);
5446 return false;
e440a328 5447 }
0c77715b 5448
5449 *cmp = mpz_cmp(left_val, right_val);
5450
5451 mpz_clear(left_val);
5452 mpz_clear(right_val);
5453
5454 return true;
5455}
5456
5457// Compare floating point constants.
5458
5459bool
5460Binary_expression::compare_float(const Numeric_constant* left_nc,
5461 const Numeric_constant* right_nc,
5462 int* cmp)
5463{
5464 mpfr_t left_val;
5465 if (!left_nc->to_float(&left_val))
5466 return false;
5467 mpfr_t right_val;
5468 if (!right_nc->to_float(&right_val))
e440a328 5469 {
0c77715b 5470 mpfr_clear(left_val);
5471 return false;
5472 }
5473
5474 // We already coerced both operands to the same type. If that type
5475 // is not an abstract type, we need to round the values accordingly.
5476 Type* type = left_nc->type();
5477 if (!type->is_abstract() && type->float_type() != NULL)
5478 {
5479 int bits = type->float_type()->bits();
5480 mpfr_prec_round(left_val, bits, GMP_RNDN);
5481 mpfr_prec_round(right_val, bits, GMP_RNDN);
e440a328 5482 }
0c77715b 5483
5484 *cmp = mpfr_cmp(left_val, right_val);
5485
5486 mpfr_clear(left_val);
5487 mpfr_clear(right_val);
5488
5489 return true;
e440a328 5490}
5491
0c77715b 5492// Compare complex constants. Complex numbers may only be compared
5493// for equality.
e440a328 5494
5495bool
0c77715b 5496Binary_expression::compare_complex(const Numeric_constant* left_nc,
5497 const Numeric_constant* right_nc,
5498 int* cmp)
e440a328 5499{
fcbea5e4 5500 mpc_t left_val;
5501 if (!left_nc->to_complex(&left_val))
0c77715b 5502 return false;
fcbea5e4 5503 mpc_t right_val;
5504 if (!right_nc->to_complex(&right_val))
e440a328 5505 {
fcbea5e4 5506 mpc_clear(left_val);
0c77715b 5507 return false;
e440a328 5508 }
0c77715b 5509
5510 // We already coerced both operands to the same type. If that type
5511 // is not an abstract type, we need to round the values accordingly.
5512 Type* type = left_nc->type();
5513 if (!type->is_abstract() && type->complex_type() != NULL)
e440a328 5514 {
0c77715b 5515 int bits = type->complex_type()->bits();
fcbea5e4 5516 mpfr_prec_round(mpc_realref(left_val), bits / 2, GMP_RNDN);
5517 mpfr_prec_round(mpc_imagref(left_val), bits / 2, GMP_RNDN);
5518 mpfr_prec_round(mpc_realref(right_val), bits / 2, GMP_RNDN);
5519 mpfr_prec_round(mpc_imagref(right_val), bits / 2, GMP_RNDN);
e440a328 5520 }
0c77715b 5521
fcbea5e4 5522 *cmp = mpc_cmp(left_val, right_val) != 0;
0c77715b 5523
fcbea5e4 5524 mpc_clear(left_val);
5525 mpc_clear(right_val);
0c77715b 5526
5527 return true;
e440a328 5528}
5529
0c77715b 5530// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. Return
5531// true if this could be done, false if not. Issue errors at LOCATION
af7a5274 5532// as appropriate, and sets *ISSUED_ERROR if it did.
e440a328 5533
5534bool
0c77715b 5535Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
5536 Numeric_constant* right_nc,
af7a5274 5537 Location location, Numeric_constant* nc,
5538 bool* issued_error)
e440a328 5539{
af7a5274 5540 *issued_error = false;
e440a328 5541 switch (op)
5542 {
5543 case OPERATOR_OROR:
5544 case OPERATOR_ANDAND:
5545 case OPERATOR_EQEQ:
5546 case OPERATOR_NOTEQ:
5547 case OPERATOR_LT:
5548 case OPERATOR_LE:
5549 case OPERATOR_GT:
5550 case OPERATOR_GE:
9767e2d3 5551 // These return boolean values, not numeric.
5552 return false;
0c77715b 5553 default:
5554 break;
5555 }
5556
5557 Type* left_type = left_nc->type();
5558 Type* right_type = right_nc->type();
5559
5560 Type* type;
5561 if (!Binary_expression::operation_type(op, left_type, right_type, &type))
5562 return false;
5563
5564 bool is_shift = op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT;
5565
5566 // When combining an untyped operand with a typed operand, we are
5567 // effectively coercing the untyped operand to the other operand's
5568 // type, so make sure that is valid.
5569 if (!left_nc->set_type(type, true, location))
5570 return false;
5571 if (!is_shift && !right_nc->set_type(type, true, location))
5572 return false;
85334a21 5573 if (is_shift
5574 && ((left_type->integer_type() == NULL
5575 && !left_type->is_abstract())
5576 || (right_type->integer_type() == NULL
5577 && !right_type->is_abstract())))
5578 return false;
0c77715b 5579
5580 bool r;
5581 if (type->complex_type() != NULL)
5582 r = Binary_expression::eval_complex(op, left_nc, right_nc, location, nc);
5583 else if (type->float_type() != NULL)
5584 r = Binary_expression::eval_float(op, left_nc, right_nc, location, nc);
5585 else
5586 r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc);
5587
5588 if (r)
af7a5274 5589 {
5590 r = nc->set_type(type, true, location);
5591 if (!r)
5592 *issued_error = true;
5593 }
0c77715b 5594
5595 return r;
5596}
5597
5598// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
5599// integer operations. Return true if this could be done, false if
5600// not.
5601
5602bool
5603Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
5604 const Numeric_constant* right_nc,
5605 Location location, Numeric_constant* nc)
5606{
5607 mpz_t left_val;
5608 if (!left_nc->to_int(&left_val))
5609 return false;
5610 mpz_t right_val;
5611 if (!right_nc->to_int(&right_val))
5612 {
5613 mpz_clear(left_val);
e440a328 5614 return false;
0c77715b 5615 }
5616
5617 mpz_t val;
5618 mpz_init(val);
5619
5620 switch (op)
5621 {
e440a328 5622 case OPERATOR_PLUS:
5623 mpz_add(val, left_val, right_val);
2c809f8f 5624 if (mpz_sizeinbase(val, 2) > 0x100000)
5625 {
631d5788 5626 go_error_at(location, "constant addition overflow");
71a45216 5627 nc->set_invalid();
2c809f8f 5628 mpz_set_ui(val, 1);
5629 }
e440a328 5630 break;
5631 case OPERATOR_MINUS:
5632 mpz_sub(val, left_val, right_val);
2c809f8f 5633 if (mpz_sizeinbase(val, 2) > 0x100000)
5634 {
631d5788 5635 go_error_at(location, "constant subtraction overflow");
71a45216 5636 nc->set_invalid();
2c809f8f 5637 mpz_set_ui(val, 1);
5638 }
e440a328 5639 break;
5640 case OPERATOR_OR:
5641 mpz_ior(val, left_val, right_val);
5642 break;
5643 case OPERATOR_XOR:
5644 mpz_xor(val, left_val, right_val);
5645 break;
5646 case OPERATOR_MULT:
5647 mpz_mul(val, left_val, right_val);
2c809f8f 5648 if (mpz_sizeinbase(val, 2) > 0x100000)
5649 {
631d5788 5650 go_error_at(location, "constant multiplication overflow");
71a45216 5651 nc->set_invalid();
2c809f8f 5652 mpz_set_ui(val, 1);
5653 }
e440a328 5654 break;
5655 case OPERATOR_DIV:
5656 if (mpz_sgn(right_val) != 0)
5657 mpz_tdiv_q(val, left_val, right_val);
5658 else
5659 {
631d5788 5660 go_error_at(location, "division by zero");
71a45216 5661 nc->set_invalid();
e440a328 5662 mpz_set_ui(val, 0);
e440a328 5663 }
5664 break;
5665 case OPERATOR_MOD:
5666 if (mpz_sgn(right_val) != 0)
5667 mpz_tdiv_r(val, left_val, right_val);
5668 else
5669 {
631d5788 5670 go_error_at(location, "division by zero");
71a45216 5671 nc->set_invalid();
e440a328 5672 mpz_set_ui(val, 0);
e440a328 5673 }
5674 break;
5675 case OPERATOR_LSHIFT:
5676 {
5677 unsigned long shift = mpz_get_ui(right_val);
0c77715b 5678 if (mpz_cmp_ui(right_val, shift) == 0 && shift <= 0x100000)
5679 mpz_mul_2exp(val, left_val, shift);
5680 else
e440a328 5681 {
631d5788 5682 go_error_at(location, "shift count overflow");
71a45216 5683 nc->set_invalid();
2c809f8f 5684 mpz_set_ui(val, 1);
e440a328 5685 }
e440a328 5686 break;
5687 }
5688 break;
5689 case OPERATOR_RSHIFT:
5690 {
5691 unsigned long shift = mpz_get_ui(right_val);
5692 if (mpz_cmp_ui(right_val, shift) != 0)
5693 {
631d5788 5694 go_error_at(location, "shift count overflow");
71a45216 5695 nc->set_invalid();
2c809f8f 5696 mpz_set_ui(val, 1);
e440a328 5697 }
e440a328 5698 else
0c77715b 5699 {
5700 if (mpz_cmp_ui(left_val, 0) >= 0)
5701 mpz_tdiv_q_2exp(val, left_val, shift);
5702 else
5703 mpz_fdiv_q_2exp(val, left_val, shift);
5704 }
e440a328 5705 break;
5706 }
5707 break;
5708 case OPERATOR_AND:
5709 mpz_and(val, left_val, right_val);
5710 break;
5711 case OPERATOR_BITCLEAR:
5712 {
5713 mpz_t tval;
5714 mpz_init(tval);
5715 mpz_com(tval, right_val);
5716 mpz_and(val, left_val, tval);
5717 mpz_clear(tval);
5718 }
5719 break;
5720 default:
c3e6f413 5721 go_unreachable();
e440a328 5722 }
5723
0c77715b 5724 mpz_clear(left_val);
5725 mpz_clear(right_val);
e440a328 5726
0c77715b 5727 if (left_nc->is_rune()
5728 || (op != OPERATOR_LSHIFT
5729 && op != OPERATOR_RSHIFT
5730 && right_nc->is_rune()))
5731 nc->set_rune(NULL, val);
5732 else
5733 nc->set_int(NULL, val);
5734
5735 mpz_clear(val);
e440a328 5736
5737 return true;
5738}
5739
0c77715b 5740// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
5741// floating point operations. Return true if this could be done,
5742// false if not.
e440a328 5743
5744bool
0c77715b 5745Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
5746 const Numeric_constant* right_nc,
5747 Location location, Numeric_constant* nc)
e440a328 5748{
0c77715b 5749 mpfr_t left_val;
5750 if (!left_nc->to_float(&left_val))
5751 return false;
5752 mpfr_t right_val;
5753 if (!right_nc->to_float(&right_val))
e440a328 5754 {
0c77715b 5755 mpfr_clear(left_val);
e440a328 5756 return false;
0c77715b 5757 }
5758
5759 mpfr_t val;
5760 mpfr_init(val);
5761
5762 bool ret = true;
5763 switch (op)
5764 {
e440a328 5765 case OPERATOR_PLUS:
5766 mpfr_add(val, left_val, right_val, GMP_RNDN);
5767 break;
5768 case OPERATOR_MINUS:
5769 mpfr_sub(val, left_val, right_val, GMP_RNDN);
5770 break;
5771 case OPERATOR_OR:
5772 case OPERATOR_XOR:
5773 case OPERATOR_AND:
5774 case OPERATOR_BITCLEAR:
0c77715b 5775 case OPERATOR_MOD:
5776 case OPERATOR_LSHIFT:
5777 case OPERATOR_RSHIFT:
5778 mpfr_set_ui(val, 0, GMP_RNDN);
5779 ret = false;
5780 break;
e440a328 5781 case OPERATOR_MULT:
5782 mpfr_mul(val, left_val, right_val, GMP_RNDN);
5783 break;
5784 case OPERATOR_DIV:
0c77715b 5785 if (!mpfr_zero_p(right_val))
5786 mpfr_div(val, left_val, right_val, GMP_RNDN);
5787 else
5788 {
631d5788 5789 go_error_at(location, "division by zero");
71a45216 5790 nc->set_invalid();
0c77715b 5791 mpfr_set_ui(val, 0, GMP_RNDN);
5792 }
e440a328 5793 break;
e440a328 5794 default:
c3e6f413 5795 go_unreachable();
e440a328 5796 }
5797
0c77715b 5798 mpfr_clear(left_val);
5799 mpfr_clear(right_val);
e440a328 5800
0c77715b 5801 nc->set_float(NULL, val);
5802 mpfr_clear(val);
e440a328 5803
0c77715b 5804 return ret;
e440a328 5805}
5806
0c77715b 5807// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
5808// complex operations. Return true if this could be done, false if
5809// not.
e440a328 5810
5811bool
0c77715b 5812Binary_expression::eval_complex(Operator op, const Numeric_constant* left_nc,
5813 const Numeric_constant* right_nc,
5814 Location location, Numeric_constant* nc)
e440a328 5815{
fcbea5e4 5816 mpc_t left_val;
5817 if (!left_nc->to_complex(&left_val))
0c77715b 5818 return false;
fcbea5e4 5819 mpc_t right_val;
5820 if (!right_nc->to_complex(&right_val))
e440a328 5821 {
fcbea5e4 5822 mpc_clear(left_val);
e440a328 5823 return false;
0c77715b 5824 }
5825
fcbea5e4 5826 mpc_t val;
5827 mpc_init2(val, mpc_precision);
0c77715b 5828
5829 bool ret = true;
5830 switch (op)
5831 {
e440a328 5832 case OPERATOR_PLUS:
fcbea5e4 5833 mpc_add(val, left_val, right_val, MPC_RNDNN);
e440a328 5834 break;
5835 case OPERATOR_MINUS:
fcbea5e4 5836 mpc_sub(val, left_val, right_val, MPC_RNDNN);
e440a328 5837 break;
5838 case OPERATOR_OR:
5839 case OPERATOR_XOR:
5840 case OPERATOR_AND:
5841 case OPERATOR_BITCLEAR:
0c77715b 5842 case OPERATOR_MOD:
5843 case OPERATOR_LSHIFT:
5844 case OPERATOR_RSHIFT:
fcbea5e4 5845 mpc_set_ui(val, 0, MPC_RNDNN);
0c77715b 5846 ret = false;
5847 break;
e440a328 5848 case OPERATOR_MULT:
fcbea5e4 5849 mpc_mul(val, left_val, right_val, MPC_RNDNN);
e440a328 5850 break;
5851 case OPERATOR_DIV:
fcbea5e4 5852 if (mpc_cmp_si(right_val, 0) == 0)
5853 {
631d5788 5854 go_error_at(location, "division by zero");
71a45216 5855 nc->set_invalid();
fcbea5e4 5856 mpc_set_ui(val, 0, MPC_RNDNN);
5857 break;
5858 }
5859 mpc_div(val, left_val, right_val, MPC_RNDNN);
e440a328 5860 break;
e440a328 5861 default:
c3e6f413 5862 go_unreachable();
e440a328 5863 }
5864
fcbea5e4 5865 mpc_clear(left_val);
5866 mpc_clear(right_val);
e440a328 5867
fcbea5e4 5868 nc->set_complex(NULL, val);
5869 mpc_clear(val);
e440a328 5870
0c77715b 5871 return ret;
e440a328 5872}
5873
5874// Lower a binary expression. We have to evaluate constant
5875// expressions now, in order to implement Go's unlimited precision
5876// constants.
5877
5878Expression*
e9d3367e 5879Binary_expression::do_lower(Gogo* gogo, Named_object*,
5880 Statement_inserter* inserter, int)
e440a328 5881{
b13c66cd 5882 Location location = this->location();
e440a328 5883 Operator op = this->op_;
5884 Expression* left = this->left_;
5885 Expression* right = this->right_;
5886
5887 const bool is_comparison = (op == OPERATOR_EQEQ
5888 || op == OPERATOR_NOTEQ
5889 || op == OPERATOR_LT
5890 || op == OPERATOR_LE
5891 || op == OPERATOR_GT
5892 || op == OPERATOR_GE);
5893
0c77715b 5894 // Numeric constant expressions.
e440a328 5895 {
0c77715b 5896 Numeric_constant left_nc;
5897 Numeric_constant right_nc;
5898 if (left->numeric_constant_value(&left_nc)
5899 && right->numeric_constant_value(&right_nc))
e440a328 5900 {
0c77715b 5901 if (is_comparison)
e440a328 5902 {
0c77715b 5903 bool result;
5904 if (!Binary_expression::compare_constant(op, &left_nc,
5905 &right_nc, location,
5906 &result))
5907 return this;
e90c9dfc 5908 return Expression::make_cast(Type::make_boolean_type(),
0c77715b 5909 Expression::make_boolean(result,
5910 location),
5911 location);
e440a328 5912 }
5913 else
5914 {
0c77715b 5915 Numeric_constant nc;
af7a5274 5916 bool issued_error;
0c77715b 5917 if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
af7a5274 5918 location, &nc,
5919 &issued_error))
5920 {
5921 if (issued_error)
5922 return Expression::make_error(location);
71a45216 5923 return this;
af7a5274 5924 }
0c77715b 5925 return nc.expression(location);
e440a328 5926 }
5927 }
e440a328 5928 }
5929
5930 // String constant expressions.
4713b5b9 5931 //
5932 // Avoid constant folding here if the left and right types are incompatible
5933 // (leave the operation intact so that the type checker can complain about it
5934 // later on). If concatenating an abstract string with a named string type,
5935 // result type needs to be of the named type (see issue 31412).
5936 if (left->type()->is_string_type()
5937 && right->type()->is_string_type()
5938 && (left->type()->named_type() == NULL
5939 || right->type()->named_type() == NULL
5940 || left->type()->named_type() == right->type()->named_type()))
e440a328 5941 {
5942 std::string left_string;
5943 std::string right_string;
5944 if (left->string_constant_value(&left_string)
5945 && right->string_constant_value(&right_string))
315fa98d 5946 {
5947 if (op == OPERATOR_PLUS)
4713b5b9 5948 {
5949 Type* result_type = (left->type()->named_type() != NULL
5950 ? left->type()
5951 : right->type());
5952 return Expression::make_string_typed(left_string + right_string,
5953 result_type, location);
5954 }
315fa98d 5955 else if (is_comparison)
5956 {
5957 int cmp = left_string.compare(right_string);
0c77715b 5958 bool r = Binary_expression::cmp_to_bool(op, cmp);
e90c9dfc 5959 return Expression::make_boolean(r, location);
b40dc774 5960 }
5961 }
b40dc774 5962 }
5963
ceeb12d7 5964 // Lower struct, array, and some interface comparisons.
e9d3367e 5965 if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
5966 {
b79832ca 5967 if (left->type()->struct_type() != NULL
5968 && right->type()->struct_type() != NULL)
e9d3367e 5969 return this->lower_struct_comparison(gogo, inserter);
5970 else if (left->type()->array_type() != NULL
b79832ca 5971 && !left->type()->is_slice_type()
5972 && right->type()->array_type() != NULL
5973 && !right->type()->is_slice_type())
e9d3367e 5974 return this->lower_array_comparison(gogo, inserter);
ceeb12d7 5975 else if ((left->type()->interface_type() != NULL
5976 && right->type()->interface_type() == NULL)
5977 || (left->type()->interface_type() == NULL
5978 && right->type()->interface_type() != NULL))
5979 return this->lower_interface_value_comparison(gogo, inserter);
e9d3367e 5980 }
5981
736a16ba 5982 // Lower string concatenation to String_concat_expression, so that
5983 // we can group sequences of string additions.
5984 if (this->left_->type()->is_string_type() && this->op_ == OPERATOR_PLUS)
5985 {
5986 Expression_list* exprs;
5987 String_concat_expression* left_sce =
5988 this->left_->string_concat_expression();
5989 if (left_sce != NULL)
5990 exprs = left_sce->exprs();
5991 else
5992 {
5993 exprs = new Expression_list();
5994 exprs->push_back(this->left_);
5995 }
5996
5997 String_concat_expression* right_sce =
5998 this->right_->string_concat_expression();
5999 if (right_sce != NULL)
6000 exprs->append(right_sce->exprs());
6001 else
6002 exprs->push_back(this->right_);
6003
6004 return Expression::make_string_concat(exprs);
6005 }
6006
e440a328 6007 return this;
6008}
6009
e9d3367e 6010// Lower a struct comparison.
6011
6012Expression*
6013Binary_expression::lower_struct_comparison(Gogo* gogo,
6014 Statement_inserter* inserter)
6015{
6016 Struct_type* st = this->left_->type()->struct_type();
6017 Struct_type* st2 = this->right_->type()->struct_type();
6018 if (st2 == NULL)
6019 return this;
3a522dcc 6020 if (st != st2
6021 && !Type::are_identical(st, st2,
6022 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
6023 NULL))
e9d3367e 6024 return this;
6025 if (!Type::are_compatible_for_comparison(true, this->left_->type(),
6026 this->right_->type(), NULL))
6027 return this;
6028
6029 // See if we can compare using memcmp. As a heuristic, we use
6030 // memcmp rather than field references and comparisons if there are
6031 // more than two fields.
113ef6a5 6032 if (st->compare_is_identity(gogo) && st->total_field_count() > 2)
e9d3367e 6033 return this->lower_compare_to_memcmp(gogo, inserter);
6034
6035 Location loc = this->location();
6036
6037 Expression* left = this->left_;
6038 Temporary_statement* left_temp = NULL;
6039 if (left->var_expression() == NULL
6040 && left->temporary_reference_expression() == NULL)
6041 {
6042 left_temp = Statement::make_temporary(left->type(), NULL, loc);
6043 inserter->insert(left_temp);
6044 left = Expression::make_set_and_use_temporary(left_temp, left, loc);
6045 }
6046
6047 Expression* right = this->right_;
6048 Temporary_statement* right_temp = NULL;
6049 if (right->var_expression() == NULL
6050 && right->temporary_reference_expression() == NULL)
6051 {
6052 right_temp = Statement::make_temporary(right->type(), NULL, loc);
6053 inserter->insert(right_temp);
6054 right = Expression::make_set_and_use_temporary(right_temp, right, loc);
6055 }
6056
6057 Expression* ret = Expression::make_boolean(true, loc);
6058 const Struct_field_list* fields = st->fields();
6059 unsigned int field_index = 0;
6060 for (Struct_field_list::const_iterator pf = fields->begin();
6061 pf != fields->end();
6062 ++pf, ++field_index)
6063 {
f5165c05 6064 if (Gogo::is_sink_name(pf->field_name()))
6065 continue;
6066
e9d3367e 6067 if (field_index > 0)
6068 {
6069 if (left_temp == NULL)
6070 left = left->copy();
6071 else
6072 left = Expression::make_temporary_reference(left_temp, loc);
6073 if (right_temp == NULL)
6074 right = right->copy();
6075 else
6076 right = Expression::make_temporary_reference(right_temp, loc);
6077 }
6078 Expression* f1 = Expression::make_field_reference(left, field_index,
6079 loc);
6080 Expression* f2 = Expression::make_field_reference(right, field_index,
6081 loc);
6082 Expression* cond = Expression::make_binary(OPERATOR_EQEQ, f1, f2, loc);
6083 ret = Expression::make_binary(OPERATOR_ANDAND, ret, cond, loc);
6084 }
6085
6086 if (this->op_ == OPERATOR_NOTEQ)
6087 ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
6088
6089 return ret;
6090}
6091
6092// Lower an array comparison.
6093
6094Expression*
6095Binary_expression::lower_array_comparison(Gogo* gogo,
6096 Statement_inserter* inserter)
6097{
6098 Array_type* at = this->left_->type()->array_type();
6099 Array_type* at2 = this->right_->type()->array_type();
6100 if (at2 == NULL)
6101 return this;
3a522dcc 6102 if (at != at2
6103 && !Type::are_identical(at, at2,
6104 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
6105 NULL))
e9d3367e 6106 return this;
6107 if (!Type::are_compatible_for_comparison(true, this->left_->type(),
6108 this->right_->type(), NULL))
6109 return this;
6110
6111 // Call memcmp directly if possible. This may let the middle-end
6112 // optimize the call.
113ef6a5 6113 if (at->compare_is_identity(gogo))
e9d3367e 6114 return this->lower_compare_to_memcmp(gogo, inserter);
6115
6116 // Call the array comparison function.
6117 Named_object* hash_fn;
6118 Named_object* equal_fn;
6119 at->type_functions(gogo, this->left_->type()->named_type(), NULL, NULL,
6120 &hash_fn, &equal_fn);
6121
6122 Location loc = this->location();
6123
6124 Expression* func = Expression::make_func_reference(equal_fn, NULL, loc);
6125
6126 Expression_list* args = new Expression_list();
6127 args->push_back(this->operand_address(inserter, this->left_));
6128 args->push_back(this->operand_address(inserter, this->right_));
e9d3367e 6129
6130 Expression* ret = Expression::make_call(func, args, false, loc);
6131
6132 if (this->op_ == OPERATOR_NOTEQ)
6133 ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
6134
6135 return ret;
6136}
6137
ceeb12d7 6138// Lower an interface to value comparison.
6139
6140Expression*
6141Binary_expression::lower_interface_value_comparison(Gogo*,
6142 Statement_inserter* inserter)
6143{
6144 Type* left_type = this->left_->type();
6145 Type* right_type = this->right_->type();
6146 Interface_type* ift;
6147 if (left_type->interface_type() != NULL)
6148 {
6149 ift = left_type->interface_type();
6150 if (!ift->implements_interface(right_type, NULL))
6151 return this;
6152 }
6153 else
6154 {
6155 ift = right_type->interface_type();
6156 if (!ift->implements_interface(left_type, NULL))
6157 return this;
6158 }
6159 if (!Type::are_compatible_for_comparison(true, left_type, right_type, NULL))
6160 return this;
6161
6162 Location loc = this->location();
6163
6164 if (left_type->interface_type() == NULL
6165 && left_type->points_to() == NULL
6166 && !this->left_->is_addressable())
6167 {
6168 Temporary_statement* temp =
6169 Statement::make_temporary(left_type, NULL, loc);
6170 inserter->insert(temp);
6171 this->left_ =
6172 Expression::make_set_and_use_temporary(temp, this->left_, loc);
6173 }
6174
6175 if (right_type->interface_type() == NULL
6176 && right_type->points_to() == NULL
6177 && !this->right_->is_addressable())
6178 {
6179 Temporary_statement* temp =
6180 Statement::make_temporary(right_type, NULL, loc);
6181 inserter->insert(temp);
6182 this->right_ =
6183 Expression::make_set_and_use_temporary(temp, this->right_, loc);
6184 }
6185
6186 return this;
6187}
6188
e9d3367e 6189// Lower a struct or array comparison to a call to memcmp.
6190
6191Expression*
6192Binary_expression::lower_compare_to_memcmp(Gogo*, Statement_inserter* inserter)
6193{
6194 Location loc = this->location();
6195
6196 Expression* a1 = this->operand_address(inserter, this->left_);
6197 Expression* a2 = this->operand_address(inserter, this->right_);
6198 Expression* len = Expression::make_type_info(this->left_->type(),
6199 TYPE_INFO_SIZE);
6200
6201 Expression* call = Runtime::make_call(Runtime::MEMCMP, loc, 3, a1, a2, len);
dbebbff8 6202 Type* int32_type = Type::lookup_integer_type("int32");
6203 Expression* zero = Expression::make_integer_ul(0, int32_type, loc);
e9d3367e 6204 return Expression::make_binary(this->op_, call, zero, loc);
6205}
6206
a32698ee 6207Expression*
5c3f3470 6208Binary_expression::do_flatten(Gogo* gogo, Named_object*,
a32698ee 6209 Statement_inserter* inserter)
6210{
6211 Location loc = this->location();
5bf8be8b 6212 if (this->left_->type()->is_error_type()
6213 || this->right_->type()->is_error_type()
6214 || this->left_->is_error_expression()
6215 || this->right_->is_error_expression())
6216 {
6217 go_assert(saw_errors());
6218 return Expression::make_error(loc);
6219 }
6220
a32698ee 6221 Temporary_statement* temp;
a32698ee 6222
6223 Type* left_type = this->left_->type();
6224 bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
6225 || this->op_ == OPERATOR_RSHIFT);
6226 bool is_idiv_op = ((this->op_ == OPERATOR_DIV &&
6227 left_type->integer_type() != NULL)
6228 || this->op_ == OPERATOR_MOD);
aad830e6 6229 bool is_string_op = (left_type->is_string_type()
6230 && this->right_->type()->is_string_type());
6231
6232 if (is_string_op)
6233 {
6234 // Mark string([]byte) operands to reuse the backing store.
6235 // String comparison does not keep the reference, so it is safe.
6236 Type_conversion_expression* lce =
6237 this->left_->conversion_expression();
6238 if (lce != NULL && lce->expr()->type()->is_slice_type())
6239 lce->set_no_copy(true);
6240 Type_conversion_expression* rce =
6241 this->right_->conversion_expression();
6242 if (rce != NULL && rce->expr()->type()->is_slice_type())
6243 rce->set_no_copy(true);
6244 }
a32698ee 6245
a32698ee 6246 if (is_shift_op
5c3f3470 6247 || (is_idiv_op
aad830e6 6248 && (gogo->check_divide_by_zero() || gogo->check_divide_overflow()))
6249 || is_string_op)
a32698ee 6250 {
545ab43b 6251 if (!this->left_->is_variable() && !this->left_->is_constant())
a32698ee 6252 {
6253 temp = Statement::make_temporary(NULL, this->left_, loc);
6254 inserter->insert(temp);
6255 this->left_ = Expression::make_temporary_reference(temp, loc);
6256 }
545ab43b 6257 if (!this->right_->is_variable() && !this->right_->is_constant())
a32698ee 6258 {
6259 temp =
6260 Statement::make_temporary(NULL, this->right_, loc);
6261 this->right_ = Expression::make_temporary_reference(temp, loc);
6262 inserter->insert(temp);
6263 }
6264 }
6265 return this;
6266}
6267
6268
e9d3367e 6269// Return the address of EXPR, cast to unsafe.Pointer.
6270
6271Expression*
6272Binary_expression::operand_address(Statement_inserter* inserter,
6273 Expression* expr)
6274{
6275 Location loc = this->location();
6276
6277 if (!expr->is_addressable())
6278 {
6279 Temporary_statement* temp = Statement::make_temporary(expr->type(), NULL,
6280 loc);
6281 inserter->insert(temp);
6282 expr = Expression::make_set_and_use_temporary(temp, expr, loc);
6283 }
6284 expr = Expression::make_unary(OPERATOR_AND, expr, loc);
6285 static_cast<Unary_expression*>(expr)->set_does_not_escape();
6286 Type* void_type = Type::make_void_type();
6287 Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
6288 return Expression::make_cast(unsafe_pointer_type, expr, loc);
6289}
6290
0c77715b 6291// Return the numeric constant value, if it has one.
e440a328 6292
6293bool
0c77715b 6294Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 6295{
0c77715b 6296 Numeric_constant left_nc;
6297 if (!this->left_->numeric_constant_value(&left_nc))
6298 return false;
6299 Numeric_constant right_nc;
6300 if (!this->right_->numeric_constant_value(&right_nc))
6301 return false;
af7a5274 6302 bool issued_error;
9767e2d3 6303 return Binary_expression::eval_constant(this->op_, &left_nc, &right_nc,
af7a5274 6304 this->location(), nc, &issued_error);
e440a328 6305}
6306
ac7ef97d 6307// Return the boolean constant value, if it has one.
6308
6309bool
6310Binary_expression::do_boolean_constant_value(bool* val) const
6311{
6312 bool is_comparison = false;
6313 switch (this->op_)
6314 {
6315 case OPERATOR_EQEQ:
6316 case OPERATOR_NOTEQ:
6317 case OPERATOR_LT:
6318 case OPERATOR_LE:
6319 case OPERATOR_GT:
6320 case OPERATOR_GE:
6321 is_comparison = true;
6322 break;
6323 case OPERATOR_ANDAND:
6324 case OPERATOR_OROR:
6325 break;
6326 default:
6327 return false;
6328 }
6329
6330 Numeric_constant left_nc, right_nc;
6331 if (is_comparison
6332 && this->left_->numeric_constant_value(&left_nc)
6333 && this->right_->numeric_constant_value(&right_nc))
6334 return Binary_expression::compare_constant(this->op_, &left_nc,
6335 &right_nc,
6336 this->location(),
6337 val);
6338
6339 std::string left_str, right_str;
6340 if (is_comparison
6341 && this->left_->string_constant_value(&left_str)
6342 && this->right_->string_constant_value(&right_str))
6343 {
6344 *val = Binary_expression::cmp_to_bool(this->op_,
6345 left_str.compare(right_str));
6346 return true;
6347 }
6348
6349 bool left_bval;
6350 if (this->left_->boolean_constant_value(&left_bval))
6351 {
6352 if (this->op_ == OPERATOR_ANDAND && !left_bval)
6353 {
6354 *val = false;
6355 return true;
6356 }
6357 else if (this->op_ == OPERATOR_OROR && left_bval)
6358 {
6359 *val = true;
6360 return true;
6361 }
6362
6363 bool right_bval;
6364 if (this->right_->boolean_constant_value(&right_bval))
6365 {
6366 switch (this->op_)
6367 {
6368 case OPERATOR_EQEQ:
6369 *val = (left_bval == right_bval);
6370 return true;
6371 case OPERATOR_NOTEQ:
6372 *val = (left_bval != right_bval);
6373 return true;
6374 case OPERATOR_ANDAND:
6375 case OPERATOR_OROR:
6376 *val = right_bval;
6377 return true;
6378 default:
6379 go_unreachable();
6380 }
6381 }
6382 }
6383
6384 return false;
6385}
6386
e440a328 6387// Note that the value is being discarded.
6388
4f2138d7 6389bool
e440a328 6390Binary_expression::do_discarding_value()
6391{
6392 if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
4f2138d7 6393 return this->right_->discarding_value();
e440a328 6394 else
4f2138d7 6395 {
6396 this->unused_value_error();
6397 return false;
6398 }
e440a328 6399}
6400
6401// Get type.
6402
6403Type*
6404Binary_expression::do_type()
6405{
5f5fea79 6406 if (this->classification() == EXPRESSION_ERROR)
6407 return Type::make_error_type();
6408
e440a328 6409 switch (this->op_)
6410 {
e440a328 6411 case OPERATOR_EQEQ:
6412 case OPERATOR_NOTEQ:
6413 case OPERATOR_LT:
6414 case OPERATOR_LE:
6415 case OPERATOR_GT:
6416 case OPERATOR_GE:
e90c9dfc 6417 if (this->type_ == NULL)
6418 this->type_ = Type::make_boolean_type();
6419 return this->type_;
e440a328 6420
6421 case OPERATOR_PLUS:
6422 case OPERATOR_MINUS:
6423 case OPERATOR_OR:
6424 case OPERATOR_XOR:
6425 case OPERATOR_MULT:
6426 case OPERATOR_DIV:
6427 case OPERATOR_MOD:
6428 case OPERATOR_AND:
6429 case OPERATOR_BITCLEAR:
e90c9dfc 6430 case OPERATOR_OROR:
6431 case OPERATOR_ANDAND:
e440a328 6432 {
0c77715b 6433 Type* type;
6434 if (!Binary_expression::operation_type(this->op_,
6435 this->left_->type(),
6436 this->right_->type(),
6437 &type))
6438 return Type::make_error_type();
6439 return type;
e440a328 6440 }
6441
6442 case OPERATOR_LSHIFT:
6443 case OPERATOR_RSHIFT:
6444 return this->left_->type();
6445
6446 default:
c3e6f413 6447 go_unreachable();
e440a328 6448 }
6449}
6450
6451// Set type for a binary expression.
6452
6453void
6454Binary_expression::do_determine_type(const Type_context* context)
6455{
6456 Type* tleft = this->left_->type();
6457 Type* tright = this->right_->type();
6458
6459 // Both sides should have the same type, except for the shift
6460 // operations. For a comparison, we should ignore the incoming
6461 // type.
6462
6463 bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
6464 || this->op_ == OPERATOR_RSHIFT);
6465
6466 bool is_comparison = (this->op_ == OPERATOR_EQEQ
6467 || this->op_ == OPERATOR_NOTEQ
6468 || this->op_ == OPERATOR_LT
6469 || this->op_ == OPERATOR_LE
6470 || this->op_ == OPERATOR_GT
6471 || this->op_ == OPERATOR_GE);
6472
c999c2a7 6473 // For constant expressions, the context of the result is not useful in
6474 // determining the types of the operands. It is only legal to use abstract
6475 // boolean, numeric, and string constants as operands where it is legal to
6476 // use non-abstract boolean, numeric, and string constants, respectively.
6477 // Any issues with the operation will be resolved in the check_types pass.
6478 bool is_constant_expr = (this->left_->is_constant()
6479 && this->right_->is_constant());
6480
e440a328 6481 Type_context subcontext(*context);
6482
9c4ff2ce 6483 if (is_constant_expr && !is_shift_op)
af7a5274 6484 {
6485 subcontext.type = NULL;
6486 subcontext.may_be_abstract = true;
6487 }
6488 else if (is_comparison)
e440a328 6489 {
6490 // In a comparison, the context does not determine the types of
6491 // the operands.
6492 subcontext.type = NULL;
6493 }
6494
6495 // Set the context for the left hand operand.
6496 if (is_shift_op)
6497 {
b40dc774 6498 // The right hand operand of a shift plays no role in
6499 // determining the type of the left hand operand.
e440a328 6500 }
6501 else if (!tleft->is_abstract())
6502 subcontext.type = tleft;
6503 else if (!tright->is_abstract())
6504 subcontext.type = tright;
6505 else if (subcontext.type == NULL)
6506 {
6507 if ((tleft->integer_type() != NULL && tright->integer_type() != NULL)
6508 || (tleft->float_type() != NULL && tright->float_type() != NULL)
6509 || (tleft->complex_type() != NULL && tright->complex_type() != NULL))
6510 {
6511 // Both sides have an abstract integer, abstract float, or
6512 // abstract complex type. Just let CONTEXT determine
6513 // whether they may remain abstract or not.
6514 }
6515 else if (tleft->complex_type() != NULL)
6516 subcontext.type = tleft;
6517 else if (tright->complex_type() != NULL)
6518 subcontext.type = tright;
6519 else if (tleft->float_type() != NULL)
6520 subcontext.type = tleft;
6521 else if (tright->float_type() != NULL)
6522 subcontext.type = tright;
6523 else
6524 subcontext.type = tleft;
f58a23ae 6525
6526 if (subcontext.type != NULL && !context->may_be_abstract)
6527 subcontext.type = subcontext.type->make_non_abstract_type();
e440a328 6528 }
6529
af7a5274 6530 this->left_->determine_type(&subcontext);
e440a328 6531
e440a328 6532 if (is_shift_op)
6533 {
b40dc774 6534 // We may have inherited an unusable type for the shift operand.
6535 // Give a useful error if that happened.
6536 if (tleft->is_abstract()
6537 && subcontext.type != NULL
8ab6effb 6538 && !subcontext.may_be_abstract
f6bc81e6 6539 && subcontext.type->interface_type() == NULL
8ab6effb 6540 && subcontext.type->integer_type() == NULL)
b40dc774 6541 this->report_error(("invalid context-determined non-integer type "
8ab6effb 6542 "for left operand of shift"));
b40dc774 6543
6544 // The context for the right hand operand is the same as for the
6545 // left hand operand, except for a shift operator.
e440a328 6546 subcontext.type = Type::lookup_integer_type("uint");
6547 subcontext.may_be_abstract = false;
6548 }
6549
af7a5274 6550 this->right_->determine_type(&subcontext);
e90c9dfc 6551
6552 if (is_comparison)
6553 {
6554 if (this->type_ != NULL && !this->type_->is_abstract())
6555 ;
6556 else if (context->type != NULL && context->type->is_boolean_type())
6557 this->type_ = context->type;
6558 else if (!context->may_be_abstract)
6559 this->type_ = Type::lookup_bool_type();
6560 }
e440a328 6561}
6562
6563// Report an error if the binary operator OP does not support TYPE.
be8b5eee 6564// OTYPE is the type of the other operand. Return whether the
6565// operation is OK. This should not be used for shift.
e440a328 6566
6567bool
be8b5eee 6568Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
b13c66cd 6569 Location location)
e440a328 6570{
6571 switch (op)
6572 {
6573 case OPERATOR_OROR:
6574 case OPERATOR_ANDAND:
c999c2a7 6575 if (!type->is_boolean_type()
6576 || !otype->is_boolean_type())
e440a328 6577 {
631d5788 6578 go_error_at(location, "expected boolean type");
e440a328 6579 return false;
6580 }
6581 break;
6582
6583 case OPERATOR_EQEQ:
6584 case OPERATOR_NOTEQ:
e9d3367e 6585 {
6586 std::string reason;
6587 if (!Type::are_compatible_for_comparison(true, type, otype, &reason))
6588 {
631d5788 6589 go_error_at(location, "%s", reason.c_str());
e9d3367e 6590 return false;
6591 }
6592 }
e440a328 6593 break;
6594
6595 case OPERATOR_LT:
6596 case OPERATOR_LE:
6597 case OPERATOR_GT:
6598 case OPERATOR_GE:
e9d3367e 6599 {
6600 std::string reason;
6601 if (!Type::are_compatible_for_comparison(false, type, otype, &reason))
6602 {
631d5788 6603 go_error_at(location, "%s", reason.c_str());
e9d3367e 6604 return false;
6605 }
6606 }
e440a328 6607 break;
6608
6609 case OPERATOR_PLUS:
6610 case OPERATOR_PLUSEQ:
c999c2a7 6611 if ((!type->is_numeric_type() && !type->is_string_type())
6612 || (!otype->is_numeric_type() && !otype->is_string_type()))
e440a328 6613 {
631d5788 6614 go_error_at(location,
e440a328 6615 "expected integer, floating, complex, or string type");
6616 return false;
6617 }
6618 break;
6619
6620 case OPERATOR_MINUS:
6621 case OPERATOR_MINUSEQ:
6622 case OPERATOR_MULT:
6623 case OPERATOR_MULTEQ:
6624 case OPERATOR_DIV:
6625 case OPERATOR_DIVEQ:
c999c2a7 6626 if (!type->is_numeric_type() || !otype->is_numeric_type())
e440a328 6627 {
631d5788 6628 go_error_at(location, "expected integer, floating, or complex type");
e440a328 6629 return false;
6630 }
6631 break;
6632
6633 case OPERATOR_MOD:
6634 case OPERATOR_MODEQ:
6635 case OPERATOR_OR:
6636 case OPERATOR_OREQ:
6637 case OPERATOR_AND:
6638 case OPERATOR_ANDEQ:
6639 case OPERATOR_XOR:
6640 case OPERATOR_XOREQ:
6641 case OPERATOR_BITCLEAR:
6642 case OPERATOR_BITCLEAREQ:
c999c2a7 6643 if (type->integer_type() == NULL || otype->integer_type() == NULL)
e440a328 6644 {
631d5788 6645 go_error_at(location, "expected integer type");
e440a328 6646 return false;
6647 }
6648 break;
6649
6650 default:
c3e6f413 6651 go_unreachable();
e440a328 6652 }
6653
6654 return true;
6655}
6656
6657// Check types.
6658
6659void
6660Binary_expression::do_check_types(Gogo*)
6661{
5f5fea79 6662 if (this->classification() == EXPRESSION_ERROR)
6663 return;
6664
e440a328 6665 Type* left_type = this->left_->type();
6666 Type* right_type = this->right_->type();
5c13bd80 6667 if (left_type->is_error() || right_type->is_error())
9fe897ef 6668 {
6669 this->set_is_error();
6670 return;
6671 }
e440a328 6672
6673 if (this->op_ == OPERATOR_EQEQ
6674 || this->op_ == OPERATOR_NOTEQ
6675 || this->op_ == OPERATOR_LT
6676 || this->op_ == OPERATOR_LE
6677 || this->op_ == OPERATOR_GT
6678 || this->op_ == OPERATOR_GE)
6679 {
907c5ecd 6680 if (left_type->is_nil_type() && right_type->is_nil_type())
6681 {
6682 this->report_error(_("invalid comparison of nil with nil"));
6683 return;
6684 }
e440a328 6685 if (!Type::are_assignable(left_type, right_type, NULL)
6686 && !Type::are_assignable(right_type, left_type, NULL))
6687 {
6688 this->report_error(_("incompatible types in binary expression"));
6689 return;
6690 }
6691 if (!Binary_expression::check_operator_type(this->op_, left_type,
be8b5eee 6692 right_type,
e440a328 6693 this->location())
6694 || !Binary_expression::check_operator_type(this->op_, right_type,
be8b5eee 6695 left_type,
e440a328 6696 this->location()))
6697 {
6698 this->set_is_error();
6699 return;
6700 }
6701 }
6702 else if (this->op_ != OPERATOR_LSHIFT && this->op_ != OPERATOR_RSHIFT)
6703 {
6704 if (!Type::are_compatible_for_binop(left_type, right_type))
6705 {
6706 this->report_error(_("incompatible types in binary expression"));
6707 return;
6708 }
6709 if (!Binary_expression::check_operator_type(this->op_, left_type,
be8b5eee 6710 right_type,
e440a328 6711 this->location()))
6712 {
6713 this->set_is_error();
6714 return;
6715 }
5c65b19d 6716 if (this->op_ == OPERATOR_DIV || this->op_ == OPERATOR_MOD)
6717 {
6718 // Division by a zero integer constant is an error.
6719 Numeric_constant rconst;
6720 unsigned long rval;
6721 if (left_type->integer_type() != NULL
6722 && this->right_->numeric_constant_value(&rconst)
6723 && rconst.to_unsigned_long(&rval) == Numeric_constant::NC_UL_VALID
6724 && rval == 0)
6725 {
6726 this->report_error(_("integer division by zero"));
6727 return;
6728 }
6729 }
e440a328 6730 }
6731 else
6732 {
6733 if (left_type->integer_type() == NULL)
6734 this->report_error(_("shift of non-integer operand"));
6735
6b5e0fac 6736 if (right_type->is_string_type())
16ac1e7c 6737 this->report_error(_("shift count not integer"));
6b5e0fac 6738 else if (!right_type->is_abstract()
16ac1e7c 6739 && right_type->integer_type() == NULL)
6740 this->report_error(_("shift count not integer"));
e440a328 6741 else
6742 {
0c77715b 6743 Numeric_constant nc;
6744 if (this->right_->numeric_constant_value(&nc))
e440a328 6745 {
0c77715b 6746 mpz_t val;
6747 if (!nc.to_int(&val))
16ac1e7c 6748 this->report_error(_("shift count not integer"));
0c77715b 6749 else
a4eba91b 6750 {
0c77715b 6751 if (mpz_sgn(val) < 0)
6752 {
6753 this->report_error(_("negative shift count"));
0c77715b 6754 Location rloc = this->right_->location();
e67508fa 6755 this->right_ = Expression::make_integer_ul(0, right_type,
6756 rloc);
0c77715b 6757 }
6758 mpz_clear(val);
a4eba91b 6759 }
e440a328 6760 }
e440a328 6761 }
6762 }
6763}
6764
ea664253 6765// Get the backend representation for a binary expression.
e440a328 6766
ea664253 6767Bexpression*
6768Binary_expression::do_get_backend(Translate_context* context)
e440a328 6769{
1b1f2abf 6770 Gogo* gogo = context->gogo();
a32698ee 6771 Location loc = this->location();
6772 Type* left_type = this->left_->type();
6773 Type* right_type = this->right_->type();
1b1f2abf 6774
e440a328 6775 bool use_left_type = true;
6776 bool is_shift_op = false;
29a2d1d8 6777 bool is_idiv_op = false;
e440a328 6778 switch (this->op_)
6779 {
6780 case OPERATOR_EQEQ:
6781 case OPERATOR_NOTEQ:
6782 case OPERATOR_LT:
6783 case OPERATOR_LE:
6784 case OPERATOR_GT:
6785 case OPERATOR_GE:
ea664253 6786 return Expression::comparison(context, this->type_, this->op_,
6787 this->left_, this->right_, loc);
e440a328 6788
6789 case OPERATOR_OROR:
e440a328 6790 case OPERATOR_ANDAND:
e440a328 6791 use_left_type = false;
6792 break;
6793 case OPERATOR_PLUS:
e440a328 6794 case OPERATOR_MINUS:
e440a328 6795 case OPERATOR_OR:
e440a328 6796 case OPERATOR_XOR:
e440a328 6797 case OPERATOR_MULT:
e440a328 6798 break;
6799 case OPERATOR_DIV:
a32698ee 6800 if (left_type->float_type() != NULL || left_type->complex_type() != NULL)
6801 break;
729f8831 6802 // Fall through.
e440a328 6803 case OPERATOR_MOD:
29a2d1d8 6804 is_idiv_op = true;
e440a328 6805 break;
6806 case OPERATOR_LSHIFT:
e440a328 6807 case OPERATOR_RSHIFT:
e440a328 6808 is_shift_op = true;
6809 break;
e440a328 6810 case OPERATOR_BITCLEAR:
a32698ee 6811 this->right_ = Expression::make_unary(OPERATOR_XOR, this->right_, loc);
6812 case OPERATOR_AND:
e440a328 6813 break;
6814 default:
c3e6f413 6815 go_unreachable();
e440a328 6816 }
6817
736a16ba 6818 // The only binary operation for string is +, and that should have
6819 // been converted to a String_concat_expression in do_lower.
6820 go_assert(!left_type->is_string_type());
a32698ee 6821
6822 // For complex division Go might want slightly different results than the
6823 // backend implementation provides, so we have our own runtime routine.
1850e20c 6824 if (this->op_ == OPERATOR_DIV && this->left_->type()->complex_type() != NULL)
6825 {
a32698ee 6826 Runtime::Function complex_code;
1850e20c 6827 switch (this->left_->type()->complex_type()->bits())
6828 {
6829 case 64:
a32698ee 6830 complex_code = Runtime::COMPLEX64_DIV;
1850e20c 6831 break;
6832 case 128:
a32698ee 6833 complex_code = Runtime::COMPLEX128_DIV;
1850e20c 6834 break;
6835 default:
6836 go_unreachable();
6837 }
a32698ee 6838 Expression* complex_div =
6839 Runtime::make_call(complex_code, loc, 2, this->left_, this->right_);
ea664253 6840 return complex_div->get_backend(context);
1850e20c 6841 }
6842
ea664253 6843 Bexpression* left = this->left_->get_backend(context);
6844 Bexpression* right = this->right_->get_backend(context);
e440a328 6845
a32698ee 6846 Type* type = use_left_type ? left_type : right_type;
6847 Btype* btype = type->get_backend(gogo);
6848
6849 Bexpression* ret =
6850 gogo->backend()->binary_expression(this->op_, left, right, loc);
6851 ret = gogo->backend()->convert_expression(btype, ret, loc);
e440a328 6852
a32698ee 6853 // Initialize overflow constants.
6854 Bexpression* overflow;
6855 mpz_t zero;
6856 mpz_init_set_ui(zero, 0UL);
6857 mpz_t one;
6858 mpz_init_set_ui(one, 1UL);
6859 mpz_t neg_one;
6860 mpz_init_set_si(neg_one, -1);
e440a328 6861
a32698ee 6862 Btype* left_btype = left_type->get_backend(gogo);
6863 Btype* right_btype = right_type->get_backend(gogo);
e440a328 6864
6865 // In Go, a shift larger than the size of the type is well-defined.
a32698ee 6866 // This is not true in C, so we need to insert a conditional.
16ac1e7c 6867 // We also need to check for a negative shift count.
e440a328 6868 if (is_shift_op)
6869 {
a32698ee 6870 go_assert(left_type->integer_type() != NULL);
16ac1e7c 6871 go_assert(right_type->integer_type() != NULL);
e440a328 6872
a32698ee 6873 int bits = left_type->integer_type()->bits();
a7c5b619 6874
6875 Numeric_constant nc;
6876 unsigned long ul;
6877 if (!this->right_->numeric_constant_value(&nc)
6878 || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID
6879 || ul >= static_cast<unsigned long>(bits))
e440a328 6880 {
a7c5b619 6881 mpz_t bitsval;
6882 mpz_init_set_ui(bitsval, bits);
6883 Bexpression* bits_expr =
6884 gogo->backend()->integer_constant_expression(right_btype, bitsval);
6885 Bexpression* compare =
6886 gogo->backend()->binary_expression(OPERATOR_LT,
6887 right, bits_expr, loc);
6888
6889 Bexpression* zero_expr =
6890 gogo->backend()->integer_constant_expression(left_btype, zero);
6891 overflow = zero_expr;
6892 Bfunction* bfn = context->function()->func_value()->get_decl();
6893 if (this->op_ == OPERATOR_RSHIFT
6894 && !left_type->integer_type()->is_unsigned())
6895 {
6896 Bexpression* neg_expr =
6897 gogo->backend()->binary_expression(OPERATOR_LT, left,
6898 zero_expr, loc);
6899 Bexpression* neg_one_expr =
6900 gogo->backend()->integer_constant_expression(left_btype,
6901 neg_one);
6902 overflow = gogo->backend()->conditional_expression(bfn,
6903 btype,
6904 neg_expr,
6905 neg_one_expr,
6906 zero_expr,
6907 loc);
6908 }
6909 ret = gogo->backend()->conditional_expression(bfn, btype, compare,
6910 ret, overflow, loc);
6911 mpz_clear(bitsval);
29a2d1d8 6912 }
16ac1e7c 6913
6914 if (!right_type->integer_type()->is_unsigned()
6915 && (!this->right_->numeric_constant_value(&nc)
6916 || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID))
6917 {
6918 Bexpression* zero_expr =
6919 gogo->backend()->integer_constant_expression(right_btype, zero);
6920 Bexpression* compare =
6921 gogo->backend()->binary_expression(OPERATOR_LT, right, zero_expr,
6922 loc);
6923 const int errcode = RUNTIME_ERROR_SHIFT_BY_NEGATIVE;
6924 Bexpression* crash =
6925 gogo->runtime_error(errcode, loc)->get_backend(context);
6926 Bfunction* bfn = context->function()->func_value()->get_decl();
6927 ret = gogo->backend()->conditional_expression(bfn, btype, compare,
6928 crash, ret, loc);
6929 }
29a2d1d8 6930 }
6931
6932 // Add checks for division by zero and division overflow as needed.
6933 if (is_idiv_op)
6934 {
5c3f3470 6935 if (gogo->check_divide_by_zero())
29a2d1d8 6936 {
6937 // right == 0
a32698ee 6938 Bexpression* zero_expr =
6939 gogo->backend()->integer_constant_expression(right_btype, zero);
6940 Bexpression* check =
6941 gogo->backend()->binary_expression(OPERATOR_EQEQ,
6942 right, zero_expr, loc);
29a2d1d8 6943
a32698ee 6944 // __go_runtime_error(RUNTIME_ERROR_DIVISION_BY_ZERO)
29a2d1d8 6945 int errcode = RUNTIME_ERROR_DIVISION_BY_ZERO;
ea664253 6946 Bexpression* crash = gogo->runtime_error(errcode,
6947 loc)->get_backend(context);
29a2d1d8 6948
6949 // right == 0 ? (__go_runtime_error(...), 0) : ret
93715b75 6950 Bfunction* bfn = context->function()->func_value()->get_decl();
6951 ret = gogo->backend()->conditional_expression(bfn, btype,
6952 check, crash,
ea664253 6953 ret, loc);
b13c66cd 6954 }
6955
5c3f3470 6956 if (gogo->check_divide_overflow())
29a2d1d8 6957 {
6958 // right == -1
6959 // FIXME: It would be nice to say that this test is expected
6960 // to return false.
a32698ee 6961
6962 Bexpression* neg_one_expr =
6963 gogo->backend()->integer_constant_expression(right_btype, neg_one);
6964 Bexpression* check =
6965 gogo->backend()->binary_expression(OPERATOR_EQEQ,
6966 right, neg_one_expr, loc);
6967
6968 Bexpression* zero_expr =
6969 gogo->backend()->integer_constant_expression(btype, zero);
6970 Bexpression* one_expr =
6971 gogo->backend()->integer_constant_expression(btype, one);
93715b75 6972 Bfunction* bfn = context->function()->func_value()->get_decl();
a32698ee 6973
6974 if (type->integer_type()->is_unsigned())
29a2d1d8 6975 {
6976 // An unsigned -1 is the largest possible number, so
6977 // dividing is always 1 or 0.
a32698ee 6978
6979 Bexpression* cmp =
6980 gogo->backend()->binary_expression(OPERATOR_EQEQ,
6981 left, right, loc);
29a2d1d8 6982 if (this->op_ == OPERATOR_DIV)
a32698ee 6983 overflow =
93715b75 6984 gogo->backend()->conditional_expression(bfn, btype, cmp,
a32698ee 6985 one_expr, zero_expr,
6986 loc);
29a2d1d8 6987 else
a32698ee 6988 overflow =
93715b75 6989 gogo->backend()->conditional_expression(bfn, btype, cmp,
a32698ee 6990 zero_expr, left,
6991 loc);
29a2d1d8 6992 }
6993 else
6994 {
6995 // Computing left / -1 is the same as computing - left,
6996 // which does not overflow since Go sets -fwrapv.
6997 if (this->op_ == OPERATOR_DIV)
a32698ee 6998 {
6999 Expression* negate_expr =
7000 Expression::make_unary(OPERATOR_MINUS, this->left_, loc);
ea664253 7001 overflow = negate_expr->get_backend(context);
a32698ee 7002 }
29a2d1d8 7003 else
a32698ee 7004 overflow = zero_expr;
29a2d1d8 7005 }
a32698ee 7006 overflow = gogo->backend()->convert_expression(btype, overflow, loc);
29a2d1d8 7007
7008 // right == -1 ? - left : ret
93715b75 7009 ret = gogo->backend()->conditional_expression(bfn, btype,
7010 check, overflow,
a32698ee 7011 ret, loc);
29a2d1d8 7012 }
e440a328 7013 }
7014
a32698ee 7015 mpz_clear(zero);
7016 mpz_clear(one);
7017 mpz_clear(neg_one);
ea664253 7018 return ret;
e440a328 7019}
7020
7021// Export a binary expression.
7022
7023void
548be246 7024Binary_expression::do_export(Export_function_body* efb) const
e440a328 7025{
548be246 7026 efb->write_c_string("(");
7027 this->left_->export_expression(efb);
e440a328 7028 switch (this->op_)
7029 {
7030 case OPERATOR_OROR:
548be246 7031 efb->write_c_string(" || ");
e440a328 7032 break;
7033 case OPERATOR_ANDAND:
548be246 7034 efb->write_c_string(" && ");
e440a328 7035 break;
7036 case OPERATOR_EQEQ:
548be246 7037 efb->write_c_string(" == ");
e440a328 7038 break;
7039 case OPERATOR_NOTEQ:
548be246 7040 efb->write_c_string(" != ");
e440a328 7041 break;
7042 case OPERATOR_LT:
548be246 7043 efb->write_c_string(" < ");
e440a328 7044 break;
7045 case OPERATOR_LE:
548be246 7046 efb->write_c_string(" <= ");
e440a328 7047 break;
7048 case OPERATOR_GT:
548be246 7049 efb->write_c_string(" > ");
e440a328 7050 break;
7051 case OPERATOR_GE:
548be246 7052 efb->write_c_string(" >= ");
e440a328 7053 break;
7054 case OPERATOR_PLUS:
548be246 7055 efb->write_c_string(" + ");
e440a328 7056 break;
7057 case OPERATOR_MINUS:
548be246 7058 efb->write_c_string(" - ");
e440a328 7059 break;
7060 case OPERATOR_OR:
548be246 7061 efb->write_c_string(" | ");
e440a328 7062 break;
7063 case OPERATOR_XOR:
548be246 7064 efb->write_c_string(" ^ ");
e440a328 7065 break;
7066 case OPERATOR_MULT:
548be246 7067 efb->write_c_string(" * ");
e440a328 7068 break;
7069 case OPERATOR_DIV:
548be246 7070 efb->write_c_string(" / ");
e440a328 7071 break;
7072 case OPERATOR_MOD:
548be246 7073 efb->write_c_string(" % ");
e440a328 7074 break;
7075 case OPERATOR_LSHIFT:
548be246 7076 efb->write_c_string(" << ");
e440a328 7077 break;
7078 case OPERATOR_RSHIFT:
548be246 7079 efb->write_c_string(" >> ");
e440a328 7080 break;
7081 case OPERATOR_AND:
548be246 7082 efb->write_c_string(" & ");
e440a328 7083 break;
7084 case OPERATOR_BITCLEAR:
548be246 7085 efb->write_c_string(" &^ ");
e440a328 7086 break;
7087 default:
c3e6f413 7088 go_unreachable();
e440a328 7089 }
548be246 7090 this->right_->export_expression(efb);
7091 efb->write_c_string(")");
e440a328 7092}
7093
7094// Import a binary expression.
7095
7096Expression*
bc8e2ef4 7097Binary_expression::do_import(Import_expression* imp, Location loc)
e440a328 7098{
7099 imp->require_c_string("(");
7100
9b92780c 7101 Expression* left = Expression::import_expression(imp, loc);
e440a328 7102
7103 Operator op;
7104 if (imp->match_c_string(" || "))
7105 {
7106 op = OPERATOR_OROR;
7107 imp->advance(4);
7108 }
7109 else if (imp->match_c_string(" && "))
7110 {
7111 op = OPERATOR_ANDAND;
7112 imp->advance(4);
7113 }
7114 else if (imp->match_c_string(" == "))
7115 {
7116 op = OPERATOR_EQEQ;
7117 imp->advance(4);
7118 }
7119 else if (imp->match_c_string(" != "))
7120 {
7121 op = OPERATOR_NOTEQ;
7122 imp->advance(4);
7123 }
7124 else if (imp->match_c_string(" < "))
7125 {
7126 op = OPERATOR_LT;
7127 imp->advance(3);
7128 }
7129 else if (imp->match_c_string(" <= "))
7130 {
7131 op = OPERATOR_LE;
7132 imp->advance(4);
7133 }
7134 else if (imp->match_c_string(" > "))
7135 {
7136 op = OPERATOR_GT;
7137 imp->advance(3);
7138 }
7139 else if (imp->match_c_string(" >= "))
7140 {
7141 op = OPERATOR_GE;
7142 imp->advance(4);
7143 }
7144 else if (imp->match_c_string(" + "))
7145 {
7146 op = OPERATOR_PLUS;
7147 imp->advance(3);
7148 }
7149 else if (imp->match_c_string(" - "))
7150 {
7151 op = OPERATOR_MINUS;
7152 imp->advance(3);
7153 }
7154 else if (imp->match_c_string(" | "))
7155 {
7156 op = OPERATOR_OR;
7157 imp->advance(3);
7158 }
7159 else if (imp->match_c_string(" ^ "))
7160 {
7161 op = OPERATOR_XOR;
7162 imp->advance(3);
7163 }
7164 else if (imp->match_c_string(" * "))
7165 {
7166 op = OPERATOR_MULT;
7167 imp->advance(3);
7168 }
7169 else if (imp->match_c_string(" / "))
7170 {
7171 op = OPERATOR_DIV;
7172 imp->advance(3);
7173 }
7174 else if (imp->match_c_string(" % "))
7175 {
7176 op = OPERATOR_MOD;
7177 imp->advance(3);
7178 }
7179 else if (imp->match_c_string(" << "))
7180 {
7181 op = OPERATOR_LSHIFT;
7182 imp->advance(4);
7183 }
7184 else if (imp->match_c_string(" >> "))
7185 {
7186 op = OPERATOR_RSHIFT;
7187 imp->advance(4);
7188 }
7189 else if (imp->match_c_string(" & "))
7190 {
7191 op = OPERATOR_AND;
7192 imp->advance(3);
7193 }
7194 else if (imp->match_c_string(" &^ "))
7195 {
7196 op = OPERATOR_BITCLEAR;
7197 imp->advance(4);
7198 }
171fd404 7199 else if (imp->match_c_string(")"))
7200 {
7201 // Not a binary operator after all.
7202 imp->advance(1);
7203 return left;
7204 }
e440a328 7205 else
7206 {
631d5788 7207 go_error_at(imp->location(), "unrecognized binary operator");
9b92780c 7208 return Expression::make_error(loc);
e440a328 7209 }
7210
9b92780c 7211 Expression* right = Expression::import_expression(imp, loc);
e440a328 7212
7213 imp->require_c_string(")");
7214
9b92780c 7215 return Expression::make_binary(op, left, right, loc);
e440a328 7216}
7217
d751bb78 7218// Dump ast representation of a binary expression.
7219
7220void
7221Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
7222{
7223 ast_dump_context->ostream() << "(";
7224 ast_dump_context->dump_expression(this->left_);
7225 ast_dump_context->ostream() << " ";
7226 ast_dump_context->dump_operator(this->op_);
7227 ast_dump_context->ostream() << " ";
7228 ast_dump_context->dump_expression(this->right_);
7229 ast_dump_context->ostream() << ") ";
7230}
7231
e440a328 7232// Make a binary expression.
7233
7234Expression*
7235Expression::make_binary(Operator op, Expression* left, Expression* right,
b13c66cd 7236 Location location)
e440a328 7237{
7238 return new Binary_expression(op, left, right, location);
7239}
7240
7241// Implement a comparison.
7242
a32698ee 7243Bexpression*
7244Expression::comparison(Translate_context* context, Type* result_type,
7245 Operator op, Expression* left, Expression* right,
7246 Location location)
e440a328 7247{
2387f644 7248 Type* left_type = left->type();
7249 Type* right_type = right->type();
ceeb12d7 7250
e67508fa 7251 Expression* zexpr = Expression::make_integer_ul(0, NULL, location);
1b1f2abf 7252
15c67ee2 7253 if (left_type->is_string_type() && right_type->is_string_type())
e440a328 7254 {
aad830e6 7255 go_assert(left->is_variable() || left->is_constant());
7256 go_assert(right->is_variable() || right->is_constant());
ae77af58 7257
6098d6cb 7258 if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
7259 {
aad830e6 7260 // (l.len == r.len
7261 // ? (l.ptr == r.ptr ? true : memcmp(l.ptr, r.ptr, r.len) == 0)
7262 // : false)
7263 Expression* llen = Expression::make_string_info(left,
7264 STRING_INFO_LENGTH,
7265 location);
7266 Expression* rlen = Expression::make_string_info(right,
7267 STRING_INFO_LENGTH,
7268 location);
7269 Expression* leneq = Expression::make_binary(OPERATOR_EQEQ, llen, rlen,
7270 location);
7271 Expression* lptr = Expression::make_string_info(left->copy(),
7272 STRING_INFO_DATA,
7273 location);
7274 Expression* rptr = Expression::make_string_info(right->copy(),
7275 STRING_INFO_DATA,
7276 location);
7277 Expression* ptreq = Expression::make_binary(OPERATOR_EQEQ, lptr, rptr,
7278 location);
7279 Expression* btrue = Expression::make_boolean(true, location);
7280 Expression* call = Runtime::make_call(Runtime::MEMCMP, location, 3,
7281 lptr->copy(), rptr->copy(),
7282 rlen->copy());
7283 Type* int32_type = Type::lookup_integer_type("int32");
7284 Expression* zero = Expression::make_integer_ul(0, int32_type, location);
7285 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, call, zero,
7286 location);
7287 Expression* cond = Expression::make_conditional(ptreq, btrue, cmp,
7288 location);
7289 Expression* bfalse = Expression::make_boolean(false, location);
7290 left = Expression::make_conditional(leneq, cond, bfalse, location);
6098d6cb 7291 right = Expression::make_boolean(true, location);
7292 }
7293 else
7294 {
7295 left = Runtime::make_call(Runtime::CMPSTRING, location, 2,
7296 left, right);
7297 right = zexpr;
7298 }
e440a328 7299 }
15c67ee2 7300 else if ((left_type->interface_type() != NULL
7301 && right_type->interface_type() == NULL
7302 && !right_type->is_nil_type())
7303 || (left_type->interface_type() == NULL
7304 && !left_type->is_nil_type()
7305 && right_type->interface_type() != NULL))
e440a328 7306 {
7307 // Comparing an interface value to a non-interface value.
7308 if (left_type->interface_type() == NULL)
7309 {
7310 std::swap(left_type, right_type);
2387f644 7311 std::swap(left, right);
e440a328 7312 }
7313
7314 // The right operand is not an interface. We need to take its
5b665222 7315 // address if it is not a direct interface type.
ceeb12d7 7316 Expression* pointer_arg = NULL;
5b665222 7317 if (right_type->is_direct_iface_type())
7318 pointer_arg = Expression::unpack_direct_iface(right, location);
e440a328 7319 else
7320 {
2387f644 7321 go_assert(right->is_addressable());
7322 pointer_arg = Expression::make_unary(OPERATOR_AND, right,
ceeb12d7 7323 location);
e440a328 7324 }
e440a328 7325
2387f644 7326 Expression* descriptor =
7327 Expression::make_type_descriptor(right_type, location);
7328 left =
ceeb12d7 7329 Runtime::make_call((left_type->interface_type()->is_empty()
6098d6cb 7330 ? Runtime::EFACEVALEQ
7331 : Runtime::IFACEVALEQ),
2387f644 7332 location, 3, left, descriptor,
ceeb12d7 7333 pointer_arg);
6098d6cb 7334 go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
7335 right = Expression::make_boolean(true, location);
e440a328 7336 }
7337 else if (left_type->interface_type() != NULL
7338 && right_type->interface_type() != NULL)
7339 {
ceeb12d7 7340 Runtime::Function compare_function;
739bad04 7341 if (left_type->interface_type()->is_empty()
7342 && right_type->interface_type()->is_empty())
6098d6cb 7343 compare_function = Runtime::EFACEEQ;
739bad04 7344 else if (!left_type->interface_type()->is_empty()
7345 && !right_type->interface_type()->is_empty())
6098d6cb 7346 compare_function = Runtime::IFACEEQ;
739bad04 7347 else
7348 {
7349 if (left_type->interface_type()->is_empty())
7350 {
739bad04 7351 std::swap(left_type, right_type);
2387f644 7352 std::swap(left, right);
739bad04 7353 }
c484d925 7354 go_assert(!left_type->interface_type()->is_empty());
7355 go_assert(right_type->interface_type()->is_empty());
6098d6cb 7356 compare_function = Runtime::IFACEEFACEEQ;
739bad04 7357 }
7358
2387f644 7359 left = Runtime::make_call(compare_function, location, 2, left, right);
6098d6cb 7360 go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
7361 right = Expression::make_boolean(true, location);
e440a328 7362 }
7363
7364 if (left_type->is_nil_type()
7365 && (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ))
7366 {
7367 std::swap(left_type, right_type);
2387f644 7368 std::swap(left, right);
e440a328 7369 }
7370
7371 if (right_type->is_nil_type())
7372 {
2387f644 7373 right = Expression::make_nil(location);
e440a328 7374 if (left_type->array_type() != NULL
7375 && left_type->array_type()->length() == NULL)
7376 {
7377 Array_type* at = left_type->array_type();
44dbe1d7 7378 bool is_lvalue = false;
7379 left = at->get_value_pointer(context->gogo(), left, is_lvalue);
e440a328 7380 }
7381 else if (left_type->interface_type() != NULL)
7382 {
7383 // An interface is nil if the first field is nil.
2387f644 7384 left = Expression::make_field_reference(left, 0, location);
e440a328 7385 }
7386 }
7387
ea664253 7388 Bexpression* left_bexpr = left->get_backend(context);
7389 Bexpression* right_bexpr = right->get_backend(context);
e90c9dfc 7390
a32698ee 7391 Gogo* gogo = context->gogo();
7392 Bexpression* ret = gogo->backend()->binary_expression(op, left_bexpr,
7393 right_bexpr, location);
7394 if (result_type != NULL)
7395 ret = gogo->backend()->convert_expression(result_type->get_backend(gogo),
7396 ret, location);
e440a328 7397 return ret;
7398}
7399
736a16ba 7400// Class String_concat_expression.
7401
7402bool
7403String_concat_expression::do_is_constant() const
7404{
7405 for (Expression_list::const_iterator pe = this->exprs_->begin();
7406 pe != this->exprs_->end();
7407 ++pe)
7408 {
7409 if (!(*pe)->is_constant())
7410 return false;
7411 }
7412 return true;
7413}
7414
d2199dbc 7415bool
7416String_concat_expression::do_is_zero_value() const
7417{
7418 for (Expression_list::const_iterator pe = this->exprs_->begin();
7419 pe != this->exprs_->end();
7420 ++pe)
7421 {
7422 if (!(*pe)->is_zero_value())
7423 return false;
7424 }
7425 return true;
7426}
7427
736a16ba 7428bool
3ae06f68 7429String_concat_expression::do_is_static_initializer() const
736a16ba 7430{
7431 for (Expression_list::const_iterator pe = this->exprs_->begin();
7432 pe != this->exprs_->end();
7433 ++pe)
7434 {
3ae06f68 7435 if (!(*pe)->is_static_initializer())
736a16ba 7436 return false;
7437 }
7438 return true;
7439}
7440
7441Type*
7442String_concat_expression::do_type()
7443{
7444 Type* t = this->exprs_->front()->type();
7445 Expression_list::iterator pe = this->exprs_->begin();
7446 ++pe;
7447 for (; pe != this->exprs_->end(); ++pe)
7448 {
7449 Type* t1;
7450 if (!Binary_expression::operation_type(OPERATOR_PLUS, t,
7451 (*pe)->type(),
7452 &t1))
7453 return Type::make_error_type();
7454 t = t1;
7455 }
7456 return t;
7457}
7458
7459void
7460String_concat_expression::do_determine_type(const Type_context* context)
7461{
7462 Type_context subcontext(*context);
7463 for (Expression_list::iterator pe = this->exprs_->begin();
7464 pe != this->exprs_->end();
7465 ++pe)
7466 {
7467 Type* t = (*pe)->type();
7468 if (!t->is_abstract())
7469 {
7470 subcontext.type = t;
7471 break;
7472 }
7473 }
7474 if (subcontext.type == NULL)
7475 subcontext.type = this->exprs_->front()->type();
7476 for (Expression_list::iterator pe = this->exprs_->begin();
7477 pe != this->exprs_->end();
7478 ++pe)
7479 (*pe)->determine_type(&subcontext);
7480}
7481
7482void
7483String_concat_expression::do_check_types(Gogo*)
7484{
7485 if (this->is_error_expression())
7486 return;
7487 Type* t = this->exprs_->front()->type();
7488 if (t->is_error())
7489 {
7490 this->set_is_error();
7491 return;
7492 }
7493 Expression_list::iterator pe = this->exprs_->begin();
7494 ++pe;
7495 for (; pe != this->exprs_->end(); ++pe)
7496 {
7497 Type* t1 = (*pe)->type();
7498 if (!Type::are_compatible_for_binop(t, t1))
7499 {
7500 this->report_error("incompatible types in binary expression");
7501 return;
7502 }
7503 if (!Binary_expression::check_operator_type(OPERATOR_PLUS, t, t1,
7504 this->location()))
7505 {
7506 this->set_is_error();
7507 return;
7508 }
7509 }
7510}
7511
7512Expression*
7513String_concat_expression::do_flatten(Gogo*, Named_object*,
85c94669 7514 Statement_inserter* inserter)
736a16ba 7515{
7516 if (this->is_error_expression())
7517 return this;
7518 Location loc = this->location();
7519 Type* type = this->type();
cb9d693f 7520
7521 // Mark string([]byte) operands to reuse the backing store.
7522 // runtime.concatstrings does not keep the reference.
7523 //
7524 // Note: in the gc runtime, if all but one inputs are empty,
7525 // concatstrings returns the only nonempty input without copy.
7526 // So it is not safe to reuse the backing store if it is a
7527 // string([]byte) conversion. So the gc compiler does the
7528 // no-copy optimization only when there is at least one
7529 // constant nonempty input. Currently the gccgo runtime
7530 // doesn't do this, so we don't do the check.
7531 for (Expression_list::iterator p = this->exprs_->begin();
7532 p != this->exprs_->end();
7533 ++p)
7534 {
7535 Type_conversion_expression* tce = (*p)->conversion_expression();
7536 if (tce != NULL)
7537 tce->set_no_copy(true);
7538 }
7539
20a381c4 7540 Expression* buf = NULL;
7541 Node* n = Node::make_node(this);
7542 if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
7543 {
7544 size_t size = 0;
7545 for (Expression_list::iterator p = this->exprs_->begin();
7546 p != this->exprs_->end();
7547 ++p)
7548 {
7549 std::string s;
7550 if ((*p)->string_constant_value(&s))
7551 size += s.length();
7552 }
7553 // Make a buffer on stack if the result does not escape.
7554 // But don't do this if we know it won't fit.
7555 if (size < (size_t)tmp_string_buf_size)
7556 {
7557 Type* byte_type = Type::lookup_integer_type("uint8");
7558 Expression* buflen =
7559 Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
7560 Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
7561 Type* array_type = Type::make_array_type(byte_type, buflen);
7562 buf = Expression::make_allocation(array_type, loc);
7563 buf->allocation_expression()->set_allocate_on_stack();
7564 buf->allocation_expression()->set_no_zero();
7565 }
7566 }
7567 if (buf == NULL)
7568 buf = Expression::make_nil(loc);
85c94669 7569 go_assert(this->exprs_->size() > 1);
7570 Expression* len =
7571 Expression::make_integer_ul(this->exprs_->size(), NULL, loc);
7572 Array_type* array_type = Type::make_array_type(type, len);
7573 array_type->set_is_array_incomparable();
7574 Expression* array =
7575 Expression::make_array_composite_literal(array_type, this->exprs_,
7576 loc);
7577 Temporary_statement* ts =
7578 Statement::make_temporary(array_type, array, loc);
7579 inserter->insert(ts);
7580 Expression* ref = Expression::make_temporary_reference(ts, loc);
7581 ref = Expression::make_unary(OPERATOR_AND, ref, loc);
7582 Expression* call =
7583 Runtime::make_call(Runtime::CONCATSTRINGS, loc, 3, buf,
7584 ref, len->copy());
736a16ba 7585 return Expression::make_cast(type, call, loc);
7586}
7587
7588void
7589String_concat_expression::do_dump_expression(
7590 Ast_dump_context* ast_dump_context) const
7591{
7592 ast_dump_context->ostream() << "concat(";
7593 ast_dump_context->dump_expression_list(this->exprs_, false);
7594 ast_dump_context->ostream() << ")";
7595}
7596
7597Expression*
7598Expression::make_string_concat(Expression_list* exprs)
7599{
7600 return new String_concat_expression(exprs);
7601}
7602
e440a328 7603// Class Bound_method_expression.
7604
7605// Traversal.
7606
7607int
7608Bound_method_expression::do_traverse(Traverse* traverse)
7609{
e0659c9e 7610 return Expression::traverse(&this->expr_, traverse);
e440a328 7611}
7612
7613// Return the type of a bound method expression. The type of this
0afbb937 7614// object is simply the type of the method with no receiver.
e440a328 7615
7616Type*
7617Bound_method_expression::do_type()
7618{
0afbb937 7619 Named_object* fn = this->method_->named_object();
7620 Function_type* fntype;
7621 if (fn->is_function())
7622 fntype = fn->func_value()->type();
7623 else if (fn->is_function_declaration())
7624 fntype = fn->func_declaration_value()->type();
e0659c9e 7625 else
7626 return Type::make_error_type();
0afbb937 7627 return fntype->copy_without_receiver();
e440a328 7628}
7629
7630// Determine the types of a method expression.
7631
7632void
7633Bound_method_expression::do_determine_type(const Type_context*)
7634{
0afbb937 7635 Named_object* fn = this->method_->named_object();
7636 Function_type* fntype;
7637 if (fn->is_function())
7638 fntype = fn->func_value()->type();
7639 else if (fn->is_function_declaration())
7640 fntype = fn->func_declaration_value()->type();
7641 else
7642 fntype = NULL;
e440a328 7643 if (fntype == NULL || !fntype->is_method())
7644 this->expr_->determine_type_no_context();
7645 else
7646 {
7647 Type_context subcontext(fntype->receiver()->type(), false);
7648 this->expr_->determine_type(&subcontext);
7649 }
7650}
7651
7652// Check the types of a method expression.
7653
7654void
7655Bound_method_expression::do_check_types(Gogo*)
7656{
0afbb937 7657 Named_object* fn = this->method_->named_object();
7658 if (!fn->is_function() && !fn->is_function_declaration())
7659 {
7660 this->report_error(_("object is not a method"));
7661 return;
7662 }
7663
7664 Function_type* fntype;
7665 if (fn->is_function())
7666 fntype = fn->func_value()->type();
7667 else if (fn->is_function_declaration())
7668 fntype = fn->func_declaration_value()->type();
e440a328 7669 else
0afbb937 7670 go_unreachable();
7671 Type* rtype = fntype->receiver()->type()->deref();
7672 Type* etype = (this->expr_type_ != NULL
7673 ? this->expr_type_
7674 : this->expr_->type());
7675 etype = etype->deref();
3a522dcc 7676 if (!Type::are_identical(rtype, etype, Type::COMPARE_TAGS, NULL))
0afbb937 7677 this->report_error(_("method type does not match object type"));
7678}
7679
7680// If a bound method expression is not simply called, then it is
7681// represented as a closure. The closure will hold a single variable,
7682// the receiver to pass to the method. The function will be a simple
7683// thunk that pulls that value from the closure and calls the method
7684// with the remaining arguments.
7685//
7686// Because method values are not common, we don't build all thunks for
7687// every methods, but instead only build them as we need them. In
7688// particular, we even build them on demand for methods defined in
7689// other packages.
7690
7691Bound_method_expression::Method_value_thunks
7692 Bound_method_expression::method_value_thunks;
7693
7694// Find or create the thunk for METHOD.
7695
7696Named_object*
7697Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
7698 Named_object* fn)
7699{
7700 std::pair<Named_object*, Named_object*> val(fn, NULL);
7701 std::pair<Method_value_thunks::iterator, bool> ins =
7702 Bound_method_expression::method_value_thunks.insert(val);
7703 if (!ins.second)
7704 {
7705 // We have seen this method before.
7706 go_assert(ins.first->second != NULL);
7707 return ins.first->second;
7708 }
7709
7710 Location loc = fn->location();
7711
7712 Function_type* orig_fntype;
7713 if (fn->is_function())
7714 orig_fntype = fn->func_value()->type();
7715 else if (fn->is_function_declaration())
7716 orig_fntype = fn->func_declaration_value()->type();
7717 else
7718 orig_fntype = NULL;
7719
7720 if (orig_fntype == NULL || !orig_fntype->is_method())
e440a328 7721 {
13f2fdb8 7722 ins.first->second =
7723 Named_object::make_erroneous_name(gogo->thunk_name());
0afbb937 7724 return ins.first->second;
e440a328 7725 }
0afbb937 7726
7727 Struct_field_list* sfl = new Struct_field_list();
f8bdf81a 7728 // The type here is wrong--it should be the C function type. But it
7729 // doesn't really matter.
0afbb937 7730 Type* vt = Type::make_pointer_type(Type::make_void_type());
13f2fdb8 7731 sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
7732 sfl->push_back(Struct_field(Typed_identifier("val",
0afbb937 7733 orig_fntype->receiver()->type(),
7734 loc)));
6bf4793c 7735 Struct_type* st = Type::make_struct_type(sfl, loc);
7736 st->set_is_struct_incomparable();
7737 Type* closure_type = Type::make_pointer_type(st);
0afbb937 7738
f8bdf81a 7739 Function_type* new_fntype = orig_fntype->copy_with_names();
0afbb937 7740
13f2fdb8 7741 std::string thunk_name = gogo->thunk_name();
da244e59 7742 Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
0afbb937 7743 false, loc);
7744
f8bdf81a 7745 Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
7746 cvar->set_is_used();
1ecc6157 7747 cvar->set_is_closure();
da244e59 7748 Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
7749 NULL, cvar);
f8bdf81a 7750 new_no->func_value()->set_closure_var(cp);
0afbb937 7751
f8bdf81a 7752 gogo->start_block(loc);
0afbb937 7753
7754 // Field 0 of the closure is the function code pointer, field 1 is
7755 // the value on which to invoke the method.
7756 Expression* arg = Expression::make_var_reference(cp, loc);
f614ea8b 7757 arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
0afbb937 7758 arg = Expression::make_field_reference(arg, 1, loc);
7759
7760 Expression* bme = Expression::make_bound_method(arg, method, fn, loc);
7761
7762 const Typed_identifier_list* orig_params = orig_fntype->parameters();
7763 Expression_list* args;
7764 if (orig_params == NULL || orig_params->empty())
7765 args = NULL;
7766 else
7767 {
7768 const Typed_identifier_list* new_params = new_fntype->parameters();
7769 args = new Expression_list();
7770 for (Typed_identifier_list::const_iterator p = new_params->begin();
f8bdf81a 7771 p != new_params->end();
0afbb937 7772 ++p)
7773 {
7774 Named_object* p_no = gogo->lookup(p->name(), NULL);
7775 go_assert(p_no != NULL
7776 && p_no->is_variable()
7777 && p_no->var_value()->is_parameter());
7778 args->push_back(Expression::make_var_reference(p_no, loc));
7779 }
7780 }
7781
7782 Call_expression* call = Expression::make_call(bme, args,
7783 orig_fntype->is_varargs(),
7784 loc);
7785 call->set_varargs_are_lowered();
7786
7787 Statement* s = Statement::make_return_from_call(call, loc);
7788 gogo->add_statement(s);
7789 Block* b = gogo->finish_block(loc);
7790 gogo->add_block(b, loc);
7791 gogo->lower_block(new_no, b);
a32698ee 7792 gogo->flatten_block(new_no, b);
0afbb937 7793 gogo->finish_function(loc);
7794
7795 ins.first->second = new_no;
7796 return new_no;
7797}
7798
7799// Return an expression to check *REF for nil while dereferencing
7800// according to FIELD_INDEXES. Update *REF to build up the field
7801// reference. This is a static function so that we don't have to
7802// worry about declaring Field_indexes in expressions.h.
7803
7804static Expression*
7805bme_check_nil(const Method::Field_indexes* field_indexes, Location loc,
7806 Expression** ref)
7807{
7808 if (field_indexes == NULL)
7809 return Expression::make_boolean(false, loc);
7810 Expression* cond = bme_check_nil(field_indexes->next, loc, ref);
7811 Struct_type* stype = (*ref)->type()->deref()->struct_type();
7812 go_assert(stype != NULL
7813 && field_indexes->field_index < stype->field_count());
7814 if ((*ref)->type()->struct_type() == NULL)
7815 {
7816 go_assert((*ref)->type()->points_to() != NULL);
7817 Expression* n = Expression::make_binary(OPERATOR_EQEQ, *ref,
7818 Expression::make_nil(loc),
7819 loc);
7820 cond = Expression::make_binary(OPERATOR_OROR, cond, n, loc);
f614ea8b 7821 *ref = Expression::make_dereference(*ref, Expression::NIL_CHECK_DEFAULT,
7822 loc);
0afbb937 7823 go_assert((*ref)->type()->struct_type() == stype);
7824 }
7825 *ref = Expression::make_field_reference(*ref, field_indexes->field_index,
7826 loc);
7827 return cond;
e440a328 7828}
7829
cd39797e 7830// Flatten a method value into a struct with nil checks. We can't do
7831// this in the lowering phase, because if the method value is called
7832// directly we don't need a thunk. That case will have been handled
7833// by Call_expression::do_lower, so if we get here then we do need a
7834// thunk.
e440a328 7835
cd39797e 7836Expression*
7837Bound_method_expression::do_flatten(Gogo* gogo, Named_object*,
7838 Statement_inserter* inserter)
e440a328 7839{
cd39797e 7840 Location loc = this->location();
7841
7842 Named_object* thunk = Bound_method_expression::create_thunk(gogo,
0afbb937 7843 this->method_,
7844 this->function_);
7845 if (thunk->is_erroneous())
7846 {
7847 go_assert(saw_errors());
cd39797e 7848 return Expression::make_error(loc);
0afbb937 7849 }
7850
cd39797e 7851 // Force the expression into a variable. This is only necessary if
7852 // we are going to do nil checks below, but it's easy enough to
7853 // always do it.
7854 Expression* expr = this->expr_;
7855 if (!expr->is_variable())
7856 {
7857 Temporary_statement* etemp = Statement::make_temporary(NULL, expr, loc);
7858 inserter->insert(etemp);
7859 expr = Expression::make_temporary_reference(etemp, loc);
7860 }
0afbb937 7861
7862 // If the method expects a value, and we have a pointer, we need to
7863 // dereference the pointer.
7864
7865 Named_object* fn = this->method_->named_object();
cd39797e 7866 Function_type *fntype;
0afbb937 7867 if (fn->is_function())
7868 fntype = fn->func_value()->type();
7869 else if (fn->is_function_declaration())
7870 fntype = fn->func_declaration_value()->type();
7871 else
7872 go_unreachable();
7873
cd39797e 7874 Expression* val = expr;
0afbb937 7875 if (fntype->receiver()->type()->points_to() == NULL
7876 && val->type()->points_to() != NULL)
f614ea8b 7877 val = Expression::make_dereference(val, NIL_CHECK_DEFAULT, loc);
0afbb937 7878
7879 // Note that we are ignoring this->expr_type_ here. The thunk will
7880 // expect a closure whose second field has type this->expr_type_ (if
7881 // that is not NULL). We are going to pass it a closure whose
7882 // second field has type this->expr_->type(). Since
7883 // this->expr_type_ is only not-NULL for pointer types, we can get
7884 // away with this.
7885
7886 Struct_field_list* fields = new Struct_field_list();
13f2fdb8 7887 fields->push_back(Struct_field(Typed_identifier("fn",
0afbb937 7888 thunk->func_value()->type(),
7889 loc)));
13f2fdb8 7890 fields->push_back(Struct_field(Typed_identifier("val", val->type(), loc)));
0afbb937 7891 Struct_type* st = Type::make_struct_type(fields, loc);
6bf4793c 7892 st->set_is_struct_incomparable();
0afbb937 7893
7894 Expression_list* vals = new Expression_list();
7895 vals->push_back(Expression::make_func_code_reference(thunk, loc));
7896 vals->push_back(val);
7897
7898 Expression* ret = Expression::make_struct_composite_literal(st, vals, loc);
c1177ba4 7899 ret = Expression::make_heap_expression(ret, loc);
0afbb937 7900
c1177ba4 7901 Node* n = Node::make_node(this);
7902 if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
7903 ret->heap_expression()->set_allocate_on_stack();
7904 else if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
7905 go_error_at(loc, "%s escapes to heap, not allowed in runtime",
7906 n->ast_format(gogo).c_str());
cd39797e 7907
7908 // If necessary, check whether the expression or any embedded
7909 // pointers are nil.
0afbb937 7910
df7ef1fd 7911 Expression* nil_check = NULL;
0afbb937 7912 if (this->method_->field_indexes() != NULL)
7913 {
0afbb937 7914 Expression* ref = expr;
7915 nil_check = bme_check_nil(this->method_->field_indexes(), loc, &ref);
7916 expr = ref;
7917 }
7918
7919 if (this->method_->is_value_method() && expr->type()->points_to() != NULL)
7920 {
7921 Expression* n = Expression::make_binary(OPERATOR_EQEQ, expr,
7922 Expression::make_nil(loc),
7923 loc);
7924 if (nil_check == NULL)
7925 nil_check = n;
7926 else
7927 nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc);
7928 }
7929
7930 if (nil_check != NULL)
7931 {
cd39797e 7932 Expression* crash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
7933 loc);
7934 // Fix the type of the conditional expression by pretending to
7935 // evaluate to RET either way through the conditional.
7936 crash = Expression::make_compound(crash, ret, loc);
7937 ret = Expression::make_conditional(nil_check, crash, ret, loc);
7938 }
7939
7940 // RET is a pointer to a struct, but we want a function type.
7941 ret = Expression::make_unsafe_cast(this->type(), ret, loc);
7942
7943 return ret;
e440a328 7944}
7945
d751bb78 7946// Dump ast representation of a bound method expression.
7947
7948void
7949Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
7950 const
7951{
7952 if (this->expr_type_ != NULL)
7953 ast_dump_context->ostream() << "(";
f03a9fbf 7954 ast_dump_context->dump_expression(this->expr_);
7955 if (this->expr_type_ != NULL)
d751bb78 7956 {
7957 ast_dump_context->ostream() << ":";
7958 ast_dump_context->dump_type(this->expr_type_);
7959 ast_dump_context->ostream() << ")";
7960 }
f03a9fbf 7961
0afbb937 7962 ast_dump_context->ostream() << "." << this->function_->name();
d751bb78 7963}
7964
e440a328 7965// Make a method expression.
7966
7967Bound_method_expression*
0afbb937 7968Expression::make_bound_method(Expression* expr, const Method* method,
7969 Named_object* function, Location location)
e440a328 7970{
0afbb937 7971 return new Bound_method_expression(expr, method, function, location);
e440a328 7972}
7973
7974// Class Builtin_call_expression. This is used for a call to a
7975// builtin function.
7976
e440a328 7977Builtin_call_expression::Builtin_call_expression(Gogo* gogo,
7978 Expression* fn,
7979 Expression_list* args,
7980 bool is_varargs,
b13c66cd 7981 Location location)
e440a328 7982 : Call_expression(fn, args, is_varargs, location),
6334270b 7983 gogo_(gogo), code_(BUILTIN_INVALID), seen_(false),
7984 recover_arg_is_set_(false)
e440a328 7985{
7986 Func_expression* fnexp = this->fn()->func_expression();
79651b1f 7987 if (fnexp == NULL)
7988 {
7989 this->code_ = BUILTIN_INVALID;
7990 return;
7991 }
e440a328 7992 const std::string& name(fnexp->named_object()->name());
7993 if (name == "append")
7994 this->code_ = BUILTIN_APPEND;
7995 else if (name == "cap")
7996 this->code_ = BUILTIN_CAP;
7997 else if (name == "close")
7998 this->code_ = BUILTIN_CLOSE;
48080209 7999 else if (name == "complex")
8000 this->code_ = BUILTIN_COMPLEX;
e440a328 8001 else if (name == "copy")
8002 this->code_ = BUILTIN_COPY;
1cce762f 8003 else if (name == "delete")
8004 this->code_ = BUILTIN_DELETE;
e440a328 8005 else if (name == "imag")
8006 this->code_ = BUILTIN_IMAG;
8007 else if (name == "len")
8008 this->code_ = BUILTIN_LEN;
8009 else if (name == "make")
8010 this->code_ = BUILTIN_MAKE;
8011 else if (name == "new")
8012 this->code_ = BUILTIN_NEW;
8013 else if (name == "panic")
8014 this->code_ = BUILTIN_PANIC;
8015 else if (name == "print")
8016 this->code_ = BUILTIN_PRINT;
8017 else if (name == "println")
8018 this->code_ = BUILTIN_PRINTLN;
8019 else if (name == "real")
8020 this->code_ = BUILTIN_REAL;
8021 else if (name == "recover")
8022 this->code_ = BUILTIN_RECOVER;
8023 else if (name == "Alignof")
8024 this->code_ = BUILTIN_ALIGNOF;
8025 else if (name == "Offsetof")
8026 this->code_ = BUILTIN_OFFSETOF;
8027 else if (name == "Sizeof")
8028 this->code_ = BUILTIN_SIZEOF;
8029 else
c3e6f413 8030 go_unreachable();
e440a328 8031}
8032
8033// Return whether this is a call to recover. This is a virtual
8034// function called from the parent class.
8035
8036bool
8037Builtin_call_expression::do_is_recover_call() const
8038{
8039 if (this->classification() == EXPRESSION_ERROR)
8040 return false;
8041 return this->code_ == BUILTIN_RECOVER;
8042}
8043
8044// Set the argument for a call to recover.
8045
8046void
8047Builtin_call_expression::do_set_recover_arg(Expression* arg)
8048{
8049 const Expression_list* args = this->args();
c484d925 8050 go_assert(args == NULL || args->empty());
e440a328 8051 Expression_list* new_args = new Expression_list();
8052 new_args->push_back(arg);
8053 this->set_args(new_args);
6334270b 8054 this->recover_arg_is_set_ = true;
e440a328 8055}
8056
e440a328 8057// Lower a builtin call expression. This turns new and make into
8058// specific expressions. We also convert to a constant if we can.
8059
8060Expression*
321e5ad2 8061Builtin_call_expression::do_lower(Gogo*, Named_object* function,
ceeb4318 8062 Statement_inserter* inserter, int)
e440a328 8063{
79651b1f 8064 if (this->is_error_expression())
a9182619 8065 return this;
8066
b13c66cd 8067 Location loc = this->location();
1cce762f 8068
a8725655 8069 if (this->is_varargs() && this->code_ != BUILTIN_APPEND)
8070 {
8071 this->report_error(_("invalid use of %<...%> with builtin function"));
1cce762f 8072 return Expression::make_error(loc);
a8725655 8073 }
8074
393ba00b 8075 if (this->code_ == BUILTIN_OFFSETOF)
8076 {
8077 Expression* arg = this->one_arg();
12e69faa 8078
8079 if (arg->bound_method_expression() != NULL
8080 || arg->interface_field_reference_expression() != NULL)
8081 {
8082 this->report_error(_("invalid use of method value as argument "
8083 "of Offsetof"));
8084 return this;
8085 }
8086
393ba00b 8087 Field_reference_expression* farg = arg->field_reference_expression();
8088 while (farg != NULL)
8089 {
8090 if (!farg->implicit())
8091 break;
8092 // When the selector refers to an embedded field,
8093 // it must not be reached through pointer indirections.
8094 if (farg->expr()->deref() != farg->expr())
8095 {
12e69faa 8096 this->report_error(_("argument of Offsetof implies "
8097 "indirection of an embedded field"));
393ba00b 8098 return this;
8099 }
8100 // Go up until we reach the original base.
8101 farg = farg->expr()->field_reference_expression();
8102 }
8103 }
f03a9fbf 8104
1cce762f 8105 if (this->is_constant())
e440a328 8106 {
0c77715b 8107 Numeric_constant nc;
8108 if (this->numeric_constant_value(&nc))
8109 return nc.expression(loc);
e440a328 8110 }
1cce762f 8111
8112 switch (this->code_)
e440a328 8113 {
1cce762f 8114 default:
8115 break;
8116
8117 case BUILTIN_NEW:
8118 {
8119 const Expression_list* args = this->args();
8120 if (args == NULL || args->size() < 1)
8121 this->report_error(_("not enough arguments"));
8122 else if (args->size() > 1)
8123 this->report_error(_("too many arguments"));
8124 else
8125 {
8126 Expression* arg = args->front();
8127 if (!arg->is_type_expression())
8128 {
631d5788 8129 go_error_at(arg->location(), "expected type");
1cce762f 8130 this->set_is_error();
8131 }
8132 else
8133 return Expression::make_allocation(arg->type(), loc);
8134 }
8135 }
8136 break;
8137
8138 case BUILTIN_MAKE:
321e5ad2 8139 return this->lower_make(inserter);
1cce762f 8140
8141 case BUILTIN_RECOVER:
e440a328 8142 if (function != NULL)
8143 function->func_value()->set_calls_recover();
8144 else
8145 {
8146 // Calling recover outside of a function always returns the
8147 // nil empty interface.
823c7e3d 8148 Type* eface = Type::make_empty_interface_type(loc);
1cce762f 8149 return Expression::make_cast(eface, Expression::make_nil(loc), loc);
e440a328 8150 }
1cce762f 8151 break;
8152
1cce762f 8153 case BUILTIN_DELETE:
8154 {
26329c24 8155 const Expression_list* args = this->args();
8156 if (args == NULL || args->size() < 2)
8157 this->report_error(_("not enough arguments"));
8158 else if (args->size() > 2)
8159 this->report_error(_("too many arguments"));
8160 else if (args->front()->type()->map_type() == NULL)
8161 this->report_error(_("argument 1 must be a map"));
8162 else
8163 {
8164 Type* key_type =
8165 args->front()->type()->map_type()->key_type();
8166 Expression_list::iterator pa = this->args()->begin();
8167 pa++;
8168 Type* arg_type = (*pa)->type();
8169 std::string reason;
8170 if (!Type::are_assignable(key_type, arg_type, &reason))
8171 {
8172 if (reason.empty())
8173 go_error_at(loc, "argument 2 has incompatible type");
8174 else
8175 go_error_at(loc, "argument 2 has incompatible type (%s)",
8176 reason.c_str());
8177 this->set_is_error();
8178 }
8179 else if (!Type::are_identical(key_type, arg_type, 0, NULL))
8180 *pa = Expression::make_cast(key_type, *pa, loc);
8181 }
1cce762f 8182 }
8183 break;
88b03a70 8184
8185 case BUILTIN_PRINT:
8186 case BUILTIN_PRINTLN:
8187 // Force all the arguments into temporary variables, so that we
8188 // don't try to evaluate something while holding the print lock.
8189 if (this->args() == NULL)
8190 break;
8191 for (Expression_list::iterator pa = this->args()->begin();
8192 pa != this->args()->end();
8193 ++pa)
8194 {
493ce3ee 8195 if (!(*pa)->is_variable() && !(*pa)->is_constant())
88b03a70 8196 {
8197 Temporary_statement* temp =
8198 Statement::make_temporary(NULL, *pa, loc);
8199 inserter->insert(temp);
8200 *pa = Expression::make_temporary_reference(temp, loc);
8201 }
8202 }
8203 break;
e440a328 8204 }
8205
8206 return this;
8207}
8208
7fdb0876 8209// Flatten a builtin call expression. This turns the arguments of some
8210// builtin calls into temporary expressions. Also expand copy and append
8211// to runtime calls.
35a54f17 8212
8213Expression*
321e5ad2 8214Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
35a54f17 8215 Statement_inserter* inserter)
8216{
26329c24 8217 if (this->is_error_expression())
8218 {
8219 go_assert(saw_errors());
8220 return this;
8221 }
8222
16cb7fec 8223 Location loc = this->location();
8224
8225 switch (this->code_)
35a54f17 8226 {
16cb7fec 8227 default:
8228 break;
8229
8230 case BUILTIN_APPEND:
d3c55148 8231 return this->flatten_append(gogo, function, inserter, NULL, NULL);
321e5ad2 8232
16cb7fec 8233 case BUILTIN_COPY:
8234 {
8235 Type* at = this->args()->front()->type();
8236 for (Expression_list::iterator pa = this->args()->begin();
8237 pa != this->args()->end();
8238 ++pa)
8239 {
8240 if ((*pa)->is_nil_expression())
8241 {
8242 Expression* nil = Expression::make_nil(loc);
8243 Expression* zero = Expression::make_integer_ul(0, NULL, loc);
8244 *pa = Expression::make_slice_value(at, nil, zero, zero, loc);
8245 }
8246 if (!(*pa)->is_variable())
8247 {
8248 Temporary_statement* temp =
8249 Statement::make_temporary(NULL, *pa, loc);
8250 inserter->insert(temp);
8251 *pa = Expression::make_temporary_reference(temp, loc);
8252 }
8253 }
7fdb0876 8254
8255 // Lower to runtime call.
8256 const Expression_list* args = this->args();
8257 go_assert(args != NULL && args->size() == 2);
8258 Expression* arg1 = args->front();
8259 Expression* arg2 = args->back();
8260 go_assert(arg1->is_variable());
8261 go_assert(arg2->is_variable());
8262 bool arg2_is_string = arg2->type()->is_string_type();
8263
8264 Expression* ret;
8265 Type* et = at->array_type()->element_type();
8266 if (et->has_pointer())
8267 {
8268 Expression* td = Expression::make_type_descriptor(et, loc);
8269 ret = Runtime::make_call(Runtime::TYPEDSLICECOPY, loc,
8270 3, td, arg1, arg2);
8271 }
8272 else
8273 {
8274 Type* int_type = Type::lookup_integer_type("int");
8275 Type* uintptr_type = Type::lookup_integer_type("uintptr");
8276
8277 // l1 = len(arg1)
8278 Named_object* lenfn = gogo->lookup_global("len");
8279 Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
8280 Expression_list* len_args = new Expression_list();
8281 len_args->push_back(arg1->copy());
8282 Expression* len1 = Expression::make_call(lenref, len_args, false, loc);
8283 gogo->lower_expression(function, inserter, &len1);
8284 gogo->flatten_expression(function, inserter, &len1);
8285 Temporary_statement* l1tmp = Statement::make_temporary(int_type, len1, loc);
8286 inserter->insert(l1tmp);
8287
8288 // l2 = len(arg2)
8289 len_args = new Expression_list();
8290 len_args->push_back(arg2->copy());
8291 Expression* len2 = Expression::make_call(lenref, len_args, false, loc);
8292 gogo->lower_expression(function, inserter, &len2);
8293 gogo->flatten_expression(function, inserter, &len2);
8294 Temporary_statement* l2tmp = Statement::make_temporary(int_type, len2, loc);
8295 inserter->insert(l2tmp);
8296
8297 // n = (l1 < l2 ? l1 : l2)
8298 Expression* l1ref = Expression::make_temporary_reference(l1tmp, loc);
8299 Expression* l2ref = Expression::make_temporary_reference(l2tmp, loc);
8300 Expression* cond = Expression::make_binary(OPERATOR_LT, l1ref, l2ref, loc);
8301 Expression* n = Expression::make_conditional(cond,
8302 l1ref->copy(),
8303 l2ref->copy(),
8304 loc);
8305 Temporary_statement* ntmp = Statement::make_temporary(NULL, n, loc);
8306 inserter->insert(ntmp);
8307
8308 // sz = n * sizeof(elem_type)
8309 Expression* nref = Expression::make_temporary_reference(ntmp, loc);
8310 nref = Expression::make_cast(uintptr_type, nref, loc);
8311 Expression* sz = Expression::make_type_info(et, TYPE_INFO_SIZE);
8312 sz = Expression::make_binary(OPERATOR_MULT, sz, nref, loc);
8313
8314 // memmove(arg1.ptr, arg2.ptr, sz)
8315 Expression* p1 = Expression::make_slice_info(arg1,
8316 SLICE_INFO_VALUE_POINTER,
8317 loc);
8318 Expression* p2 = (arg2_is_string
8319 ? Expression::make_string_info(arg2,
8320 STRING_INFO_DATA,
8321 loc)
8322 : Expression::make_slice_info(arg2,
8323 SLICE_INFO_VALUE_POINTER,
8324 loc));
8325 Expression* call = Runtime::make_call(Runtime::BUILTIN_MEMMOVE, loc, 3,
8326 p1, p2, sz);
8327
8328 // n is the return value of copy
8329 nref = Expression::make_temporary_reference(ntmp, loc);
8330 ret = Expression::make_compound(call, nref, loc);
8331 }
8332 return ret;
16cb7fec 8333 }
8334 break;
8335
8336 case BUILTIN_PANIC:
35a54f17 8337 for (Expression_list::iterator pa = this->args()->begin();
16cb7fec 8338 pa != this->args()->end();
8339 ++pa)
8340 {
8341 if (!(*pa)->is_variable() && (*pa)->type()->interface_type() != NULL)
55e8ba6a 8342 {
16cb7fec 8343 Temporary_statement* temp =
8344 Statement::make_temporary(NULL, *pa, loc);
8345 inserter->insert(temp);
8346 *pa = Expression::make_temporary_reference(temp, loc);
55e8ba6a 8347 }
16cb7fec 8348 }
7739537f 8349 break;
0d5530d9 8350
8351 case BUILTIN_LEN:
132ed071 8352 case BUILTIN_CAP:
321e5ad2 8353 {
8354 Expression_list::iterator pa = this->args()->begin();
8355 if (!(*pa)->is_variable()
8356 && ((*pa)->type()->map_type() != NULL
8357 || (*pa)->type()->channel_type() != NULL))
8358 {
8359 Temporary_statement* temp =
8360 Statement::make_temporary(NULL, *pa, loc);
8361 inserter->insert(temp);
8362 *pa = Expression::make_temporary_reference(temp, loc);
8363 }
8364 }
8365 break;
26329c24 8366
8367 case BUILTIN_DELETE:
8368 {
8369 // Lower to a runtime function call.
8370 const Expression_list* args = this->args();
8371
8372 // Since this function returns no value it must appear in
8373 // a statement by itself, so we don't have to worry about
8374 // order of evaluation of values around it. Evaluate the
8375 // map first to get order of evaluation right.
8376 Map_type* mt = args->front()->type()->map_type();
8377 Temporary_statement* map_temp =
8378 Statement::make_temporary(mt, args->front(), loc);
8379 inserter->insert(map_temp);
8380
8381 Temporary_statement* key_temp =
8382 Statement::make_temporary(mt->key_type(), args->back(), loc);
8383 inserter->insert(key_temp);
8384
8385 Expression* e1 = Expression::make_type_descriptor(mt, loc);
8386 Expression* e2 = Expression::make_temporary_reference(map_temp,
8387 loc);
8388 Expression* e3 = Expression::make_temporary_reference(key_temp,
8389 loc);
8390
8391 Runtime::Function code;
8392 switch (mt->algorithm(gogo))
8393 {
8394 case Map_type::MAP_ALG_FAST32:
8395 case Map_type::MAP_ALG_FAST32PTR:
8396 {
8397 code = Runtime::MAPDELETE_FAST32;
8398 Type* uint32_type = Type::lookup_integer_type("uint32");
8399 Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
8400 e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
8401 e3 = Expression::make_unsafe_cast(uint32_ptr_type, e3,
8402 loc);
8403 e3 = Expression::make_dereference(e3,
8404 Expression::NIL_CHECK_NOT_NEEDED,
8405 loc);
8406 break;
8407 }
8408 case Map_type::MAP_ALG_FAST64:
8409 case Map_type::MAP_ALG_FAST64PTR:
8410 {
8411 code = Runtime::MAPDELETE_FAST64;
8412 Type* uint64_type = Type::lookup_integer_type("uint64");
8413 Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
8414 e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
8415 e3 = Expression::make_unsafe_cast(uint64_ptr_type, e3,
8416 loc);
8417 e3 = Expression::make_dereference(e3,
8418 Expression::NIL_CHECK_NOT_NEEDED,
8419 loc);
8420 break;
8421 }
8422 case Map_type::MAP_ALG_FASTSTR:
8423 code = Runtime::MAPDELETE_FASTSTR;
8424 break;
8425 default:
8426 code = Runtime::MAPDELETE;
8427
8428 // If the call to delete is deferred, and is in a loop,
8429 // then the loop will only have a single instance of the
8430 // temporary variable. Passing the address of the
8431 // temporary variable here means that the deferred call
8432 // will see the last value in the loop, not the current
8433 // value. So for this unusual case copy the value into
8434 // the heap.
8435 if (!this->is_deferred())
8436 e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
8437 else
8438 {
8439 Expression* a = Expression::make_allocation(mt->key_type(),
8440 loc);
8441 Temporary_statement* atemp =
8442 Statement::make_temporary(NULL, a, loc);
8443 inserter->insert(atemp);
8444
8445 a = Expression::make_temporary_reference(atemp, loc);
8446 a = Expression::make_dereference(a, NIL_CHECK_NOT_NEEDED, loc);
8447 Statement* s = Statement::make_assignment(a, e3, loc);
8448 inserter->insert(s);
8449
8450 e3 = Expression::make_temporary_reference(atemp, loc);
8451 }
8452 }
8453
8454 return Runtime::make_call(code, loc, 3, e1, e2, e3);
8455 }
35a54f17 8456 }
16cb7fec 8457
35a54f17 8458 return this;
8459}
8460
a9182619 8461// Lower a make expression.
8462
8463Expression*
321e5ad2 8464Builtin_call_expression::lower_make(Statement_inserter* inserter)
a9182619 8465{
b13c66cd 8466 Location loc = this->location();
a9182619 8467
8468 const Expression_list* args = this->args();
8469 if (args == NULL || args->size() < 1)
8470 {
8471 this->report_error(_("not enough arguments"));
8472 return Expression::make_error(this->location());
8473 }
8474
8475 Expression_list::const_iterator parg = args->begin();
8476
8477 Expression* first_arg = *parg;
8478 if (!first_arg->is_type_expression())
8479 {
631d5788 8480 go_error_at(first_arg->location(), "expected type");
a9182619 8481 this->set_is_error();
8482 return Expression::make_error(this->location());
8483 }
8484 Type* type = first_arg->type();
8485
22deed0d 8486 if (!type->in_heap())
8487 go_error_at(first_arg->location(),
37423a84 8488 "cannot make slice of go:notinheap type");
22deed0d 8489
a9182619 8490 bool is_slice = false;
8491 bool is_map = false;
8492 bool is_chan = false;
411eb89e 8493 if (type->is_slice_type())
a9182619 8494 is_slice = true;
8495 else if (type->map_type() != NULL)
8496 is_map = true;
8497 else if (type->channel_type() != NULL)
8498 is_chan = true;
8499 else
8500 {
8501 this->report_error(_("invalid type for make function"));
8502 return Expression::make_error(this->location());
8503 }
8504
f6bc81e6 8505 Type_context int_context(Type::lookup_integer_type("int"), false);
8506
a9182619 8507 ++parg;
8508 Expression* len_arg;
ccea2b36 8509 bool len_small = false;
a9182619 8510 if (parg == args->end())
8511 {
8512 if (is_slice)
8513 {
8514 this->report_error(_("length required when allocating a slice"));
8515 return Expression::make_error(this->location());
8516 }
e67508fa 8517 len_arg = Expression::make_integer_ul(0, NULL, loc);
33d1d391 8518 len_small = true;
a9182619 8519 }
8520 else
8521 {
8522 len_arg = *parg;
f6bc81e6 8523 len_arg->determine_type(&int_context);
a065edc5 8524 if (len_arg->type()->integer_type() == NULL)
8525 {
8526 go_error_at(len_arg->location(), "non-integer len argument in make");
8527 return Expression::make_error(this->location());
8528 }
ccea2b36 8529 if (!this->check_int_value(len_arg, true, &len_small))
1ad00fd4 8530 return Expression::make_error(this->location());
a9182619 8531 ++parg;
8532 }
8533
8534 Expression* cap_arg = NULL;
ccea2b36 8535 bool cap_small = false;
72bf0e6e 8536 Numeric_constant nclen;
8537 Numeric_constant nccap;
8538 unsigned long vlen;
8539 unsigned long vcap;
a9182619 8540 if (is_slice && parg != args->end())
8541 {
8542 cap_arg = *parg;
f6bc81e6 8543 cap_arg->determine_type(&int_context);
a065edc5 8544 if (cap_arg->type()->integer_type() == NULL)
8545 {
8546 go_error_at(cap_arg->location(), "non-integer cap argument in make");
8547 return Expression::make_error(this->location());
8548 }
ccea2b36 8549 if (!this->check_int_value(cap_arg, false, &cap_small))
1ad00fd4 8550 return Expression::make_error(this->location());
8551
1ad00fd4 8552 if (len_arg->numeric_constant_value(&nclen)
8553 && cap_arg->numeric_constant_value(&nccap)
8554 && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
8555 && nccap.to_unsigned_long(&vcap) == Numeric_constant::NC_UL_VALID
8556 && vlen > vcap)
a9182619 8557 {
1ad00fd4 8558 this->report_error(_("len larger than cap"));
a9182619 8559 return Expression::make_error(this->location());
8560 }
1ad00fd4 8561
a9182619 8562 ++parg;
8563 }
8564
8565 if (parg != args->end())
8566 {
8567 this->report_error(_("too many arguments to make"));
8568 return Expression::make_error(this->location());
8569 }
8570
b13c66cd 8571 Location type_loc = first_arg->location();
a9182619 8572
8573 Expression* call;
8574 if (is_slice)
8575 {
d633d0fb 8576 Temporary_statement* len_temp = NULL;
8577 if (!len_arg->is_constant())
8578 {
8579 len_temp = Statement::make_temporary(NULL, len_arg, loc);
8580 inserter->insert(len_temp);
8581 len_arg = Expression::make_temporary_reference(len_temp, loc);
8582 }
8583
a9182619 8584 if (cap_arg == NULL)
321e5ad2 8585 {
72bf0e6e 8586 cap_small = len_small;
d633d0fb 8587 if (len_temp == NULL)
8588 cap_arg = len_arg->copy();
8589 else
8590 cap_arg = Expression::make_temporary_reference(len_temp, loc);
8591 }
8592 else if (!cap_arg->is_constant())
8593 {
8594 Temporary_statement* cap_temp = Statement::make_temporary(NULL,
8595 cap_arg,
8596 loc);
8597 inserter->insert(cap_temp);
8598 cap_arg = Expression::make_temporary_reference(cap_temp, loc);
321e5ad2 8599 }
ccea2b36 8600
72bf0e6e 8601 Type* et = type->array_type()->element_type();
8602 Expression* type_arg = Expression::make_type_descriptor(et, type_loc);
ccea2b36 8603 Runtime::Function code = Runtime::MAKESLICE;
8604 if (!len_small || !cap_small)
8605 code = Runtime::MAKESLICE64;
d633d0fb 8606 Expression* mem = Runtime::make_call(code, loc, 3, type_arg, len_arg,
8607 cap_arg);
8608 mem = Expression::make_unsafe_cast(Type::make_pointer_type(et), mem,
8609 loc);
f81232c1 8610 Type* int_type = Type::lookup_integer_type("int");
8611 len_arg = Expression::make_cast(int_type, len_arg->copy(), loc);
8612 cap_arg = Expression::make_cast(int_type, cap_arg->copy(), loc);
8613 call = Expression::make_slice_value(type, mem, len_arg, cap_arg, loc);
a9182619 8614 }
8615 else if (is_map)
321e5ad2 8616 {
8617 Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
33d1d391 8618 if (!len_small)
8619 call = Runtime::make_call(Runtime::MAKEMAP64, loc, 3, type_arg,
8620 len_arg,
8621 Expression::make_nil(loc));
8622 else
8623 {
8624 Numeric_constant nclen;
8625 unsigned long vlen;
8626 if (len_arg->numeric_constant_value(&nclen)
8627 && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
8628 && vlen <= Map_type::bucket_size)
8629 call = Runtime::make_call(Runtime::MAKEMAP_SMALL, loc, 0);
8630 else
8631 call = Runtime::make_call(Runtime::MAKEMAP, loc, 3, type_arg,
8632 len_arg,
8633 Expression::make_nil(loc));
8634 }
321e5ad2 8635 }
a9182619 8636 else if (is_chan)
321e5ad2 8637 {
8638 Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
1423c90a 8639 Runtime::Function code = Runtime::MAKECHAN;
8640 if (!len_small)
8641 code = Runtime::MAKECHAN64;
8642 call = Runtime::make_call(code, loc, 2, type_arg, len_arg);
321e5ad2 8643 }
a9182619 8644 else
8645 go_unreachable();
8646
8647 return Expression::make_unsafe_cast(type, call, loc);
8648}
8649
321e5ad2 8650// Flatten a call to the predeclared append function. We do this in
8651// the flatten phase, not the lowering phase, so that we run after
d3c55148 8652// type checking and after order_evaluations. If ASSIGN_LHS is not
8653// NULL, this append is the right-hand-side of an assignment and
8654// ASSIGN_LHS is the left-hand-side; in that case, set LHS directly
8655// rather than returning a slice. This lets us omit a write barrier
8656// in common cases like a = append(a, ...) when the slice does not
8657// need to grow. ENCLOSING is not NULL iff ASSIGN_LHS is not NULL.
321e5ad2 8658
8659Expression*
8660Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
d3c55148 8661 Statement_inserter* inserter,
8662 Expression* assign_lhs,
8663 Block* enclosing)
321e5ad2 8664{
8665 if (this->is_error_expression())
8666 return this;
8667
8668 Location loc = this->location();
8669
8670 const Expression_list* args = this->args();
8671 go_assert(args != NULL && !args->empty());
8672
8673 Type* slice_type = args->front()->type();
8674 go_assert(slice_type->is_slice_type());
8675 Type* element_type = slice_type->array_type()->element_type();
8676
8677 if (args->size() == 1)
8678 {
8679 // append(s) evaluates to s.
d3c55148 8680 if (assign_lhs != NULL)
8681 return NULL;
321e5ad2 8682 return args->front();
8683 }
8684
8685 Type* int_type = Type::lookup_integer_type("int");
8686 Type* uint_type = Type::lookup_integer_type("uint");
8687
8688 // Implementing
8689 // append(s1, s2...)
8690 // or
8691 // append(s1, a1, a2, a3, ...)
8692
8693 // s1tmp := s1
8694 Temporary_statement* s1tmp = Statement::make_temporary(NULL, args->front(),
8695 loc);
8696 inserter->insert(s1tmp);
8697
8698 // l1tmp := len(s1tmp)
8699 Named_object* lenfn = gogo->lookup_global("len");
8700 Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
8701 Expression_list* call_args = new Expression_list();
8702 call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
8703 Expression* len = Expression::make_call(lenref, call_args, false, loc);
8704 gogo->lower_expression(function, inserter, &len);
8705 gogo->flatten_expression(function, inserter, &len);
8706 Temporary_statement* l1tmp = Statement::make_temporary(int_type, len, loc);
8707 inserter->insert(l1tmp);
8708
8709 Temporary_statement* s2tmp = NULL;
8710 Temporary_statement* l2tmp = NULL;
8711 Expression_list* add = NULL;
8712 Expression* len2;
38ba9eec 8713 Call_expression* makecall = NULL;
321e5ad2 8714 if (this->is_varargs())
8715 {
8716 go_assert(args->size() == 2);
8717
38ba9eec 8718 std::pair<Call_expression*, Temporary_statement*> p =
8719 Expression::find_makeslice_call(args->back());
8720 makecall = p.first;
8721 if (makecall != NULL)
8722 {
8723 // We are handling
8724 // append(s, make([]T, len[, cap])...))
8725 // which has already been lowered to
8726 // append(s, runtime.makeslice(T, len, cap)).
8727 // We will optimize this to directly zeroing the tail,
8728 // instead of allocating a new slice then copy.
8729
8730 // Retrieve the length. Cannot reference s2 as we will remove
8731 // the makeslice call.
8732 Expression* len_arg = makecall->args()->at(1);
8733 len_arg = Expression::make_cast(int_type, len_arg, loc);
8734 l2tmp = Statement::make_temporary(int_type, len_arg, loc);
8735 inserter->insert(l2tmp);
8736
8737 Expression* cap_arg = makecall->args()->at(2);
8738 cap_arg = Expression::make_cast(int_type, cap_arg, loc);
8739 Temporary_statement* c2tmp =
8740 Statement::make_temporary(int_type, cap_arg, loc);
8741 inserter->insert(c2tmp);
8742
8743 // Check bad len/cap here.
8744 // if len2 < 0 { panicmakeslicelen(); }
8745 len2 = Expression::make_temporary_reference(l2tmp, loc);
8746 Expression* zero = Expression::make_integer_ul(0, int_type, loc);
8747 Expression* cond = Expression::make_binary(OPERATOR_LT, len2,
8748 zero, loc);
8749 Expression* arg =
8750 Expression::make_integer_ul(RUNTIME_ERROR_MAKE_SLICE_LEN_OUT_OF_BOUNDS,
8751 NULL, loc);
8752 Expression* call = Runtime::make_call(Runtime::RUNTIME_ERROR,
8753 loc, 1, arg);
8754 cond = Expression::make_conditional(cond, call, zero->copy(), loc);
8755 gogo->lower_expression(function, inserter, &cond);
8756 gogo->flatten_expression(function, inserter, &cond);
8757 Statement* s = Statement::make_statement(cond, false);
8758 inserter->insert(s);
8759
8760 // if cap2 < 0 { panicmakeslicecap(); }
8761 Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc);
8762 cond = Expression::make_binary(OPERATOR_LT, cap2,
8763 zero->copy(), loc);
8764 arg = Expression::make_integer_ul(RUNTIME_ERROR_MAKE_SLICE_CAP_OUT_OF_BOUNDS,
8765 NULL, loc);
8766 call = Runtime::make_call(Runtime::RUNTIME_ERROR, loc, 1, arg);
8767 cond = Expression::make_conditional(cond, call, zero->copy(), loc);
8768 gogo->lower_expression(function, inserter, &cond);
8769 gogo->flatten_expression(function, inserter, &cond);
8770 s = Statement::make_statement(cond, false);
8771 inserter->insert(s);
8772
8773 // Remove the original makeslice call.
8774 Temporary_statement* ts = p.second;
8775 if (ts != NULL && ts->uses() == 1)
8776 ts->set_init(Expression::make_nil(loc));
8777 }
8778 else
8779 {
8780 // s2tmp := s2
8781 s2tmp = Statement::make_temporary(NULL, args->back(), loc);
8782 inserter->insert(s2tmp);
321e5ad2 8783
38ba9eec 8784 // l2tmp := len(s2tmp)
8785 lenref = Expression::make_func_reference(lenfn, NULL, loc);
8786 call_args = new Expression_list();
8787 call_args->push_back(Expression::make_temporary_reference(s2tmp, loc));
8788 len = Expression::make_call(lenref, call_args, false, loc);
8789 gogo->lower_expression(function, inserter, &len);
8790 gogo->flatten_expression(function, inserter, &len);
8791 l2tmp = Statement::make_temporary(int_type, len, loc);
8792 inserter->insert(l2tmp);
8793 }
321e5ad2 8794
8795 // len2 = l2tmp
8796 len2 = Expression::make_temporary_reference(l2tmp, loc);
8797 }
8798 else
8799 {
8800 // We have to ensure that all the arguments are in variables
8801 // now, because otherwise if one of them is an index expression
8802 // into the current slice we could overwrite it before we fetch
8803 // it.
8804 add = new Expression_list();
8805 Expression_list::const_iterator pa = args->begin();
8806 for (++pa; pa != args->end(); ++pa)
8807 {
8808 if ((*pa)->is_variable())
8809 add->push_back(*pa);
8810 else
8811 {
8812 Temporary_statement* tmp = Statement::make_temporary(NULL, *pa,
8813 loc);
8814 inserter->insert(tmp);
8815 add->push_back(Expression::make_temporary_reference(tmp, loc));
8816 }
8817 }
8818
8819 // len2 = len(add)
8820 len2 = Expression::make_integer_ul(add->size(), int_type, loc);
8821 }
8822
8823 // ntmp := l1tmp + len2
8824 Expression* ref = Expression::make_temporary_reference(l1tmp, loc);
8825 Expression* sum = Expression::make_binary(OPERATOR_PLUS, ref, len2, loc);
8826 gogo->lower_expression(function, inserter, &sum);
8827 gogo->flatten_expression(function, inserter, &sum);
8828 Temporary_statement* ntmp = Statement::make_temporary(int_type, sum, loc);
8829 inserter->insert(ntmp);
8830
8831 // s1tmp = uint(ntmp) > uint(cap(s1tmp)) ?
8832 // growslice(type, s1tmp, ntmp) :
8833 // s1tmp[:ntmp]
8834 // Using uint here means that if the computation of ntmp overflowed,
8835 // we will call growslice which will panic.
8836
321e5ad2 8837 Named_object* capfn = gogo->lookup_global("cap");
8838 Expression* capref = Expression::make_func_reference(capfn, NULL, loc);
8839 call_args = new Expression_list();
8840 call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
16c9b8e5 8841 Expression* cap = Expression::make_call(capref, call_args, false, loc);
8842 gogo->lower_expression(function, inserter, &cap);
8843 gogo->flatten_expression(function, inserter, &cap);
8844 Temporary_statement* c1tmp = Statement::make_temporary(int_type, cap, loc);
8845 inserter->insert(c1tmp);
8846
8847 Expression* left = Expression::make_temporary_reference(ntmp, loc);
8848 left = Expression::make_cast(uint_type, left, loc);
8849 Expression* right = Expression::make_temporary_reference(c1tmp, loc);
321e5ad2 8850 right = Expression::make_cast(uint_type, right, loc);
8851
8852 Expression* cond = Expression::make_binary(OPERATOR_GT, left, right, loc);
8853
16c9b8e5 8854 Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
321e5ad2 8855 Expression* a1 = Expression::make_type_descriptor(element_type, loc);
8856 Expression* a2 = Expression::make_temporary_reference(s1tmp, loc);
16c9b8e5 8857 a2 = slice_type->array_type()->get_value_pointer(gogo, a2, false);
8858 a2 = Expression::make_cast(unsafe_ptr_type, a2, loc);
8859 Expression* a3 = Expression::make_temporary_reference(l1tmp, loc);
8860 Expression* a4 = Expression::make_temporary_reference(c1tmp, loc);
8861 Expression* a5 = Expression::make_temporary_reference(ntmp, loc);
8862 Expression* call = Runtime::make_call(Runtime::GROWSLICE, loc, 5,
8863 a1, a2, a3, a4, a5);
321e5ad2 8864 call = Expression::make_unsafe_cast(slice_type, call, loc);
8865
8866 ref = Expression::make_temporary_reference(s1tmp, loc);
8867 Expression* zero = Expression::make_integer_ul(0, int_type, loc);
8868 Expression* ref2 = Expression::make_temporary_reference(ntmp, loc);
3d135120 8869 ref = Expression::make_array_index(ref, zero, ref2, NULL, loc);
8870 ref->array_index_expression()->set_needs_bounds_check(false);
321e5ad2 8871
d3c55148 8872 if (assign_lhs == NULL)
8873 {
8874 Expression* rhs = Expression::make_conditional(cond, call, ref, loc);
8875
8876 gogo->lower_expression(function, inserter, &rhs);
8877 gogo->flatten_expression(function, inserter, &rhs);
8878
8879 ref = Expression::make_temporary_reference(s1tmp, loc);
8880 Statement* assign = Statement::make_assignment(ref, rhs, loc);
8881 inserter->insert(assign);
8882 }
8883 else
8884 {
8885 gogo->lower_expression(function, inserter, &cond);
8886 gogo->flatten_expression(function, inserter, &cond);
8887 gogo->lower_expression(function, inserter, &call);
8888 gogo->flatten_expression(function, inserter, &call);
8889 gogo->lower_expression(function, inserter, &ref);
8890 gogo->flatten_expression(function, inserter, &ref);
8891
8892 Block* then_block = new Block(enclosing, loc);
8893 Assignment_statement* assign =
8894 Statement::make_assignment(assign_lhs, call, loc);
8895 then_block->add_statement(assign);
321e5ad2 8896
d3c55148 8897 Block* else_block = new Block(enclosing, loc);
8898 assign = Statement::make_assignment(assign_lhs->copy(), ref, loc);
8899 // This assignment will not change the pointer value, so it does
8900 // not need a write barrier.
8901 assign->set_omit_write_barrier();
8902 else_block->add_statement(assign);
321e5ad2 8903
d3c55148 8904 Statement* s = Statement::make_if_statement(cond, then_block,
8905 else_block, loc);
8906 inserter->insert(s);
8907
8908 ref = Expression::make_temporary_reference(s1tmp, loc);
8909 assign = Statement::make_assignment(ref, assign_lhs->copy(), loc);
8910 inserter->insert(assign);
8911 }
321e5ad2 8912
38ba9eec 8913 Type* uintptr_type = Type::lookup_integer_type("uintptr");
8914
321e5ad2 8915 if (this->is_varargs())
8916 {
38ba9eec 8917 if (makecall != NULL)
7fdb0876 8918 {
38ba9eec 8919 // memclr(&s1tmp[l1tmp], l2tmp*sizeof(elem))
7fdb0876 8920 a1 = Expression::make_temporary_reference(s1tmp, loc);
8921 ref = Expression::make_temporary_reference(l1tmp, loc);
8922 a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
8923 a1->array_index_expression()->set_needs_bounds_check(false);
8924 a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
8925
7fdb0876 8926 ref = Expression::make_temporary_reference(l2tmp, loc);
8927 ref = Expression::make_cast(uintptr_type, ref, loc);
38ba9eec 8928 a2 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
8929 a2 = Expression::make_binary(OPERATOR_MULT, a2, ref, loc);
7fdb0876 8930
07ccb2ee 8931 if (element_type->has_pointer())
8932 call = Runtime::make_call(Runtime::MEMCLRHASPTR, loc, 2, a1, a2);
8933 else
8934 {
8935 Type* int32_type = Type::lookup_integer_type("int32");
8936 Expression* zero =
8937 Expression::make_integer_ul(0, int32_type, loc);
8938 call = Runtime::make_call(Runtime::BUILTIN_MEMSET, loc, 3, a1,
8939 zero, a2);
8940 }
38ba9eec 8941
8942 if (element_type->has_pointer())
8943 {
8944 // For a slice containing pointers, growslice already zeroed
8945 // the memory. We only need to zero in non-growing case.
8946 // Note: growslice does not zero the memory in non-pointer case.
8947 Expression* left =
8948 Expression::make_temporary_reference(ntmp, loc);
8949 left = Expression::make_cast(uint_type, left, loc);
8950 Expression* right =
8951 Expression::make_temporary_reference(c1tmp, loc);
8952 right = Expression::make_cast(uint_type, right, loc);
8953 Expression* cond =
8954 Expression::make_binary(OPERATOR_GT, left, right, loc);
8955 Expression* zero = Expression::make_integer_ul(0, int_type, loc);
8956 call = Expression::make_conditional(cond, call, zero, loc);
8957 }
8958 }
8959 else
8960 {
8961 if (element_type->has_pointer())
8962 {
8963 // copy(s1tmp[l1tmp:], s2tmp)
8964 a1 = Expression::make_temporary_reference(s1tmp, loc);
8965 ref = Expression::make_temporary_reference(l1tmp, loc);
8966 Expression* nil = Expression::make_nil(loc);
8967 a1 = Expression::make_array_index(a1, ref, nil, NULL, loc);
8968 a1->array_index_expression()->set_needs_bounds_check(false);
8969
8970 a2 = Expression::make_temporary_reference(s2tmp, loc);
8971
8972 Named_object* copyfn = gogo->lookup_global("copy");
8973 Expression* copyref = Expression::make_func_reference(copyfn, NULL, loc);
8974 call_args = new Expression_list();
8975 call_args->push_back(a1);
8976 call_args->push_back(a2);
8977 call = Expression::make_call(copyref, call_args, false, loc);
8978 }
8979 else
8980 {
8981 // memmove(&s1tmp[l1tmp], s2tmp.ptr, l2tmp*sizeof(elem))
8982 a1 = Expression::make_temporary_reference(s1tmp, loc);
8983 ref = Expression::make_temporary_reference(l1tmp, loc);
8984 a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
8985 a1->array_index_expression()->set_needs_bounds_check(false);
8986 a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
8987
8988 a2 = Expression::make_temporary_reference(s2tmp, loc);
8989 a2 = (a2->type()->is_string_type()
8990 ? Expression::make_string_info(a2,
8991 STRING_INFO_DATA,
8992 loc)
8993 : Expression::make_slice_info(a2,
8994 SLICE_INFO_VALUE_POINTER,
8995 loc));
8996
8997 ref = Expression::make_temporary_reference(l2tmp, loc);
8998 ref = Expression::make_cast(uintptr_type, ref, loc);
8999 a3 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
9000 a3 = Expression::make_binary(OPERATOR_MULT, a3, ref, loc);
9001
9002 call = Runtime::make_call(Runtime::BUILTIN_MEMMOVE, loc, 3,
9003 a1, a2, a3);
9004 }
7fdb0876 9005 }
321e5ad2 9006 gogo->lower_expression(function, inserter, &call);
9007 gogo->flatten_expression(function, inserter, &call);
9008 inserter->insert(Statement::make_statement(call, false));
9009 }
9010 else
9011 {
9012 // For each argument:
9013 // s1tmp[l1tmp+i] = a
9014 unsigned long i = 0;
9015 for (Expression_list::const_iterator pa = add->begin();
9016 pa != add->end();
9017 ++pa, ++i)
9018 {
9019 ref = Expression::make_temporary_reference(s1tmp, loc);
9020 ref2 = Expression::make_temporary_reference(l1tmp, loc);
9021 Expression* off = Expression::make_integer_ul(i, int_type, loc);
9022 ref2 = Expression::make_binary(OPERATOR_PLUS, ref2, off, loc);
3d135120 9023 Expression* lhs = Expression::make_array_index(ref, ref2, NULL,
9024 NULL, loc);
9025 lhs->array_index_expression()->set_needs_bounds_check(false);
321e5ad2 9026 gogo->lower_expression(function, inserter, &lhs);
9027 gogo->flatten_expression(function, inserter, &lhs);
e007b1eb 9028 Expression* elem = *pa;
9029 if (!Type::are_identical(element_type, elem->type(), 0, NULL)
9030 && element_type->interface_type() != NULL)
9031 elem = Expression::make_cast(element_type, elem, loc);
03118c21 9032 // The flatten pass runs after the write barrier pass, so we
9033 // need to insert a write barrier here if necessary.
d3c55148 9034 // However, if ASSIGN_LHS is not NULL, we have been called
9035 // directly before the write barrier pass.
9036 Statement* assign;
9037 if (assign_lhs != NULL
9038 || !gogo->assign_needs_write_barrier(lhs))
e007b1eb 9039 assign = Statement::make_assignment(lhs, elem, loc);
03118c21 9040 else
9041 {
9042 Function* f = function == NULL ? NULL : function->func_value();
9043 assign = gogo->assign_with_write_barrier(f, NULL, inserter,
e007b1eb 9044 lhs, elem, loc);
03118c21 9045 }
321e5ad2 9046 inserter->insert(assign);
9047 }
9048 }
9049
d3c55148 9050 if (assign_lhs != NULL)
9051 return NULL;
9052
321e5ad2 9053 return Expression::make_temporary_reference(s1tmp, loc);
9054}
9055
a9182619 9056// Return whether an expression has an integer value. Report an error
9057// if not. This is used when handling calls to the predeclared make
ccea2b36 9058// function. Set *SMALL if the value is known to fit in type "int".
a9182619 9059
9060bool
ccea2b36 9061Builtin_call_expression::check_int_value(Expression* e, bool is_length,
9062 bool *small)
a9182619 9063{
ccea2b36 9064 *small = false;
9065
0c77715b 9066 Numeric_constant nc;
1ad00fd4 9067 if (e->numeric_constant_value(&nc))
a9182619 9068 {
1ad00fd4 9069 unsigned long v;
9070 switch (nc.to_unsigned_long(&v))
9071 {
9072 case Numeric_constant::NC_UL_VALID:
1b10c5e7 9073 break;
1ad00fd4 9074 case Numeric_constant::NC_UL_NOTINT:
631d5788 9075 go_error_at(e->location(), "non-integer %s argument to make",
9076 is_length ? "len" : "cap");
1ad00fd4 9077 return false;
9078 case Numeric_constant::NC_UL_NEGATIVE:
631d5788 9079 go_error_at(e->location(), "negative %s argument to make",
9080 is_length ? "len" : "cap");
1ad00fd4 9081 return false;
9082 case Numeric_constant::NC_UL_BIG:
9083 // We don't want to give a compile-time error for a 64-bit
9084 // value on a 32-bit target.
1b10c5e7 9085 break;
1ad00fd4 9086 }
1b10c5e7 9087
9088 mpz_t val;
9089 if (!nc.to_int(&val))
9090 go_unreachable();
9091 int bits = mpz_sizeinbase(val, 2);
9092 mpz_clear(val);
9093 Type* int_type = Type::lookup_integer_type("int");
9094 if (bits >= int_type->integer_type()->bits())
9095 {
631d5788 9096 go_error_at(e->location(), "%s argument too large for make",
9097 is_length ? "len" : "cap");
1b10c5e7 9098 return false;
9099 }
9100
ccea2b36 9101 *small = true;
1b10c5e7 9102 return true;
a9182619 9103 }
9104
1ad00fd4 9105 if (e->type()->integer_type() != NULL)
ccea2b36 9106 {
9107 int ebits = e->type()->integer_type()->bits();
9108 int intbits = Type::lookup_integer_type("int")->integer_type()->bits();
9109
9110 // We can treat ebits == intbits as small even for an unsigned
9111 // integer type, because we will convert the value to int and
9112 // then reject it in the runtime if it is negative.
9113 *small = ebits <= intbits;
9114
9115 return true;
9116 }
1ad00fd4 9117
631d5788 9118 go_error_at(e->location(), "non-integer %s argument to make",
9119 is_length ? "len" : "cap");
a9182619 9120 return false;
9121}
9122
e440a328 9123// Return the type of the real or imag functions, given the type of
fcbea5e4 9124// the argument. We need to map complex64 to float32 and complex128
9125// to float64, so it has to be done by name. This returns NULL if it
9126// can't figure out the type.
e440a328 9127
9128Type*
9129Builtin_call_expression::real_imag_type(Type* arg_type)
9130{
9131 if (arg_type == NULL || arg_type->is_abstract())
9132 return NULL;
9133 Named_type* nt = arg_type->named_type();
9134 if (nt == NULL)
9135 return NULL;
9136 while (nt->real_type()->named_type() != NULL)
9137 nt = nt->real_type()->named_type();
48080209 9138 if (nt->name() == "complex64")
e440a328 9139 return Type::lookup_float_type("float32");
9140 else if (nt->name() == "complex128")
9141 return Type::lookup_float_type("float64");
9142 else
9143 return NULL;
9144}
9145
48080209 9146// Return the type of the complex function, given the type of one of the
e440a328 9147// argments. Like real_imag_type, we have to map by name.
9148
9149Type*
48080209 9150Builtin_call_expression::complex_type(Type* arg_type)
e440a328 9151{
9152 if (arg_type == NULL || arg_type->is_abstract())
9153 return NULL;
9154 Named_type* nt = arg_type->named_type();
9155 if (nt == NULL)
9156 return NULL;
9157 while (nt->real_type()->named_type() != NULL)
9158 nt = nt->real_type()->named_type();
48080209 9159 if (nt->name() == "float32")
e440a328 9160 return Type::lookup_complex_type("complex64");
9161 else if (nt->name() == "float64")
9162 return Type::lookup_complex_type("complex128");
9163 else
9164 return NULL;
9165}
9166
9167// Return a single argument, or NULL if there isn't one.
9168
9169Expression*
9170Builtin_call_expression::one_arg() const
9171{
9172 const Expression_list* args = this->args();
aa615cb3 9173 if (args == NULL || args->size() != 1)
e440a328 9174 return NULL;
9175 return args->front();
9176}
9177
83921647 9178// A traversal class which looks for a call or receive expression.
9179
9180class Find_call_expression : public Traverse
9181{
9182 public:
9183 Find_call_expression()
9184 : Traverse(traverse_expressions),
9185 found_(false)
9186 { }
9187
9188 int
9189 expression(Expression**);
9190
9191 bool
9192 found()
9193 { return this->found_; }
9194
9195 private:
9196 bool found_;
9197};
9198
9199int
9200Find_call_expression::expression(Expression** pexpr)
9201{
4714afb2 9202 Expression* expr = *pexpr;
9203 if (!expr->is_constant()
9204 && (expr->call_expression() != NULL
9205 || expr->receive_expression() != NULL))
83921647 9206 {
9207 this->found_ = true;
9208 return TRAVERSE_EXIT;
9209 }
9210 return TRAVERSE_CONTINUE;
9211}
9212
4714afb2 9213// Return whether calling len or cap on EXPR, of array type, is a
9214// constant. The language spec says "the expressions len(s) and
9215// cap(s) are constants if the type of s is an array or pointer to an
9216// array and the expression s does not contain channel receives or
9217// (non-constant) function calls."
9218
9219bool
9220Builtin_call_expression::array_len_is_constant(Expression* expr)
9221{
9222 go_assert(expr->type()->deref()->array_type() != NULL
9223 && !expr->type()->deref()->is_slice_type());
9224 if (expr->is_constant())
9225 return true;
9226 Find_call_expression find_call;
9227 Expression::traverse(&expr, &find_call);
9228 return !find_call.found();
9229}
9230
83921647 9231// Return whether this is constant: len of a string constant, or len
9232// or cap of an array, or unsafe.Sizeof, unsafe.Offsetof,
9233// unsafe.Alignof.
e440a328 9234
9235bool
9236Builtin_call_expression::do_is_constant() const
9237{
12e69faa 9238 if (this->is_error_expression())
9239 return true;
e440a328 9240 switch (this->code_)
9241 {
9242 case BUILTIN_LEN:
9243 case BUILTIN_CAP:
9244 {
0f914071 9245 if (this->seen_)
9246 return false;
9247
e440a328 9248 Expression* arg = this->one_arg();
9249 if (arg == NULL)
9250 return false;
9251 Type* arg_type = arg->type();
9252
9253 if (arg_type->points_to() != NULL
9254 && arg_type->points_to()->array_type() != NULL
411eb89e 9255 && !arg_type->points_to()->is_slice_type())
e440a328 9256 arg_type = arg_type->points_to();
9257
9258 if (arg_type->array_type() != NULL
54934d77 9259 && arg_type->array_type()->length() != NULL)
9260 {
9261 this->seen_ = true;
9262 bool ret = Builtin_call_expression::array_len_is_constant(arg);
9263 this->seen_ = false;
9264 return ret;
9265 }
e440a328 9266
9267 if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
0f914071 9268 {
9269 this->seen_ = true;
9270 bool ret = arg->is_constant();
9271 this->seen_ = false;
9272 return ret;
9273 }
e440a328 9274 }
9275 break;
9276
9277 case BUILTIN_SIZEOF:
9278 case BUILTIN_ALIGNOF:
9279 return this->one_arg() != NULL;
9280
9281 case BUILTIN_OFFSETOF:
9282 {
9283 Expression* arg = this->one_arg();
9284 if (arg == NULL)
9285 return false;
9286 return arg->field_reference_expression() != NULL;
9287 }
9288
48080209 9289 case BUILTIN_COMPLEX:
e440a328 9290 {
9291 const Expression_list* args = this->args();
9292 if (args != NULL && args->size() == 2)
9293 return args->front()->is_constant() && args->back()->is_constant();
9294 }
9295 break;
9296
9297 case BUILTIN_REAL:
9298 case BUILTIN_IMAG:
9299 {
9300 Expression* arg = this->one_arg();
9301 return arg != NULL && arg->is_constant();
9302 }
9303
9304 default:
9305 break;
9306 }
9307
9308 return false;
9309}
9310
0c77715b 9311// Return a numeric constant if possible.
e440a328 9312
9313bool
0c77715b 9314Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 9315{
9316 if (this->code_ == BUILTIN_LEN
9317 || this->code_ == BUILTIN_CAP)
9318 {
9319 Expression* arg = this->one_arg();
9320 if (arg == NULL)
9321 return false;
9322 Type* arg_type = arg->type();
9323
9324 if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
9325 {
9326 std::string sval;
9327 if (arg->string_constant_value(&sval))
9328 {
0c77715b 9329 nc->set_unsigned_long(Type::lookup_integer_type("int"),
9330 sval.length());
e440a328 9331 return true;
9332 }
9333 }
9334
9335 if (arg_type->points_to() != NULL
9336 && arg_type->points_to()->array_type() != NULL
411eb89e 9337 && !arg_type->points_to()->is_slice_type())
e440a328 9338 arg_type = arg_type->points_to();
9339
9340 if (arg_type->array_type() != NULL
9341 && arg_type->array_type()->length() != NULL)
9342 {
0f914071 9343 if (this->seen_)
9344 return false;
e440a328 9345 Expression* e = arg_type->array_type()->length();
0f914071 9346 this->seen_ = true;
0c77715b 9347 bool r = e->numeric_constant_value(nc);
0f914071 9348 this->seen_ = false;
9349 if (r)
e440a328 9350 {
0c77715b 9351 if (!nc->set_type(Type::lookup_integer_type("int"), false,
9352 this->location()))
9353 r = false;
e440a328 9354 }
0c77715b 9355 return r;
e440a328 9356 }
9357 }
9358 else if (this->code_ == BUILTIN_SIZEOF
9359 || this->code_ == BUILTIN_ALIGNOF)
9360 {
9361 Expression* arg = this->one_arg();
9362 if (arg == NULL)
9363 return false;
9364 Type* arg_type = arg->type();
5c13bd80 9365 if (arg_type->is_error())
e440a328 9366 return false;
9367 if (arg_type->is_abstract())
7200ac0e 9368 arg_type = arg_type->make_non_abstract_type();
2c809f8f 9369 if (this->seen_)
9370 return false;
927a01eb 9371
3f378015 9372 int64_t ret;
e440a328 9373 if (this->code_ == BUILTIN_SIZEOF)
9374 {
2c809f8f 9375 this->seen_ = true;
9376 bool ok = arg_type->backend_type_size(this->gogo_, &ret);
9377 this->seen_ = false;
9378 if (!ok)
e440a328 9379 return false;
9380 }
9381 else if (this->code_ == BUILTIN_ALIGNOF)
9382 {
2c809f8f 9383 bool ok;
9384 this->seen_ = true;
637bd3af 9385 if (arg->field_reference_expression() == NULL)
2c809f8f 9386 ok = arg_type->backend_type_align(this->gogo_, &ret);
637bd3af 9387 else
e440a328 9388 {
9389 // Calling unsafe.Alignof(s.f) returns the alignment of
9390 // the type of f when it is used as a field in a struct.
2c809f8f 9391 ok = arg_type->backend_type_field_align(this->gogo_, &ret);
e440a328 9392 }
2c809f8f 9393 this->seen_ = false;
9394 if (!ok)
9395 return false;
e440a328 9396 }
9397 else
c3e6f413 9398 go_unreachable();
927a01eb 9399
3f378015 9400 mpz_t zval;
9401 set_mpz_from_int64(&zval, ret);
9402 nc->set_int(Type::lookup_integer_type("uintptr"), zval);
9403 mpz_clear(zval);
e440a328 9404 return true;
9405 }
9406 else if (this->code_ == BUILTIN_OFFSETOF)
9407 {
9408 Expression* arg = this->one_arg();
9409 if (arg == NULL)
9410 return false;
9411 Field_reference_expression* farg = arg->field_reference_expression();
9412 if (farg == NULL)
9413 return false;
2c809f8f 9414 if (this->seen_)
9415 return false;
9416
3f378015 9417 int64_t total_offset = 0;
9a4bd570 9418 while (true)
9419 {
9420 Expression* struct_expr = farg->expr();
9421 Type* st = struct_expr->type();
9422 if (st->struct_type() == NULL)
9423 return false;
9424 if (st->named_type() != NULL)
9425 st->named_type()->convert(this->gogo_);
fbabafbd 9426 if (st->is_error_type())
9427 {
9428 go_assert(saw_errors());
9429 return false;
9430 }
3f378015 9431 int64_t offset;
2c809f8f 9432 this->seen_ = true;
9433 bool ok = st->struct_type()->backend_field_offset(this->gogo_,
9434 farg->field_index(),
9435 &offset);
9436 this->seen_ = false;
9437 if (!ok)
9438 return false;
9a4bd570 9439 total_offset += offset;
9440 if (farg->implicit() && struct_expr->field_reference_expression() != NULL)
9441 {
9442 // Go up until we reach the original base.
9443 farg = struct_expr->field_reference_expression();
9444 continue;
9445 }
9446 break;
9447 }
3f378015 9448 mpz_t zval;
9449 set_mpz_from_int64(&zval, total_offset);
9450 nc->set_int(Type::lookup_integer_type("uintptr"), zval);
9451 mpz_clear(zval);
e440a328 9452 return true;
9453 }
0c77715b 9454 else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG)
e440a328 9455 {
9456 Expression* arg = this->one_arg();
9457 if (arg == NULL)
9458 return false;
9459
0c77715b 9460 Numeric_constant argnc;
9461 if (!arg->numeric_constant_value(&argnc))
9462 return false;
9463
fcbea5e4 9464 mpc_t val;
9465 if (!argnc.to_complex(&val))
0c77715b 9466 return false;
e440a328 9467
0c77715b 9468 Type* type = Builtin_call_expression::real_imag_type(argnc.type());
9469 if (this->code_ == BUILTIN_REAL)
fcbea5e4 9470 nc->set_float(type, mpc_realref(val));
0c77715b 9471 else
fcbea5e4 9472 nc->set_float(type, mpc_imagref(val));
9473 mpc_clear(val);
0c77715b 9474 return true;
e440a328 9475 }
0c77715b 9476 else if (this->code_ == BUILTIN_COMPLEX)
e440a328 9477 {
9478 const Expression_list* args = this->args();
9479 if (args == NULL || args->size() != 2)
9480 return false;
9481
0c77715b 9482 Numeric_constant rnc;
9483 if (!args->front()->numeric_constant_value(&rnc))
9484 return false;
9485 Numeric_constant inc;
9486 if (!args->back()->numeric_constant_value(&inc))
9487 return false;
9488
9489 if (rnc.type() != NULL
9490 && !rnc.type()->is_abstract()
9491 && inc.type() != NULL
9492 && !inc.type()->is_abstract()
3a522dcc 9493 && !Type::are_identical(rnc.type(), inc.type(),
9494 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
9495 NULL))
0c77715b 9496 return false;
9497
e440a328 9498 mpfr_t r;
0c77715b 9499 if (!rnc.to_float(&r))
9500 return false;
9501 mpfr_t i;
9502 if (!inc.to_float(&i))
e440a328 9503 {
9504 mpfr_clear(r);
9505 return false;
9506 }
9507
0c77715b 9508 Type* arg_type = rnc.type();
9509 if (arg_type == NULL || arg_type->is_abstract())
9510 arg_type = inc.type();
e440a328 9511
fcbea5e4 9512 mpc_t val;
9513 mpc_init2(val, mpc_precision);
9514 mpc_set_fr_fr(val, r, i, MPC_RNDNN);
e440a328 9515 mpfr_clear(r);
9516 mpfr_clear(i);
9517
fcbea5e4 9518 Type* type = Builtin_call_expression::complex_type(arg_type);
9519 nc->set_complex(type, val);
9520
9521 mpc_clear(val);
9522
0c77715b 9523 return true;
e440a328 9524 }
9525
9526 return false;
9527}
9528
a7549a6a 9529// Give an error if we are discarding the value of an expression which
9530// should not normally be discarded. We don't give an error for
9531// discarding the value of an ordinary function call, but we do for
9532// builtin functions, purely for consistency with the gc compiler.
9533
4f2138d7 9534bool
a7549a6a 9535Builtin_call_expression::do_discarding_value()
9536{
9537 switch (this->code_)
9538 {
9539 case BUILTIN_INVALID:
9540 default:
9541 go_unreachable();
9542
9543 case BUILTIN_APPEND:
9544 case BUILTIN_CAP:
9545 case BUILTIN_COMPLEX:
9546 case BUILTIN_IMAG:
9547 case BUILTIN_LEN:
9548 case BUILTIN_MAKE:
9549 case BUILTIN_NEW:
9550 case BUILTIN_REAL:
9551 case BUILTIN_ALIGNOF:
9552 case BUILTIN_OFFSETOF:
9553 case BUILTIN_SIZEOF:
9554 this->unused_value_error();
4f2138d7 9555 return false;
a7549a6a 9556
9557 case BUILTIN_CLOSE:
9558 case BUILTIN_COPY:
1cce762f 9559 case BUILTIN_DELETE:
a7549a6a 9560 case BUILTIN_PANIC:
9561 case BUILTIN_PRINT:
9562 case BUILTIN_PRINTLN:
9563 case BUILTIN_RECOVER:
4f2138d7 9564 return true;
a7549a6a 9565 }
9566}
9567
e440a328 9568// Return the type.
9569
9570Type*
9571Builtin_call_expression::do_type()
9572{
79651b1f 9573 if (this->is_error_expression())
9574 return Type::make_error_type();
e440a328 9575 switch (this->code_)
9576 {
9577 case BUILTIN_INVALID:
9578 default:
79651b1f 9579 return Type::make_error_type();
e440a328 9580
9581 case BUILTIN_NEW:
e440a328 9582 {
9583 const Expression_list* args = this->args();
9584 if (args == NULL || args->empty())
9585 return Type::make_error_type();
9586 return Type::make_pointer_type(args->front()->type());
9587 }
9588
a065edc5 9589 case BUILTIN_MAKE:
9590 {
9591 const Expression_list* args = this->args();
9592 if (args == NULL || args->empty())
9593 return Type::make_error_type();
9594 return args->front()->type();
9595 }
9596
e440a328 9597 case BUILTIN_CAP:
9598 case BUILTIN_COPY:
9599 case BUILTIN_LEN:
7ba86326 9600 return Type::lookup_integer_type("int");
9601
e440a328 9602 case BUILTIN_ALIGNOF:
9603 case BUILTIN_OFFSETOF:
9604 case BUILTIN_SIZEOF:
7ba86326 9605 return Type::lookup_integer_type("uintptr");
e440a328 9606
9607 case BUILTIN_CLOSE:
1cce762f 9608 case BUILTIN_DELETE:
e440a328 9609 case BUILTIN_PANIC:
9610 case BUILTIN_PRINT:
9611 case BUILTIN_PRINTLN:
9612 return Type::make_void_type();
9613
e440a328 9614 case BUILTIN_RECOVER:
823c7e3d 9615 return Type::make_empty_interface_type(Linemap::predeclared_location());
e440a328 9616
9617 case BUILTIN_APPEND:
9618 {
9619 const Expression_list* args = this->args();
9620 if (args == NULL || args->empty())
9621 return Type::make_error_type();
3ff4863b 9622 Type *ret = args->front()->type();
9623 if (!ret->is_slice_type())
9624 return Type::make_error_type();
9625 return ret;
e440a328 9626 }
9627
9628 case BUILTIN_REAL:
9629 case BUILTIN_IMAG:
9630 {
9631 Expression* arg = this->one_arg();
9632 if (arg == NULL)
9633 return Type::make_error_type();
9634 Type* t = arg->type();
9635 if (t->is_abstract())
9636 t = t->make_non_abstract_type();
9637 t = Builtin_call_expression::real_imag_type(t);
9638 if (t == NULL)
9639 t = Type::make_error_type();
9640 return t;
9641 }
9642
48080209 9643 case BUILTIN_COMPLEX:
e440a328 9644 {
9645 const Expression_list* args = this->args();
9646 if (args == NULL || args->size() != 2)
9647 return Type::make_error_type();
9648 Type* t = args->front()->type();
9649 if (t->is_abstract())
9650 {
9651 t = args->back()->type();
9652 if (t->is_abstract())
9653 t = t->make_non_abstract_type();
9654 }
48080209 9655 t = Builtin_call_expression::complex_type(t);
e440a328 9656 if (t == NULL)
9657 t = Type::make_error_type();
9658 return t;
9659 }
9660 }
9661}
9662
9663// Determine the type.
9664
9665void
9666Builtin_call_expression::do_determine_type(const Type_context* context)
9667{
fb94b0ca 9668 if (!this->determining_types())
9669 return;
9670
e440a328 9671 this->fn()->determine_type_no_context();
9672
9673 const Expression_list* args = this->args();
9674
9675 bool is_print;
9676 Type* arg_type = NULL;
321e5ad2 9677 Type* trailing_arg_types = NULL;
e440a328 9678 switch (this->code_)
9679 {
9680 case BUILTIN_PRINT:
9681 case BUILTIN_PRINTLN:
9682 // Do not force a large integer constant to "int".
9683 is_print = true;
9684 break;
9685
9686 case BUILTIN_REAL:
9687 case BUILTIN_IMAG:
48080209 9688 arg_type = Builtin_call_expression::complex_type(context->type);
f6bc81e6 9689 if (arg_type == NULL)
9690 arg_type = Type::lookup_complex_type("complex128");
e440a328 9691 is_print = false;
9692 break;
9693
48080209 9694 case BUILTIN_COMPLEX:
e440a328 9695 {
48080209 9696 // For the complex function the type of one operand can
e440a328 9697 // determine the type of the other, as in a binary expression.
9698 arg_type = Builtin_call_expression::real_imag_type(context->type);
f6bc81e6 9699 if (arg_type == NULL)
9700 arg_type = Type::lookup_float_type("float64");
e440a328 9701 if (args != NULL && args->size() == 2)
9702 {
9703 Type* t1 = args->front()->type();
c849bb59 9704 Type* t2 = args->back()->type();
e440a328 9705 if (!t1->is_abstract())
9706 arg_type = t1;
9707 else if (!t2->is_abstract())
9708 arg_type = t2;
9709 }
9710 is_print = false;
9711 }
9712 break;
9713
321e5ad2 9714 case BUILTIN_APPEND:
9715 if (!this->is_varargs()
9716 && args != NULL
9717 && !args->empty()
9718 && args->front()->type()->is_slice_type())
9719 trailing_arg_types =
9720 args->front()->type()->array_type()->element_type();
9721 is_print = false;
9722 break;
9723
e440a328 9724 default:
9725 is_print = false;
9726 break;
9727 }
9728
9729 if (args != NULL)
9730 {
9731 for (Expression_list::const_iterator pa = args->begin();
9732 pa != args->end();
9733 ++pa)
9734 {
9735 Type_context subcontext;
9736 subcontext.type = arg_type;
9737
9738 if (is_print)
9739 {
9740 // We want to print large constants, we so can't just
9741 // use the appropriate nonabstract type. Use uint64 for
9742 // an integer if we know it is nonnegative, otherwise
9743 // use int64 for a integer, otherwise use float64 for a
9744 // float or complex128 for a complex.
9745 Type* want_type = NULL;
9746 Type* atype = (*pa)->type();
9747 if (atype->is_abstract())
9748 {
9749 if (atype->integer_type() != NULL)
9750 {
0c77715b 9751 Numeric_constant nc;
9752 if (this->numeric_constant_value(&nc))
9753 {
9754 mpz_t val;
9755 if (nc.to_int(&val))
9756 {
9757 if (mpz_sgn(val) >= 0)
9758 want_type = Type::lookup_integer_type("uint64");
9759 mpz_clear(val);
9760 }
9761 }
9762 if (want_type == NULL)
e440a328 9763 want_type = Type::lookup_integer_type("int64");
e440a328 9764 }
9765 else if (atype->float_type() != NULL)
9766 want_type = Type::lookup_float_type("float64");
9767 else if (atype->complex_type() != NULL)
9768 want_type = Type::lookup_complex_type("complex128");
9769 else if (atype->is_abstract_string_type())
9770 want_type = Type::lookup_string_type();
9771 else if (atype->is_abstract_boolean_type())
9772 want_type = Type::lookup_bool_type();
9773 else
c3e6f413 9774 go_unreachable();
e440a328 9775 subcontext.type = want_type;
9776 }
9777 }
9778
9779 (*pa)->determine_type(&subcontext);
321e5ad2 9780
9781 if (trailing_arg_types != NULL)
9782 {
9783 arg_type = trailing_arg_types;
9784 trailing_arg_types = NULL;
9785 }
e440a328 9786 }
9787 }
9788}
9789
9790// If there is exactly one argument, return true. Otherwise give an
9791// error message and return false.
9792
9793bool
9794Builtin_call_expression::check_one_arg()
9795{
9796 const Expression_list* args = this->args();
9797 if (args == NULL || args->size() < 1)
9798 {
9799 this->report_error(_("not enough arguments"));
9800 return false;
9801 }
9802 else if (args->size() > 1)
9803 {
9804 this->report_error(_("too many arguments"));
9805 return false;
9806 }
9807 if (args->front()->is_error_expression()
5c13bd80 9808 || args->front()->type()->is_error())
e440a328 9809 {
9810 this->set_is_error();
9811 return false;
9812 }
9813 return true;
9814}
9815
9816// Check argument types for a builtin function.
9817
9818void
9819Builtin_call_expression::do_check_types(Gogo*)
9820{
375646ea 9821 if (this->is_error_expression())
9822 return;
e440a328 9823 switch (this->code_)
9824 {
9825 case BUILTIN_INVALID:
9826 case BUILTIN_NEW:
9827 case BUILTIN_MAKE:
cd238b8d 9828 case BUILTIN_DELETE:
e440a328 9829 return;
9830
9831 case BUILTIN_LEN:
9832 case BUILTIN_CAP:
9833 {
9834 // The single argument may be either a string or an array or a
9835 // map or a channel, or a pointer to a closed array.
9836 if (this->check_one_arg())
9837 {
9838 Type* arg_type = this->one_arg()->type();
9839 if (arg_type->points_to() != NULL
9840 && arg_type->points_to()->array_type() != NULL
411eb89e 9841 && !arg_type->points_to()->is_slice_type())
e440a328 9842 arg_type = arg_type->points_to();
9843 if (this->code_ == BUILTIN_CAP)
9844 {
5c13bd80 9845 if (!arg_type->is_error()
e440a328 9846 && arg_type->array_type() == NULL
9847 && arg_type->channel_type() == NULL)
9848 this->report_error(_("argument must be array or slice "
9849 "or channel"));
9850 }
9851 else
9852 {
5c13bd80 9853 if (!arg_type->is_error()
e440a328 9854 && !arg_type->is_string_type()
9855 && arg_type->array_type() == NULL
9856 && arg_type->map_type() == NULL
9857 && arg_type->channel_type() == NULL)
9858 this->report_error(_("argument must be string or "
9859 "array or slice or map or channel"));
9860 }
9861 }
9862 }
9863 break;
9864
9865 case BUILTIN_PRINT:
9866 case BUILTIN_PRINTLN:
9867 {
9868 const Expression_list* args = this->args();
9869 if (args == NULL)
9870 {
9871 if (this->code_ == BUILTIN_PRINT)
631d5788 9872 go_warning_at(this->location(), 0,
37423a84 9873 "no arguments for built-in function %<%s%>",
e440a328 9874 (this->code_ == BUILTIN_PRINT
9875 ? "print"
9876 : "println"));
9877 }
9878 else
9879 {
9880 for (Expression_list::const_iterator p = args->begin();
9881 p != args->end();
9882 ++p)
9883 {
9884 Type* type = (*p)->type();
5c13bd80 9885 if (type->is_error()
e440a328 9886 || type->is_string_type()
9887 || type->integer_type() != NULL
9888 || type->float_type() != NULL
9889 || type->complex_type() != NULL
9890 || type->is_boolean_type()
9891 || type->points_to() != NULL
9892 || type->interface_type() != NULL
9893 || type->channel_type() != NULL
9894 || type->map_type() != NULL
9895 || type->function_type() != NULL
411eb89e 9896 || type->is_slice_type())
e440a328 9897 ;
acf8e158 9898 else if ((*p)->is_type_expression())
9899 {
9900 // If this is a type expression it's going to give
9901 // an error anyhow, so we don't need one here.
9902 }
e440a328 9903 else
9904 this->report_error(_("unsupported argument type to "
9905 "builtin function"));
9906 }
9907 }
9908 }
9909 break;
9910
9911 case BUILTIN_CLOSE:
e440a328 9912 if (this->check_one_arg())
9913 {
9914 if (this->one_arg()->type()->channel_type() == NULL)
9915 this->report_error(_("argument must be channel"));
5202d986 9916 else if (!this->one_arg()->type()->channel_type()->may_send())
9917 this->report_error(_("cannot close receive-only channel"));
e440a328 9918 }
9919 break;
9920
9921 case BUILTIN_PANIC:
9922 case BUILTIN_SIZEOF:
9923 case BUILTIN_ALIGNOF:
9924 this->check_one_arg();
9925 break;
9926
9927 case BUILTIN_RECOVER:
6334270b 9928 if (this->args() != NULL
9929 && !this->args()->empty()
9930 && !this->recover_arg_is_set_)
e440a328 9931 this->report_error(_("too many arguments"));
9932 break;
9933
9934 case BUILTIN_OFFSETOF:
9935 if (this->check_one_arg())
9936 {
9937 Expression* arg = this->one_arg();
9938 if (arg->field_reference_expression() == NULL)
9939 this->report_error(_("argument must be a field reference"));
9940 }
9941 break;
9942
9943 case BUILTIN_COPY:
9944 {
9945 const Expression_list* args = this->args();
9946 if (args == NULL || args->size() < 2)
9947 {
9948 this->report_error(_("not enough arguments"));
9949 break;
9950 }
9951 else if (args->size() > 2)
9952 {
9953 this->report_error(_("too many arguments"));
9954 break;
9955 }
9956 Type* arg1_type = args->front()->type();
9957 Type* arg2_type = args->back()->type();
5c13bd80 9958 if (arg1_type->is_error() || arg2_type->is_error())
6bebb39d 9959 {
9960 this->set_is_error();
9961 break;
9962 }
e440a328 9963
9964 Type* e1;
411eb89e 9965 if (arg1_type->is_slice_type())
e440a328 9966 e1 = arg1_type->array_type()->element_type();
9967 else
9968 {
9969 this->report_error(_("left argument must be a slice"));
9970 break;
9971 }
9972
411eb89e 9973 if (arg2_type->is_slice_type())
60963afd 9974 {
9975 Type* e2 = arg2_type->array_type()->element_type();
3a522dcc 9976 if (!Type::are_identical(e1, e2, Type::COMPARE_TAGS, NULL))
60963afd 9977 this->report_error(_("element types must be the same"));
9978 }
e440a328 9979 else if (arg2_type->is_string_type())
e440a328 9980 {
60963afd 9981 if (e1->integer_type() == NULL || !e1->integer_type()->is_byte())
9982 this->report_error(_("first argument must be []byte"));
e440a328 9983 }
60963afd 9984 else
9985 this->report_error(_("second argument must be slice or string"));
e440a328 9986 }
9987 break;
9988
9989 case BUILTIN_APPEND:
9990 {
9991 const Expression_list* args = this->args();
321e5ad2 9992 if (args == NULL || args->empty())
e440a328 9993 {
9994 this->report_error(_("not enough arguments"));
9995 break;
9996 }
321e5ad2 9997
9998 Type* slice_type = args->front()->type();
9999 if (!slice_type->is_slice_type())
6bebb39d 10000 {
321e5ad2 10001 if (slice_type->is_error_type())
10002 break;
10003 if (slice_type->is_nil_type())
10004 go_error_at(args->front()->location(), "use of untyped nil");
10005 else
10006 go_error_at(args->front()->location(),
10007 "argument 1 must be a slice");
6bebb39d 10008 this->set_is_error();
10009 break;
10010 }
cd238b8d 10011
321e5ad2 10012 Type* element_type = slice_type->array_type()->element_type();
22deed0d 10013 if (!element_type->in_heap())
10014 go_error_at(args->front()->location(),
37423a84 10015 "cannot append to slice of go:notinheap type");
321e5ad2 10016 if (this->is_varargs())
4fd4fcf4 10017 {
321e5ad2 10018 if (!args->back()->type()->is_slice_type()
10019 && !args->back()->type()->is_string_type())
10020 {
10021 go_error_at(args->back()->location(),
10022 "invalid use of %<...%> with non-slice/non-string");
10023 this->set_is_error();
10024 break;
10025 }
4fd4fcf4 10026
321e5ad2 10027 if (args->size() < 2)
10028 {
10029 this->report_error(_("not enough arguments"));
10030 break;
10031 }
10032 if (args->size() > 2)
10033 {
10034 this->report_error(_("too many arguments"));
10035 break;
10036 }
10037
10038 if (args->back()->type()->is_string_type()
10039 && element_type->integer_type() != NULL
10040 && element_type->integer_type()->is_byte())
10041 {
10042 // Permit append(s1, s2...) when s1 is a slice of
10043 // bytes and s2 is a string type.
10044 }
e440a328 10045 else
10046 {
321e5ad2 10047 // We have to test for assignment compatibility to a
10048 // slice of the element type, which is not necessarily
10049 // the same as the type of the first argument: the
10050 // first argument might have a named type.
10051 Type* check_type = Type::make_array_type(element_type, NULL);
10052 std::string reason;
10053 if (!Type::are_assignable(check_type, args->back()->type(),
10054 &reason))
10055 {
10056 if (reason.empty())
10057 go_error_at(args->back()->location(),
10058 "argument 2 has invalid type");
10059 else
10060 go_error_at(args->back()->location(),
10061 "argument 2 has invalid type (%s)",
10062 reason.c_str());
10063 this->set_is_error();
10064 break;
10065 }
10066 }
10067 }
10068 else
10069 {
10070 Expression_list::const_iterator pa = args->begin();
10071 int i = 2;
10072 for (++pa; pa != args->end(); ++pa, ++i)
10073 {
10074 std::string reason;
10075 if (!Type::are_assignable(element_type, (*pa)->type(),
10076 &reason))
10077 {
10078 if (reason.empty())
10079 go_error_at((*pa)->location(),
10080 "argument %d has incompatible type", i);
10081 else
10082 go_error_at((*pa)->location(),
10083 "argument %d has incompatible type (%s)",
10084 i, reason.c_str());
10085 this->set_is_error();
10086 }
e440a328 10087 }
10088 }
e440a328 10089 }
321e5ad2 10090 break;
e440a328 10091
10092 case BUILTIN_REAL:
10093 case BUILTIN_IMAG:
10094 if (this->check_one_arg())
10095 {
10096 if (this->one_arg()->type()->complex_type() == NULL)
10097 this->report_error(_("argument must have complex type"));
10098 }
10099 break;
10100
48080209 10101 case BUILTIN_COMPLEX:
e440a328 10102 {
10103 const Expression_list* args = this->args();
10104 if (args == NULL || args->size() < 2)
10105 this->report_error(_("not enough arguments"));
10106 else if (args->size() > 2)
10107 this->report_error(_("too many arguments"));
10108 else if (args->front()->is_error_expression()
5c13bd80 10109 || args->front()->type()->is_error()
e440a328 10110 || args->back()->is_error_expression()
5c13bd80 10111 || args->back()->type()->is_error())
e440a328 10112 this->set_is_error();
10113 else if (!Type::are_identical(args->front()->type(),
3a522dcc 10114 args->back()->type(),
10115 Type::COMPARE_TAGS, NULL))
48080209 10116 this->report_error(_("complex arguments must have identical types"));
e440a328 10117 else if (args->front()->type()->float_type() == NULL)
48080209 10118 this->report_error(_("complex arguments must have "
e440a328 10119 "floating-point type"));
10120 }
10121 break;
10122
10123 default:
c3e6f413 10124 go_unreachable();
e440a328 10125 }
10126}
10127
72666aed 10128Expression*
10129Builtin_call_expression::do_copy()
10130{
10131 Call_expression* bce =
10132 new Builtin_call_expression(this->gogo_, this->fn()->copy(),
da244e59 10133 (this->args() == NULL
10134 ? NULL
10135 : this->args()->copy()),
72666aed 10136 this->is_varargs(),
10137 this->location());
10138
10139 if (this->varargs_are_lowered())
10140 bce->set_varargs_are_lowered();
28819633 10141 if (this->is_deferred())
10142 bce->set_is_deferred();
10143 if (this->is_concurrent())
10144 bce->set_is_concurrent();
72666aed 10145 return bce;
10146}
10147
ea664253 10148// Return the backend representation for a builtin function.
e440a328 10149
ea664253 10150Bexpression*
10151Builtin_call_expression::do_get_backend(Translate_context* context)
e440a328 10152{
10153 Gogo* gogo = context->gogo();
b13c66cd 10154 Location location = this->location();
a0d8874e 10155
10156 if (this->is_erroneous_call())
10157 {
10158 go_assert(saw_errors());
10159 return gogo->backend()->error_expression();
10160 }
10161
e440a328 10162 switch (this->code_)
10163 {
10164 case BUILTIN_INVALID:
10165 case BUILTIN_NEW:
10166 case BUILTIN_MAKE:
c3e6f413 10167 go_unreachable();
e440a328 10168
10169 case BUILTIN_LEN:
10170 case BUILTIN_CAP:
10171 {
10172 const Expression_list* args = this->args();
c484d925 10173 go_assert(args != NULL && args->size() == 1);
2c809f8f 10174 Expression* arg = args->front();
e440a328 10175 Type* arg_type = arg->type();
0f914071 10176
10177 if (this->seen_)
10178 {
c484d925 10179 go_assert(saw_errors());
ea664253 10180 return context->backend()->error_expression();
0f914071 10181 }
10182 this->seen_ = true;
0f914071 10183 this->seen_ = false;
e440a328 10184 if (arg_type->points_to() != NULL)
10185 {
10186 arg_type = arg_type->points_to();
c484d925 10187 go_assert(arg_type->array_type() != NULL
411eb89e 10188 && !arg_type->is_slice_type());
f614ea8b 10189 arg = Expression::make_dereference(arg, NIL_CHECK_DEFAULT,
10190 location);
e440a328 10191 }
10192
1b1f2abf 10193 Type* int_type = Type::lookup_integer_type("int");
2c809f8f 10194 Expression* val;
e440a328 10195 if (this->code_ == BUILTIN_LEN)
10196 {
10197 if (arg_type->is_string_type())
2c809f8f 10198 val = Expression::make_string_info(arg, STRING_INFO_LENGTH,
10199 location);
e440a328 10200 else if (arg_type->array_type() != NULL)
0f914071 10201 {
10202 if (this->seen_)
10203 {
c484d925 10204 go_assert(saw_errors());
ea664253 10205 return context->backend()->error_expression();
0f914071 10206 }
10207 this->seen_ = true;
2c809f8f 10208 val = arg_type->array_type()->get_length(gogo, arg);
0f914071 10209 this->seen_ = false;
10210 }
0d5530d9 10211 else if (arg_type->map_type() != NULL
10212 || arg_type->channel_type() != NULL)
10213 {
10214 // The first field is the length. If the pointer is
10215 // nil, the length is zero.
10216 Type* pint_type = Type::make_pointer_type(int_type);
10217 arg = Expression::make_unsafe_cast(pint_type, arg, location);
10218 Expression* nil = Expression::make_nil(location);
10219 nil = Expression::make_cast(pint_type, nil, location);
10220 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
10221 arg, nil, location);
10222 Expression* zero = Expression::make_integer_ul(0, int_type,
10223 location);
f614ea8b 10224 Expression* indir =
10225 Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED,
10226 location);
0d5530d9 10227 val = Expression::make_conditional(cmp, zero, indir, location);
10228 }
e440a328 10229 else
c3e6f413 10230 go_unreachable();
e440a328 10231 }
10232 else
10233 {
10234 if (arg_type->array_type() != NULL)
0f914071 10235 {
10236 if (this->seen_)
10237 {
c484d925 10238 go_assert(saw_errors());
ea664253 10239 return context->backend()->error_expression();
0f914071 10240 }
10241 this->seen_ = true;
2c809f8f 10242 val = arg_type->array_type()->get_capacity(gogo, arg);
0f914071 10243 this->seen_ = false;
10244 }
e440a328 10245 else if (arg_type->channel_type() != NULL)
132ed071 10246 {
10247 // The second field is the capacity. If the pointer
10248 // is nil, the capacity is zero.
10249 Type* uintptr_type = Type::lookup_integer_type("uintptr");
10250 Type* pint_type = Type::make_pointer_type(int_type);
10251 Expression* parg = Expression::make_unsafe_cast(uintptr_type,
10252 arg,
10253 location);
10254 int off = int_type->integer_type()->bits() / 8;
10255 Expression* eoff = Expression::make_integer_ul(off,
10256 uintptr_type,
10257 location);
10258 parg = Expression::make_binary(OPERATOR_PLUS, parg, eoff,
10259 location);
10260 parg = Expression::make_unsafe_cast(pint_type, parg, location);
10261 Expression* nil = Expression::make_nil(location);
10262 nil = Expression::make_cast(pint_type, nil, location);
10263 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
10264 arg, nil, location);
10265 Expression* zero = Expression::make_integer_ul(0, int_type,
10266 location);
f614ea8b 10267 Expression* indir =
10268 Expression::make_dereference(parg, NIL_CHECK_NOT_NEEDED,
10269 location);
132ed071 10270 val = Expression::make_conditional(cmp, zero, indir, location);
10271 }
e440a328 10272 else
c3e6f413 10273 go_unreachable();
e440a328 10274 }
10275
2c809f8f 10276 return Expression::make_cast(int_type, val,
ea664253 10277 location)->get_backend(context);
e440a328 10278 }
10279
10280 case BUILTIN_PRINT:
10281 case BUILTIN_PRINTLN:
10282 {
10283 const bool is_ln = this->code_ == BUILTIN_PRINTLN;
88b03a70 10284
10285 Expression* print_stmts = Runtime::make_call(Runtime::PRINTLOCK,
10286 location, 0);
e440a328 10287
10288 const Expression_list* call_args = this->args();
10289 if (call_args != NULL)
10290 {
10291 for (Expression_list::const_iterator p = call_args->begin();
10292 p != call_args->end();
10293 ++p)
10294 {
10295 if (is_ln && p != call_args->begin())
10296 {
2c809f8f 10297 Expression* print_space =
88b03a70 10298 Runtime::make_call(Runtime::PRINTSP, location, 0);
e440a328 10299
2c809f8f 10300 print_stmts =
10301 Expression::make_compound(print_stmts, print_space,
10302 location);
10303 }
e440a328 10304
2c809f8f 10305 Expression* arg = *p;
10306 Type* type = arg->type();
10307 Runtime::Function code;
e440a328 10308 if (type->is_string_type())
88b03a70 10309 code = Runtime::PRINTSTRING;
e440a328 10310 else if (type->integer_type() != NULL
10311 && type->integer_type()->is_unsigned())
10312 {
e440a328 10313 Type* itype = Type::lookup_integer_type("uint64");
2c809f8f 10314 arg = Expression::make_cast(itype, arg, location);
32e9e3f2 10315 if (gogo->compiling_runtime()
10316 && type->named_type() != NULL
10317 && gogo->unpack_hidden_name(type->named_type()->name())
10318 == "hex")
10319 code = Runtime::PRINTHEX;
10320 else
10321 code = Runtime::PRINTUINT;
e440a328 10322 }
10323 else if (type->integer_type() != NULL)
10324 {
e440a328 10325 Type* itype = Type::lookup_integer_type("int64");
2c809f8f 10326 arg = Expression::make_cast(itype, arg, location);
88b03a70 10327 code = Runtime::PRINTINT;
e440a328 10328 }
10329 else if (type->float_type() != NULL)
10330 {
2c809f8f 10331 Type* dtype = Type::lookup_float_type("float64");
10332 arg = Expression::make_cast(dtype, arg, location);
88b03a70 10333 code = Runtime::PRINTFLOAT;
e440a328 10334 }
10335 else if (type->complex_type() != NULL)
10336 {
2c809f8f 10337 Type* ctype = Type::lookup_complex_type("complex128");
10338 arg = Expression::make_cast(ctype, arg, location);
88b03a70 10339 code = Runtime::PRINTCOMPLEX;
e440a328 10340 }
10341 else if (type->is_boolean_type())
88b03a70 10342 code = Runtime::PRINTBOOL;
e440a328 10343 else if (type->points_to() != NULL
10344 || type->channel_type() != NULL
10345 || type->map_type() != NULL
10346 || type->function_type() != NULL)
10347 {
2c809f8f 10348 arg = Expression::make_cast(type, arg, location);
88b03a70 10349 code = Runtime::PRINTPOINTER;
e440a328 10350 }
10351 else if (type->interface_type() != NULL)
10352 {
10353 if (type->interface_type()->is_empty())
88b03a70 10354 code = Runtime::PRINTEFACE;
e440a328 10355 else
88b03a70 10356 code = Runtime::PRINTIFACE;
e440a328 10357 }
411eb89e 10358 else if (type->is_slice_type())
88b03a70 10359 code = Runtime::PRINTSLICE;
e440a328 10360 else
cd238b8d 10361 {
10362 go_assert(saw_errors());
ea664253 10363 return context->backend()->error_expression();
cd238b8d 10364 }
e440a328 10365
2c809f8f 10366 Expression* call = Runtime::make_call(code, location, 1, arg);
88b03a70 10367 print_stmts = Expression::make_compound(print_stmts, call,
10368 location);
e440a328 10369 }
10370 }
10371
10372 if (is_ln)
10373 {
2c809f8f 10374 Expression* print_nl =
88b03a70 10375 Runtime::make_call(Runtime::PRINTNL, location, 0);
10376 print_stmts = Expression::make_compound(print_stmts, print_nl,
10377 location);
e440a328 10378 }
10379
88b03a70 10380 Expression* unlock = Runtime::make_call(Runtime::PRINTUNLOCK,
10381 location, 0);
10382 print_stmts = Expression::make_compound(print_stmts, unlock, location);
32e3ff69 10383
ea664253 10384 return print_stmts->get_backend(context);
e440a328 10385 }
10386
10387 case BUILTIN_PANIC:
10388 {
10389 const Expression_list* args = this->args();
c484d925 10390 go_assert(args != NULL && args->size() == 1);
e440a328 10391 Expression* arg = args->front();
b13c66cd 10392 Type *empty =
823c7e3d 10393 Type::make_empty_interface_type(Linemap::predeclared_location());
2c809f8f 10394 arg = Expression::convert_for_assignment(gogo, empty, arg, location);
10395
10396 Expression* panic =
03ac9de4 10397 Runtime::make_call(Runtime::GOPANIC, location, 1, arg);
ea664253 10398 return panic->get_backend(context);
e440a328 10399 }
10400
10401 case BUILTIN_RECOVER:
10402 {
10403 // The argument is set when building recover thunks. It's a
10404 // boolean value which is true if we can recover a value now.
10405 const Expression_list* args = this->args();
c484d925 10406 go_assert(args != NULL && args->size() == 1);
e440a328 10407 Expression* arg = args->front();
b13c66cd 10408 Type *empty =
823c7e3d 10409 Type::make_empty_interface_type(Linemap::predeclared_location());
e440a328 10410
e440a328 10411 Expression* nil = Expression::make_nil(location);
e007b1eb 10412 nil = Expression::make_interface_value(empty, nil, nil, location);
e440a328 10413
10414 // We need to handle a deferred call to recover specially,
10415 // because it changes whether it can recover a panic or not.
10416 // See test7 in test/recover1.go.
2c809f8f 10417 Expression* recover = Runtime::make_call((this->is_deferred()
03ac9de4 10418 ? Runtime::DEFERREDRECOVER
10419 : Runtime::GORECOVER),
2c809f8f 10420 location, 0);
10421 Expression* cond =
10422 Expression::make_conditional(arg, recover, nil, location);
ea664253 10423 return cond->get_backend(context);
e440a328 10424 }
10425
10426 case BUILTIN_CLOSE:
e440a328 10427 {
10428 const Expression_list* args = this->args();
c484d925 10429 go_assert(args != NULL && args->size() == 1);
e440a328 10430 Expression* arg = args->front();
2c809f8f 10431 Expression* close = Runtime::make_call(Runtime::CLOSE, location,
10432 1, arg);
ea664253 10433 return close->get_backend(context);
e440a328 10434 }
10435
10436 case BUILTIN_SIZEOF:
10437 case BUILTIN_OFFSETOF:
10438 case BUILTIN_ALIGNOF:
10439 {
0c77715b 10440 Numeric_constant nc;
10441 unsigned long val;
10442 if (!this->numeric_constant_value(&nc)
10443 || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
7f1d9abd 10444 {
c484d925 10445 go_assert(saw_errors());
ea664253 10446 return context->backend()->error_expression();
7f1d9abd 10447 }
7ba86326 10448 Type* uintptr_type = Type::lookup_integer_type("uintptr");
2c809f8f 10449 mpz_t ival;
10450 nc.get_int(&ival);
10451 Expression* int_cst =
e67508fa 10452 Expression::make_integer_z(&ival, uintptr_type, location);
2c809f8f 10453 mpz_clear(ival);
ea664253 10454 return int_cst->get_backend(context);
e440a328 10455 }
10456
10457 case BUILTIN_COPY:
7fdb0876 10458 // Handled in Builtin_call_expression::do_flatten.
10459 go_unreachable();
e440a328 10460
10461 case BUILTIN_APPEND:
321e5ad2 10462 // Handled in Builtin_call_expression::flatten_append.
10463 go_unreachable();
e440a328 10464
10465 case BUILTIN_REAL:
10466 case BUILTIN_IMAG:
10467 {
10468 const Expression_list* args = this->args();
c484d925 10469 go_assert(args != NULL && args->size() == 1);
2c809f8f 10470
10471 Bexpression* ret;
ea664253 10472 Bexpression* bcomplex = args->front()->get_backend(context);
2c809f8f 10473 if (this->code_ == BUILTIN_REAL)
10474 ret = gogo->backend()->real_part_expression(bcomplex, location);
10475 else
10476 ret = gogo->backend()->imag_part_expression(bcomplex, location);
ea664253 10477 return ret;
e440a328 10478 }
10479
48080209 10480 case BUILTIN_COMPLEX:
e440a328 10481 {
10482 const Expression_list* args = this->args();
c484d925 10483 go_assert(args != NULL && args->size() == 2);
ea664253 10484 Bexpression* breal = args->front()->get_backend(context);
10485 Bexpression* bimag = args->back()->get_backend(context);
10486 return gogo->backend()->complex_expression(breal, bimag, location);
e440a328 10487 }
10488
10489 default:
c3e6f413 10490 go_unreachable();
e440a328 10491 }
10492}
10493
10494// We have to support exporting a builtin call expression, because
10495// code can set a constant to the result of a builtin expression.
10496
10497void
548be246 10498Builtin_call_expression::do_export(Export_function_body* efb) const
e440a328 10499{
0c77715b 10500 Numeric_constant nc;
e3d09834 10501 if (this->numeric_constant_value(&nc))
0c77715b 10502 {
e3d09834 10503 if (nc.is_int())
10504 {
10505 mpz_t val;
10506 nc.get_int(&val);
10507 Integer_expression::export_integer(efb, val);
10508 mpz_clear(val);
10509 }
10510 else if (nc.is_float())
10511 {
10512 mpfr_t fval;
10513 nc.get_float(&fval);
10514 Float_expression::export_float(efb, fval);
10515 mpfr_clear(fval);
10516 }
10517 else if (nc.is_complex())
10518 {
10519 mpc_t cval;
10520 nc.get_complex(&cval);
10521 Complex_expression::export_complex(efb, cval);
10522 mpc_clear(cval);
10523 }
10524 else
10525 go_unreachable();
e440a328 10526
e3d09834 10527 // A trailing space lets us reliably identify the end of the number.
10528 efb->write_c_string(" ");
e440a328 10529 }
e3d09834 10530 else
e440a328 10531 {
e3d09834 10532 const char *s = NULL;
10533 switch (this->code_)
10534 {
10535 default:
10536 go_unreachable();
10537 case BUILTIN_APPEND:
10538 s = "append";
10539 break;
10540 case BUILTIN_COPY:
10541 s = "copy";
10542 break;
10543 case BUILTIN_LEN:
10544 s = "len";
10545 break;
10546 case BUILTIN_CAP:
10547 s = "cap";
10548 break;
26329c24 10549 case BUILTIN_DELETE:
10550 s = "delete";
10551 break;
e3d09834 10552 case BUILTIN_PRINT:
10553 s = "print";
10554 break;
10555 case BUILTIN_PRINTLN:
10556 s = "println";
10557 break;
10558 case BUILTIN_PANIC:
10559 s = "panic";
10560 break;
10561 case BUILTIN_RECOVER:
10562 s = "recover";
10563 break;
10564 case BUILTIN_CLOSE:
10565 s = "close";
10566 break;
10567 case BUILTIN_REAL:
10568 s = "real";
10569 break;
10570 case BUILTIN_IMAG:
10571 s = "imag";
10572 break;
10573 case BUILTIN_COMPLEX:
10574 s = "complex";
10575 break;
10576 }
10577 efb->write_c_string(s);
10578 this->export_arguments(efb);
e440a328 10579 }
e440a328 10580}
10581
10582// Class Call_expression.
10583
8381eda7 10584// A Go function can be viewed in a couple of different ways. The
10585// code of a Go function becomes a backend function with parameters
10586// whose types are simply the backend representation of the Go types.
10587// If there are multiple results, they are returned as a backend
10588// struct.
10589
10590// However, when Go code refers to a function other than simply
10591// calling it, the backend type of that function is actually a struct.
10592// The first field of the struct points to the Go function code
10593// (sometimes a wrapper as described below). The remaining fields
10594// hold addresses of closed-over variables. This struct is called a
10595// closure.
10596
10597// There are a few cases to consider.
10598
10599// A direct function call of a known function in package scope. In
10600// this case there are no closed-over variables, and we know the name
10601// of the function code. We can simply produce a backend call to the
10602// function directly, and not worry about the closure.
10603
10604// A direct function call of a known function literal. In this case
10605// we know the function code and we know the closure. We generate the
10606// function code such that it expects an additional final argument of
10607// the closure type. We pass the closure as the last argument, after
10608// the other arguments.
10609
10610// An indirect function call. In this case we have a closure. We
10611// load the pointer to the function code from the first field of the
10612// closure. We pass the address of the closure as the last argument.
10613
10614// A call to a method of an interface. Type methods are always at
10615// package scope, so we call the function directly, and don't worry
10616// about the closure.
10617
10618// This means that for a function at package scope we have two cases.
10619// One is the direct call, which has no closure. The other is the
10620// indirect call, which does have a closure. We can't simply ignore
10621// the closure, even though it is the last argument, because that will
10622// fail on targets where the function pops its arguments. So when
10623// generating a closure for a package-scope function we set the
10624// function code pointer in the closure to point to a wrapper
10625// function. This wrapper function accepts a final argument that
10626// points to the closure, ignores it, and calls the real function as a
10627// direct function call. This wrapper will normally be efficient, and
10628// can often simply be a tail call to the real function.
10629
10630// We don't use GCC's static chain pointer because 1) we don't need
10631// it; 2) GCC only permits using a static chain to call a known
10632// function, so we can't use it for an indirect call anyhow. Since we
10633// can't use it for an indirect call, we may as well not worry about
10634// using it for a direct call either.
10635
10636// We pass the closure last rather than first because it means that
10637// the function wrapper we put into a closure for a package-scope
10638// function can normally just be a tail call to the real function.
10639
10640// For method expressions we generate a wrapper that loads the
10641// receiver from the closure and then calls the method. This
10642// unfortunately forces reshuffling the arguments, since there is a
10643// new first argument, but we can't avoid reshuffling either for
10644// method expressions or for indirect calls of package-scope
10645// functions, and since the latter are more common we reshuffle for
10646// method expressions.
10647
10648// Note that the Go code retains the Go types. The extra final
10649// argument only appears when we convert to the backend
10650// representation.
10651
e440a328 10652// Traversal.
10653
10654int
10655Call_expression::do_traverse(Traverse* traverse)
10656{
0c0dacab 10657 // If we are calling a function in a different package that returns
10658 // an unnamed type, this may be the only chance we get to traverse
10659 // that type. We don't traverse this->type_ because it may be a
10660 // Call_multiple_result_type that will just lead back here.
10661 if (this->type_ != NULL && !this->type_->is_error_type())
10662 {
10663 Function_type *fntype = this->get_function_type();
10664 if (fntype != NULL && Type::traverse(fntype, traverse) == TRAVERSE_EXIT)
10665 return TRAVERSE_EXIT;
10666 }
e440a328 10667 if (Expression::traverse(&this->fn_, traverse) == TRAVERSE_EXIT)
10668 return TRAVERSE_EXIT;
10669 if (this->args_ != NULL)
10670 {
10671 if (this->args_->traverse(traverse) == TRAVERSE_EXIT)
10672 return TRAVERSE_EXIT;
10673 }
10674 return TRAVERSE_CONTINUE;
10675}
10676
10677// Lower a call statement.
10678
10679Expression*
ceeb4318 10680Call_expression::do_lower(Gogo* gogo, Named_object* function,
10681 Statement_inserter* inserter, int)
e440a328 10682{
b13c66cd 10683 Location loc = this->location();
09ea332d 10684
ceeb4318 10685 // A type cast can look like a function call.
e440a328 10686 if (this->fn_->is_type_expression()
10687 && this->args_ != NULL
10688 && this->args_->size() == 1)
10689 return Expression::make_cast(this->fn_->type(), this->args_->front(),
09ea332d 10690 loc);
e440a328 10691
88f06749 10692 // Because do_type will return an error type and thus prevent future
10693 // errors, check for that case now to ensure that the error gets
10694 // reported.
37448b10 10695 Function_type* fntype = this->get_function_type();
10696 if (fntype == NULL)
88f06749 10697 {
10698 if (!this->fn_->type()->is_error())
10699 this->report_error(_("expected function"));
5f1045b5 10700 this->set_is_error();
10701 return this;
88f06749 10702 }
10703
e440a328 10704 // Handle an argument which is a call to a function which returns
10705 // multiple results.
10706 if (this->args_ != NULL
10707 && this->args_->size() == 1
37448b10 10708 && this->args_->front()->call_expression() != NULL)
e440a328 10709 {
e440a328 10710 size_t rc = this->args_->front()->call_expression()->result_count();
10711 if (rc > 1
37448b10 10712 && ((fntype->parameters() != NULL
10713 && (fntype->parameters()->size() == rc
10714 || (fntype->is_varargs()
10715 && fntype->parameters()->size() - 1 <= rc)))
10716 || fntype->is_builtin()))
e440a328 10717 {
10718 Call_expression* call = this->args_->front()->call_expression();
e90ecd2d 10719 call->set_is_multi_value_arg();
c33af8e4 10720 if (this->is_varargs_)
10721 {
10722 // It is not clear which result of a multiple result call
10723 // the ellipsis operator should be applied to. If we unpack the
10724 // the call into its individual results here, the ellipsis will be
10725 // applied to the last result.
631d5788 10726 go_error_at(call->location(),
10727 _("multiple-value argument in single-value context"));
c33af8e4 10728 return Expression::make_error(call->location());
10729 }
10730
e440a328 10731 Expression_list* args = new Expression_list;
10732 for (size_t i = 0; i < rc; ++i)
10733 args->push_back(Expression::make_call_result(call, i));
10734 // We can't return a new call expression here, because this
42535814 10735 // one may be referenced by Call_result expressions. We
10736 // also can't delete the old arguments, because we may still
10737 // traverse them somewhere up the call stack. FIXME.
e440a328 10738 this->args_ = args;
10739 }
10740 }
10741
37448b10 10742 // Recognize a call to a builtin function.
10743 if (fntype->is_builtin())
28819633 10744 {
10745 Builtin_call_expression* bce =
10746 new Builtin_call_expression(gogo, this->fn_, this->args_,
10747 this->is_varargs_, loc);
10748 if (this->is_deferred_)
10749 bce->set_is_deferred();
10750 if (this->is_concurrent_)
10751 bce->set_is_concurrent();
10752 return bce;
10753 }
37448b10 10754
ceeb4318 10755 // If this call returns multiple results, create a temporary
5731103c 10756 // variable to hold them.
10757 if (this->result_count() > 1 && this->call_temp_ == NULL)
ceeb4318 10758 {
5731103c 10759 Struct_field_list* sfl = new Struct_field_list();
10760 Function_type* fntype = this->get_function_type();
37448b10 10761 const Typed_identifier_list* results = fntype->results();
5731103c 10762 Location loc = this->location();
10763
10764 int i = 0;
10765 char buf[20];
ceeb4318 10766 for (Typed_identifier_list::const_iterator p = results->begin();
5731103c 10767 p != results->end();
10768 ++p, ++i)
10769 {
10770 snprintf(buf, sizeof buf, "res%d", i);
10771 sfl->push_back(Struct_field(Typed_identifier(buf, p->type(), loc)));
10772 }
10773
10774 Struct_type* st = Type::make_struct_type(sfl, loc);
10775 st->set_is_struct_incomparable();
10776 this->call_temp_ = Statement::make_temporary(st, NULL, loc);
10777 inserter->insert(this->call_temp_);
ceeb4318 10778 }
10779
e440a328 10780 // Handle a call to a varargs function by packaging up the extra
10781 // parameters.
37448b10 10782 if (fntype->is_varargs())
e440a328 10783 {
e440a328 10784 const Typed_identifier_list* parameters = fntype->parameters();
c484d925 10785 go_assert(parameters != NULL && !parameters->empty());
e440a328 10786 Type* varargs_type = parameters->back().type();
09ea332d 10787 this->lower_varargs(gogo, function, inserter, varargs_type,
0e9a2e72 10788 parameters->size(), SLICE_STORAGE_MAY_ESCAPE);
09ea332d 10789 }
10790
10791 // If this is call to a method, call the method directly passing the
10792 // object as the first parameter.
10793 Bound_method_expression* bme = this->fn_->bound_method_expression();
10794 if (bme != NULL)
10795 {
0afbb937 10796 Named_object* methodfn = bme->function();
5b665222 10797 Function_type* mft = (methodfn->is_function()
10798 ? methodfn->func_value()->type()
10799 : methodfn->func_declaration_value()->type());
09ea332d 10800 Expression* first_arg = bme->first_argument();
10801
5b665222 10802 // We always pass a pointer when calling a method, except for
10803 // direct interface types when calling a value method.
10804 if (!first_arg->type()->is_error()
10805 && !first_arg->type()->is_direct_iface_type())
09ea332d 10806 {
10807 first_arg = Expression::make_unary(OPERATOR_AND, first_arg, loc);
10808 // We may need to create a temporary variable so that we can
10809 // take the address. We can't do that here because it will
10810 // mess up the order of evaluation.
10811 Unary_expression* ue = static_cast<Unary_expression*>(first_arg);
10812 ue->set_create_temp();
10813 }
5b665222 10814 else if (mft->receiver()->type()->points_to() == NULL
10815 && first_arg->type()->points_to() != NULL
10816 && first_arg->type()->points_to()->is_direct_iface_type())
10817 first_arg = Expression::make_dereference(first_arg,
10818 Expression::NIL_CHECK_DEFAULT,
10819 loc);
09ea332d 10820
10821 // If we are calling a method which was inherited from an
10822 // embedded struct, and the method did not get a stub, then the
10823 // first type may be wrong.
10824 Type* fatype = bme->first_argument_type();
10825 if (fatype != NULL)
10826 {
10827 if (fatype->points_to() == NULL)
10828 fatype = Type::make_pointer_type(fatype);
10829 first_arg = Expression::make_unsafe_cast(fatype, first_arg, loc);
10830 }
10831
10832 Expression_list* new_args = new Expression_list();
10833 new_args->push_back(first_arg);
10834 if (this->args_ != NULL)
10835 {
10836 for (Expression_list::const_iterator p = this->args_->begin();
10837 p != this->args_->end();
10838 ++p)
10839 new_args->push_back(*p);
10840 }
10841
10842 // We have to change in place because this structure may be
10843 // referenced by Call_result_expressions. We can't delete the
10844 // old arguments, because we may be traversing them up in some
10845 // caller. FIXME.
10846 this->args_ = new_args;
0afbb937 10847 this->fn_ = Expression::make_func_reference(methodfn, NULL,
09ea332d 10848 bme->location());
e440a328 10849 }
10850
81affb1d 10851 // If this is a call to an imported function for which we have an
10852 // inlinable function body, add it to the list of functions to give
10853 // to the backend as inlining opportunities.
10854 Func_expression* fe = this->fn_->func_expression();
10855 if (fe != NULL
10856 && fe->named_object()->is_function_declaration()
10857 && fe->named_object()->func_declaration_value()->has_imported_body())
10858 gogo->add_imported_inlinable_function(fe->named_object());
10859
e440a328 10860 return this;
10861}
10862
10863// Lower a call to a varargs function. FUNCTION is the function in
10864// which the call occurs--it's not the function we are calling.
10865// VARARGS_TYPE is the type of the varargs parameter, a slice type.
10866// PARAM_COUNT is the number of parameters of the function we are
10867// calling; the last of these parameters will be the varargs
10868// parameter.
10869
09ea332d 10870void
e440a328 10871Call_expression::lower_varargs(Gogo* gogo, Named_object* function,
ceeb4318 10872 Statement_inserter* inserter,
0e9a2e72 10873 Type* varargs_type, size_t param_count,
10874 Slice_storage_escape_disp escape_disp)
e440a328 10875{
10876 if (this->varargs_are_lowered_)
09ea332d 10877 return;
e440a328 10878
b13c66cd 10879 Location loc = this->location();
e440a328 10880
c484d925 10881 go_assert(param_count > 0);
411eb89e 10882 go_assert(varargs_type->is_slice_type());
e440a328 10883
10884 size_t arg_count = this->args_ == NULL ? 0 : this->args_->size();
10885 if (arg_count < param_count - 1)
10886 {
10887 // Not enough arguments; will be caught in check_types.
09ea332d 10888 return;
e440a328 10889 }
10890
10891 Expression_list* old_args = this->args_;
10892 Expression_list* new_args = new Expression_list();
10893 bool push_empty_arg = false;
10894 if (old_args == NULL || old_args->empty())
10895 {
c484d925 10896 go_assert(param_count == 1);
e440a328 10897 push_empty_arg = true;
10898 }
10899 else
10900 {
10901 Expression_list::const_iterator pa;
10902 int i = 1;
10903 for (pa = old_args->begin(); pa != old_args->end(); ++pa, ++i)
10904 {
10905 if (static_cast<size_t>(i) == param_count)
10906 break;
10907 new_args->push_back(*pa);
10908 }
10909
10910 // We have reached the varargs parameter.
10911
10912 bool issued_error = false;
10913 if (pa == old_args->end())
10914 push_empty_arg = true;
10915 else if (pa + 1 == old_args->end() && this->is_varargs_)
10916 new_args->push_back(*pa);
10917 else if (this->is_varargs_)
10918 {
a6645f74 10919 if ((*pa)->type()->is_slice_type())
10920 this->report_error(_("too many arguments"));
10921 else
10922 {
631d5788 10923 go_error_at(this->location(),
10924 _("invalid use of %<...%> with non-slice"));
a6645f74 10925 this->set_is_error();
10926 }
09ea332d 10927 return;
e440a328 10928 }
e440a328 10929 else
10930 {
10931 Type* element_type = varargs_type->array_type()->element_type();
10932 Expression_list* vals = new Expression_list;
10933 for (; pa != old_args->end(); ++pa, ++i)
10934 {
10935 // Check types here so that we get a better message.
10936 Type* patype = (*pa)->type();
b13c66cd 10937 Location paloc = (*pa)->location();
e440a328 10938 if (!this->check_argument_type(i, element_type, patype,
10939 paloc, issued_error))
10940 continue;
10941 vals->push_back(*pa);
10942 }
0e9a2e72 10943 Slice_construction_expression* sce =
e440a328 10944 Expression::make_slice_composite_literal(varargs_type, vals, loc);
0e9a2e72 10945 if (escape_disp == SLICE_STORAGE_DOES_NOT_ESCAPE)
10946 sce->set_storage_does_not_escape();
10947 Expression* val = sce;
09ea332d 10948 gogo->lower_expression(function, inserter, &val);
e440a328 10949 new_args->push_back(val);
10950 }
10951 }
10952
10953 if (push_empty_arg)
10954 new_args->push_back(Expression::make_nil(loc));
10955
10956 // We can't return a new call expression here, because this one may
6d4c2432 10957 // be referenced by Call_result expressions. FIXME. We can't
10958 // delete OLD_ARGS because we may have both a Call_expression and a
10959 // Builtin_call_expression which refer to them. FIXME.
e440a328 10960 this->args_ = new_args;
10961 this->varargs_are_lowered_ = true;
e440a328 10962}
10963
2c809f8f 10964// Flatten a call with multiple results into a temporary.
10965
10966Expression*
b8e86a51 10967Call_expression::do_flatten(Gogo* gogo, Named_object*,
10968 Statement_inserter* inserter)
2c809f8f 10969{
5bf8be8b 10970 if (this->is_erroneous_call())
10971 {
10972 go_assert(saw_errors());
10973 return Expression::make_error(this->location());
10974 }
b8e86a51 10975
91c0fd76 10976 if (this->is_flattened_)
10977 return this;
10978 this->is_flattened_ = true;
10979
b8e86a51 10980 // Add temporary variables for all arguments that require type
10981 // conversion.
10982 Function_type* fntype = this->get_function_type();
9782d556 10983 if (fntype == NULL)
10984 {
10985 go_assert(saw_errors());
10986 return this;
10987 }
b8e86a51 10988 if (this->args_ != NULL && !this->args_->empty()
10989 && fntype->parameters() != NULL && !fntype->parameters()->empty())
10990 {
10991 bool is_interface_method =
10992 this->fn_->interface_field_reference_expression() != NULL;
10993
10994 Expression_list *args = new Expression_list();
10995 Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
10996 Expression_list::const_iterator pa = this->args_->begin();
10997 if (!is_interface_method && fntype->is_method())
10998 {
10999 // The receiver argument.
11000 args->push_back(*pa);
11001 ++pa;
11002 }
11003 for (; pa != this->args_->end(); ++pa, ++pp)
11004 {
11005 go_assert(pp != fntype->parameters()->end());
3a522dcc 11006 if (Type::are_identical(pp->type(), (*pa)->type(),
11007 Type::COMPARE_TAGS, NULL))
b8e86a51 11008 args->push_back(*pa);
11009 else
11010 {
11011 Location loc = (*pa)->location();
8ba8cc87 11012 Expression* arg = *pa;
11013 if (!arg->is_variable())
11014 {
11015 Temporary_statement *temp =
11016 Statement::make_temporary(NULL, arg, loc);
11017 inserter->insert(temp);
11018 arg = Expression::make_temporary_reference(temp, loc);
11019 }
11020 arg = Expression::convert_for_assignment(gogo, pp->type(), arg,
11021 loc);
11022 args->push_back(arg);
b8e86a51 11023 }
11024 }
11025 delete this->args_;
11026 this->args_ = args;
11027 }
11028
6c8a521f 11029 // Lower to compiler intrinsic if possible.
11030 Func_expression* fe = this->fn_->func_expression();
2f0168ee 11031 if (!this->is_concurrent_ && !this->is_deferred_
11032 && fe != NULL
6c8a521f 11033 && (fe->named_object()->is_function_declaration()
11034 || fe->named_object()->is_function()))
11035 {
11036 Expression* ret = this->intrinsify(gogo, inserter);
11037 if (ret != NULL)
11038 return ret;
11039 }
11040
2c809f8f 11041 return this;
11042}
11043
6c8a521f 11044// Lower a call to a compiler intrinsic if possible.
11045// Returns NULL if it is not an intrinsic.
11046
11047Expression*
11048Call_expression::intrinsify(Gogo* gogo,
11049 Statement_inserter* inserter)
11050{
11051 Func_expression* fe = this->fn_->func_expression();
11052 Named_object* no = fe->named_object();
11053 std::string name = Gogo::unpack_hidden_name(no->name());
11054 std::string package = (no->package() != NULL
11055 ? no->package()->pkgpath()
11056 : gogo->pkgpath());
11057 Location loc = this->location();
11058
11059 Type* int_type = Type::lookup_integer_type("int");
daccb2bc 11060 Type* int32_type = Type::lookup_integer_type("int32");
11061 Type* int64_type = Type::lookup_integer_type("int64");
11062 Type* uint_type = Type::lookup_integer_type("uint");
6c8a521f 11063 Type* uint32_type = Type::lookup_integer_type("uint32");
11064 Type* uint64_type = Type::lookup_integer_type("uint64");
11065 Type* uintptr_type = Type::lookup_integer_type("uintptr");
daccb2bc 11066 Type* pointer_type = Type::make_pointer_type(Type::make_void_type());
11067
11068 int int_size = int_type->named_type()->real_type()->integer_type()->bits() / 8;
11069 int ptr_size = uintptr_type->named_type()->real_type()->integer_type()->bits() / 8;
6c8a521f 11070
2f0168ee 11071 if (package == "sync/atomic")
11072 {
11073 // sync/atomic functions and runtime/internal/atomic functions
11074 // are very similar. In order not to duplicate code, we just
11075 // redirect to the latter and let the code below to handle them.
11076 // In case there is no equivalent functions (slight variance
11077 // in types), we just make an artificial name (begin with '$').
11078 // Note: no StorePointer, SwapPointer, and CompareAndSwapPointer,
11079 // as they need write barriers.
11080 if (name == "LoadInt32")
11081 name = "$Loadint32";
11082 else if (name == "LoadInt64")
11083 name = "Loadint64";
11084 else if (name == "LoadUint32")
11085 name = "Load";
11086 else if (name == "LoadUint64")
11087 name = "Load64";
11088 else if (name == "LoadUintptr")
11089 name = "Loaduintptr";
11090 else if (name == "LoadPointer")
11091 name = "Loadp";
11092 else if (name == "StoreInt32")
11093 name = "$Storeint32";
11094 else if (name == "StoreInt64")
11095 name = "$Storeint64";
11096 else if (name == "StoreUint32")
11097 name = "Store";
11098 else if (name == "StoreUint64")
11099 name = "Store64";
11100 else if (name == "StoreUintptr")
11101 name = "Storeuintptr";
11102 else if (name == "AddInt32")
11103 name = "$Xaddint32";
11104 else if (name == "AddInt64")
11105 name = "Xaddint64";
11106 else if (name == "AddUint32")
11107 name = "Xadd";
11108 else if (name == "AddUint64")
11109 name = "Xadd64";
11110 else if (name == "AddUintptr")
11111 name = "Xadduintptr";
11112 else if (name == "SwapInt32")
11113 name = "$Xchgint32";
11114 else if (name == "SwapInt64")
11115 name = "$Xchgint64";
11116 else if (name == "SwapUint32")
11117 name = "Xchg";
11118 else if (name == "SwapUint64")
11119 name = "Xchg64";
11120 else if (name == "SwapUintptr")
11121 name = "Xchguintptr";
11122 else if (name == "CompareAndSwapInt32")
11123 name = "$Casint32";
11124 else if (name == "CompareAndSwapInt64")
11125 name = "$Casint64";
11126 else if (name == "CompareAndSwapUint32")
11127 name = "Cas";
11128 else if (name == "CompareAndSwapUint64")
11129 name = "Cas64";
11130 else if (name == "CompareAndSwapUintptr")
11131 name = "Casuintptr";
11132 else
11133 return NULL;
11134
11135 package = "runtime/internal/atomic";
11136 }
11137
fdae40b7 11138 if (package == "runtime/internal/sys")
11139 {
11140 // runtime/internal/sys functions and math/bits functions
11141 // are very similar. In order not to duplicate code, we just
11142 // redirect to the latter and let the code below to handle them.
11143 if (name == "Bswap32")
11144 name = "ReverseBytes32";
11145 else if (name == "Bswap64")
11146 name = "ReverseBytes64";
11147 else if (name == "Ctz32")
11148 name = "TrailingZeros32";
11149 else if (name == "Ctz64")
11150 name = "TrailingZeros64";
11151 else
11152 return NULL;
11153
11154 package = "math/bits";
11155 }
11156
6c8a521f 11157 if (package == "runtime")
11158 {
11159 // Handle a couple of special runtime functions. In the runtime
11160 // package, getcallerpc returns the PC of the caller, and
11161 // getcallersp returns the frame pointer of the caller. Implement
11162 // these by turning them into calls to GCC builtin functions. We
11163 // could implement them in normal code, but then we would have to
11164 // explicitly unwind the stack. These functions are intended to be
11165 // efficient. Note that this technique obviously only works for
11166 // direct calls, but that is the only way they are used.
11167 if (name == "getcallerpc"
11168 && (this->args_ == NULL || this->args_->size() == 0))
11169 {
11170 Expression* arg = Expression::make_integer_ul(0, uint32_type, loc);
11171 Expression* call =
11172 Runtime::make_call(Runtime::BUILTIN_RETURN_ADDRESS, loc,
11173 1, arg);
11174 // The builtin functions return void*, but the Go functions return uintptr.
11175 return Expression::make_cast(uintptr_type, call, loc);
11176 }
11177 else if (name == "getcallersp"
11178 && (this->args_ == NULL || this->args_->size() == 0))
11179
11180 {
11181 Expression* call =
11182 Runtime::make_call(Runtime::BUILTIN_DWARF_CFA, loc, 0);
11183 // The builtin functions return void*, but the Go functions return uintptr.
11184 return Expression::make_cast(uintptr_type, call, loc);
11185 }
11186 }
fdae40b7 11187 else if (package == "math/bits")
6c8a521f 11188 {
fdae40b7 11189 if ((name == "ReverseBytes16" || name == "ReverseBytes32"
11190 || name == "ReverseBytes64" || name == "ReverseBytes")
6c8a521f 11191 && this->args_ != NULL && this->args_->size() == 1)
11192 {
fdae40b7 11193 Runtime::Function code;
11194 if (name == "ReverseBytes16")
11195 code = Runtime::BUILTIN_BSWAP16;
11196 else if (name == "ReverseBytes32")
11197 code = Runtime::BUILTIN_BSWAP32;
11198 else if (name == "ReverseBytes64")
11199 code = Runtime::BUILTIN_BSWAP64;
11200 else if (name == "ReverseBytes")
11201 code = (int_size == 8 ? Runtime::BUILTIN_BSWAP64 : Runtime::BUILTIN_BSWAP32);
11202 else
11203 go_unreachable();
6c8a521f 11204 Expression* arg = this->args_->front();
fdae40b7 11205 Expression* call = Runtime::make_call(code, loc, 1, arg);
11206 if (name == "ReverseBytes")
11207 return Expression::make_cast(uint_type, call, loc);
11208 return call;
6c8a521f 11209 }
fdae40b7 11210 else if ((name == "TrailingZeros8" || name == "TrailingZeros16")
6c8a521f 11211 && this->args_ != NULL && this->args_->size() == 1)
11212 {
fdae40b7 11213 // GCC does not have a ctz8 or ctz16 intrinsic. We do
11214 // ctz32(0x100 | arg) or ctz32(0x10000 | arg).
6c8a521f 11215 Expression* arg = this->args_->front();
fdae40b7 11216 arg = Expression::make_cast(uint32_type, arg, loc);
11217 unsigned long mask = (name == "TrailingZeros8" ? 0x100 : 0x10000);
11218 Expression* c = Expression::make_integer_ul(mask, uint32_type, loc);
11219 arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
11220 Expression* call = Runtime::make_call(Runtime::BUILTIN_CTZ, loc, 1, arg);
11221 return Expression::make_cast(int_type, call, loc);
6c8a521f 11222 }
fdae40b7 11223 else if ((name == "TrailingZeros32"
11224 || (name == "TrailingZeros" && int_size == 4))
6c8a521f 11225 && this->args_ != NULL && this->args_->size() == 1)
11226 {
11227 Expression* arg = this->args_->front();
11228 if (!arg->is_variable())
11229 {
11230 Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
11231 inserter->insert(ts);
11232 arg = Expression::make_temporary_reference(ts, loc);
11233 }
11234 // arg == 0 ? 32 : __builtin_ctz(arg)
11235 Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
11236 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
11237 Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
11238 Expression* call = Runtime::make_call(Runtime::BUILTIN_CTZ, loc, 1, arg->copy());
11239 call = Expression::make_cast(int_type, call, loc);
11240 return Expression::make_conditional(cmp, c32, call, loc);
11241 }
fdae40b7 11242 else if ((name == "TrailingZeros64"
11243 || (name == "TrailingZeros" && int_size == 8))
6c8a521f 11244 && this->args_ != NULL && this->args_->size() == 1)
11245 {
11246 Expression* arg = this->args_->front();
11247 if (!arg->is_variable())
11248 {
11249 Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
11250 inserter->insert(ts);
11251 arg = Expression::make_temporary_reference(ts, loc);
11252 }
11253 // arg == 0 ? 64 : __builtin_ctzll(arg)
11254 Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
11255 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
11256 Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
11257 Expression* call = Runtime::make_call(Runtime::BUILTIN_CTZLL, loc, 1, arg->copy());
11258 call = Expression::make_cast(int_type, call, loc);
11259 return Expression::make_conditional(cmp, c64, call, loc);
11260 }
fdae40b7 11261 else if ((name == "LeadingZeros8" || name == "LeadingZeros16"
11262 || name == "Len8" || name == "Len16")
11263 && this->args_ != NULL && this->args_->size() == 1)
11264 {
11265 // GCC does not have a clz8 ir clz16 intrinsic. We do
11266 // clz32(arg<<24 | 0xffffff) or clz32(arg<<16 | 0xffff).
11267 Expression* arg = this->args_->front();
11268 arg = Expression::make_cast(uint32_type, arg, loc);
11269 unsigned long shift =
11270 ((name == "LeadingZeros8" || name == "Len8") ? 24 : 16);
11271 Expression* c = Expression::make_integer_ul(shift, uint32_type, loc);
11272 arg = Expression::make_binary(OPERATOR_LSHIFT, arg, c, loc);
11273 unsigned long mask =
11274 ((name == "LeadingZeros8" || name == "Len8") ? 0xffffff : 0xffff);
11275 c = Expression::make_integer_ul(mask, uint32_type, loc);
11276 arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
11277 Expression* call = Runtime::make_call(Runtime::BUILTIN_CLZ, loc, 1, arg);
11278 call = Expression::make_cast(int_type, call, loc);
11279 // len = width - clz
11280 if (name == "Len8")
11281 {
11282 c = Expression::make_integer_ul(8, int_type, loc);
11283 return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
11284 }
11285 else if (name == "Len16")
11286 {
11287 c = Expression::make_integer_ul(16, int_type, loc);
11288 return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
11289 }
11290 return call;
11291 }
11292 else if ((name == "LeadingZeros32" || name == "Len32"
11293 || ((name == "LeadingZeros" || name == "Len") && int_size == 4))
11294 && this->args_ != NULL && this->args_->size() == 1)
11295 {
11296 Expression* arg = this->args_->front();
11297 if (!arg->is_variable())
11298 {
11299 Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
11300 inserter->insert(ts);
11301 arg = Expression::make_temporary_reference(ts, loc);
11302 }
11303 // arg == 0 ? 32 : __builtin_clz(arg)
11304 Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
11305 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
11306 Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
11307 Expression* call = Runtime::make_call(Runtime::BUILTIN_CLZ, loc, 1, arg->copy());
11308 call = Expression::make_cast(int_type, call, loc);
11309 Expression* cond = Expression::make_conditional(cmp, c32, call, loc);
11310 // len = 32 - clz
11311 if (name == "Len32" || name == "Len")
11312 return Expression::make_binary(OPERATOR_MINUS, c32->copy(), cond, loc);
11313 return cond;
11314 }
11315 else if ((name == "LeadingZeros64" || name == "Len64"
11316 || ((name == "LeadingZeros" || name == "Len") && int_size == 8))
11317 && this->args_ != NULL && this->args_->size() == 1)
11318 {
11319 Expression* arg = this->args_->front();
11320 if (!arg->is_variable())
11321 {
11322 Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
11323 inserter->insert(ts);
11324 arg = Expression::make_temporary_reference(ts, loc);
11325 }
11326 // arg == 0 ? 64 : __builtin_clzll(arg)
11327 Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
11328 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
11329 Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
11330 Expression* call = Runtime::make_call(Runtime::BUILTIN_CLZLL, loc, 1, arg->copy());
11331 call = Expression::make_cast(int_type, call, loc);
11332 Expression* cond = Expression::make_conditional(cmp, c64, call, loc);
11333 // len = 64 - clz
11334 if (name == "Len64" || name == "Len")
11335 return Expression::make_binary(OPERATOR_MINUS, c64->copy(), cond, loc);
11336 return cond;
11337 }
11338 else if ((name == "OnesCount8" || name == "OnesCount16"
11339 || name == "OnesCount32" || name == "OnesCount64"
11340 || name == "OnesCount")
11341 && this->args_ != NULL && this->args_->size() == 1)
11342 {
11343 Runtime::Function code;
11344 if (name == "OnesCount64")
11345 code = Runtime::BUILTIN_POPCOUNTLL;
11346 else if (name == "OnesCount")
11347 code = (int_size == 8 ? Runtime::BUILTIN_POPCOUNTLL : Runtime::BUILTIN_POPCOUNT);
11348 else
11349 code = Runtime::BUILTIN_POPCOUNT;
11350 Expression* arg = this->args_->front();
11351 Expression* call = Runtime::make_call(code, loc, 1, arg);
11352 return Expression::make_cast(int_type, call, loc);
11353 }
6c8a521f 11354 }
daccb2bc 11355 else if (package == "runtime/internal/atomic")
11356 {
11357 int memorder = __ATOMIC_SEQ_CST;
11358
11359 if ((name == "Load" || name == "Load64" || name == "Loadint64" || name == "Loadp"
2f0168ee 11360 || name == "Loaduint" || name == "Loaduintptr" || name == "LoadAcq"
11361 || name == "$Loadint32")
daccb2bc 11362 && this->args_ != NULL && this->args_->size() == 1)
11363 {
11364 if (int_size < 8 && (name == "Load64" || name == "Loadint64"))
11365 // On 32-bit architectures we need to check alignment.
11366 // Not intrinsify for now.
11367 return NULL;
11368
11369 Runtime::Function code;
11370 Type* res_type;
11371 if (name == "Load")
11372 {
11373 code = Runtime::ATOMIC_LOAD_4;
11374 res_type = uint32_type;
11375 }
11376 else if (name == "Load64")
11377 {
11378 code = Runtime::ATOMIC_LOAD_8;
11379 res_type = uint64_type;
11380 }
2f0168ee 11381 else if (name == "$Loadint32")
11382 {
11383 code = Runtime::ATOMIC_LOAD_4;
11384 res_type = int32_type;
11385 }
daccb2bc 11386 else if (name == "Loadint64")
11387 {
11388 code = Runtime::ATOMIC_LOAD_8;
11389 res_type = int64_type;
11390 }
11391 else if (name == "Loaduint")
11392 {
11393 code = (int_size == 8
11394 ? Runtime::ATOMIC_LOAD_8
11395 : Runtime::ATOMIC_LOAD_4);
11396 res_type = uint_type;
11397 }
11398 else if (name == "Loaduintptr")
11399 {
11400 code = (ptr_size == 8
11401 ? Runtime::ATOMIC_LOAD_8
11402 : Runtime::ATOMIC_LOAD_4);
11403 res_type = uintptr_type;
11404 }
11405 else if (name == "Loadp")
11406 {
11407 code = (ptr_size == 8
11408 ? Runtime::ATOMIC_LOAD_8
11409 : Runtime::ATOMIC_LOAD_4);
11410 res_type = pointer_type;
11411 }
11412 else if (name == "LoadAcq")
11413 {
11414 code = Runtime::ATOMIC_LOAD_4;
11415 res_type = uint32_type;
11416 memorder = __ATOMIC_ACQUIRE;
11417 }
11418 else
11419 go_unreachable();
11420 Expression* a1 = this->args_->front();
11421 Expression* a2 = Expression::make_integer_ul(memorder, int32_type, loc);
11422 Expression* call = Runtime::make_call(code, loc, 2, a1, a2);
11423 return Expression::make_unsafe_cast(res_type, call, loc);
11424 }
11425
11426 if ((name == "Store" || name == "Store64" || name == "StorepNoWB"
2f0168ee 11427 || name == "Storeuintptr" || name == "StoreRel"
11428 || name == "$Storeint32" || name == "$Storeint64")
daccb2bc 11429 && this->args_ != NULL && this->args_->size() == 2)
11430 {
2f0168ee 11431 if (int_size < 8 && (name == "Store64" || name == "$Storeint64"))
daccb2bc 11432 return NULL;
11433
11434 Runtime::Function code;
11435 Expression* a1 = this->args_->at(0);
11436 Expression* a2 = this->args_->at(1);
11437 if (name == "Store")
11438 code = Runtime::ATOMIC_STORE_4;
11439 else if (name == "Store64")
11440 code = Runtime::ATOMIC_STORE_8;
2f0168ee 11441 else if (name == "$Storeint32")
11442 code = Runtime::ATOMIC_STORE_4;
11443 else if (name == "$Storeint64")
11444 code = Runtime::ATOMIC_STORE_8;
daccb2bc 11445 else if (name == "Storeuintptr")
11446 code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
11447 else if (name == "StorepNoWB")
11448 {
11449 code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
11450 a2 = Expression::make_unsafe_cast(uintptr_type, a2, loc);
11451 a2 = Expression::make_cast(uint64_type, a2, loc);
11452 }
11453 else if (name == "StoreRel")
11454 {
11455 code = Runtime::ATOMIC_STORE_4;
11456 memorder = __ATOMIC_RELEASE;
11457 }
11458 else
11459 go_unreachable();
11460 Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
11461 return Runtime::make_call(code, loc, 3, a1, a2, a3);
11462 }
11463
2f0168ee 11464 if ((name == "Xchg" || name == "Xchg64" || name == "Xchguintptr"
11465 || name == "$Xchgint32" || name == "$Xchgint64")
daccb2bc 11466 && this->args_ != NULL && this->args_->size() == 2)
11467 {
2f0168ee 11468 if (int_size < 8 && (name == "Xchg64" || name == "Xchgint64"))
daccb2bc 11469 return NULL;
11470
11471 Runtime::Function code;
11472 Type* res_type;
11473 if (name == "Xchg")
11474 {
11475 code = Runtime::ATOMIC_EXCHANGE_4;
11476 res_type = uint32_type;
11477 }
11478 else if (name == "Xchg64")
11479 {
11480 code = Runtime::ATOMIC_EXCHANGE_8;
11481 res_type = uint64_type;
11482 }
2f0168ee 11483 else if (name == "$Xchgint32")
11484 {
11485 code = Runtime::ATOMIC_EXCHANGE_4;
11486 res_type = int32_type;
11487 }
11488 else if (name == "$Xchgint64")
11489 {
11490 code = Runtime::ATOMIC_EXCHANGE_8;
11491 res_type = int64_type;
11492 }
daccb2bc 11493 else if (name == "Xchguintptr")
11494 {
11495 code = (ptr_size == 8
11496 ? Runtime::ATOMIC_EXCHANGE_8
11497 : Runtime::ATOMIC_EXCHANGE_4);
11498 res_type = uintptr_type;
11499 }
11500 else
11501 go_unreachable();
11502 Expression* a1 = this->args_->at(0);
11503 Expression* a2 = this->args_->at(1);
11504 Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
11505 Expression* call = Runtime::make_call(code, loc, 3, a1, a2, a3);
11506 return Expression::make_cast(res_type, call, loc);
11507 }
11508
11509 if ((name == "Cas" || name == "Cas64" || name == "Casuintptr"
2f0168ee 11510 || name == "Casp1" || name == "CasRel"
11511 || name == "$Casint32" || name == "$Casint64")
daccb2bc 11512 && this->args_ != NULL && this->args_->size() == 3)
11513 {
2f0168ee 11514 if (int_size < 8 && (name == "Cas64" || name == "$Casint64"))
daccb2bc 11515 return NULL;
11516
11517 Runtime::Function code;
11518 Expression* a1 = this->args_->at(0);
11519
11520 // Builtin cas takes a pointer to the old value.
11521 // Store it in a temporary and take the address.
11522 Expression* a2 = this->args_->at(1);
11523 Temporary_statement* ts = Statement::make_temporary(NULL, a2, loc);
11524 inserter->insert(ts);
11525 a2 = Expression::make_temporary_reference(ts, loc);
11526 a2 = Expression::make_unary(OPERATOR_AND, a2, loc);
11527
11528 Expression* a3 = this->args_->at(2);
11529 if (name == "Cas")
11530 code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
11531 else if (name == "Cas64")
11532 code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
2f0168ee 11533 else if (name == "$Casint32")
11534 code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
11535 else if (name == "$Casint64")
11536 code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
daccb2bc 11537 else if (name == "Casuintptr")
11538 code = (ptr_size == 8
11539 ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
11540 : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
11541 else if (name == "Casp1")
11542 {
11543 code = (ptr_size == 8
11544 ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
11545 : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
11546 a3 = Expression::make_unsafe_cast(uintptr_type, a3, loc);
11547 a3 = Expression::make_cast(uint64_type, a3, loc);
11548 }
11549 else if (name == "CasRel")
11550 {
11551 code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
11552 memorder = __ATOMIC_RELEASE;
11553 }
11554 else
11555 go_unreachable();
11556 Expression* a4 = Expression::make_boolean(false, loc);
11557 Expression* a5 = Expression::make_integer_ul(memorder, int32_type, loc);
11558 Expression* a6 = Expression::make_integer_ul(__ATOMIC_RELAXED, int32_type, loc);
11559 return Runtime::make_call(code, loc, 6, a1, a2, a3, a4, a5, a6);
11560 }
11561
11562 if ((name == "Xadd" || name == "Xadd64" || name == "Xaddint64"
2f0168ee 11563 || name == "Xadduintptr" || name == "$Xaddint32")
daccb2bc 11564 && this->args_ != NULL && this->args_->size() == 2)
11565 {
11566 if (int_size < 8 && (name == "Xadd64" || name == "Xaddint64"))
11567 return NULL;
11568
11569 Runtime::Function code;
11570 Type* res_type;
11571 if (name == "Xadd")
11572 {
11573 code = Runtime::ATOMIC_ADD_FETCH_4;
11574 res_type = uint32_type;
11575 }
11576 else if (name == "Xadd64")
11577 {
11578 code = Runtime::ATOMIC_ADD_FETCH_8;
11579 res_type = uint64_type;
11580 }
2f0168ee 11581 else if (name == "$Xaddint32")
11582 {
11583 code = Runtime::ATOMIC_ADD_FETCH_4;
11584 res_type = int32_type;
11585 }
daccb2bc 11586 else if (name == "Xaddint64")
11587 {
11588 code = Runtime::ATOMIC_ADD_FETCH_8;
11589 res_type = int64_type;
11590 }
11591 else if (name == "Xadduintptr")
11592 {
11593 code = (ptr_size == 8
11594 ? Runtime::ATOMIC_ADD_FETCH_8
11595 : Runtime::ATOMIC_ADD_FETCH_4);
11596 res_type = uintptr_type;
11597 }
11598 else
11599 go_unreachable();
11600 Expression* a1 = this->args_->at(0);
11601 Expression* a2 = this->args_->at(1);
11602 Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
11603 Expression* call = Runtime::make_call(code, loc, 3, a1, a2, a3);
11604 return Expression::make_cast(res_type, call, loc);
11605 }
11606
11607 if ((name == "And8" || name == "Or8")
11608 && this->args_ != NULL && this->args_->size() == 2)
11609 {
11610 Runtime::Function code;
11611 if (name == "And8")
11612 code = Runtime::ATOMIC_AND_FETCH_1;
11613 else if (name == "Or8")
11614 code = Runtime::ATOMIC_OR_FETCH_1;
11615 else
11616 go_unreachable();
11617 Expression* a1 = this->args_->at(0);
11618 Expression* a2 = this->args_->at(1);
11619 Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
11620 return Runtime::make_call(code, loc, 3, a1, a2, a3);
11621 }
11622 }
6c8a521f 11623
11624 return NULL;
11625}
11626
e007b1eb 11627// Make implicit type conversions explicit.
11628
11629void
11630Call_expression::do_add_conversions()
11631{
11632 // Skip call that requires a thunk. We generate conversions inside the thunk.
11633 if (this->is_concurrent_ || this->is_deferred_)
11634 return;
11635
11636 if (this->args_ == NULL || this->args_->empty())
11637 return;
11638
11639 Function_type* fntype = this->get_function_type();
11640 if (fntype == NULL)
11641 {
11642 go_assert(saw_errors());
11643 return;
11644 }
11645 if (fntype->parameters() == NULL || fntype->parameters()->empty())
11646 return;
11647
11648 Location loc = this->location();
11649 Expression_list::iterator pa = this->args_->begin();
11650 Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
11651 bool is_interface_method =
11652 this->fn_->interface_field_reference_expression() != NULL;
11653 if (!is_interface_method && fntype->is_method())
11654 {
11655 // Skip the receiver argument, which cannot be interface.
11656 pa++;
11657 }
11658 for (; pa != this->args_->end(); ++pa, ++pp)
11659 {
11660 Type* pt = pp->type();
11661 if (!Type::are_identical(pt, (*pa)->type(), 0, NULL)
11662 && pt->interface_type() != NULL)
11663 *pa = Expression::make_cast(pt, *pa, loc);
11664 }
11665}
11666
ceeb4318 11667// Get the function type. This can return NULL in error cases.
e440a328 11668
11669Function_type*
11670Call_expression::get_function_type() const
11671{
11672 return this->fn_->type()->function_type();
11673}
11674
11675// Return the number of values which this call will return.
11676
11677size_t
11678Call_expression::result_count() const
11679{
11680 const Function_type* fntype = this->get_function_type();
11681 if (fntype == NULL)
11682 return 0;
11683 if (fntype->results() == NULL)
11684 return 0;
11685 return fntype->results()->size();
11686}
11687
5731103c 11688// Return the temporary that holds the result for a call with multiple
11689// results.
ceeb4318 11690
11691Temporary_statement*
5731103c 11692Call_expression::results() const
ceeb4318 11693{
5731103c 11694 if (this->call_temp_ == NULL)
cd238b8d 11695 {
11696 go_assert(saw_errors());
11697 return NULL;
11698 }
5731103c 11699 return this->call_temp_;
ceeb4318 11700}
11701
1373401e 11702// Set the number of results expected from a call expression.
11703
11704void
11705Call_expression::set_expected_result_count(size_t count)
11706{
11707 go_assert(this->expected_result_count_ == 0);
11708 this->expected_result_count_ = count;
11709}
11710
e440a328 11711// Return whether this is a call to the predeclared function recover.
11712
11713bool
11714Call_expression::is_recover_call() const
11715{
11716 return this->do_is_recover_call();
11717}
11718
11719// Set the argument to the recover function.
11720
11721void
11722Call_expression::set_recover_arg(Expression* arg)
11723{
11724 this->do_set_recover_arg(arg);
11725}
11726
11727// Virtual functions also implemented by Builtin_call_expression.
11728
11729bool
11730Call_expression::do_is_recover_call() const
11731{
11732 return false;
11733}
11734
11735void
11736Call_expression::do_set_recover_arg(Expression*)
11737{
c3e6f413 11738 go_unreachable();
e440a328 11739}
11740
ceeb4318 11741// We have found an error with this call expression; return true if
11742// we should report it.
11743
11744bool
11745Call_expression::issue_error()
11746{
11747 if (this->issued_error_)
11748 return false;
11749 else
11750 {
11751 this->issued_error_ = true;
11752 return true;
11753 }
11754}
11755
5bf8be8b 11756// Whether or not this call contains errors, either in the call or the
11757// arguments to the call.
11758
11759bool
11760Call_expression::is_erroneous_call()
11761{
11762 if (this->is_error_expression() || this->fn()->is_error_expression())
11763 return true;
11764
11765 if (this->args() == NULL)
11766 return false;
11767 for (Expression_list::iterator pa = this->args()->begin();
11768 pa != this->args()->end();
11769 ++pa)
11770 {
11771 if ((*pa)->type()->is_error_type() || (*pa)->is_error_expression())
11772 return true;
11773 }
11774 return false;
11775}
11776
e440a328 11777// Get the type.
11778
11779Type*
11780Call_expression::do_type()
11781{
11782 if (this->type_ != NULL)
11783 return this->type_;
11784
11785 Type* ret;
11786 Function_type* fntype = this->get_function_type();
11787 if (fntype == NULL)
11788 return Type::make_error_type();
11789
11790 const Typed_identifier_list* results = fntype->results();
11791 if (results == NULL)
11792 ret = Type::make_void_type();
11793 else if (results->size() == 1)
11794 ret = results->begin()->type();
11795 else
2801343b 11796 ret = Type::make_call_multiple_result_type(this);
e440a328 11797
11798 this->type_ = ret;
11799
11800 return this->type_;
11801}
11802
11803// Determine types for a call expression. We can use the function
11804// parameter types to set the types of the arguments.
11805
11806void
11807Call_expression::do_determine_type(const Type_context*)
11808{
fb94b0ca 11809 if (!this->determining_types())
11810 return;
11811
e440a328 11812 this->fn_->determine_type_no_context();
11813 Function_type* fntype = this->get_function_type();
11814 const Typed_identifier_list* parameters = NULL;
11815 if (fntype != NULL)
11816 parameters = fntype->parameters();
11817 if (this->args_ != NULL)
11818 {
11819 Typed_identifier_list::const_iterator pt;
11820 if (parameters != NULL)
11821 pt = parameters->begin();
09ea332d 11822 bool first = true;
e440a328 11823 for (Expression_list::const_iterator pa = this->args_->begin();
11824 pa != this->args_->end();
11825 ++pa)
11826 {
09ea332d 11827 if (first)
11828 {
11829 first = false;
11830 // If this is a method, the first argument is the
11831 // receiver.
11832 if (fntype != NULL && fntype->is_method())
11833 {
11834 Type* rtype = fntype->receiver()->type();
11835 // The receiver is always passed as a pointer.
11836 if (rtype->points_to() == NULL)
11837 rtype = Type::make_pointer_type(rtype);
11838 Type_context subcontext(rtype, false);
11839 (*pa)->determine_type(&subcontext);
11840 continue;
11841 }
11842 }
11843
e440a328 11844 if (parameters != NULL && pt != parameters->end())
11845 {
11846 Type_context subcontext(pt->type(), false);
11847 (*pa)->determine_type(&subcontext);
11848 ++pt;
11849 }
11850 else
11851 (*pa)->determine_type_no_context();
11852 }
11853 }
11854}
11855
fb94b0ca 11856// Called when determining types for a Call_expression. Return true
11857// if we should go ahead, false if they have already been determined.
11858
11859bool
11860Call_expression::determining_types()
11861{
11862 if (this->types_are_determined_)
11863 return false;
11864 else
11865 {
11866 this->types_are_determined_ = true;
11867 return true;
11868 }
11869}
11870
e440a328 11871// Check types for parameter I.
11872
11873bool
11874Call_expression::check_argument_type(int i, const Type* parameter_type,
11875 const Type* argument_type,
b13c66cd 11876 Location argument_location,
e440a328 11877 bool issued_error)
11878{
11879 std::string reason;
1eae365b 11880 if (!Type::are_assignable(parameter_type, argument_type, &reason))
e440a328 11881 {
11882 if (!issued_error)
11883 {
11884 if (reason.empty())
631d5788 11885 go_error_at(argument_location, "argument %d has incompatible type", i);
e440a328 11886 else
631d5788 11887 go_error_at(argument_location,
11888 "argument %d has incompatible type (%s)",
11889 i, reason.c_str());
e440a328 11890 }
11891 this->set_is_error();
11892 return false;
11893 }
11894 return true;
11895}
11896
11897// Check types.
11898
11899void
11900Call_expression::do_check_types(Gogo*)
11901{
a6645f74 11902 if (this->classification() == EXPRESSION_ERROR)
11903 return;
11904
e440a328 11905 Function_type* fntype = this->get_function_type();
11906 if (fntype == NULL)
11907 {
5c13bd80 11908 if (!this->fn_->type()->is_error())
e440a328 11909 this->report_error(_("expected function"));
11910 return;
11911 }
11912
1373401e 11913 if (this->expected_result_count_ != 0
11914 && this->expected_result_count_ != this->result_count())
11915 {
11916 if (this->issue_error())
11917 this->report_error(_("function result count mismatch"));
11918 this->set_is_error();
11919 return;
11920 }
11921
09ea332d 11922 bool is_method = fntype->is_method();
11923 if (is_method)
e440a328 11924 {
09ea332d 11925 go_assert(this->args_ != NULL && !this->args_->empty());
11926 Type* rtype = fntype->receiver()->type();
11927 Expression* first_arg = this->args_->front();
1eae365b 11928 // We dereference the values since receivers are always passed
11929 // as pointers.
09ea332d 11930 std::string reason;
1eae365b 11931 if (!Type::are_assignable(rtype->deref(), first_arg->type()->deref(),
11932 &reason))
e440a328 11933 {
09ea332d 11934 if (reason.empty())
11935 this->report_error(_("incompatible type for receiver"));
11936 else
e440a328 11937 {
631d5788 11938 go_error_at(this->location(),
11939 "incompatible type for receiver (%s)",
11940 reason.c_str());
09ea332d 11941 this->set_is_error();
e440a328 11942 }
11943 }
11944 }
11945
11946 // Note that varargs was handled by the lower_varargs() method, so
a6645f74 11947 // we don't have to worry about it here unless something is wrong.
11948 if (this->is_varargs_ && !this->varargs_are_lowered_)
11949 {
11950 if (!fntype->is_varargs())
11951 {
631d5788 11952 go_error_at(this->location(),
11953 _("invalid use of %<...%> calling non-variadic function"));
a6645f74 11954 this->set_is_error();
11955 return;
11956 }
11957 }
e440a328 11958
11959 const Typed_identifier_list* parameters = fntype->parameters();
33d1d391 11960 if (this->args_ == NULL || this->args_->size() == 0)
e440a328 11961 {
11962 if (parameters != NULL && !parameters->empty())
11963 this->report_error(_("not enough arguments"));
11964 }
11965 else if (parameters == NULL)
09ea332d 11966 {
11967 if (!is_method || this->args_->size() > 1)
11968 this->report_error(_("too many arguments"));
11969 }
1373401e 11970 else if (this->args_->size() == 1
11971 && this->args_->front()->call_expression() != NULL
11972 && this->args_->front()->call_expression()->result_count() > 1)
11973 {
11974 // This is F(G()) when G returns more than one result. If the
11975 // results can be matched to parameters, it would have been
11976 // lowered in do_lower. If we get here we know there is a
11977 // mismatch.
11978 if (this->args_->front()->call_expression()->result_count()
11979 < parameters->size())
11980 this->report_error(_("not enough arguments"));
11981 else
11982 this->report_error(_("too many arguments"));
11983 }
e440a328 11984 else
11985 {
11986 int i = 0;
09ea332d 11987 Expression_list::const_iterator pa = this->args_->begin();
11988 if (is_method)
11989 ++pa;
11990 for (Typed_identifier_list::const_iterator pt = parameters->begin();
11991 pt != parameters->end();
11992 ++pt, ++pa, ++i)
e440a328 11993 {
09ea332d 11994 if (pa == this->args_->end())
e440a328 11995 {
09ea332d 11996 this->report_error(_("not enough arguments"));
e440a328 11997 return;
11998 }
11999 this->check_argument_type(i + 1, pt->type(), (*pa)->type(),
12000 (*pa)->location(), false);
12001 }
09ea332d 12002 if (pa != this->args_->end())
12003 this->report_error(_("too many arguments"));
e440a328 12004 }
12005}
12006
72666aed 12007Expression*
12008Call_expression::do_copy()
12009{
12010 Call_expression* call =
12011 Expression::make_call(this->fn_->copy(),
12012 (this->args_ == NULL
12013 ? NULL
12014 : this->args_->copy()),
12015 this->is_varargs_, this->location());
12016
12017 if (this->varargs_are_lowered_)
12018 call->set_varargs_are_lowered();
28819633 12019 if (this->is_deferred_)
12020 call->set_is_deferred();
12021 if (this->is_concurrent_)
12022 call->set_is_concurrent();
72666aed 12023 return call;
12024}
12025
e440a328 12026// Return whether we have to use a temporary variable to ensure that
12027// we evaluate this call expression in order. If the call returns no
ceeb4318 12028// results then it will inevitably be executed last.
e440a328 12029
12030bool
12031Call_expression::do_must_eval_in_order() const
12032{
ceeb4318 12033 return this->result_count() > 0;
e440a328 12034}
12035
e440a328 12036// Get the function and the first argument to use when calling an
12037// interface method.
12038
2387f644 12039Expression*
e440a328 12040Call_expression::interface_method_function(
e440a328 12041 Interface_field_reference_expression* interface_method,
db122cb9 12042 Expression** first_arg_ptr,
12043 Location location)
e440a328 12044{
db122cb9 12045 Expression* object = interface_method->get_underlying_object();
12046 Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
12047 *first_arg_ptr =
12048 Expression::make_unsafe_cast(unsafe_ptr_type, object, location);
2387f644 12049 return interface_method->get_function();
e440a328 12050}
12051
12052// Build the call expression.
12053
ea664253 12054Bexpression*
12055Call_expression::do_get_backend(Translate_context* context)
e440a328 12056{
5731103c 12057 Location location = this->location();
12058
2c809f8f 12059 if (this->call_ != NULL)
5731103c 12060 {
12061 // If the call returns multiple results, make a new reference to
12062 // the temporary.
12063 if (this->call_temp_ != NULL)
12064 {
12065 Expression* ref =
12066 Expression::make_temporary_reference(this->call_temp_, location);
12067 return ref->get_backend(context);
12068 }
12069
12070 return this->call_;
12071 }
e440a328 12072
12073 Function_type* fntype = this->get_function_type();
12074 if (fntype == NULL)
ea664253 12075 return context->backend()->error_expression();
e440a328 12076
12077 if (this->fn_->is_error_expression())
ea664253 12078 return context->backend()->error_expression();
e440a328 12079
12080 Gogo* gogo = context->gogo();
e440a328 12081
12082 Func_expression* func = this->fn_->func_expression();
e440a328 12083 Interface_field_reference_expression* interface_method =
12084 this->fn_->interface_field_reference_expression();
12085 const bool has_closure = func != NULL && func->closure() != NULL;
09ea332d 12086 const bool is_interface_method = interface_method != NULL;
e440a328 12087
f8bdf81a 12088 bool has_closure_arg;
8381eda7 12089 if (has_closure)
f8bdf81a 12090 has_closure_arg = true;
8381eda7 12091 else if (func != NULL)
f8bdf81a 12092 has_closure_arg = false;
8381eda7 12093 else if (is_interface_method)
f8bdf81a 12094 has_closure_arg = false;
8381eda7 12095 else
f8bdf81a 12096 has_closure_arg = true;
8381eda7 12097
fa502e3a 12098 Expression* first_arg = NULL;
12099 if (!is_interface_method && fntype->is_method())
12100 {
12101 first_arg = this->args_->front();
12102 if (first_arg->type()->points_to() == NULL
12103 && first_arg->type()->is_direct_iface_type())
12104 first_arg = Expression::unpack_direct_iface(first_arg,
12105 first_arg->location());
12106 }
12107
e440a328 12108 int nargs;
2c809f8f 12109 std::vector<Bexpression*> fn_args;
e440a328 12110 if (this->args_ == NULL || this->args_->empty())
12111 {
f8bdf81a 12112 nargs = is_interface_method ? 1 : 0;
2c809f8f 12113 if (nargs > 0)
12114 fn_args.resize(1);
e440a328 12115 }
09ea332d 12116 else if (fntype->parameters() == NULL || fntype->parameters()->empty())
12117 {
12118 // Passing a receiver parameter.
12119 go_assert(!is_interface_method
12120 && fntype->is_method()
12121 && this->args_->size() == 1);
f8bdf81a 12122 nargs = 1;
2c809f8f 12123 fn_args.resize(1);
fa502e3a 12124 fn_args[0] = first_arg->get_backend(context);
09ea332d 12125 }
e440a328 12126 else
12127 {
12128 const Typed_identifier_list* params = fntype->parameters();
e440a328 12129
12130 nargs = this->args_->size();
09ea332d 12131 int i = is_interface_method ? 1 : 0;
e440a328 12132 nargs += i;
2c809f8f 12133 fn_args.resize(nargs);
e440a328 12134
12135 Typed_identifier_list::const_iterator pp = params->begin();
09ea332d 12136 Expression_list::const_iterator pe = this->args_->begin();
12137 if (!is_interface_method && fntype->is_method())
12138 {
fa502e3a 12139 fn_args[i] = first_arg->get_backend(context);
09ea332d 12140 ++pe;
12141 ++i;
12142 }
12143 for (; pe != this->args_->end(); ++pe, ++pp, ++i)
e440a328 12144 {
c484d925 12145 go_assert(pp != params->end());
2c809f8f 12146 Expression* arg =
12147 Expression::convert_for_assignment(gogo, pp->type(), *pe,
12148 location);
ea664253 12149 fn_args[i] = arg->get_backend(context);
e440a328 12150 }
c484d925 12151 go_assert(pp == params->end());
f8bdf81a 12152 go_assert(i == nargs);
e440a328 12153 }
12154
2c809f8f 12155 Expression* fn;
12156 Expression* closure = NULL;
8381eda7 12157 if (func != NULL)
12158 {
12159 Named_object* no = func->named_object();
2c809f8f 12160 fn = Expression::make_func_code_reference(no, location);
12161 if (has_closure)
12162 closure = func->closure();
8381eda7 12163 }
09ea332d 12164 else if (!is_interface_method)
8381eda7 12165 {
2c809f8f 12166 closure = this->fn_;
12167
12168 // The backend representation of this function type is a pointer
12169 // to a struct whose first field is the actual function to call.
12170 Type* pfntype =
12171 Type::make_pointer_type(
12172 Type::make_pointer_type(Type::make_void_type()));
12173 fn = Expression::make_unsafe_cast(pfntype, this->fn_, location);
f614ea8b 12174 fn = Expression::make_dereference(fn, NIL_CHECK_NOT_NEEDED, location);
2c809f8f 12175 }
e440a328 12176 else
cf609de4 12177 {
2387f644 12178 Expression* first_arg;
db122cb9 12179 fn = this->interface_method_function(interface_method, &first_arg,
12180 location);
ea664253 12181 fn_args[0] = first_arg->get_backend(context);
e440a328 12182 }
12183
1ecc6157 12184 Bexpression* bclosure = NULL;
12185 if (has_closure_arg)
12186 bclosure = closure->get_backend(context);
f8bdf81a 12187 else
1ecc6157 12188 go_assert(closure == NULL);
f8bdf81a 12189
ea664253 12190 Bexpression* bfn = fn->get_backend(context);
80d1e1a8 12191
12192 // When not calling a named function directly, use a type conversion
12193 // in case the type of the function is a recursive type which refers
12194 // to itself. We don't do this for an interface method because 1)
12195 // an interface method never refers to itself, so we always have a
12196 // function type here; 2) we pass an extra first argument to an
12197 // interface method, so fntype is not correct.
12198 if (func == NULL && !is_interface_method)
12199 {
12200 Btype* bft = fntype->get_backend_fntype(gogo);
12201 bfn = gogo->backend()->convert_expression(bft, bfn, location);
12202 }
12203
4ced7af9 12204 Bfunction* bfunction = NULL;
12205 if (context->function())
12206 bfunction = context->function()->func_value()->get_decl();
12207 Bexpression* call = gogo->backend()->call_expression(bfunction, bfn,
12208 fn_args, bclosure,
12209 location);
e440a328 12210
5731103c 12211 if (this->call_temp_ != NULL)
e440a328 12212 {
5731103c 12213 // This case occurs when the call returns multiple results.
e440a328 12214
5731103c 12215 Expression* ref = Expression::make_temporary_reference(this->call_temp_,
12216 location);
12217 Bexpression* bref = ref->get_backend(context);
12218 Bstatement* bassn = gogo->backend()->assignment_statement(bfunction,
12219 bref, call,
12220 location);
e440a328 12221
5731103c 12222 ref = Expression::make_temporary_reference(this->call_temp_, location);
12223 this->call_ = ref->get_backend(context);
12224
12225 return gogo->backend()->compound_expression(bassn, this->call_,
12226 location);
2c809f8f 12227 }
e440a328 12228
2c809f8f 12229 this->call_ = call;
ea664253 12230 return this->call_;
e440a328 12231}
12232
e3d09834 12233// The cost of inlining a call expression.
12234
12235int
12236Call_expression::do_inlining_cost() const
12237{
12238 Func_expression* fn = this->fn_->func_expression();
12239
12240 // FIXME: We don't yet support all kinds of calls.
12241 if (fn != NULL && fn->closure() != NULL)
12242 return 0x100000;
12243 if (this->fn_->interface_field_reference_expression())
12244 return 0x100000;
12245 if (this->get_function_type()->is_method())
12246 return 0x100000;
12247
12248 return 5;
12249}
12250
12251// Export a call expression.
12252
12253void
12254Call_expression::do_export(Export_function_body* efb) const
12255{
12256 this->fn_->export_expression(efb);
12257 this->export_arguments(efb);
12258}
12259
12260// Export call expression arguments.
12261
12262void
12263Call_expression::export_arguments(Export_function_body* efb) const
12264{
12265 efb->write_c_string("(");
12266 if (this->args_ != NULL && !this->args_->empty())
12267 {
12268 Expression_list::const_iterator pa = this->args_->begin();
12269 (*pa)->export_expression(efb);
12270 for (pa++; pa != this->args_->end(); pa++)
12271 {
12272 efb->write_c_string(", ");
12273 (*pa)->export_expression(efb);
12274 }
12275 if (this->is_varargs_)
12276 efb->write_c_string("...");
12277 }
12278 efb->write_c_string(")");
12279}
12280
12281// Dump ast representation for a call expression.
d751bb78 12282
12283void
12284Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
12285{
12286 this->fn_->dump_expression(ast_dump_context);
12287 ast_dump_context->ostream() << "(";
12288 if (args_ != NULL)
12289 ast_dump_context->dump_expression_list(this->args_);
12290
12291 ast_dump_context->ostream() << ") ";
12292}
12293
e440a328 12294// Make a call expression.
12295
12296Call_expression*
12297Expression::make_call(Expression* fn, Expression_list* args, bool is_varargs,
b13c66cd 12298 Location location)
e440a328 12299{
12300 return new Call_expression(fn, args, is_varargs, location);
12301}
12302
da244e59 12303// Class Call_result_expression.
e440a328 12304
12305// Traverse a call result.
12306
12307int
12308Call_result_expression::do_traverse(Traverse* traverse)
12309{
12310 if (traverse->remember_expression(this->call_))
12311 {
12312 // We have already traversed the call expression.
12313 return TRAVERSE_CONTINUE;
12314 }
12315 return Expression::traverse(&this->call_, traverse);
12316}
12317
12318// Get the type.
12319
12320Type*
12321Call_result_expression::do_type()
12322{
425dd051 12323 if (this->classification() == EXPRESSION_ERROR)
12324 return Type::make_error_type();
12325
e440a328 12326 // THIS->CALL_ can be replaced with a temporary reference due to
12327 // Call_expression::do_must_eval_in_order when there is an error.
12328 Call_expression* ce = this->call_->call_expression();
12329 if (ce == NULL)
5e85f268 12330 {
12331 this->set_is_error();
12332 return Type::make_error_type();
12333 }
e440a328 12334 Function_type* fntype = ce->get_function_type();
12335 if (fntype == NULL)
5e85f268 12336 {
e37658e2 12337 if (ce->issue_error())
99b3f06f 12338 {
12339 if (!ce->fn()->type()->is_error())
12340 this->report_error(_("expected function"));
12341 }
5e85f268 12342 this->set_is_error();
12343 return Type::make_error_type();
12344 }
e440a328 12345 const Typed_identifier_list* results = fntype->results();
ceeb4318 12346 if (results == NULL || results->size() < 2)
7b8d861f 12347 {
ceeb4318 12348 if (ce->issue_error())
12349 this->report_error(_("number of results does not match "
12350 "number of values"));
7b8d861f 12351 return Type::make_error_type();
12352 }
e440a328 12353 Typed_identifier_list::const_iterator pr = results->begin();
12354 for (unsigned int i = 0; i < this->index_; ++i)
12355 {
12356 if (pr == results->end())
425dd051 12357 break;
e440a328 12358 ++pr;
12359 }
12360 if (pr == results->end())
425dd051 12361 {
ceeb4318 12362 if (ce->issue_error())
12363 this->report_error(_("number of results does not match "
12364 "number of values"));
425dd051 12365 return Type::make_error_type();
12366 }
e440a328 12367 return pr->type();
12368}
12369
425dd051 12370// Check the type. Just make sure that we trigger the warning in
12371// do_type.
e440a328 12372
12373void
12374Call_result_expression::do_check_types(Gogo*)
12375{
425dd051 12376 this->type();
e440a328 12377}
12378
12379// Determine the type. We have nothing to do here, but the 0 result
12380// needs to pass down to the caller.
12381
12382void
12383Call_result_expression::do_determine_type(const Type_context*)
12384{
fb94b0ca 12385 this->call_->determine_type_no_context();
e440a328 12386}
12387
ea664253 12388// Return the backend representation. We just refer to the temporary set by the
12389// call expression. We don't do this at lowering time because it makes it
ceeb4318 12390// hard to evaluate the call at the right time.
e440a328 12391
ea664253 12392Bexpression*
12393Call_result_expression::do_get_backend(Translate_context* context)
e440a328 12394{
ceeb4318 12395 Call_expression* ce = this->call_->call_expression();
cd238b8d 12396 if (ce == NULL)
12397 {
12398 go_assert(this->call_->is_error_expression());
ea664253 12399 return context->backend()->error_expression();
cd238b8d 12400 }
5731103c 12401 Temporary_statement* ts = ce->results();
cd238b8d 12402 if (ts == NULL)
12403 {
12404 go_assert(saw_errors());
ea664253 12405 return context->backend()->error_expression();
cd238b8d 12406 }
ceeb4318 12407 Expression* ref = Expression::make_temporary_reference(ts, this->location());
5731103c 12408 ref = Expression::make_field_reference(ref, this->index_, this->location());
ea664253 12409 return ref->get_backend(context);
e440a328 12410}
12411
d751bb78 12412// Dump ast representation for a call result expression.
12413
12414void
12415Call_result_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
12416 const
12417{
f03a9fbf 12418 // FIXME: Wouldn't it be better if the call is assigned to a temporary
d751bb78 12419 // (struct) and the fields are referenced instead.
12420 ast_dump_context->ostream() << this->index_ << "@(";
12421 ast_dump_context->dump_expression(this->call_);
12422 ast_dump_context->ostream() << ")";
12423}
12424
e440a328 12425// Make a reference to a single result of a call which returns
12426// multiple results.
12427
12428Expression*
12429Expression::make_call_result(Call_expression* call, unsigned int index)
12430{
12431 return new Call_result_expression(call, index);
12432}
12433
12434// Class Index_expression.
12435
12436// Traversal.
12437
12438int
12439Index_expression::do_traverse(Traverse* traverse)
12440{
12441 if (Expression::traverse(&this->left_, traverse) == TRAVERSE_EXIT
12442 || Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT
12443 || (this->end_ != NULL
acf2b673 12444 && Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
12445 || (this->cap_ != NULL
12446 && Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT))
e440a328 12447 return TRAVERSE_EXIT;
12448 return TRAVERSE_CONTINUE;
12449}
12450
12451// Lower an index expression. This converts the generic index
12452// expression into an array index, a string index, or a map index.
12453
12454Expression*
ceeb4318 12455Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
e440a328 12456{
b13c66cd 12457 Location location = this->location();
e440a328 12458 Expression* left = this->left_;
12459 Expression* start = this->start_;
12460 Expression* end = this->end_;
acf2b673 12461 Expression* cap = this->cap_;
e440a328 12462
12463 Type* type = left->type();
5c13bd80 12464 if (type->is_error())
d9f3743a 12465 {
12466 go_assert(saw_errors());
12467 return Expression::make_error(location);
12468 }
b0cf7ddd 12469 else if (left->is_type_expression())
12470 {
631d5788 12471 go_error_at(location, "attempt to index type expression");
b0cf7ddd 12472 return Expression::make_error(location);
12473 }
e440a328 12474 else if (type->array_type() != NULL)
acf2b673 12475 return Expression::make_array_index(left, start, end, cap, location);
e440a328 12476 else if (type->points_to() != NULL
12477 && type->points_to()->array_type() != NULL
411eb89e 12478 && !type->points_to()->is_slice_type())
e440a328 12479 {
f614ea8b 12480 Expression* deref =
12481 Expression::make_dereference(left, NIL_CHECK_DEFAULT, location);
38092374 12482
12483 // For an ordinary index into the array, the pointer will be
12484 // dereferenced. For a slice it will not--the resulting slice
12485 // will simply reuse the pointer, which is incorrect if that
12486 // pointer is nil.
12487 if (end != NULL || cap != NULL)
12488 deref->issue_nil_check();
12489
acf2b673 12490 return Expression::make_array_index(deref, start, end, cap, location);
e440a328 12491 }
12492 else if (type->is_string_type())
acf2b673 12493 {
12494 if (cap != NULL)
12495 {
631d5788 12496 go_error_at(location, "invalid 3-index slice of string");
acf2b673 12497 return Expression::make_error(location);
12498 }
12499 return Expression::make_string_index(left, start, end, location);
12500 }
e440a328 12501 else if (type->map_type() != NULL)
12502 {
acf2b673 12503 if (end != NULL || cap != NULL)
e440a328 12504 {
631d5788 12505 go_error_at(location, "invalid slice of map");
e440a328 12506 return Expression::make_error(location);
12507 }
0d5530d9 12508 return Expression::make_map_index(left, start, location);
e440a328 12509 }
b1aba207 12510 else if (cap != NULL)
12511 {
12512 go_error_at(location,
12513 "invalid 3-index slice of object that is not a slice");
12514 return Expression::make_error(location);
12515 }
12516 else if (end != NULL)
12517 {
12518 go_error_at(location,
12519 ("attempt to slice object that is not "
12520 "array, slice, or string"));
12521 return Expression::make_error(location);
12522 }
e440a328 12523 else
12524 {
631d5788 12525 go_error_at(location,
b1aba207 12526 ("attempt to index object that is not "
12527 "array, slice, string, or map"));
e440a328 12528 return Expression::make_error(location);
12529 }
12530}
12531
acf2b673 12532// Write an indexed expression
12533// (expr[expr:expr:expr], expr[expr:expr] or expr[expr]) to a dump context.
d751bb78 12534
12535void
f03a9fbf 12536Index_expression::dump_index_expression(Ast_dump_context* ast_dump_context,
12537 const Expression* expr,
d751bb78 12538 const Expression* start,
acf2b673 12539 const Expression* end,
12540 const Expression* cap)
d751bb78 12541{
12542 expr->dump_expression(ast_dump_context);
12543 ast_dump_context->ostream() << "[";
12544 start->dump_expression(ast_dump_context);
12545 if (end != NULL)
12546 {
12547 ast_dump_context->ostream() << ":";
12548 end->dump_expression(ast_dump_context);
12549 }
acf2b673 12550 if (cap != NULL)
12551 {
12552 ast_dump_context->ostream() << ":";
12553 cap->dump_expression(ast_dump_context);
12554 }
d751bb78 12555 ast_dump_context->ostream() << "]";
12556}
12557
12558// Dump ast representation for an index expression.
12559
12560void
f03a9fbf 12561Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 12562 const
12563{
f03a9fbf 12564 Index_expression::dump_index_expression(ast_dump_context, this->left_,
acf2b673 12565 this->start_, this->end_, this->cap_);
d751bb78 12566}
12567
e440a328 12568// Make an index expression.
12569
12570Expression*
12571Expression::make_index(Expression* left, Expression* start, Expression* end,
acf2b673 12572 Expression* cap, Location location)
e440a328 12573{
acf2b673 12574 return new Index_expression(left, start, end, cap, location);
e440a328 12575}
12576
da244e59 12577// Class Array_index_expression.
e440a328 12578
12579// Array index traversal.
12580
12581int
12582Array_index_expression::do_traverse(Traverse* traverse)
12583{
12584 if (Expression::traverse(&this->array_, traverse) == TRAVERSE_EXIT)
12585 return TRAVERSE_EXIT;
12586 if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
12587 return TRAVERSE_EXIT;
12588 if (this->end_ != NULL)
12589 {
12590 if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
12591 return TRAVERSE_EXIT;
12592 }
acf2b673 12593 if (this->cap_ != NULL)
12594 {
12595 if (Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
12596 return TRAVERSE_EXIT;
12597 }
e440a328 12598 return TRAVERSE_CONTINUE;
12599}
12600
12601// Return the type of an array index.
12602
12603Type*
12604Array_index_expression::do_type()
12605{
12606 if (this->type_ == NULL)
12607 {
12608 Array_type* type = this->array_->type()->array_type();
12609 if (type == NULL)
12610 this->type_ = Type::make_error_type();
12611 else if (this->end_ == NULL)
12612 this->type_ = type->element_type();
411eb89e 12613 else if (type->is_slice_type())
e440a328 12614 {
12615 // A slice of a slice has the same type as the original
12616 // slice.
12617 this->type_ = this->array_->type()->deref();
12618 }
12619 else
12620 {
12621 // A slice of an array is a slice.
12622 this->type_ = Type::make_array_type(type->element_type(), NULL);
12623 }
12624 }
12625 return this->type_;
12626}
12627
12628// Set the type of an array index.
12629
12630void
12631Array_index_expression::do_determine_type(const Type_context*)
12632{
12633 this->array_->determine_type_no_context();
f77aa642 12634
12635 Type_context index_context(Type::lookup_integer_type("int"), false);
12636 if (this->start_->is_constant())
12637 this->start_->determine_type(&index_context);
12638 else
12639 this->start_->determine_type_no_context();
e440a328 12640 if (this->end_ != NULL)
f77aa642 12641 {
12642 if (this->end_->is_constant())
12643 this->end_->determine_type(&index_context);
12644 else
12645 this->end_->determine_type_no_context();
12646 }
acf2b673 12647 if (this->cap_ != NULL)
f77aa642 12648 {
12649 if (this->cap_->is_constant())
12650 this->cap_->determine_type(&index_context);
12651 else
12652 this->cap_->determine_type_no_context();
12653 }
e440a328 12654}
12655
12656// Check types of an array index.
12657
12658void
b7327dbf 12659Array_index_expression::do_check_types(Gogo*)
e440a328 12660{
f6bc81e6 12661 Numeric_constant nc;
12662 unsigned long v;
12663 if (this->start_->type()->integer_type() == NULL
12664 && !this->start_->type()->is_error()
12665 && (!this->start_->numeric_constant_value(&nc)
12666 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 12667 this->report_error(_("index must be integer"));
12668 if (this->end_ != NULL
12669 && this->end_->type()->integer_type() == NULL
99b3f06f 12670 && !this->end_->type()->is_error()
12671 && !this->end_->is_nil_expression()
f6bc81e6 12672 && !this->end_->is_error_expression()
12673 && (!this->end_->numeric_constant_value(&nc)
12674 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 12675 this->report_error(_("slice end must be integer"));
acf2b673 12676 if (this->cap_ != NULL
12677 && this->cap_->type()->integer_type() == NULL
12678 && !this->cap_->type()->is_error()
12679 && !this->cap_->is_nil_expression()
12680 && !this->cap_->is_error_expression()
12681 && (!this->cap_->numeric_constant_value(&nc)
12682 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
12683 this->report_error(_("slice capacity must be integer"));
e440a328 12684
12685 Array_type* array_type = this->array_->type()->array_type();
f9c68f17 12686 if (array_type == NULL)
12687 {
c484d925 12688 go_assert(this->array_->type()->is_error());
f9c68f17 12689 return;
12690 }
e440a328 12691
12692 unsigned int int_bits =
12693 Type::lookup_integer_type("int")->integer_type()->bits();
12694
0c77715b 12695 Numeric_constant lvalnc;
e440a328 12696 mpz_t lval;
e440a328 12697 bool lval_valid = (array_type->length() != NULL
0c77715b 12698 && array_type->length()->numeric_constant_value(&lvalnc)
12699 && lvalnc.to_int(&lval));
12700 Numeric_constant inc;
e440a328 12701 mpz_t ival;
0bd5d859 12702 bool ival_valid = false;
0c77715b 12703 if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
e440a328 12704 {
0bd5d859 12705 ival_valid = true;
e440a328 12706 if (mpz_sgn(ival) < 0
12707 || mpz_sizeinbase(ival, 2) >= int_bits
12708 || (lval_valid
12709 && (this->end_ == NULL
12710 ? mpz_cmp(ival, lval) >= 0
12711 : mpz_cmp(ival, lval) > 0)))
12712 {
631d5788 12713 go_error_at(this->start_->location(), "array index out of bounds");
e440a328 12714 this->set_is_error();
12715 }
12716 }
12717 if (this->end_ != NULL && !this->end_->is_nil_expression())
12718 {
0c77715b 12719 Numeric_constant enc;
12720 mpz_t eval;
acf2b673 12721 bool eval_valid = false;
0c77715b 12722 if (this->end_->numeric_constant_value(&enc) && enc.to_int(&eval))
e440a328 12723 {
acf2b673 12724 eval_valid = true;
0c77715b 12725 if (mpz_sgn(eval) < 0
12726 || mpz_sizeinbase(eval, 2) >= int_bits
12727 || (lval_valid && mpz_cmp(eval, lval) > 0))
e440a328 12728 {
631d5788 12729 go_error_at(this->end_->location(), "array index out of bounds");
e440a328 12730 this->set_is_error();
12731 }
0bd5d859 12732 else if (ival_valid && mpz_cmp(ival, eval) > 0)
12733 this->report_error(_("inverted slice range"));
e440a328 12734 }
acf2b673 12735
12736 Numeric_constant cnc;
12737 mpz_t cval;
12738 if (this->cap_ != NULL
12739 && this->cap_->numeric_constant_value(&cnc) && cnc.to_int(&cval))
12740 {
12741 if (mpz_sgn(cval) < 0
12742 || mpz_sizeinbase(cval, 2) >= int_bits
12743 || (lval_valid && mpz_cmp(cval, lval) > 0))
12744 {
631d5788 12745 go_error_at(this->cap_->location(), "array index out of bounds");
acf2b673 12746 this->set_is_error();
12747 }
12748 else if (ival_valid && mpz_cmp(ival, cval) > 0)
12749 {
631d5788 12750 go_error_at(this->cap_->location(),
12751 "invalid slice index: capacity less than start");
acf2b673 12752 this->set_is_error();
12753 }
12754 else if (eval_valid && mpz_cmp(eval, cval) > 0)
12755 {
631d5788 12756 go_error_at(this->cap_->location(),
12757 "invalid slice index: capacity less than length");
acf2b673 12758 this->set_is_error();
12759 }
12760 mpz_clear(cval);
12761 }
12762
12763 if (eval_valid)
12764 mpz_clear(eval);
e440a328 12765 }
0bd5d859 12766 if (ival_valid)
12767 mpz_clear(ival);
0c77715b 12768 if (lval_valid)
12769 mpz_clear(lval);
e440a328 12770
12771 // A slice of an array requires an addressable array. A slice of a
12772 // slice is always possible.
411eb89e 12773 if (this->end_ != NULL && !array_type->is_slice_type())
88ec30c8 12774 {
12775 if (!this->array_->is_addressable())
8da39c3b 12776 this->report_error(_("slice of unaddressable value"));
88ec30c8 12777 else
b7327dbf 12778 // Set the array address taken but not escape. The escape
12779 // analysis will make it escape to heap when needed.
12780 this->array_->address_taken(false);
88ec30c8 12781 }
e440a328 12782}
12783
71a38860 12784// The subexpressions of an array index must be evaluated in order.
12785// If this is indexing into an array, rather than a slice, then only
12786// the index should be evaluated. Since this is called for values on
12787// the left hand side of an assigment, evaluating the array, meaning
12788// copying the array, will cause a different array to be modified.
12789
12790bool
12791Array_index_expression::do_must_eval_subexpressions_in_order(
12792 int* skip) const
12793{
12794 *skip = this->array_->type()->is_slice_type() ? 0 : 1;
12795 return true;
12796}
12797
2c809f8f 12798// Flatten array indexing by using temporary variables for slices and indexes.
35a54f17 12799
12800Expression*
12801Array_index_expression::do_flatten(Gogo*, Named_object*,
12802 Statement_inserter* inserter)
12803{
12804 Location loc = this->location();
5bf8be8b 12805 Expression* array = this->array_;
12806 Expression* start = this->start_;
12807 Expression* end = this->end_;
12808 Expression* cap = this->cap_;
12809 if (array->is_error_expression()
12810 || array->type()->is_error_type()
12811 || start->is_error_expression()
12812 || start->type()->is_error_type()
12813 || (end != NULL
12814 && (end->is_error_expression() || end->type()->is_error_type()))
12815 || (cap != NULL
12816 && (cap->is_error_expression() || cap->type()->is_error_type())))
12817 {
12818 go_assert(saw_errors());
12819 return Expression::make_error(loc);
12820 }
12821
2c809f8f 12822 Temporary_statement* temp;
5bf8be8b 12823 if (array->type()->is_slice_type() && !array->is_variable())
35a54f17 12824 {
5bf8be8b 12825 temp = Statement::make_temporary(NULL, array, loc);
35a54f17 12826 inserter->insert(temp);
12827 this->array_ = Expression::make_temporary_reference(temp, loc);
12828 }
5bf8be8b 12829 if (!start->is_variable())
2c809f8f 12830 {
5bf8be8b 12831 temp = Statement::make_temporary(NULL, start, loc);
2c809f8f 12832 inserter->insert(temp);
12833 this->start_ = Expression::make_temporary_reference(temp, loc);
12834 }
5bf8be8b 12835 if (end != NULL
12836 && !end->is_nil_expression()
12837 && !end->is_variable())
2c809f8f 12838 {
5bf8be8b 12839 temp = Statement::make_temporary(NULL, end, loc);
2c809f8f 12840 inserter->insert(temp);
12841 this->end_ = Expression::make_temporary_reference(temp, loc);
12842 }
03118c21 12843 if (cap != NULL && !cap->is_variable())
2c809f8f 12844 {
5bf8be8b 12845 temp = Statement::make_temporary(NULL, cap, loc);
2c809f8f 12846 inserter->insert(temp);
12847 this->cap_ = Expression::make_temporary_reference(temp, loc);
12848 }
12849
35a54f17 12850 return this;
12851}
12852
e440a328 12853// Return whether this expression is addressable.
12854
12855bool
12856Array_index_expression::do_is_addressable() const
12857{
12858 // A slice expression is not addressable.
12859 if (this->end_ != NULL)
12860 return false;
12861
12862 // An index into a slice is addressable.
411eb89e 12863 if (this->array_->type()->is_slice_type())
e440a328 12864 return true;
12865
12866 // An index into an array is addressable if the array is
12867 // addressable.
12868 return this->array_->is_addressable();
12869}
12870
bf1323be 12871void
12872Array_index_expression::do_address_taken(bool escapes)
12873{
12874 // In &x[0], if x is a slice, then x's address is not taken.
12875 if (!this->array_->type()->is_slice_type())
12876 this->array_->address_taken(escapes);
12877}
12878
ea664253 12879// Get the backend representation for an array index.
e440a328 12880
ea664253 12881Bexpression*
12882Array_index_expression::do_get_backend(Translate_context* context)
e440a328 12883{
e440a328 12884 Array_type* array_type = this->array_->type()->array_type();
d8cd8e2d 12885 if (array_type == NULL)
12886 {
c484d925 12887 go_assert(this->array_->type()->is_error());
ea664253 12888 return context->backend()->error_expression();
d8cd8e2d 12889 }
35a54f17 12890 go_assert(!array_type->is_slice_type() || this->array_->is_variable());
e440a328 12891
2c809f8f 12892 Location loc = this->location();
12893 Gogo* gogo = context->gogo();
12894
6dfedc16 12895 Type* int_type = Type::lookup_integer_type("int");
12896 Btype* int_btype = int_type->get_backend(gogo);
e440a328 12897
2c809f8f 12898 // We need to convert the length and capacity to the Go "int" type here
12899 // because the length of a fixed-length array could be of type "uintptr"
12900 // and gimple disallows binary operations between "uintptr" and other
12901 // integer types. FIXME.
12902 Bexpression* length = NULL;
a04bfdfc 12903 if (this->end_ == NULL || this->end_->is_nil_expression())
12904 {
35a54f17 12905 Expression* len = array_type->get_length(gogo, this->array_);
ea664253 12906 length = len->get_backend(context);
2c809f8f 12907 length = gogo->backend()->convert_expression(int_btype, length, loc);
a04bfdfc 12908 }
12909
2c809f8f 12910 Bexpression* capacity = NULL;
a04bfdfc 12911 if (this->end_ != NULL)
12912 {
35a54f17 12913 Expression* cap = array_type->get_capacity(gogo, this->array_);
ea664253 12914 capacity = cap->get_backend(context);
2c809f8f 12915 capacity = gogo->backend()->convert_expression(int_btype, capacity, loc);
a04bfdfc 12916 }
12917
2c809f8f 12918 Bexpression* cap_arg = capacity;
acf2b673 12919 if (this->cap_ != NULL)
12920 {
ea664253 12921 cap_arg = this->cap_->get_backend(context);
2c809f8f 12922 cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
acf2b673 12923 }
12924
2c809f8f 12925 if (length == NULL)
12926 length = cap_arg;
e440a328 12927
6dfedc16 12928 if (this->start_->type()->integer_type() == NULL
12929 && !Type::are_convertible(int_type, this->start_->type(), NULL))
12930 {
12931 go_assert(saw_errors());
12932 return context->backend()->error_expression();
12933 }
d9f3743a 12934
ea664253 12935 Bexpression* start = this->start_->get_backend(context);
2c809f8f 12936 start = gogo->backend()->convert_expression(int_btype, start, loc);
3d135120 12937
12938 Bexpression* crash = NULL;
12939 Bexpression* bad_index = NULL;
12940 if (this->needs_bounds_check_)
12941 {
12942 int code = (array_type->length() != NULL
12943 ? (this->end_ == NULL
12944 ? RUNTIME_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS
12945 : RUNTIME_ERROR_ARRAY_SLICE_OUT_OF_BOUNDS)
12946 : (this->end_ == NULL
12947 ? RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS
12948 : RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS));
12949 crash = gogo->runtime_error(code, loc)->get_backend(context);
12950 bad_index = Expression::check_bounds(this->start_, loc)->get_backend(context);
12951 Bexpression* start_too_large =
12952 gogo->backend()->binary_expression((this->end_ == NULL
12953 ? OPERATOR_GE
12954 : OPERATOR_GT),
12955 start,
12956 (this->end_ == NULL
12957 ? length
12958 : capacity),
12959 loc);
12960 bad_index = gogo->backend()->binary_expression(OPERATOR_OROR,
12961 start_too_large,
12962 bad_index, loc);
12963 }
12964
e440a328 12965
93715b75 12966 Bfunction* bfn = context->function()->func_value()->get_decl();
e440a328 12967 if (this->end_ == NULL)
12968 {
12969 // Simple array indexing. This has to return an l-value, so
2c809f8f 12970 // wrap the index check into START.
3d135120 12971 if (this->needs_bounds_check_)
12972 start =
12973 gogo->backend()->conditional_expression(bfn, int_btype, bad_index,
12974 crash, start, loc);
e440a328 12975
2c809f8f 12976 Bexpression* ret;
e440a328 12977 if (array_type->length() != NULL)
12978 {
ea664253 12979 Bexpression* array = this->array_->get_backend(context);
2c809f8f 12980 ret = gogo->backend()->array_index_expression(array, start, loc);
e440a328 12981 }
12982 else
12983 {
2c809f8f 12984 // Slice.
12985 Expression* valptr =
44dbe1d7 12986 array_type->get_value_pointer(gogo, this->array_,
12987 this->is_lvalue_);
ea664253 12988 Bexpression* ptr = valptr->get_backend(context);
2c809f8f 12989 ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc);
9b27b43c 12990
12991 Type* ele_type = this->array_->type()->array_type()->element_type();
12992 Btype* ele_btype = ele_type->get_backend(gogo);
12993 ret = gogo->backend()->indirect_expression(ele_btype, ptr, true, loc);
e440a328 12994 }
ea664253 12995 return ret;
e440a328 12996 }
12997
12998 // Array slice.
12999
acf2b673 13000 if (this->cap_ != NULL)
13001 {
2c809f8f 13002 cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
13003
3d135120 13004 if (this->needs_bounds_check_)
13005 {
13006 Bexpression* bounds_bcheck =
13007 Expression::check_bounds(this->cap_, loc)->get_backend(context);
13008 bad_index =
13009 gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck,
13010 bad_index, loc);
13011
13012 Bexpression* cap_too_small =
13013 gogo->backend()->binary_expression(OPERATOR_LT, cap_arg, start, loc);
13014 Bexpression* cap_too_large =
13015 gogo->backend()->binary_expression(OPERATOR_GT, cap_arg, capacity, loc);
13016 Bexpression* bad_cap =
13017 gogo->backend()->binary_expression(OPERATOR_OROR, cap_too_small,
13018 cap_too_large, loc);
13019 bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_cap,
13020 bad_index, loc);
13021 }
2c809f8f 13022 }
13023
13024 Bexpression* end;
e440a328 13025 if (this->end_->is_nil_expression())
2c809f8f 13026 end = length;
e440a328 13027 else
13028 {
ea664253 13029 end = this->end_->get_backend(context);
2c809f8f 13030 end = gogo->backend()->convert_expression(int_btype, end, loc);
3d135120 13031 if (this->needs_bounds_check_)
13032 {
13033 Bexpression* bounds_bcheck =
13034 Expression::check_bounds(this->end_, loc)->get_backend(context);
13035 bad_index =
13036 gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck,
13037 bad_index, loc);
13038
13039 Bexpression* end_too_small =
13040 gogo->backend()->binary_expression(OPERATOR_LT, end, start, loc);
13041 Bexpression* end_too_large =
13042 gogo->backend()->binary_expression(OPERATOR_GT, end, cap_arg, loc);
13043 Bexpression* bad_end =
13044 gogo->backend()->binary_expression(OPERATOR_OROR, end_too_small,
13045 end_too_large, loc);
13046 bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_end,
13047 bad_index, loc);
13048 }
e440a328 13049 }
13050
2c809f8f 13051 Bexpression* result_length =
13052 gogo->backend()->binary_expression(OPERATOR_MINUS, end, start, loc);
e440a328 13053
2c809f8f 13054 Bexpression* result_capacity =
13055 gogo->backend()->binary_expression(OPERATOR_MINUS, cap_arg, start, loc);
e440a328 13056
03118c21 13057 // If the new capacity is zero, don't change val. Otherwise we can
13058 // get a pointer to the next object in memory, keeping it live
13059 // unnecessarily. When the capacity is zero, the actual pointer
13060 // value doesn't matter.
13061 Bexpression* zero =
13062 Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
13063 Bexpression* cond =
13064 gogo->backend()->binary_expression(OPERATOR_EQEQ, result_capacity, zero,
13065 loc);
13066 Bexpression* offset = gogo->backend()->conditional_expression(bfn, int_btype,
13067 cond, zero,
13068 start, loc);
44dbe1d7 13069 Expression* valptr = array_type->get_value_pointer(gogo, this->array_,
13070 this->is_lvalue_);
03118c21 13071 Bexpression* val = valptr->get_backend(context);
13072 val = gogo->backend()->pointer_offset_expression(val, offset, loc);
13073
2c809f8f 13074 Btype* struct_btype = this->type()->get_backend(gogo);
13075 std::vector<Bexpression*> init;
13076 init.push_back(val);
13077 init.push_back(result_length);
13078 init.push_back(result_capacity);
e440a328 13079
3d135120 13080 Bexpression* ret =
2c809f8f 13081 gogo->backend()->constructor_expression(struct_btype, init, loc);
3d135120 13082 if (this->needs_bounds_check_)
13083 ret = gogo->backend()->conditional_expression(bfn, struct_btype, bad_index,
13084 crash, ret, loc);
13085 return ret;
e440a328 13086}
13087
171fd404 13088// Export an array index expression.
13089
13090void
13091Array_index_expression::do_export(Export_function_body* efb) const
13092{
13093 efb->write_c_string("(");
13094 this->array_->export_expression(efb);
13095 efb->write_c_string(")[");
13096
13097 Type* old_context = efb->type_context();
13098 efb->set_type_context(Type::lookup_integer_type("int"));
13099
13100 this->start_->export_expression(efb);
13101 if (this->end_ == NULL)
13102 go_assert(this->cap_ == NULL);
13103 else
13104 {
13105 efb->write_c_string(":");
13106 if (!this->end_->is_nil_expression())
13107 this->end_->export_expression(efb);
13108 if (this->cap_ != NULL)
13109 {
13110 efb->write_c_string(":");
13111 this->cap_->export_expression(efb);
13112 }
13113 }
13114
13115 efb->set_type_context(old_context);
13116
13117 efb->write_c_string("]");
13118}
13119
d751bb78 13120// Dump ast representation for an array index expression.
13121
13122void
f03a9fbf 13123Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 13124 const
13125{
f03a9fbf 13126 Index_expression::dump_index_expression(ast_dump_context, this->array_,
acf2b673 13127 this->start_, this->end_, this->cap_);
d751bb78 13128}
13129
acf2b673 13130// Make an array index expression. END and CAP may be NULL.
e440a328 13131
13132Expression*
13133Expression::make_array_index(Expression* array, Expression* start,
acf2b673 13134 Expression* end, Expression* cap,
13135 Location location)
e440a328 13136{
acf2b673 13137 return new Array_index_expression(array, start, end, cap, location);
e440a328 13138}
13139
50075d74 13140// Class String_index_expression.
e440a328 13141
13142// String index traversal.
13143
13144int
13145String_index_expression::do_traverse(Traverse* traverse)
13146{
13147 if (Expression::traverse(&this->string_, traverse) == TRAVERSE_EXIT)
13148 return TRAVERSE_EXIT;
13149 if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
13150 return TRAVERSE_EXIT;
13151 if (this->end_ != NULL)
13152 {
13153 if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
13154 return TRAVERSE_EXIT;
13155 }
13156 return TRAVERSE_CONTINUE;
13157}
13158
2c809f8f 13159Expression*
13160String_index_expression::do_flatten(Gogo*, Named_object*,
13161 Statement_inserter* inserter)
e440a328 13162{
2c809f8f 13163 Location loc = this->location();
5bf8be8b 13164 Expression* string = this->string_;
13165 Expression* start = this->start_;
13166 Expression* end = this->end_;
13167 if (string->is_error_expression()
13168 || string->type()->is_error_type()
13169 || start->is_error_expression()
13170 || start->type()->is_error_type()
13171 || (end != NULL
13172 && (end->is_error_expression() || end->type()->is_error_type())))
13173 {
13174 go_assert(saw_errors());
13175 return Expression::make_error(loc);
13176 }
13177
13178 Temporary_statement* temp;
2c809f8f 13179 if (!this->string_->is_variable())
13180 {
13181 temp = Statement::make_temporary(NULL, this->string_, loc);
13182 inserter->insert(temp);
13183 this->string_ = Expression::make_temporary_reference(temp, loc);
13184 }
13185 if (!this->start_->is_variable())
13186 {
13187 temp = Statement::make_temporary(NULL, this->start_, loc);
13188 inserter->insert(temp);
13189 this->start_ = Expression::make_temporary_reference(temp, loc);
13190 }
13191 if (this->end_ != NULL
13192 && !this->end_->is_nil_expression()
13193 && !this->end_->is_variable())
13194 {
13195 temp = Statement::make_temporary(NULL, this->end_, loc);
13196 inserter->insert(temp);
13197 this->end_ = Expression::make_temporary_reference(temp, loc);
13198 }
13199
13200 return this;
13201}
13202
13203// Return the type of a string index.
13204
13205Type*
13206String_index_expression::do_type()
13207{
13208 if (this->end_ == NULL)
13209 return Type::lookup_integer_type("uint8");
13210 else
13211 return this->string_->type();
13212}
13213
13214// Determine the type of a string index.
13215
13216void
13217String_index_expression::do_determine_type(const Type_context*)
13218{
13219 this->string_->determine_type_no_context();
f77aa642 13220
13221 Type_context index_context(Type::lookup_integer_type("int"), false);
13222 if (this->start_->is_constant())
13223 this->start_->determine_type(&index_context);
13224 else
13225 this->start_->determine_type_no_context();
e440a328 13226 if (this->end_ != NULL)
f77aa642 13227 {
13228 if (this->end_->is_constant())
13229 this->end_->determine_type(&index_context);
13230 else
13231 this->end_->determine_type_no_context();
13232 }
e440a328 13233}
13234
13235// Check types of a string index.
13236
13237void
13238String_index_expression::do_check_types(Gogo*)
13239{
acdc230d 13240 Numeric_constant nc;
13241 unsigned long v;
13242 if (this->start_->type()->integer_type() == NULL
13243 && !this->start_->type()->is_error()
13244 && (!this->start_->numeric_constant_value(&nc)
13245 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 13246 this->report_error(_("index must be integer"));
13247 if (this->end_ != NULL
13248 && this->end_->type()->integer_type() == NULL
acdc230d 13249 && !this->end_->type()->is_error()
13250 && !this->end_->is_nil_expression()
13251 && !this->end_->is_error_expression()
13252 && (!this->end_->numeric_constant_value(&nc)
13253 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 13254 this->report_error(_("slice end must be integer"));
13255
13256 std::string sval;
13257 bool sval_valid = this->string_->string_constant_value(&sval);
13258
0c77715b 13259 Numeric_constant inc;
e440a328 13260 mpz_t ival;
0bd5d859 13261 bool ival_valid = false;
0c77715b 13262 if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
e440a328 13263 {
0bd5d859 13264 ival_valid = true;
e440a328 13265 if (mpz_sgn(ival) < 0
b10f32fb 13266 || (sval_valid
13267 && (this->end_ == NULL
13268 ? mpz_cmp_ui(ival, sval.length()) >= 0
13269 : mpz_cmp_ui(ival, sval.length()) > 0)))
e440a328 13270 {
631d5788 13271 go_error_at(this->start_->location(), "string index out of bounds");
e440a328 13272 this->set_is_error();
13273 }
13274 }
13275 if (this->end_ != NULL && !this->end_->is_nil_expression())
13276 {
0c77715b 13277 Numeric_constant enc;
13278 mpz_t eval;
13279 if (this->end_->numeric_constant_value(&enc) && enc.to_int(&eval))
e440a328 13280 {
0c77715b 13281 if (mpz_sgn(eval) < 0
13282 || (sval_valid && mpz_cmp_ui(eval, sval.length()) > 0))
e440a328 13283 {
631d5788 13284 go_error_at(this->end_->location(), "string index out of bounds");
e440a328 13285 this->set_is_error();
13286 }
0bd5d859 13287 else if (ival_valid && mpz_cmp(ival, eval) > 0)
13288 this->report_error(_("inverted slice range"));
0c77715b 13289 mpz_clear(eval);
e440a328 13290 }
13291 }
0bd5d859 13292 if (ival_valid)
13293 mpz_clear(ival);
e440a328 13294}
13295
ea664253 13296// Get the backend representation for a string index.
e440a328 13297
ea664253 13298Bexpression*
13299String_index_expression::do_get_backend(Translate_context* context)
e440a328 13300{
b13c66cd 13301 Location loc = this->location();
2c809f8f 13302 Expression* bad_index = Expression::check_bounds(this->start_, loc);
e440a328 13303
2c809f8f 13304 int code = (this->end_ == NULL
13305 ? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS
13306 : RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS);
e440a328 13307
2c809f8f 13308 Gogo* gogo = context->gogo();
ea664253 13309 Bexpression* crash = gogo->runtime_error(code, loc)->get_backend(context);
1b1f2abf 13310
13311 Type* int_type = Type::lookup_integer_type("int");
e440a328 13312
2c809f8f 13313 // It is possible that an error occurred earlier because the start index
13314 // cannot be represented as an integer type. In this case, we shouldn't
13315 // try casting the starting index into an integer since
13316 // Type_conversion_expression will fail to get the backend representation.
13317 // FIXME.
13318 if (this->start_->type()->integer_type() == NULL
13319 && !Type::are_convertible(int_type, this->start_->type(), NULL))
13320 {
13321 go_assert(saw_errors());
ea664253 13322 return context->backend()->error_expression();
2c809f8f 13323 }
e440a328 13324
28bc9435 13325 go_assert(this->string_->is_variable());
13326 go_assert(this->start_->is_variable());
13327
2c809f8f 13328 Expression* start = Expression::make_cast(int_type, this->start_, loc);
93715b75 13329 Bfunction* bfn = context->function()->func_value()->get_decl();
e440a328 13330
28bc9435 13331 Expression* length =
13332 Expression::make_string_info(this->string_, STRING_INFO_LENGTH, loc);
13333 Expression* bytes =
13334 Expression::make_string_info(this->string_, STRING_INFO_DATA, loc);
13335
13336 Bexpression* bstart = start->get_backend(context);
13337 Bexpression* ptr = bytes->get_backend(context);
13338
2c809f8f 13339 if (this->end_ == NULL)
13340 {
2c809f8f 13341 Expression* start_too_large =
13342 Expression::make_binary(OPERATOR_GE, start, length, loc);
13343 bad_index = Expression::make_binary(OPERATOR_OROR, start_too_large,
13344 bad_index, loc);
e440a328 13345
2c809f8f 13346 ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc);
9b27b43c 13347 Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
f03a9fbf 13348 Bexpression* index =
9b27b43c 13349 gogo->backend()->indirect_expression(ubtype, ptr, true, loc);
e440a328 13350
2c809f8f 13351 Btype* byte_btype = bytes->type()->points_to()->get_backend(gogo);
ea664253 13352 Bexpression* index_error = bad_index->get_backend(context);
93715b75 13353 return gogo->backend()->conditional_expression(bfn, byte_btype,
13354 index_error, crash,
13355 index, loc);
2c809f8f 13356 }
13357
13358 Expression* end = NULL;
13359 if (this->end_->is_nil_expression())
28bc9435 13360 end = length;
e440a328 13361 else
13362 {
28bc9435 13363 go_assert(this->end_->is_variable());
2c809f8f 13364 Expression* bounds_check = Expression::check_bounds(this->end_, loc);
13365 bad_index =
13366 Expression::make_binary(OPERATOR_OROR, bounds_check, bad_index, loc);
13367 end = Expression::make_cast(int_type, this->end_, loc);
28bc9435 13368
13369 Expression* end_too_large =
13370 Expression::make_binary(OPERATOR_GT, end, length, loc);
13371 bad_index = Expression::make_binary(OPERATOR_OROR, end_too_large,
13372 bad_index, loc);
e440a328 13373 }
28bc9435 13374 Expression* start_too_large =
13375 Expression::make_binary(OPERATOR_GT, start->copy(), end->copy(), loc);
13376 bad_index = Expression::make_binary(OPERATOR_OROR, start_too_large,
13377 bad_index, loc);
13378
13379 end = end->copy();
13380 Bexpression* bend = end->get_backend(context);
13381 Bexpression* new_length =
13382 gogo->backend()->binary_expression(OPERATOR_MINUS, bend, bstart, loc);
2c809f8f 13383
28bc9435 13384 // If the new length is zero, don't change pointer. Otherwise we can
13385 // get a pointer to the next object in memory, keeping it live
13386 // unnecessarily. When the length is zero, the actual pointer
13387 // value doesn't matter.
13388 Btype* int_btype = int_type->get_backend(gogo);
13389 Bexpression* zero =
13390 Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
13391 Bexpression* cond =
13392 gogo->backend()->binary_expression(OPERATOR_EQEQ, new_length, zero,
13393 loc);
13394 Bexpression* offset =
13395 gogo->backend()->conditional_expression(bfn, int_btype, cond, zero,
13396 bstart, loc);
13397
13398 ptr = gogo->backend()->pointer_offset_expression(ptr, offset, loc);
13399
13400 Btype* str_btype = this->type()->get_backend(gogo);
13401 std::vector<Bexpression*> init;
13402 init.push_back(ptr);
13403 init.push_back(new_length);
13404 Bexpression* bstrslice =
13405 gogo->backend()->constructor_expression(str_btype, init, loc);
2c809f8f 13406
ea664253 13407 Bexpression* index_error = bad_index->get_backend(context);
93715b75 13408 return gogo->backend()->conditional_expression(bfn, str_btype, index_error,
ea664253 13409 crash, bstrslice, loc);
e440a328 13410}
13411
171fd404 13412// Export a string index expression.
13413
13414void
13415String_index_expression::do_export(Export_function_body* efb) const
13416{
13417 efb->write_c_string("(");
13418 this->string_->export_expression(efb);
13419 efb->write_c_string(")[");
13420
13421 Type* old_context = efb->type_context();
13422 efb->set_type_context(Type::lookup_integer_type("int"));
13423
13424 this->start_->export_expression(efb);
13425 if (this->end_ != NULL)
13426 {
13427 efb->write_c_string(":");
13428 if (!this->end_->is_nil_expression())
13429 this->end_->export_expression(efb);
13430 }
13431
13432 efb->set_type_context(old_context);
13433
13434 efb->write_c_string("]");
13435}
13436
d751bb78 13437// Dump ast representation for a string index expression.
13438
13439void
13440String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
13441 const
13442{
acf2b673 13443 Index_expression::dump_index_expression(ast_dump_context, this->string_,
13444 this->start_, this->end_, NULL);
d751bb78 13445}
13446
e440a328 13447// Make a string index expression. END may be NULL.
13448
13449Expression*
13450Expression::make_string_index(Expression* string, Expression* start,
b13c66cd 13451 Expression* end, Location location)
e440a328 13452{
13453 return new String_index_expression(string, start, end, location);
13454}
13455
13456// Class Map_index.
13457
13458// Get the type of the map.
13459
13460Map_type*
13461Map_index_expression::get_map_type() const
13462{
0d5530d9 13463 Map_type* mt = this->map_->type()->map_type();
c7524fae 13464 if (mt == NULL)
c484d925 13465 go_assert(saw_errors());
e440a328 13466 return mt;
13467}
13468
13469// Map index traversal.
13470
13471int
13472Map_index_expression::do_traverse(Traverse* traverse)
13473{
13474 if (Expression::traverse(&this->map_, traverse) == TRAVERSE_EXIT)
13475 return TRAVERSE_EXIT;
13476 return Expression::traverse(&this->index_, traverse);
13477}
13478
2c809f8f 13479// We need to pass in a pointer to the key, so flatten the index into a
13480// temporary variable if it isn't already. The value pointer will be
13481// dereferenced and checked for nil, so flatten into a temporary to avoid
13482// recomputation.
13483
13484Expression*
91c0fd76 13485Map_index_expression::do_flatten(Gogo* gogo, Named_object*,
2c809f8f 13486 Statement_inserter* inserter)
13487{
91c0fd76 13488 Location loc = this->location();
2c809f8f 13489 Map_type* mt = this->get_map_type();
5bf8be8b 13490 if (this->index()->is_error_expression()
13491 || this->index()->type()->is_error_type()
13492 || mt->is_error_type())
13493 {
13494 go_assert(saw_errors());
13495 return Expression::make_error(loc);
13496 }
13497
e2b25cf3 13498 // Avoid copy for string([]byte) conversions used in map keys.
13499 // mapaccess doesn't keep the reference, so this is safe.
13500 Type_conversion_expression* ce = this->index_->conversion_expression();
13501 if (ce != NULL && ce->type()->is_string_type()
13502 && ce->expr()->type()->is_slice_type())
13503 ce->set_no_copy(true);
13504
3a522dcc 13505 if (!Type::are_identical(mt->key_type(), this->index_->type(),
13506 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
13507 NULL))
91c0fd76 13508 {
13509 if (this->index_->type()->interface_type() != NULL
13510 && !this->index_->is_variable())
13511 {
13512 Temporary_statement* temp =
13513 Statement::make_temporary(NULL, this->index_, loc);
13514 inserter->insert(temp);
13515 this->index_ = Expression::make_temporary_reference(temp, loc);
13516 }
13517 this->index_ = Expression::convert_for_assignment(gogo, mt->key_type(),
13518 this->index_, loc);
13519 }
2c809f8f 13520
13521 if (!this->index_->is_variable())
13522 {
13523 Temporary_statement* temp = Statement::make_temporary(NULL, this->index_,
91c0fd76 13524 loc);
2c809f8f 13525 inserter->insert(temp);
91c0fd76 13526 this->index_ = Expression::make_temporary_reference(temp, loc);
2c809f8f 13527 }
13528
13529 if (this->value_pointer_ == NULL)
0d5530d9 13530 this->get_value_pointer(gogo);
5bf8be8b 13531 if (this->value_pointer_->is_error_expression()
13532 || this->value_pointer_->type()->is_error_type())
13533 return Expression::make_error(loc);
2c809f8f 13534 if (!this->value_pointer_->is_variable())
13535 {
13536 Temporary_statement* temp =
91c0fd76 13537 Statement::make_temporary(NULL, this->value_pointer_, loc);
2c809f8f 13538 inserter->insert(temp);
91c0fd76 13539 this->value_pointer_ = Expression::make_temporary_reference(temp, loc);
2c809f8f 13540 }
13541
13542 return this;
13543}
13544
e440a328 13545// Return the type of a map index.
13546
13547Type*
13548Map_index_expression::do_type()
13549{
c7524fae 13550 Map_type* mt = this->get_map_type();
13551 if (mt == NULL)
13552 return Type::make_error_type();
0d5530d9 13553 return mt->val_type();
e440a328 13554}
13555
13556// Fix the type of a map index.
13557
13558void
13559Map_index_expression::do_determine_type(const Type_context*)
13560{
13561 this->map_->determine_type_no_context();
c7524fae 13562 Map_type* mt = this->get_map_type();
13563 Type* key_type = mt == NULL ? NULL : mt->key_type();
13564 Type_context subcontext(key_type, false);
e440a328 13565 this->index_->determine_type(&subcontext);
13566}
13567
13568// Check types of a map index.
13569
13570void
13571Map_index_expression::do_check_types(Gogo*)
13572{
13573 std::string reason;
c7524fae 13574 Map_type* mt = this->get_map_type();
13575 if (mt == NULL)
13576 return;
13577 if (!Type::are_assignable(mt->key_type(), this->index_->type(), &reason))
e440a328 13578 {
13579 if (reason.empty())
13580 this->report_error(_("incompatible type for map index"));
13581 else
13582 {
631d5788 13583 go_error_at(this->location(), "incompatible type for map index (%s)",
13584 reason.c_str());
e440a328 13585 this->set_is_error();
13586 }
13587 }
13588}
13589
e007b1eb 13590// Add explicit type conversions.
13591
13592void
13593Map_index_expression::do_add_conversions()
13594{
13595 Map_type* mt = this->get_map_type();
13596 if (mt == NULL)
13597 return;
13598 Type* lt = mt->key_type();
13599 Type* rt = this->index_->type();
13600 if (!Type::are_identical(lt, rt, 0, NULL)
13601 && lt->interface_type() != NULL)
13602 this->index_ = Expression::make_cast(lt, this->index_, this->location());
13603}
13604
ea664253 13605// Get the backend representation for a map index.
e440a328 13606
ea664253 13607Bexpression*
13608Map_index_expression::do_get_backend(Translate_context* context)
e440a328 13609{
13610 Map_type* type = this->get_map_type();
c7524fae 13611 if (type == NULL)
2c809f8f 13612 {
13613 go_assert(saw_errors());
ea664253 13614 return context->backend()->error_expression();
2c809f8f 13615 }
e440a328 13616
2c809f8f 13617 go_assert(this->value_pointer_ != NULL
13618 && this->value_pointer_->is_variable());
e440a328 13619
f614ea8b 13620 Expression* val = Expression::make_dereference(this->value_pointer_,
13621 NIL_CHECK_NOT_NEEDED,
13622 this->location());
0d5530d9 13623 return val->get_backend(context);
e440a328 13624}
13625
0d5530d9 13626// Get an expression for the map index. This returns an expression
13627// that evaluates to a pointer to a value. If the key is not in the
13628// map, the pointer will point to a zero value.
e440a328 13629
2c809f8f 13630Expression*
0d5530d9 13631Map_index_expression::get_value_pointer(Gogo* gogo)
e440a328 13632{
2c809f8f 13633 if (this->value_pointer_ == NULL)
746d2e73 13634 {
2c809f8f 13635 Map_type* type = this->get_map_type();
13636 if (type == NULL)
746d2e73 13637 {
2c809f8f 13638 go_assert(saw_errors());
13639 return Expression::make_error(this->location());
746d2e73 13640 }
e440a328 13641
2c809f8f 13642 Location loc = this->location();
13643 Expression* map_ref = this->map_;
e440a328 13644
0d5530d9 13645 Expression* index_ptr = Expression::make_unary(OPERATOR_AND,
13646 this->index_,
2c809f8f 13647 loc);
0d5530d9 13648
26329c24 13649 Expression* type_expr = Expression::make_type_descriptor(type, loc);
0d5530d9 13650 Expression* zero = type->fat_zero_value(gogo);
0d5530d9 13651 Expression* map_index;
0d5530d9 13652 if (zero == NULL)
26329c24 13653 {
13654 Runtime::Function code;
13655 Expression* key;
13656 switch (type->algorithm(gogo))
13657 {
13658 case Map_type::MAP_ALG_FAST32:
13659 case Map_type::MAP_ALG_FAST32PTR:
13660 {
13661 Type* uint32_type = Type::lookup_integer_type("uint32");
13662 Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
13663 key = Expression::make_unsafe_cast(uint32_ptr_type, index_ptr,
13664 loc);
13665 key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
13666 loc);
13667 code = Runtime::MAPACCESS1_FAST32;
13668 break;
13669 }
13670 case Map_type::MAP_ALG_FAST64:
13671 case Map_type::MAP_ALG_FAST64PTR:
13672 {
13673 Type* uint64_type = Type::lookup_integer_type("uint64");
13674 Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
13675 key = Expression::make_unsafe_cast(uint64_ptr_type, index_ptr,
13676 loc);
13677 key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
13678 loc);
13679 code = Runtime::MAPACCESS1_FAST64;
13680 break;
13681 }
13682 case Map_type::MAP_ALG_FASTSTR:
13683 key = this->index_;
13684 code = Runtime::MAPACCESS1_FASTSTR;
13685 break;
13686 default:
13687 key = index_ptr;
13688 code = Runtime::MAPACCESS1;
13689 break;
13690 }
13691 map_index = Runtime::make_call(code, loc, 3,
13692 type_expr, map_ref, key);
13693 }
0d5530d9 13694 else
26329c24 13695 map_index = Runtime::make_call(Runtime::MAPACCESS1_FAT, loc, 4,
13696 type_expr, map_ref, index_ptr, zero);
2c809f8f 13697
13698 Type* val_type = type->val_type();
13699 this->value_pointer_ =
13700 Expression::make_unsafe_cast(Type::make_pointer_type(val_type),
13701 map_index, this->location());
13702 }
0d5530d9 13703
2c809f8f 13704 return this->value_pointer_;
e440a328 13705}
13706
171fd404 13707// Export a map index expression.
13708
13709void
13710Map_index_expression::do_export(Export_function_body* efb) const
13711{
13712 efb->write_c_string("(");
13713 this->map_->export_expression(efb);
13714 efb->write_c_string(")[");
13715
13716 Type* old_context = efb->type_context();
13717 efb->set_type_context(this->get_map_type()->key_type());
13718
13719 this->index_->export_expression(efb);
13720
13721 efb->set_type_context(old_context);
13722
13723 efb->write_c_string("]");
13724}
13725
d751bb78 13726// Dump ast representation for a map index expression
13727
13728void
f03a9fbf 13729Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 13730 const
13731{
acf2b673 13732 Index_expression::dump_index_expression(ast_dump_context, this->map_,
13733 this->index_, NULL, NULL);
d751bb78 13734}
13735
e440a328 13736// Make a map index expression.
13737
13738Map_index_expression*
13739Expression::make_map_index(Expression* map, Expression* index,
b13c66cd 13740 Location location)
e440a328 13741{
13742 return new Map_index_expression(map, index, location);
13743}
13744
13745// Class Field_reference_expression.
13746
149eabc5 13747// Lower a field reference expression. There is nothing to lower, but
13748// this is where we generate the tracking information for fields with
13749// the magic go:"track" tag.
13750
13751Expression*
13752Field_reference_expression::do_lower(Gogo* gogo, Named_object* function,
13753 Statement_inserter* inserter, int)
13754{
13755 Struct_type* struct_type = this->expr_->type()->struct_type();
13756 if (struct_type == NULL)
13757 {
13758 // Error will be reported elsewhere.
13759 return this;
13760 }
13761 const Struct_field* field = struct_type->field(this->field_index_);
13762 if (field == NULL)
13763 return this;
13764 if (!field->has_tag())
13765 return this;
13766 if (field->tag().find("go:\"track\"") == std::string::npos)
13767 return this;
13768
604e278d 13769 // References from functions generated by the compiler don't count.
c6292d1d 13770 if (function != NULL && function->func_value()->is_type_specific_function())
604e278d 13771 return this;
13772
149eabc5 13773 // We have found a reference to a tracked field. Build a call to
13774 // the runtime function __go_fieldtrack with a string that describes
13775 // the field. FIXME: We should only call this once per referenced
13776 // field per function, not once for each reference to the field.
13777
13778 if (this->called_fieldtrack_)
13779 return this;
13780 this->called_fieldtrack_ = true;
13781
13782 Location loc = this->location();
13783
13784 std::string s = "fieldtrack \"";
e65055a5 13785 Named_type* nt = this->expr_->type()->unalias()->named_type();
149eabc5 13786 if (nt == NULL || nt->named_object()->package() == NULL)
13787 s.append(gogo->pkgpath());
13788 else
13789 s.append(nt->named_object()->package()->pkgpath());
13790 s.push_back('.');
13791 if (nt != NULL)
5c29ad36 13792 s.append(Gogo::unpack_hidden_name(nt->name()));
149eabc5 13793 s.push_back('.');
13794 s.append(field->field_name());
13795 s.push_back('"');
13796
13797 // We can't use a string here, because internally a string holds a
13798 // pointer to the actual bytes; when the linker garbage collects the
13799 // string, it won't garbage collect the bytes. So we use a
13800 // [...]byte.
13801
e67508fa 13802 Expression* length_expr = Expression::make_integer_ul(s.length(), NULL, loc);
149eabc5 13803
13804 Type* byte_type = gogo->lookup_global("byte")->type_value();
6bf4793c 13805 Array_type* array_type = Type::make_array_type(byte_type, length_expr);
13806 array_type->set_is_array_incomparable();
149eabc5 13807
13808 Expression_list* bytes = new Expression_list();
13809 for (std::string::const_iterator p = s.begin(); p != s.end(); p++)
13810 {
e67508fa 13811 unsigned char c = static_cast<unsigned char>(*p);
13812 bytes->push_back(Expression::make_integer_ul(c, NULL, loc));
149eabc5 13813 }
13814
13815 Expression* e = Expression::make_composite_literal(array_type, 0, false,
62750cd5 13816 bytes, false, loc);
149eabc5 13817
13818 Variable* var = new Variable(array_type, e, true, false, false, loc);
13819
13820 static int count;
13821 char buf[50];
13822 snprintf(buf, sizeof buf, "fieldtrack.%d", count);
13823 ++count;
13824
13825 Named_object* no = gogo->add_variable(buf, var);
13826 e = Expression::make_var_reference(no, loc);
13827 e = Expression::make_unary(OPERATOR_AND, e, loc);
13828
13829 Expression* call = Runtime::make_call(Runtime::FIELDTRACK, loc, 1, e);
604e278d 13830 gogo->lower_expression(function, inserter, &call);
149eabc5 13831 inserter->insert(Statement::make_statement(call, false));
13832
13833 // Put this function, and the global variable we just created, into
13834 // unique sections. This will permit the linker to garbage collect
13835 // them if they are not referenced. The effect is that the only
13836 // strings, indicating field references, that will wind up in the
13837 // executable will be those for functions that are actually needed.
66a6be58 13838 if (function != NULL)
13839 function->func_value()->set_in_unique_section();
149eabc5 13840 var->set_in_unique_section();
13841
13842 return this;
13843}
13844
e440a328 13845// Return the type of a field reference.
13846
13847Type*
13848Field_reference_expression::do_type()
13849{
b0e628fb 13850 Type* type = this->expr_->type();
5c13bd80 13851 if (type->is_error())
b0e628fb 13852 return type;
13853 Struct_type* struct_type = type->struct_type();
c484d925 13854 go_assert(struct_type != NULL);
e440a328 13855 return struct_type->field(this->field_index_)->type();
13856}
13857
13858// Check the types for a field reference.
13859
13860void
13861Field_reference_expression::do_check_types(Gogo*)
13862{
b0e628fb 13863 Type* type = this->expr_->type();
5c13bd80 13864 if (type->is_error())
b0e628fb 13865 return;
13866 Struct_type* struct_type = type->struct_type();
c484d925 13867 go_assert(struct_type != NULL);
13868 go_assert(struct_type->field(this->field_index_) != NULL);
e440a328 13869}
13870
ea664253 13871// Get the backend representation for a field reference.
e440a328 13872
ea664253 13873Bexpression*
13874Field_reference_expression::do_get_backend(Translate_context* context)
e440a328 13875{
ea664253 13876 Bexpression* bstruct = this->expr_->get_backend(context);
13877 return context->gogo()->backend()->struct_field_expression(bstruct,
13878 this->field_index_,
13879 this->location());
e440a328 13880}
13881
d751bb78 13882// Dump ast representation for a field reference expression.
13883
13884void
13885Field_reference_expression::do_dump_expression(
13886 Ast_dump_context* ast_dump_context) const
13887{
13888 this->expr_->dump_expression(ast_dump_context);
13889 ast_dump_context->ostream() << "." << this->field_index_;
13890}
13891
e440a328 13892// Make a reference to a qualified identifier in an expression.
13893
13894Field_reference_expression*
13895Expression::make_field_reference(Expression* expr, unsigned int field_index,
b13c66cd 13896 Location location)
e440a328 13897{
13898 return new Field_reference_expression(expr, field_index, location);
13899}
13900
13901// Class Interface_field_reference_expression.
13902
2387f644 13903// Return an expression for the pointer to the function to call.
e440a328 13904
2387f644 13905Expression*
13906Interface_field_reference_expression::get_function()
e440a328 13907{
2387f644 13908 Expression* ref = this->expr_;
13909 Location loc = this->location();
13910 if (ref->type()->points_to() != NULL)
f614ea8b 13911 ref = Expression::make_dereference(ref, NIL_CHECK_DEFAULT, loc);
e440a328 13912
2387f644 13913 Expression* mtable =
13914 Expression::make_interface_info(ref, INTERFACE_INFO_METHODS, loc);
13915 Struct_type* mtable_type = mtable->type()->points_to()->struct_type();
e440a328 13916
13917 std::string name = Gogo::unpack_hidden_name(this->name_);
2387f644 13918 unsigned int index;
13919 const Struct_field* field = mtable_type->find_local_field(name, &index);
13920 go_assert(field != NULL);
f614ea8b 13921
13922 mtable = Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, loc);
2387f644 13923 return Expression::make_field_reference(mtable, index, loc);
e440a328 13924}
13925
2387f644 13926// Return an expression for the first argument to pass to the interface
e440a328 13927// function.
13928
2387f644 13929Expression*
13930Interface_field_reference_expression::get_underlying_object()
e440a328 13931{
2387f644 13932 Expression* expr = this->expr_;
13933 if (expr->type()->points_to() != NULL)
f614ea8b 13934 expr = Expression::make_dereference(expr, NIL_CHECK_DEFAULT,
13935 this->location());
2387f644 13936 return Expression::make_interface_info(expr, INTERFACE_INFO_OBJECT,
13937 this->location());
e440a328 13938}
13939
13940// Traversal.
13941
13942int
13943Interface_field_reference_expression::do_traverse(Traverse* traverse)
13944{
13945 return Expression::traverse(&this->expr_, traverse);
13946}
13947
0afbb937 13948// Lower the expression. If this expression is not called, we need to
13949// evaluate the expression twice when converting to the backend
13950// interface. So introduce a temporary variable if necessary.
13951
13952Expression*
9782d556 13953Interface_field_reference_expression::do_flatten(Gogo*, Named_object*,
13954 Statement_inserter* inserter)
0afbb937 13955{
5bf8be8b 13956 if (this->expr_->is_error_expression()
13957 || this->expr_->type()->is_error_type())
13958 {
13959 go_assert(saw_errors());
13960 return Expression::make_error(this->location());
13961 }
13962
2387f644 13963 if (!this->expr_->is_variable())
0afbb937 13964 {
13965 Temporary_statement* temp =
9189e53b 13966 Statement::make_temporary(NULL, this->expr_, this->location());
0afbb937 13967 inserter->insert(temp);
9189e53b 13968 this->expr_ = Expression::make_temporary_reference(temp, this->location());
0afbb937 13969 }
13970 return this;
13971}
13972
e440a328 13973// Return the type of an interface field reference.
13974
13975Type*
13976Interface_field_reference_expression::do_type()
13977{
13978 Type* expr_type = this->expr_->type();
13979
13980 Type* points_to = expr_type->points_to();
13981 if (points_to != NULL)
13982 expr_type = points_to;
13983
13984 Interface_type* interface_type = expr_type->interface_type();
13985 if (interface_type == NULL)
13986 return Type::make_error_type();
13987
13988 const Typed_identifier* method = interface_type->find_method(this->name_);
13989 if (method == NULL)
13990 return Type::make_error_type();
13991
13992 return method->type();
13993}
13994
13995// Determine types.
13996
13997void
13998Interface_field_reference_expression::do_determine_type(const Type_context*)
13999{
14000 this->expr_->determine_type_no_context();
14001}
14002
14003// Check the types for an interface field reference.
14004
14005void
14006Interface_field_reference_expression::do_check_types(Gogo*)
14007{
14008 Type* type = this->expr_->type();
14009
14010 Type* points_to = type->points_to();
14011 if (points_to != NULL)
14012 type = points_to;
14013
14014 Interface_type* interface_type = type->interface_type();
14015 if (interface_type == NULL)
5c491127 14016 {
14017 if (!type->is_error_type())
14018 this->report_error(_("expected interface or pointer to interface"));
14019 }
e440a328 14020 else
14021 {
14022 const Typed_identifier* method =
14023 interface_type->find_method(this->name_);
14024 if (method == NULL)
14025 {
631d5788 14026 go_error_at(this->location(), "method %qs not in interface",
14027 Gogo::message_name(this->name_).c_str());
e440a328 14028 this->set_is_error();
14029 }
14030 }
14031}
14032
0afbb937 14033// If an interface field reference is not simply called, then it is
14034// represented as a closure. The closure will hold a single variable,
14035// the value of the interface on which the method should be called.
14036// The function will be a simple thunk that pulls the value from the
14037// closure and calls the method with the remaining arguments.
14038
14039// Because method values are not common, we don't build all thunks for
14040// all possible interface methods, but instead only build them as we
14041// need them. In particular, we even build them on demand for
14042// interface methods defined in other packages.
14043
14044Interface_field_reference_expression::Interface_method_thunks
14045 Interface_field_reference_expression::interface_method_thunks;
14046
14047// Find or create the thunk to call method NAME on TYPE.
14048
14049Named_object*
14050Interface_field_reference_expression::create_thunk(Gogo* gogo,
14051 Interface_type* type,
14052 const std::string& name)
14053{
14054 std::pair<Interface_type*, Method_thunks*> val(type, NULL);
14055 std::pair<Interface_method_thunks::iterator, bool> ins =
14056 Interface_field_reference_expression::interface_method_thunks.insert(val);
14057 if (ins.second)
14058 {
14059 // This is the first time we have seen this interface.
14060 ins.first->second = new Method_thunks();
14061 }
14062
14063 for (Method_thunks::const_iterator p = ins.first->second->begin();
14064 p != ins.first->second->end();
14065 p++)
14066 if (p->first == name)
14067 return p->second;
14068
14069 Location loc = type->location();
14070
14071 const Typed_identifier* method_id = type->find_method(name);
14072 if (method_id == NULL)
13f2fdb8 14073 return Named_object::make_erroneous_name(gogo->thunk_name());
0afbb937 14074
14075 Function_type* orig_fntype = method_id->type()->function_type();
14076 if (orig_fntype == NULL)
13f2fdb8 14077 return Named_object::make_erroneous_name(gogo->thunk_name());
0afbb937 14078
14079 Struct_field_list* sfl = new Struct_field_list();
f8bdf81a 14080 // The type here is wrong--it should be the C function type. But it
14081 // doesn't really matter.
0afbb937 14082 Type* vt = Type::make_pointer_type(Type::make_void_type());
13f2fdb8 14083 sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
14084 sfl->push_back(Struct_field(Typed_identifier("val", type, loc)));
6bf4793c 14085 Struct_type* st = Type::make_struct_type(sfl, loc);
14086 st->set_is_struct_incomparable();
14087 Type* closure_type = Type::make_pointer_type(st);
0afbb937 14088
f8bdf81a 14089 Function_type* new_fntype = orig_fntype->copy_with_names();
0afbb937 14090
13f2fdb8 14091 std::string thunk_name = gogo->thunk_name();
da244e59 14092 Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
0afbb937 14093 false, loc);
14094
f8bdf81a 14095 Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
14096 cvar->set_is_used();
1ecc6157 14097 cvar->set_is_closure();
da244e59 14098 Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
14099 NULL, cvar);
f8bdf81a 14100 new_no->func_value()->set_closure_var(cp);
0afbb937 14101
f8bdf81a 14102 gogo->start_block(loc);
0afbb937 14103
14104 // Field 0 of the closure is the function code pointer, field 1 is
14105 // the value on which to invoke the method.
14106 Expression* arg = Expression::make_var_reference(cp, loc);
f614ea8b 14107 arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
0afbb937 14108 arg = Expression::make_field_reference(arg, 1, loc);
14109
14110 Expression *ifre = Expression::make_interface_field_reference(arg, name,
14111 loc);
14112
14113 const Typed_identifier_list* orig_params = orig_fntype->parameters();
14114 Expression_list* args;
14115 if (orig_params == NULL || orig_params->empty())
14116 args = NULL;
14117 else
14118 {
14119 const Typed_identifier_list* new_params = new_fntype->parameters();
14120 args = new Expression_list();
14121 for (Typed_identifier_list::const_iterator p = new_params->begin();
f8bdf81a 14122 p != new_params->end();
0afbb937 14123 ++p)
14124 {
14125 Named_object* p_no = gogo->lookup(p->name(), NULL);
14126 go_assert(p_no != NULL
14127 && p_no->is_variable()
14128 && p_no->var_value()->is_parameter());
14129 args->push_back(Expression::make_var_reference(p_no, loc));
14130 }
14131 }
14132
14133 Call_expression* call = Expression::make_call(ifre, args,
14134 orig_fntype->is_varargs(),
14135 loc);
14136 call->set_varargs_are_lowered();
14137
14138 Statement* s = Statement::make_return_from_call(call, loc);
14139 gogo->add_statement(s);
14140 Block* b = gogo->finish_block(loc);
14141 gogo->add_block(b, loc);
14142 gogo->lower_block(new_no, b);
a32698ee 14143 gogo->flatten_block(new_no, b);
0afbb937 14144 gogo->finish_function(loc);
14145
14146 ins.first->second->push_back(std::make_pair(name, new_no));
14147 return new_no;
14148}
14149
ea664253 14150// Get the backend representation for a method value.
e440a328 14151
ea664253 14152Bexpression*
14153Interface_field_reference_expression::do_get_backend(Translate_context* context)
e440a328 14154{
0afbb937 14155 Interface_type* type = this->expr_->type()->interface_type();
14156 if (type == NULL)
14157 {
14158 go_assert(saw_errors());
ea664253 14159 return context->backend()->error_expression();
0afbb937 14160 }
14161
14162 Named_object* thunk =
14163 Interface_field_reference_expression::create_thunk(context->gogo(),
14164 type, this->name_);
14165 if (thunk->is_erroneous())
14166 {
14167 go_assert(saw_errors());
ea664253 14168 return context->backend()->error_expression();
0afbb937 14169 }
14170
14171 // FIXME: We should lower this earlier, but we can't it lower it in
14172 // the lowering pass because at that point we don't know whether we
14173 // need to create the thunk or not. If the expression is called, we
14174 // don't need the thunk.
14175
14176 Location loc = this->location();
14177
14178 Struct_field_list* fields = new Struct_field_list();
13f2fdb8 14179 fields->push_back(Struct_field(Typed_identifier("fn",
0afbb937 14180 thunk->func_value()->type(),
14181 loc)));
13f2fdb8 14182 fields->push_back(Struct_field(Typed_identifier("val",
0afbb937 14183 this->expr_->type(),
14184 loc)));
14185 Struct_type* st = Type::make_struct_type(fields, loc);
6bf4793c 14186 st->set_is_struct_incomparable();
0afbb937 14187
14188 Expression_list* vals = new Expression_list();
14189 vals->push_back(Expression::make_func_code_reference(thunk, loc));
14190 vals->push_back(this->expr_);
14191
14192 Expression* expr = Expression::make_struct_composite_literal(st, vals, loc);
ea664253 14193 Bexpression* bclosure =
14194 Expression::make_heap_expression(expr, loc)->get_backend(context);
0afbb937 14195
4df0c2d4 14196 Gogo* gogo = context->gogo();
14197 Btype* btype = this->type()->get_backend(gogo);
14198 bclosure = gogo->backend()->convert_expression(btype, bclosure, loc);
14199
2387f644 14200 Expression* nil_check =
14201 Expression::make_binary(OPERATOR_EQEQ, this->expr_,
14202 Expression::make_nil(loc), loc);
ea664253 14203 Bexpression* bnil_check = nil_check->get_backend(context);
0afbb937 14204
ea664253 14205 Bexpression* bcrash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
14206 loc)->get_backend(context);
2387f644 14207
93715b75 14208 Bfunction* bfn = context->function()->func_value()->get_decl();
2387f644 14209 Bexpression* bcond =
93715b75 14210 gogo->backend()->conditional_expression(bfn, NULL,
14211 bnil_check, bcrash, NULL, loc);
0ab48656 14212 Bfunction* bfunction = context->function()->func_value()->get_decl();
14213 Bstatement* cond_statement =
14214 gogo->backend()->expression_statement(bfunction, bcond);
ea664253 14215 return gogo->backend()->compound_expression(cond_statement, bclosure, loc);
e440a328 14216}
14217
d751bb78 14218// Dump ast representation for an interface field reference.
14219
14220void
14221Interface_field_reference_expression::do_dump_expression(
14222 Ast_dump_context* ast_dump_context) const
14223{
14224 this->expr_->dump_expression(ast_dump_context);
14225 ast_dump_context->ostream() << "." << this->name_;
14226}
14227
e440a328 14228// Make a reference to a field in an interface.
14229
14230Expression*
14231Expression::make_interface_field_reference(Expression* expr,
14232 const std::string& field,
b13c66cd 14233 Location location)
e440a328 14234{
14235 return new Interface_field_reference_expression(expr, field, location);
14236}
14237
14238// A general selector. This is a Parser_expression for LEFT.NAME. It
14239// is lowered after we know the type of the left hand side.
14240
14241class Selector_expression : public Parser_expression
14242{
14243 public:
14244 Selector_expression(Expression* left, const std::string& name,
b13c66cd 14245 Location location)
e440a328 14246 : Parser_expression(EXPRESSION_SELECTOR, location),
14247 left_(left), name_(name)
14248 { }
14249
14250 protected:
14251 int
14252 do_traverse(Traverse* traverse)
14253 { return Expression::traverse(&this->left_, traverse); }
14254
14255 Expression*
ceeb4318 14256 do_lower(Gogo*, Named_object*, Statement_inserter*, int);
e440a328 14257
14258 Expression*
14259 do_copy()
14260 {
14261 return new Selector_expression(this->left_->copy(), this->name_,
14262 this->location());
14263 }
14264
d751bb78 14265 void
14266 do_dump_expression(Ast_dump_context* ast_dump_context) const;
14267
e440a328 14268 private:
14269 Expression*
14270 lower_method_expression(Gogo*);
14271
14272 // The expression on the left hand side.
14273 Expression* left_;
14274 // The name on the right hand side.
14275 std::string name_;
14276};
14277
14278// Lower a selector expression once we know the real type of the left
14279// hand side.
14280
14281Expression*
ceeb4318 14282Selector_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*,
14283 int)
e440a328 14284{
14285 Expression* left = this->left_;
14286 if (left->is_type_expression())
14287 return this->lower_method_expression(gogo);
14288 return Type::bind_field_or_method(gogo, left->type(), left, this->name_,
14289 this->location());
14290}
14291
14292// Lower a method expression T.M or (*T).M. We turn this into a
14293// function literal.
14294
14295Expression*
14296Selector_expression::lower_method_expression(Gogo* gogo)
14297{
b13c66cd 14298 Location location = this->location();
868b439e 14299 Type* left_type = this->left_->type();
14300 Type* type = left_type;
e440a328 14301 const std::string& name(this->name_);
14302
14303 bool is_pointer;
14304 if (type->points_to() == NULL)
14305 is_pointer = false;
14306 else
14307 {
14308 is_pointer = true;
14309 type = type->points_to();
14310 }
14311 Named_type* nt = type->named_type();
14312 if (nt == NULL)
14313 {
631d5788 14314 go_error_at(location,
14315 ("method expression requires named type or "
14316 "pointer to named type"));
e440a328 14317 return Expression::make_error(location);
14318 }
14319
14320 bool is_ambiguous;
14321 Method* method = nt->method_function(name, &is_ambiguous);
ab1468c3 14322 const Typed_identifier* imethod = NULL;
dcc8506b 14323 if (method == NULL && !is_pointer)
ab1468c3 14324 {
14325 Interface_type* it = nt->interface_type();
14326 if (it != NULL)
14327 imethod = it->find_method(name);
14328 }
14329
f03a9fbf 14330 if ((method == NULL && imethod == NULL)
868b439e 14331 || (left_type->named_type() != NULL && left_type->points_to() != NULL))
e440a328 14332 {
14333 if (!is_ambiguous)
631d5788 14334 go_error_at(location, "type %<%s%s%> has no method %<%s%>",
14335 is_pointer ? "*" : "",
14336 nt->message_name().c_str(),
14337 Gogo::message_name(name).c_str());
e440a328 14338 else
631d5788 14339 go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
14340 Gogo::message_name(name).c_str(),
14341 is_pointer ? "*" : "",
14342 nt->message_name().c_str());
e440a328 14343 return Expression::make_error(location);
14344 }
14345
ab1468c3 14346 if (method != NULL && !is_pointer && !method->is_value_method())
e440a328 14347 {
631d5788 14348 go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
14349 nt->message_name().c_str(),
14350 Gogo::message_name(name).c_str());
e440a328 14351 return Expression::make_error(location);
14352 }
14353
14354 // Build a new function type in which the receiver becomes the first
14355 // argument.
ab1468c3 14356 Function_type* method_type;
14357 if (method != NULL)
14358 {
14359 method_type = method->type();
c484d925 14360 go_assert(method_type->is_method());
ab1468c3 14361 }
14362 else
14363 {
14364 method_type = imethod->type()->function_type();
c484d925 14365 go_assert(method_type != NULL && !method_type->is_method());
ab1468c3 14366 }
e440a328 14367
14368 const char* const receiver_name = "$this";
14369 Typed_identifier_list* parameters = new Typed_identifier_list();
14370 parameters->push_back(Typed_identifier(receiver_name, this->left_->type(),
14371 location));
14372
14373 const Typed_identifier_list* method_parameters = method_type->parameters();
14374 if (method_parameters != NULL)
14375 {
f470da59 14376 int i = 0;
e440a328 14377 for (Typed_identifier_list::const_iterator p = method_parameters->begin();
14378 p != method_parameters->end();
f470da59 14379 ++p, ++i)
14380 {
68883531 14381 if (!p->name().empty())
f470da59 14382 parameters->push_back(*p);
14383 else
14384 {
14385 char buf[20];
14386 snprintf(buf, sizeof buf, "$param%d", i);
14387 parameters->push_back(Typed_identifier(buf, p->type(),
14388 p->location()));
14389 }
14390 }
e440a328 14391 }
14392
14393 const Typed_identifier_list* method_results = method_type->results();
14394 Typed_identifier_list* results;
14395 if (method_results == NULL)
14396 results = NULL;
14397 else
14398 {
14399 results = new Typed_identifier_list();
14400 for (Typed_identifier_list::const_iterator p = method_results->begin();
14401 p != method_results->end();
14402 ++p)
14403 results->push_back(*p);
14404 }
f03a9fbf 14405
e440a328 14406 Function_type* fntype = Type::make_function_type(NULL, parameters, results,
14407 location);
14408 if (method_type->is_varargs())
14409 fntype->set_is_varargs();
14410
14411 // We generate methods which always takes a pointer to the receiver
14412 // as their first argument. If this is for a pointer type, we can
14413 // simply reuse the existing function. We use an internal hack to
14414 // get the right type.
8381eda7 14415 // FIXME: This optimization is disabled because it doesn't yet work
14416 // with function descriptors when the method expression is not
14417 // directly called.
14418 if (method != NULL && is_pointer && false)
e440a328 14419 {
14420 Named_object* mno = (method->needs_stub_method()
14421 ? method->stub_object()
14422 : method->named_object());
14423 Expression* f = Expression::make_func_reference(mno, NULL, location);
14424 f = Expression::make_cast(fntype, f, location);
14425 Type_conversion_expression* tce =
14426 static_cast<Type_conversion_expression*>(f);
14427 tce->set_may_convert_function_types();
14428 return f;
14429 }
14430
13f2fdb8 14431 Named_object* no = gogo->start_function(gogo->thunk_name(), fntype, false,
e440a328 14432 location);
14433
14434 Named_object* vno = gogo->lookup(receiver_name, NULL);
c484d925 14435 go_assert(vno != NULL);
e440a328 14436 Expression* ve = Expression::make_var_reference(vno, location);
ab1468c3 14437 Expression* bm;
14438 if (method != NULL)
14439 bm = Type::bind_field_or_method(gogo, nt, ve, name, location);
14440 else
14441 bm = Expression::make_interface_field_reference(ve, name, location);
f690b0bb 14442
14443 // Even though we found the method above, if it has an error type we
14444 // may see an error here.
14445 if (bm->is_error_expression())
463fe805 14446 {
14447 gogo->finish_function(location);
14448 return bm;
14449 }
e440a328 14450
14451 Expression_list* args;
f470da59 14452 if (parameters->size() <= 1)
e440a328 14453 args = NULL;
14454 else
14455 {
14456 args = new Expression_list();
f470da59 14457 Typed_identifier_list::const_iterator p = parameters->begin();
14458 ++p;
14459 for (; p != parameters->end(); ++p)
e440a328 14460 {
14461 vno = gogo->lookup(p->name(), NULL);
c484d925 14462 go_assert(vno != NULL);
e440a328 14463 args->push_back(Expression::make_var_reference(vno, location));
14464 }
14465 }
14466
ceeb4318 14467 gogo->start_block(location);
14468
e440a328 14469 Call_expression* call = Expression::make_call(bm, args,
14470 method_type->is_varargs(),
14471 location);
14472
0afbb937 14473 Statement* s = Statement::make_return_from_call(call, location);
e440a328 14474 gogo->add_statement(s);
14475
ceeb4318 14476 Block* b = gogo->finish_block(location);
14477
14478 gogo->add_block(b, location);
14479
14480 // Lower the call in case there are multiple results.
14481 gogo->lower_block(no, b);
a32698ee 14482 gogo->flatten_block(no, b);
ceeb4318 14483
e440a328 14484 gogo->finish_function(location);
14485
14486 return Expression::make_func_reference(no, NULL, location);
14487}
14488
d751bb78 14489// Dump the ast for a selector expression.
14490
14491void
f03a9fbf 14492Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 14493 const
14494{
14495 ast_dump_context->dump_expression(this->left_);
14496 ast_dump_context->ostream() << ".";
14497 ast_dump_context->ostream() << this->name_;
14498}
f03a9fbf 14499
e440a328 14500// Make a selector expression.
14501
14502Expression*
14503Expression::make_selector(Expression* left, const std::string& name,
b13c66cd 14504 Location location)
e440a328 14505{
14506 return new Selector_expression(left, name, location);
14507}
14508
da244e59 14509// Class Allocation_expression.
e440a328 14510
da244e59 14511int
14512Allocation_expression::do_traverse(Traverse* traverse)
e440a328 14513{
da244e59 14514 return Type::traverse(this->type_, traverse);
14515}
e440a328 14516
da244e59 14517Type*
14518Allocation_expression::do_type()
14519{
14520 return Type::make_pointer_type(this->type_);
14521}
e440a328 14522
22deed0d 14523void
14524Allocation_expression::do_check_types(Gogo*)
14525{
14526 if (!this->type_->in_heap())
37423a84 14527 go_error_at(this->location(), "cannot heap allocate go:notinheap type");
22deed0d 14528}
14529
da244e59 14530// Make a copy of an allocation expression.
e440a328 14531
da244e59 14532Expression*
14533Allocation_expression::do_copy()
14534{
14535 Allocation_expression* alloc =
de590a61 14536 new Allocation_expression(this->type_->copy_expressions(),
14537 this->location());
da244e59 14538 if (this->allocate_on_stack_)
14539 alloc->set_allocate_on_stack();
20a381c4 14540 if (this->no_zero_)
14541 alloc->set_no_zero();
da244e59 14542 return alloc;
14543}
e440a328 14544
ea664253 14545// Return the backend representation for an allocation expression.
e440a328 14546
ea664253 14547Bexpression*
14548Allocation_expression::do_get_backend(Translate_context* context)
e440a328 14549{
2c809f8f 14550 Gogo* gogo = context->gogo();
14551 Location loc = this->location();
06e83d10 14552 Btype* btype = this->type_->get_backend(gogo);
da244e59 14553
5973ede0 14554 if (this->allocate_on_stack_)
da244e59 14555 {
2a305b85 14556 int64_t size;
14557 bool ok = this->type_->backend_type_size(gogo, &size);
14558 if (!ok)
14559 {
14560 go_assert(saw_errors());
14561 return gogo->backend()->error_expression();
14562 }
06e83d10 14563 Bstatement* decl;
14564 Named_object* fn = context->function();
14565 go_assert(fn != NULL);
14566 Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
20a381c4 14567 Bexpression* init = (this->no_zero_
14568 ? NULL
14569 : gogo->backend()->zero_expression(btype));
06e83d10 14570 Bvariable* temp =
14571 gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
20a381c4 14572 init, true, loc, &decl);
06e83d10 14573 Bexpression* ret = gogo->backend()->var_expression(temp, loc);
14574 ret = gogo->backend()->address_expression(ret, loc);
14575 ret = gogo->backend()->compound_expression(decl, ret, loc);
14576 return ret;
da244e59 14577 }
14578
2a305b85 14579 Bexpression* space =
ea664253 14580 gogo->allocate_memory(this->type_, loc)->get_backend(context);
d5d1c295 14581 Btype* pbtype = gogo->backend()->pointer_type(btype);
ea664253 14582 return gogo->backend()->convert_expression(pbtype, space, loc);
e440a328 14583}
14584
d751bb78 14585// Dump ast representation for an allocation expression.
14586
14587void
f03a9fbf 14588Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 14589 const
14590{
14591 ast_dump_context->ostream() << "new(";
14592 ast_dump_context->dump_type(this->type_);
14593 ast_dump_context->ostream() << ")";
14594}
14595
e440a328 14596// Make an allocation expression.
14597
14598Expression*
b13c66cd 14599Expression::make_allocation(Type* type, Location location)
e440a328 14600{
14601 return new Allocation_expression(type, location);
14602}
14603
e32de7ba 14604// Class Ordered_value_list.
e440a328 14605
14606int
e32de7ba 14607Ordered_value_list::traverse_vals(Traverse* traverse)
e440a328 14608{
0c4f5a19 14609 if (this->vals_ != NULL)
14610 {
14611 if (this->traverse_order_ == NULL)
14612 {
14613 if (this->vals_->traverse(traverse) == TRAVERSE_EXIT)
14614 return TRAVERSE_EXIT;
14615 }
14616 else
14617 {
e32de7ba 14618 for (std::vector<unsigned long>::const_iterator p =
14619 this->traverse_order_->begin();
0c4f5a19 14620 p != this->traverse_order_->end();
14621 ++p)
14622 {
14623 if (Expression::traverse(&this->vals_->at(*p), traverse)
14624 == TRAVERSE_EXIT)
14625 return TRAVERSE_EXIT;
14626 }
14627 }
14628 }
e32de7ba 14629 return TRAVERSE_CONTINUE;
14630}
14631
14632// Class Struct_construction_expression.
14633
14634// Traversal.
14635
14636int
14637Struct_construction_expression::do_traverse(Traverse* traverse)
14638{
14639 if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
14640 return TRAVERSE_EXIT;
e440a328 14641 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
14642 return TRAVERSE_EXIT;
14643 return TRAVERSE_CONTINUE;
14644}
14645
14646// Return whether this is a constant initializer.
14647
14648bool
14649Struct_construction_expression::is_constant_struct() const
14650{
e32de7ba 14651 if (this->vals() == NULL)
e440a328 14652 return true;
e32de7ba 14653 for (Expression_list::const_iterator pv = this->vals()->begin();
14654 pv != this->vals()->end();
e440a328 14655 ++pv)
14656 {
14657 if (*pv != NULL
14658 && !(*pv)->is_constant()
14659 && (!(*pv)->is_composite_literal()
14660 || (*pv)->is_nonconstant_composite_literal()))
14661 return false;
14662 }
14663
14664 const Struct_field_list* fields = this->type_->struct_type()->fields();
14665 for (Struct_field_list::const_iterator pf = fields->begin();
14666 pf != fields->end();
14667 ++pf)
14668 {
14669 // There are no constant constructors for interfaces.
14670 if (pf->type()->interface_type() != NULL)
14671 return false;
14672 }
14673
14674 return true;
14675}
14676
d2199dbc 14677// Return whether this is a zero value.
14678
14679bool
14680Struct_construction_expression::do_is_zero_value() const
14681{
14682 if (this->vals() == NULL)
14683 return true;
14684 for (Expression_list::const_iterator pv = this->vals()->begin();
14685 pv != this->vals()->end();
14686 ++pv)
14687 if (*pv != NULL && !(*pv)->is_zero_value())
14688 return false;
14689
14690 const Struct_field_list* fields = this->type_->struct_type()->fields();
14691 for (Struct_field_list::const_iterator pf = fields->begin();
14692 pf != fields->end();
14693 ++pf)
14694 {
14695 // Interface conversion may cause a zero value being converted
14696 // to a non-zero value, like interface{}(0). Be conservative.
14697 if (pf->type()->interface_type() != NULL)
14698 return false;
14699 }
14700
14701 return true;
14702}
14703
3ae06f68 14704// Return whether this struct can be used as a constant initializer.
f9ca30f9 14705
14706bool
3ae06f68 14707Struct_construction_expression::do_is_static_initializer() const
f9ca30f9 14708{
e32de7ba 14709 if (this->vals() == NULL)
f9ca30f9 14710 return true;
e32de7ba 14711 for (Expression_list::const_iterator pv = this->vals()->begin();
14712 pv != this->vals()->end();
f9ca30f9 14713 ++pv)
14714 {
3ae06f68 14715 if (*pv != NULL && !(*pv)->is_static_initializer())
f9ca30f9 14716 return false;
14717 }
de048538 14718
14719 const Struct_field_list* fields = this->type_->struct_type()->fields();
14720 for (Struct_field_list::const_iterator pf = fields->begin();
14721 pf != fields->end();
14722 ++pf)
14723 {
14724 // There are no constant constructors for interfaces.
14725 if (pf->type()->interface_type() != NULL)
14726 return false;
14727 }
14728
f9ca30f9 14729 return true;
14730}
14731
e440a328 14732// Final type determination.
14733
14734void
14735Struct_construction_expression::do_determine_type(const Type_context*)
14736{
e32de7ba 14737 if (this->vals() == NULL)
e440a328 14738 return;
14739 const Struct_field_list* fields = this->type_->struct_type()->fields();
e32de7ba 14740 Expression_list::const_iterator pv = this->vals()->begin();
e440a328 14741 for (Struct_field_list::const_iterator pf = fields->begin();
14742 pf != fields->end();
14743 ++pf, ++pv)
14744 {
e32de7ba 14745 if (pv == this->vals()->end())
e440a328 14746 return;
14747 if (*pv != NULL)
14748 {
14749 Type_context subcontext(pf->type(), false);
14750 (*pv)->determine_type(&subcontext);
14751 }
14752 }
a6cb4c0e 14753 // Extra values are an error we will report elsewhere; we still want
14754 // to determine the type to avoid knockon errors.
e32de7ba 14755 for (; pv != this->vals()->end(); ++pv)
a6cb4c0e 14756 (*pv)->determine_type_no_context();
e440a328 14757}
14758
14759// Check types.
14760
14761void
14762Struct_construction_expression::do_check_types(Gogo*)
14763{
e32de7ba 14764 if (this->vals() == NULL)
e440a328 14765 return;
14766
14767 Struct_type* st = this->type_->struct_type();
e32de7ba 14768 if (this->vals()->size() > st->field_count())
e440a328 14769 {
14770 this->report_error(_("too many expressions for struct"));
14771 return;
14772 }
14773
14774 const Struct_field_list* fields = st->fields();
e32de7ba 14775 Expression_list::const_iterator pv = this->vals()->begin();
e440a328 14776 int i = 0;
14777 for (Struct_field_list::const_iterator pf = fields->begin();
14778 pf != fields->end();
14779 ++pf, ++pv, ++i)
14780 {
e32de7ba 14781 if (pv == this->vals()->end())
e440a328 14782 {
14783 this->report_error(_("too few expressions for struct"));
14784 break;
14785 }
14786
14787 if (*pv == NULL)
14788 continue;
14789
14790 std::string reason;
14791 if (!Type::are_assignable(pf->type(), (*pv)->type(), &reason))
14792 {
14793 if (reason.empty())
631d5788 14794 go_error_at((*pv)->location(),
14795 "incompatible type for field %d in struct construction",
14796 i + 1);
e440a328 14797 else
631d5788 14798 go_error_at((*pv)->location(),
14799 ("incompatible type for field %d in "
14800 "struct construction (%s)"),
14801 i + 1, reason.c_str());
e440a328 14802 this->set_is_error();
14803 }
14804 }
e32de7ba 14805 go_assert(pv == this->vals()->end());
e440a328 14806}
14807
de590a61 14808// Copy.
14809
14810Expression*
14811Struct_construction_expression::do_copy()
14812{
14813 Struct_construction_expression* ret =
14814 new Struct_construction_expression(this->type_->copy_expressions(),
14815 (this->vals() == NULL
14816 ? NULL
14817 : this->vals()->copy()),
14818 this->location());
14819 if (this->traverse_order() != NULL)
14820 ret->set_traverse_order(this->traverse_order());
14821 return ret;
14822}
14823
8ba8cc87 14824// Flatten a struct construction expression. Store the values into
14825// temporaries in case they need interface conversion.
14826
14827Expression*
14828Struct_construction_expression::do_flatten(Gogo*, Named_object*,
14829 Statement_inserter* inserter)
14830{
e32de7ba 14831 if (this->vals() == NULL)
8ba8cc87 14832 return this;
14833
14834 // If this is a constant struct, we don't need temporaries.
de048538 14835 if (this->is_constant_struct() || this->is_static_initializer())
8ba8cc87 14836 return this;
14837
14838 Location loc = this->location();
e32de7ba 14839 for (Expression_list::iterator pv = this->vals()->begin();
14840 pv != this->vals()->end();
8ba8cc87 14841 ++pv)
14842 {
14843 if (*pv != NULL)
14844 {
5bf8be8b 14845 if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type())
14846 {
14847 go_assert(saw_errors());
14848 return Expression::make_error(loc);
14849 }
8ba8cc87 14850 if (!(*pv)->is_variable())
14851 {
14852 Temporary_statement* temp =
14853 Statement::make_temporary(NULL, *pv, loc);
14854 inserter->insert(temp);
14855 *pv = Expression::make_temporary_reference(temp, loc);
14856 }
14857 }
14858 }
14859 return this;
14860}
14861
e007b1eb 14862// Make implicit type conversions explicit.
14863
14864void
14865Struct_construction_expression::do_add_conversions()
14866{
14867 if (this->vals() == NULL)
14868 return;
14869
14870 Location loc = this->location();
14871 const Struct_field_list* fields = this->type_->struct_type()->fields();
14872 Expression_list::iterator pv = this->vals()->begin();
14873 for (Struct_field_list::const_iterator pf = fields->begin();
14874 pf != fields->end();
14875 ++pf, ++pv)
14876 {
14877 if (pv == this->vals()->end())
14878 break;
14879 if (*pv != NULL)
14880 {
14881 Type* ft = pf->type();
14882 if (!Type::are_identical(ft, (*pv)->type(), 0, NULL)
14883 && ft->interface_type() != NULL)
14884 *pv = Expression::make_cast(ft, *pv, loc);
14885 }
14886 }
14887}
14888
ea664253 14889// Return the backend representation for constructing a struct.
e440a328 14890
ea664253 14891Bexpression*
14892Struct_construction_expression::do_get_backend(Translate_context* context)
e440a328 14893{
14894 Gogo* gogo = context->gogo();
14895
2c809f8f 14896 Btype* btype = this->type_->get_backend(gogo);
e32de7ba 14897 if (this->vals() == NULL)
ea664253 14898 return gogo->backend()->zero_expression(btype);
e440a328 14899
e440a328 14900 const Struct_field_list* fields = this->type_->struct_type()->fields();
e32de7ba 14901 Expression_list::const_iterator pv = this->vals()->begin();
2c809f8f 14902 std::vector<Bexpression*> init;
14903 for (Struct_field_list::const_iterator pf = fields->begin();
14904 pf != fields->end();
14905 ++pf)
e440a328 14906 {
63697958 14907 Btype* fbtype = pf->type()->get_backend(gogo);
e32de7ba 14908 if (pv == this->vals()->end())
2c809f8f 14909 init.push_back(gogo->backend()->zero_expression(fbtype));
e440a328 14910 else if (*pv == NULL)
14911 {
2c809f8f 14912 init.push_back(gogo->backend()->zero_expression(fbtype));
e440a328 14913 ++pv;
14914 }
14915 else
14916 {
2c809f8f 14917 Expression* val =
14918 Expression::convert_for_assignment(gogo, pf->type(),
14919 *pv, this->location());
ea664253 14920 init.push_back(val->get_backend(context));
e440a328 14921 ++pv;
14922 }
e440a328 14923 }
0fdf8340 14924 if (this->type_->struct_type()->has_padding())
14925 {
14926 // Feed an extra value if there is a padding field.
14927 Btype *fbtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
14928 init.push_back(gogo->backend()->zero_expression(fbtype));
14929 }
ea664253 14930 return gogo->backend()->constructor_expression(btype, init, this->location());
e440a328 14931}
14932
14933// Export a struct construction.
14934
14935void
548be246 14936Struct_construction_expression::do_export(Export_function_body* efb) const
e440a328 14937{
204d4af4 14938 efb->write_c_string("$convert(");
548be246 14939 efb->write_type(this->type_);
e32de7ba 14940 for (Expression_list::const_iterator pv = this->vals()->begin();
14941 pv != this->vals()->end();
e440a328 14942 ++pv)
14943 {
548be246 14944 efb->write_c_string(", ");
e440a328 14945 if (*pv != NULL)
548be246 14946 (*pv)->export_expression(efb);
e440a328 14947 }
548be246 14948 efb->write_c_string(")");
e440a328 14949}
14950
d751bb78 14951// Dump ast representation of a struct construction expression.
14952
14953void
14954Struct_construction_expression::do_dump_expression(
14955 Ast_dump_context* ast_dump_context) const
14956{
d751bb78 14957 ast_dump_context->dump_type(this->type_);
14958 ast_dump_context->ostream() << "{";
e32de7ba 14959 ast_dump_context->dump_expression_list(this->vals());
d751bb78 14960 ast_dump_context->ostream() << "}";
14961}
14962
e440a328 14963// Make a struct composite literal. This used by the thunk code.
14964
14965Expression*
14966Expression::make_struct_composite_literal(Type* type, Expression_list* vals,
b13c66cd 14967 Location location)
e440a328 14968{
c484d925 14969 go_assert(type->struct_type() != NULL);
e440a328 14970 return new Struct_construction_expression(type, vals, location);
14971}
14972
da244e59 14973// Class Array_construction_expression.
e440a328 14974
14975// Traversal.
14976
14977int
14978Array_construction_expression::do_traverse(Traverse* traverse)
14979{
e32de7ba 14980 if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
e440a328 14981 return TRAVERSE_EXIT;
14982 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
14983 return TRAVERSE_EXIT;
14984 return TRAVERSE_CONTINUE;
14985}
14986
14987// Return whether this is a constant initializer.
14988
14989bool
14990Array_construction_expression::is_constant_array() const
14991{
e32de7ba 14992 if (this->vals() == NULL)
e440a328 14993 return true;
14994
14995 // There are no constant constructors for interfaces.
14996 if (this->type_->array_type()->element_type()->interface_type() != NULL)
14997 return false;
14998
e32de7ba 14999 for (Expression_list::const_iterator pv = this->vals()->begin();
15000 pv != this->vals()->end();
e440a328 15001 ++pv)
15002 {
15003 if (*pv != NULL
15004 && !(*pv)->is_constant()
15005 && (!(*pv)->is_composite_literal()
15006 || (*pv)->is_nonconstant_composite_literal()))
15007 return false;
15008 }
15009 return true;
15010}
15011
d2199dbc 15012// Return whether this is a zero value.
15013
15014bool
15015Array_construction_expression::do_is_zero_value() const
15016{
15017 if (this->vals() == NULL)
15018 return true;
15019
15020 // Interface conversion may cause a zero value being converted
15021 // to a non-zero value, like interface{}(0). Be conservative.
15022 if (this->type_->array_type()->element_type()->interface_type() != NULL)
15023 return false;
15024
15025 for (Expression_list::const_iterator pv = this->vals()->begin();
15026 pv != this->vals()->end();
15027 ++pv)
15028 if (*pv != NULL && !(*pv)->is_zero_value())
15029 return false;
15030
15031 return true;
15032}
15033
3ae06f68 15034// Return whether this can be used a constant initializer.
f9ca30f9 15035
15036bool
3ae06f68 15037Array_construction_expression::do_is_static_initializer() const
f9ca30f9 15038{
e32de7ba 15039 if (this->vals() == NULL)
f9ca30f9 15040 return true;
de048538 15041
15042 // There are no constant constructors for interfaces.
15043 if (this->type_->array_type()->element_type()->interface_type() != NULL)
15044 return false;
15045
e32de7ba 15046 for (Expression_list::const_iterator pv = this->vals()->begin();
15047 pv != this->vals()->end();
f9ca30f9 15048 ++pv)
15049 {
3ae06f68 15050 if (*pv != NULL && !(*pv)->is_static_initializer())
f9ca30f9 15051 return false;
15052 }
15053 return true;
15054}
15055
e440a328 15056// Final type determination.
15057
15058void
15059Array_construction_expression::do_determine_type(const Type_context*)
15060{
e32de7ba 15061 if (this->vals() == NULL)
e440a328 15062 return;
15063 Type_context subcontext(this->type_->array_type()->element_type(), false);
e32de7ba 15064 for (Expression_list::const_iterator pv = this->vals()->begin();
15065 pv != this->vals()->end();
e440a328 15066 ++pv)
15067 {
15068 if (*pv != NULL)
15069 (*pv)->determine_type(&subcontext);
15070 }
15071}
15072
15073// Check types.
15074
15075void
15076Array_construction_expression::do_check_types(Gogo*)
15077{
e32de7ba 15078 if (this->vals() == NULL)
e440a328 15079 return;
15080
15081 Array_type* at = this->type_->array_type();
15082 int i = 0;
15083 Type* element_type = at->element_type();
e32de7ba 15084 for (Expression_list::const_iterator pv = this->vals()->begin();
15085 pv != this->vals()->end();
e440a328 15086 ++pv, ++i)
15087 {
15088 if (*pv != NULL
15089 && !Type::are_assignable(element_type, (*pv)->type(), NULL))
15090 {
631d5788 15091 go_error_at((*pv)->location(),
15092 "incompatible type for element %d in composite literal",
15093 i + 1);
e440a328 15094 this->set_is_error();
15095 }
15096 }
e440a328 15097}
15098
8ba8cc87 15099// Flatten an array construction expression. Store the values into
15100// temporaries in case they need interface conversion.
15101
15102Expression*
15103Array_construction_expression::do_flatten(Gogo*, Named_object*,
15104 Statement_inserter* inserter)
15105{
e32de7ba 15106 if (this->vals() == NULL)
8ba8cc87 15107 return this;
15108
15109 // If this is a constant array, we don't need temporaries.
de048538 15110 if (this->is_constant_array() || this->is_static_initializer())
8ba8cc87 15111 return this;
15112
15113 Location loc = this->location();
e32de7ba 15114 for (Expression_list::iterator pv = this->vals()->begin();
15115 pv != this->vals()->end();
8ba8cc87 15116 ++pv)
15117 {
15118 if (*pv != NULL)
15119 {
5bf8be8b 15120 if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type())
15121 {
15122 go_assert(saw_errors());
15123 return Expression::make_error(loc);
15124 }
8ba8cc87 15125 if (!(*pv)->is_variable())
15126 {
15127 Temporary_statement* temp =
15128 Statement::make_temporary(NULL, *pv, loc);
15129 inserter->insert(temp);
15130 *pv = Expression::make_temporary_reference(temp, loc);
15131 }
15132 }
15133 }
15134 return this;
15135}
15136
e007b1eb 15137// Make implicit type conversions explicit.
15138
15139void
15140Array_construction_expression::do_add_conversions()
15141{
15142 if (this->vals() == NULL)
15143 return;
15144
15145 Type* et = this->type_->array_type()->element_type();
15146 if (et->interface_type() == NULL)
15147 return;
15148
15149 Location loc = this->location();
15150 for (Expression_list::iterator pv = this->vals()->begin();
15151 pv != this->vals()->end();
15152 ++pv)
15153 if (!Type::are_identical(et, (*pv)->type(), 0, NULL))
15154 *pv = Expression::make_cast(et, *pv, loc);
15155}
15156
2c809f8f 15157// Get a constructor expression for the array values.
e440a328 15158
2c809f8f 15159Bexpression*
15160Array_construction_expression::get_constructor(Translate_context* context,
15161 Btype* array_btype)
e440a328 15162{
e440a328 15163 Type* element_type = this->type_->array_type()->element_type();
2c809f8f 15164
15165 std::vector<unsigned long> indexes;
15166 std::vector<Bexpression*> vals;
15167 Gogo* gogo = context->gogo();
e32de7ba 15168 if (this->vals() != NULL)
e440a328 15169 {
15170 size_t i = 0;
ffe743ca 15171 std::vector<unsigned long>::const_iterator pi;
15172 if (this->indexes_ != NULL)
15173 pi = this->indexes_->begin();
e32de7ba 15174 for (Expression_list::const_iterator pv = this->vals()->begin();
15175 pv != this->vals()->end();
e440a328 15176 ++pv, ++i)
15177 {
ffe743ca 15178 if (this->indexes_ != NULL)
15179 go_assert(pi != this->indexes_->end());
ffe743ca 15180
15181 if (this->indexes_ == NULL)
2c809f8f 15182 indexes.push_back(i);
ffe743ca 15183 else
2c809f8f 15184 indexes.push_back(*pi);
e440a328 15185 if (*pv == NULL)
63697958 15186 {
63697958 15187 Btype* ebtype = element_type->get_backend(gogo);
15188 Bexpression *zv = gogo->backend()->zero_expression(ebtype);
2c809f8f 15189 vals.push_back(zv);
63697958 15190 }
e440a328 15191 else
15192 {
2c809f8f 15193 Expression* val_expr =
15194 Expression::convert_for_assignment(gogo, element_type, *pv,
15195 this->location());
ea664253 15196 vals.push_back(val_expr->get_backend(context));
e440a328 15197 }
ffe743ca 15198 if (this->indexes_ != NULL)
15199 ++pi;
e440a328 15200 }
ffe743ca 15201 if (this->indexes_ != NULL)
15202 go_assert(pi == this->indexes_->end());
e440a328 15203 }
2c809f8f 15204 return gogo->backend()->array_constructor_expression(array_btype, indexes,
15205 vals, this->location());
e440a328 15206}
15207
15208// Export an array construction.
15209
15210void
548be246 15211Array_construction_expression::do_export(Export_function_body* efb) const
e440a328 15212{
204d4af4 15213 efb->write_c_string("$convert(");
548be246 15214 efb->write_type(this->type_);
e32de7ba 15215 if (this->vals() != NULL)
e440a328 15216 {
ffe743ca 15217 std::vector<unsigned long>::const_iterator pi;
15218 if (this->indexes_ != NULL)
15219 pi = this->indexes_->begin();
e32de7ba 15220 for (Expression_list::const_iterator pv = this->vals()->begin();
15221 pv != this->vals()->end();
e440a328 15222 ++pv)
15223 {
548be246 15224 efb->write_c_string(", ");
ffe743ca 15225
15226 if (this->indexes_ != NULL)
15227 {
15228 char buf[100];
15229 snprintf(buf, sizeof buf, "%lu", *pi);
548be246 15230 efb->write_c_string(buf);
15231 efb->write_c_string(":");
ffe743ca 15232 }
15233
e440a328 15234 if (*pv != NULL)
548be246 15235 (*pv)->export_expression(efb);
ffe743ca 15236
15237 if (this->indexes_ != NULL)
15238 ++pi;
e440a328 15239 }
15240 }
548be246 15241 efb->write_c_string(")");
e440a328 15242}
15243
0e9a2e72 15244// Dump ast representation of an array construction expression.
d751bb78 15245
15246void
15247Array_construction_expression::do_dump_expression(
15248 Ast_dump_context* ast_dump_context) const
15249{
ffe743ca 15250 Expression* length = this->type_->array_type()->length();
8b1c301d 15251
15252 ast_dump_context->ostream() << "[" ;
15253 if (length != NULL)
15254 {
15255 ast_dump_context->dump_expression(length);
15256 }
15257 ast_dump_context->ostream() << "]" ;
d751bb78 15258 ast_dump_context->dump_type(this->type_);
0e9a2e72 15259 this->dump_slice_storage_expression(ast_dump_context);
d751bb78 15260 ast_dump_context->ostream() << "{" ;
ffe743ca 15261 if (this->indexes_ == NULL)
e32de7ba 15262 ast_dump_context->dump_expression_list(this->vals());
ffe743ca 15263 else
15264 {
e32de7ba 15265 Expression_list::const_iterator pv = this->vals()->begin();
ffe743ca 15266 for (std::vector<unsigned long>::const_iterator pi =
15267 this->indexes_->begin();
15268 pi != this->indexes_->end();
15269 ++pi, ++pv)
15270 {
15271 if (pi != this->indexes_->begin())
15272 ast_dump_context->ostream() << ", ";
15273 ast_dump_context->ostream() << *pi << ':';
15274 ast_dump_context->dump_expression(*pv);
15275 }
15276 }
d751bb78 15277 ast_dump_context->ostream() << "}" ;
15278
15279}
15280
da244e59 15281// Class Fixed_array_construction_expression.
e440a328 15282
da244e59 15283Fixed_array_construction_expression::Fixed_array_construction_expression(
15284 Type* type, const std::vector<unsigned long>* indexes,
15285 Expression_list* vals, Location location)
15286 : Array_construction_expression(EXPRESSION_FIXED_ARRAY_CONSTRUCTION,
15287 type, indexes, vals, location)
15288{ go_assert(type->array_type() != NULL && !type->is_slice_type()); }
e440a328 15289
de590a61 15290
15291// Copy.
15292
15293Expression*
15294Fixed_array_construction_expression::do_copy()
15295{
15296 Type* t = this->type()->copy_expressions();
15297 return new Fixed_array_construction_expression(t, this->indexes(),
15298 (this->vals() == NULL
15299 ? NULL
15300 : this->vals()->copy()),
15301 this->location());
15302}
15303
ea664253 15304// Return the backend representation for constructing a fixed array.
e440a328 15305
ea664253 15306Bexpression*
15307Fixed_array_construction_expression::do_get_backend(Translate_context* context)
e440a328 15308{
9f0e0513 15309 Type* type = this->type();
15310 Btype* btype = type->get_backend(context->gogo());
ea664253 15311 return this->get_constructor(context, btype);
e440a328 15312}
15313
76f85fd6 15314Expression*
15315Expression::make_array_composite_literal(Type* type, Expression_list* vals,
15316 Location location)
15317{
15318 go_assert(type->array_type() != NULL && !type->is_slice_type());
15319 return new Fixed_array_construction_expression(type, NULL, vals, location);
15320}
15321
da244e59 15322// Class Slice_construction_expression.
e440a328 15323
da244e59 15324Slice_construction_expression::Slice_construction_expression(
15325 Type* type, const std::vector<unsigned long>* indexes,
15326 Expression_list* vals, Location location)
15327 : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
15328 type, indexes, vals, location),
0e9a2e72 15329 valtype_(NULL), array_val_(NULL), slice_storage_(NULL),
15330 storage_escapes_(true)
e440a328 15331{
da244e59 15332 go_assert(type->is_slice_type());
23d77f91 15333
da244e59 15334 unsigned long lenval;
15335 Expression* length;
15336 if (vals == NULL || vals->empty())
15337 lenval = 0;
15338 else
15339 {
15340 if (this->indexes() == NULL)
15341 lenval = vals->size();
15342 else
15343 lenval = indexes->back() + 1;
15344 }
15345 Type* int_type = Type::lookup_integer_type("int");
15346 length = Expression::make_integer_ul(lenval, int_type, location);
15347 Type* element_type = type->array_type()->element_type();
6bf4793c 15348 Array_type* array_type = Type::make_array_type(element_type, length);
15349 array_type->set_is_array_incomparable();
15350 this->valtype_ = array_type;
da244e59 15351}
e440a328 15352
23d77f91 15353// Traversal.
15354
15355int
15356Slice_construction_expression::do_traverse(Traverse* traverse)
15357{
15358 if (this->Array_construction_expression::do_traverse(traverse)
15359 == TRAVERSE_EXIT)
15360 return TRAVERSE_EXIT;
15361 if (Type::traverse(this->valtype_, traverse) == TRAVERSE_EXIT)
15362 return TRAVERSE_EXIT;
0e9a2e72 15363 if (this->array_val_ != NULL
15364 && Expression::traverse(&this->array_val_, traverse) == TRAVERSE_EXIT)
15365 return TRAVERSE_EXIT;
15366 if (this->slice_storage_ != NULL
15367 && Expression::traverse(&this->slice_storage_, traverse) == TRAVERSE_EXIT)
15368 return TRAVERSE_EXIT;
23d77f91 15369 return TRAVERSE_CONTINUE;
15370}
15371
0e9a2e72 15372// Helper routine to create fixed array value underlying the slice literal.
15373// May be called during flattening, or later during do_get_backend().
e440a328 15374
0e9a2e72 15375Expression*
15376Slice_construction_expression::create_array_val()
e440a328 15377{
f9c68f17 15378 Array_type* array_type = this->type()->array_type();
15379 if (array_type == NULL)
15380 {
c484d925 15381 go_assert(this->type()->is_error());
0e9a2e72 15382 return NULL;
f9c68f17 15383 }
15384
f23d7786 15385 Location loc = this->location();
23d77f91 15386 go_assert(this->valtype_ != NULL);
3d60812e 15387
f23d7786 15388 Expression_list* vals = this->vals();
0e9a2e72 15389 return new Fixed_array_construction_expression(
15390 this->valtype_, this->indexes(), vals, loc);
15391}
15392
15393// If we're previous established that the slice storage does not
15394// escape, then create a separate array temp val here for it. We
15395// need to do this as part of flattening so as to be able to insert
15396// the new temp statement.
15397
15398Expression*
15399Slice_construction_expression::do_flatten(Gogo* gogo, Named_object* no,
15400 Statement_inserter* inserter)
15401{
15402 if (this->type()->array_type() == NULL)
15403 return NULL;
15404
15405 // Base class flattening first
15406 this->Array_construction_expression::do_flatten(gogo, no, inserter);
15407
a1bbc2c3 15408 // Create a stack-allocated storage temp if storage won't escape
03118c21 15409 if (!this->storage_escapes_
15410 && this->slice_storage_ == NULL
15411 && this->element_count() > 0)
0e9a2e72 15412 {
15413 Location loc = this->location();
03118c21 15414 this->array_val_ = this->create_array_val();
0e9a2e72 15415 go_assert(this->array_val_);
15416 Temporary_statement* temp =
15417 Statement::make_temporary(this->valtype_, this->array_val_, loc);
15418 inserter->insert(temp);
15419 this->slice_storage_ = Expression::make_temporary_reference(temp, loc);
15420 }
15421 return this;
15422}
15423
15424// When dumping a slice construction expression that has an explicit
15425// storeage temp, emit the temp here (if we don't do this the storage
15426// temp appears unused in the AST dump).
15427
15428void
15429Slice_construction_expression::
15430dump_slice_storage_expression(Ast_dump_context* ast_dump_context) const
15431{
15432 if (this->slice_storage_ == NULL)
15433 return;
15434 ast_dump_context->ostream() << "storage=" ;
15435 ast_dump_context->dump_expression(this->slice_storage_);
15436}
15437
de590a61 15438// Copy.
15439
15440Expression*
15441Slice_construction_expression::do_copy()
15442{
15443 return new Slice_construction_expression(this->type()->copy_expressions(),
15444 this->indexes(),
15445 (this->vals() == NULL
15446 ? NULL
15447 : this->vals()->copy()),
15448 this->location());
15449}
15450
0e9a2e72 15451// Return the backend representation for constructing a slice.
15452
15453Bexpression*
15454Slice_construction_expression::do_get_backend(Translate_context* context)
15455{
15456 if (this->array_val_ == NULL)
03118c21 15457 this->array_val_ = this->create_array_val();
0e9a2e72 15458 if (this->array_val_ == NULL)
15459 {
15460 go_assert(this->type()->is_error());
15461 return context->backend()->error_expression();
15462 }
15463
15464 Location loc = this->location();
e440a328 15465
3ae06f68 15466 bool is_static_initializer = this->array_val_->is_static_initializer();
d8829beb 15467
15468 // We have to copy the initial values into heap memory if we are in
3ae06f68 15469 // a function or if the values are not constants.
15470 bool copy_to_heap = context->function() != NULL || !is_static_initializer;
e440a328 15471
f23d7786 15472 Expression* space;
0e9a2e72 15473
15474 if (this->slice_storage_ != NULL)
15475 {
15476 go_assert(!this->storage_escapes_);
15477 space = Expression::make_unary(OPERATOR_AND, this->slice_storage_, loc);
15478 }
15479 else if (!copy_to_heap)
e440a328 15480 {
f23d7786 15481 // The initializer will only run once.
0e9a2e72 15482 space = Expression::make_unary(OPERATOR_AND, this->array_val_, loc);
f23d7786 15483 space->unary_expression()->set_is_slice_init();
e440a328 15484 }
15485 else
45ff893b 15486 {
5973ede0 15487 go_assert(this->storage_escapes_ || this->element_count() == 0);
0e9a2e72 15488 space = Expression::make_heap_expression(this->array_val_, loc);
45ff893b 15489 }
d633d0fb 15490 Array_type* at = this->valtype_->array_type();
15491 Type* et = at->element_type();
15492 space = Expression::make_unsafe_cast(Type::make_pointer_type(et),
15493 space, loc);
e440a328 15494
2c809f8f 15495 // Build a constructor for the slice.
d633d0fb 15496 Expression* len = at->length();
f23d7786 15497 Expression* slice_val =
15498 Expression::make_slice_value(this->type(), space, len, len, loc);
ea664253 15499 return slice_val->get_backend(context);
e440a328 15500}
15501
15502// Make a slice composite literal. This is used by the type
15503// descriptor code.
15504
0e9a2e72 15505Slice_construction_expression*
e440a328 15506Expression::make_slice_composite_literal(Type* type, Expression_list* vals,
b13c66cd 15507 Location location)
e440a328 15508{
411eb89e 15509 go_assert(type->is_slice_type());
2c809f8f 15510 return new Slice_construction_expression(type, NULL, vals, location);
e440a328 15511}
15512
da244e59 15513// Class Map_construction_expression.
e440a328 15514
15515// Traversal.
15516
15517int
15518Map_construction_expression::do_traverse(Traverse* traverse)
15519{
15520 if (this->vals_ != NULL
15521 && this->vals_->traverse(traverse) == TRAVERSE_EXIT)
15522 return TRAVERSE_EXIT;
15523 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
15524 return TRAVERSE_EXIT;
15525 return TRAVERSE_CONTINUE;
15526}
15527
2c809f8f 15528// Flatten constructor initializer into a temporary variable since
15529// we need to take its address for __go_construct_map.
15530
15531Expression*
15532Map_construction_expression::do_flatten(Gogo* gogo, Named_object*,
15533 Statement_inserter* inserter)
15534{
15535 if (!this->is_error_expression()
15536 && this->vals_ != NULL
15537 && !this->vals_->empty()
15538 && this->constructor_temp_ == NULL)
15539 {
15540 Map_type* mt = this->type_->map_type();
15541 Type* key_type = mt->key_type();
15542 Type* val_type = mt->val_type();
15543 this->element_type_ = Type::make_builtin_struct_type(2,
15544 "__key", key_type,
15545 "__val", val_type);
15546
15547 Expression_list* value_pairs = new Expression_list();
15548 Location loc = this->location();
15549
15550 size_t i = 0;
15551 for (Expression_list::const_iterator pv = this->vals_->begin();
15552 pv != this->vals_->end();
15553 ++pv, ++i)
15554 {
15555 Expression_list* key_value_pair = new Expression_list();
91c0fd76 15556 Expression* key = *pv;
5bf8be8b 15557 if (key->is_error_expression() || key->type()->is_error_type())
15558 {
15559 go_assert(saw_errors());
15560 return Expression::make_error(loc);
15561 }
91c0fd76 15562 if (key->type()->interface_type() != NULL && !key->is_variable())
15563 {
15564 Temporary_statement* temp =
15565 Statement::make_temporary(NULL, key, loc);
15566 inserter->insert(temp);
15567 key = Expression::make_temporary_reference(temp, loc);
15568 }
15569 key = Expression::convert_for_assignment(gogo, key_type, key, loc);
2c809f8f 15570
15571 ++pv;
91c0fd76 15572 Expression* val = *pv;
5bf8be8b 15573 if (val->is_error_expression() || val->type()->is_error_type())
15574 {
15575 go_assert(saw_errors());
15576 return Expression::make_error(loc);
15577 }
91c0fd76 15578 if (val->type()->interface_type() != NULL && !val->is_variable())
15579 {
15580 Temporary_statement* temp =
15581 Statement::make_temporary(NULL, val, loc);
15582 inserter->insert(temp);
15583 val = Expression::make_temporary_reference(temp, loc);
15584 }
15585 val = Expression::convert_for_assignment(gogo, val_type, val, loc);
2c809f8f 15586
15587 key_value_pair->push_back(key);
15588 key_value_pair->push_back(val);
15589 value_pairs->push_back(
15590 Expression::make_struct_composite_literal(this->element_type_,
15591 key_value_pair, loc));
15592 }
15593
e67508fa 15594 Expression* element_count = Expression::make_integer_ul(i, NULL, loc);
6bf4793c 15595 Array_type* ctor_type =
2c809f8f 15596 Type::make_array_type(this->element_type_, element_count);
6bf4793c 15597 ctor_type->set_is_array_incomparable();
2c809f8f 15598 Expression* constructor =
15599 new Fixed_array_construction_expression(ctor_type, NULL,
15600 value_pairs, loc);
15601
15602 this->constructor_temp_ =
15603 Statement::make_temporary(NULL, constructor, loc);
15604 constructor->issue_nil_check();
15605 this->constructor_temp_->set_is_address_taken();
15606 inserter->insert(this->constructor_temp_);
15607 }
15608
15609 return this;
15610}
15611
e440a328 15612// Final type determination.
15613
15614void
15615Map_construction_expression::do_determine_type(const Type_context*)
15616{
15617 if (this->vals_ == NULL)
15618 return;
15619
15620 Map_type* mt = this->type_->map_type();
15621 Type_context key_context(mt->key_type(), false);
15622 Type_context val_context(mt->val_type(), false);
15623 for (Expression_list::const_iterator pv = this->vals_->begin();
15624 pv != this->vals_->end();
15625 ++pv)
15626 {
15627 (*pv)->determine_type(&key_context);
15628 ++pv;
15629 (*pv)->determine_type(&val_context);
15630 }
15631}
15632
15633// Check types.
15634
15635void
15636Map_construction_expression::do_check_types(Gogo*)
15637{
15638 if (this->vals_ == NULL)
15639 return;
15640
15641 Map_type* mt = this->type_->map_type();
15642 int i = 0;
15643 Type* key_type = mt->key_type();
15644 Type* val_type = mt->val_type();
15645 for (Expression_list::const_iterator pv = this->vals_->begin();
15646 pv != this->vals_->end();
15647 ++pv, ++i)
15648 {
15649 if (!Type::are_assignable(key_type, (*pv)->type(), NULL))
15650 {
631d5788 15651 go_error_at((*pv)->location(),
15652 "incompatible type for element %d key in map construction",
15653 i + 1);
e440a328 15654 this->set_is_error();
15655 }
15656 ++pv;
15657 if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
15658 {
631d5788 15659 go_error_at((*pv)->location(),
15660 ("incompatible type for element %d value "
15661 "in map construction"),
e440a328 15662 i + 1);
15663 this->set_is_error();
15664 }
15665 }
15666}
15667
de590a61 15668// Copy.
15669
15670Expression*
15671Map_construction_expression::do_copy()
15672{
15673 return new Map_construction_expression(this->type_->copy_expressions(),
15674 (this->vals_ == NULL
15675 ? NULL
15676 : this->vals_->copy()),
15677 this->location());
15678}
15679
e007b1eb 15680// Make implicit type conversions explicit.
15681
15682void
15683Map_construction_expression::do_add_conversions()
15684{
15685 if (this->vals_ == NULL || this->vals_->empty())
15686 return;
15687
15688 Map_type* mt = this->type_->map_type();
15689 Type* kt = mt->key_type();
15690 Type* vt = mt->val_type();
15691 bool key_is_interface = (kt->interface_type() != NULL);
15692 bool val_is_interface = (vt->interface_type() != NULL);
15693 if (!key_is_interface && !val_is_interface)
15694 return;
15695
15696 Location loc = this->location();
15697 for (Expression_list::iterator pv = this->vals_->begin();
15698 pv != this->vals_->end();
15699 ++pv)
15700 {
15701 if (key_is_interface &&
15702 !Type::are_identical(kt, (*pv)->type(), 0, NULL))
15703 *pv = Expression::make_cast(kt, *pv, loc);
15704 ++pv;
15705 if (val_is_interface &&
15706 !Type::are_identical(vt, (*pv)->type(), 0, NULL))
15707 *pv = Expression::make_cast(vt, *pv, loc);
15708 }
15709}
15710
ea664253 15711// Return the backend representation for constructing a map.
e440a328 15712
ea664253 15713Bexpression*
15714Map_construction_expression::do_get_backend(Translate_context* context)
e440a328 15715{
2c809f8f 15716 if (this->is_error_expression())
ea664253 15717 return context->backend()->error_expression();
2c809f8f 15718 Location loc = this->location();
e440a328 15719
e440a328 15720 size_t i = 0;
2c809f8f 15721 Expression* ventries;
e440a328 15722 if (this->vals_ == NULL || this->vals_->empty())
2c809f8f 15723 ventries = Expression::make_nil(loc);
e440a328 15724 else
15725 {
2c809f8f 15726 go_assert(this->constructor_temp_ != NULL);
15727 i = this->vals_->size() / 2;
e440a328 15728
2c809f8f 15729 Expression* ctor_ref =
15730 Expression::make_temporary_reference(this->constructor_temp_, loc);
15731 ventries = Expression::make_unary(OPERATOR_AND, ctor_ref, loc);
15732 }
e440a328 15733
2c809f8f 15734 Map_type* mt = this->type_->map_type();
15735 if (this->element_type_ == NULL)
15736 this->element_type_ =
15737 Type::make_builtin_struct_type(2,
15738 "__key", mt->key_type(),
15739 "__val", mt->val_type());
0d5530d9 15740 Expression* descriptor = Expression::make_type_descriptor(mt, loc);
2c809f8f 15741
15742 Type* uintptr_t = Type::lookup_integer_type("uintptr");
e67508fa 15743 Expression* count = Expression::make_integer_ul(i, uintptr_t, loc);
2c809f8f 15744
15745 Expression* entry_size =
15746 Expression::make_type_info(this->element_type_, TYPE_INFO_SIZE);
15747
15748 unsigned int field_index;
15749 const Struct_field* valfield =
15750 this->element_type_->find_local_field("__val", &field_index);
15751 Expression* val_offset =
15752 Expression::make_struct_field_offset(this->element_type_, valfield);
2c809f8f 15753
15754 Expression* map_ctor =
0d5530d9 15755 Runtime::make_call(Runtime::CONSTRUCT_MAP, loc, 5, descriptor, count,
15756 entry_size, val_offset, ventries);
ea664253 15757 return map_ctor->get_backend(context);
2c809f8f 15758}
e440a328 15759
2c809f8f 15760// Export an array construction.
e440a328 15761
2c809f8f 15762void
548be246 15763Map_construction_expression::do_export(Export_function_body* efb) const
2c809f8f 15764{
204d4af4 15765 efb->write_c_string("$convert(");
548be246 15766 efb->write_type(this->type_);
2c809f8f 15767 for (Expression_list::const_iterator pv = this->vals_->begin();
15768 pv != this->vals_->end();
15769 ++pv)
15770 {
548be246 15771 efb->write_c_string(", ");
15772 (*pv)->export_expression(efb);
2c809f8f 15773 }
548be246 15774 efb->write_c_string(")");
2c809f8f 15775}
e440a328 15776
2c809f8f 15777// Dump ast representation for a map construction expression.
d751bb78 15778
15779void
15780Map_construction_expression::do_dump_expression(
15781 Ast_dump_context* ast_dump_context) const
15782{
d751bb78 15783 ast_dump_context->ostream() << "{" ;
8b1c301d 15784 ast_dump_context->dump_expression_list(this->vals_, true);
d751bb78 15785 ast_dump_context->ostream() << "}";
15786}
15787
7795ac51 15788// Class Composite_literal_expression.
e440a328 15789
15790// Traversal.
15791
15792int
15793Composite_literal_expression::do_traverse(Traverse* traverse)
15794{
dbffccfc 15795 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
e440a328 15796 return TRAVERSE_EXIT;
dbffccfc 15797
15798 // If this is a struct composite literal with keys, then the keys
15799 // are field names, not expressions. We don't want to traverse them
15800 // in that case. If we do, we can give an erroneous error "variable
15801 // initializer refers to itself." See bug482.go in the testsuite.
15802 if (this->has_keys_ && this->vals_ != NULL)
15803 {
15804 // The type may not be resolvable at this point.
15805 Type* type = this->type_;
a01f2481 15806
7795ac51 15807 for (int depth = 0; depth < this->depth_; ++depth)
a01f2481 15808 {
15809 if (type->array_type() != NULL)
15810 type = type->array_type()->element_type();
15811 else if (type->map_type() != NULL)
7795ac51 15812 {
15813 if (this->key_path_[depth])
15814 type = type->map_type()->key_type();
15815 else
15816 type = type->map_type()->val_type();
15817 }
a01f2481 15818 else
15819 {
15820 // This error will be reported during lowering.
15821 return TRAVERSE_CONTINUE;
15822 }
15823 }
15824
dbffccfc 15825 while (true)
15826 {
15827 if (type->classification() == Type::TYPE_NAMED)
15828 type = type->named_type()->real_type();
15829 else if (type->classification() == Type::TYPE_FORWARD)
15830 {
15831 Type* t = type->forwarded();
15832 if (t == type)
15833 break;
15834 type = t;
15835 }
15836 else
15837 break;
15838 }
15839
15840 if (type->classification() == Type::TYPE_STRUCT)
15841 {
15842 Expression_list::iterator p = this->vals_->begin();
15843 while (p != this->vals_->end())
15844 {
15845 // Skip key.
15846 ++p;
15847 go_assert(p != this->vals_->end());
15848 if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
15849 return TRAVERSE_EXIT;
15850 ++p;
15851 }
15852 return TRAVERSE_CONTINUE;
15853 }
15854 }
15855
15856 if (this->vals_ != NULL)
15857 return this->vals_->traverse(traverse);
15858
15859 return TRAVERSE_CONTINUE;
e440a328 15860}
15861
15862// Lower a generic composite literal into a specific version based on
15863// the type.
15864
15865Expression*
ceeb4318 15866Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
15867 Statement_inserter* inserter, int)
e440a328 15868{
15869 Type* type = this->type_;
15870
7795ac51 15871 for (int depth = 0; depth < this->depth_; ++depth)
e440a328 15872 {
67a2ed75 15873 type = type->deref();
e440a328 15874 if (type->array_type() != NULL)
15875 type = type->array_type()->element_type();
15876 else if (type->map_type() != NULL)
7795ac51 15877 {
15878 if (this->key_path_[depth])
15879 type = type->map_type()->key_type();
15880 else
15881 type = type->map_type()->val_type();
15882 }
e440a328 15883 else
15884 {
5c13bd80 15885 if (!type->is_error())
631d5788 15886 go_error_at(this->location(),
15887 ("may only omit types within composite literals "
15888 "of slice, array, or map type"));
e440a328 15889 return Expression::make_error(this->location());
15890 }
15891 }
15892
e00772b3 15893 Type *pt = type->points_to();
15894 bool is_pointer = false;
15895 if (pt != NULL)
15896 {
15897 is_pointer = true;
15898 type = pt;
15899 }
15900
15901 Expression* ret;
5c13bd80 15902 if (type->is_error())
e440a328 15903 return Expression::make_error(this->location());
15904 else if (type->struct_type() != NULL)
e00772b3 15905 ret = this->lower_struct(gogo, type);
e440a328 15906 else if (type->array_type() != NULL)
113ef6a5 15907 ret = this->lower_array(type);
e440a328 15908 else if (type->map_type() != NULL)
e00772b3 15909 ret = this->lower_map(gogo, function, inserter, type);
e440a328 15910 else
15911 {
631d5788 15912 go_error_at(this->location(),
15913 ("expected struct, slice, array, or map type "
15914 "for composite literal"));
e440a328 15915 return Expression::make_error(this->location());
15916 }
e00772b3 15917
15918 if (is_pointer)
2c809f8f 15919 ret = Expression::make_heap_expression(ret, this->location());
e00772b3 15920
15921 return ret;
e440a328 15922}
15923
15924// Lower a struct composite literal.
15925
15926Expression*
81c4b26b 15927Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
e440a328 15928{
b13c66cd 15929 Location location = this->location();
e440a328 15930 Struct_type* st = type->struct_type();
15931 if (this->vals_ == NULL || !this->has_keys_)
07daa4e7 15932 {
e6013c28 15933 if (this->vals_ != NULL
15934 && !this->vals_->empty()
15935 && type->named_type() != NULL
15936 && type->named_type()->named_object()->package() != NULL)
15937 {
15938 for (Struct_field_list::const_iterator pf = st->fields()->begin();
15939 pf != st->fields()->end();
15940 ++pf)
07daa4e7 15941 {
07ba7f26 15942 if (Gogo::is_hidden_name(pf->field_name())
15943 || pf->is_embedded_builtin(gogo))
631d5788 15944 go_error_at(this->location(),
15945 "assignment of unexported field %qs in %qs literal",
15946 Gogo::message_name(pf->field_name()).c_str(),
15947 type->named_type()->message_name().c_str());
07daa4e7 15948 }
15949 }
15950
15951 return new Struct_construction_expression(type, this->vals_, location);
15952 }
e440a328 15953
15954 size_t field_count = st->field_count();
15955 std::vector<Expression*> vals(field_count);
e32de7ba 15956 std::vector<unsigned long>* traverse_order = new(std::vector<unsigned long>);
e440a328 15957 Expression_list::const_iterator p = this->vals_->begin();
62750cd5 15958 Expression* external_expr = NULL;
15959 const Named_object* external_no = NULL;
e440a328 15960 while (p != this->vals_->end())
15961 {
15962 Expression* name_expr = *p;
15963
15964 ++p;
c484d925 15965 go_assert(p != this->vals_->end());
e440a328 15966 Expression* val = *p;
15967
15968 ++p;
15969
15970 if (name_expr == NULL)
15971 {
631d5788 15972 go_error_at(val->location(),
15973 "mixture of field and value initializers");
e440a328 15974 return Expression::make_error(location);
15975 }
15976
15977 bool bad_key = false;
15978 std::string name;
81c4b26b 15979 const Named_object* no = NULL;
e440a328 15980 switch (name_expr->classification())
15981 {
15982 case EXPRESSION_UNKNOWN_REFERENCE:
15983 name = name_expr->unknown_expression()->name();
7f7ce694 15984 if (type->named_type() != NULL)
15985 {
15986 // If the named object found for this field name comes from a
15987 // different package than the struct it is a part of, do not count
15988 // this incorrect lookup as a usage of the object's package.
15989 no = name_expr->unknown_expression()->named_object();
15990 if (no->package() != NULL
15991 && no->package() != type->named_type()->named_object()->package())
15992 no->package()->forget_usage(name_expr);
15993 }
e440a328 15994 break;
15995
15996 case EXPRESSION_CONST_REFERENCE:
81c4b26b 15997 no = static_cast<Const_expression*>(name_expr)->named_object();
e440a328 15998 break;
15999
16000 case EXPRESSION_TYPE:
16001 {
16002 Type* t = name_expr->type();
16003 Named_type* nt = t->named_type();
16004 if (nt == NULL)
16005 bad_key = true;
16006 else
81c4b26b 16007 no = nt->named_object();
e440a328 16008 }
16009 break;
16010
16011 case EXPRESSION_VAR_REFERENCE:
81c4b26b 16012 no = name_expr->var_expression()->named_object();
e440a328 16013 break;
16014
b0c09712 16015 case EXPRESSION_ENCLOSED_VAR_REFERENCE:
16016 no = name_expr->enclosed_var_expression()->variable();
e440a328 16017 break;
16018
b0c09712 16019 case EXPRESSION_FUNC_REFERENCE:
16020 no = name_expr->func_expression()->named_object();
e440a328 16021 break;
16022
16023 default:
16024 bad_key = true;
16025 break;
16026 }
16027 if (bad_key)
16028 {
631d5788 16029 go_error_at(name_expr->location(), "expected struct field name");
e440a328 16030 return Expression::make_error(location);
16031 }
16032
81c4b26b 16033 if (no != NULL)
16034 {
62750cd5 16035 if (no->package() != NULL && external_expr == NULL)
16036 {
16037 external_expr = name_expr;
16038 external_no = no;
16039 }
16040
81c4b26b 16041 name = no->name();
16042
16043 // A predefined name won't be packed. If it starts with a
16044 // lower case letter we need to check for that case, because
2d29d278 16045 // the field name will be packed. FIXME.
81c4b26b 16046 if (!Gogo::is_hidden_name(name)
16047 && name[0] >= 'a'
16048 && name[0] <= 'z')
16049 {
16050 Named_object* gno = gogo->lookup_global(name.c_str());
16051 if (gno == no)
16052 name = gogo->pack_hidden_name(name, false);
16053 }
16054 }
16055
e440a328 16056 unsigned int index;
16057 const Struct_field* sf = st->find_local_field(name, &index);
16058 if (sf == NULL)
16059 {
631d5788 16060 go_error_at(name_expr->location(), "unknown field %qs in %qs",
16061 Gogo::message_name(name).c_str(),
16062 (type->named_type() != NULL
16063 ? type->named_type()->message_name().c_str()
16064 : "unnamed struct"));
e440a328 16065 return Expression::make_error(location);
16066 }
16067 if (vals[index] != NULL)
16068 {
631d5788 16069 go_error_at(name_expr->location(),
16070 "duplicate value for field %qs in %qs",
16071 Gogo::message_name(name).c_str(),
16072 (type->named_type() != NULL
16073 ? type->named_type()->message_name().c_str()
16074 : "unnamed struct"));
e440a328 16075 return Expression::make_error(location);
16076 }
16077
07daa4e7 16078 if (type->named_type() != NULL
16079 && type->named_type()->named_object()->package() != NULL
07ba7f26 16080 && (Gogo::is_hidden_name(sf->field_name())
16081 || sf->is_embedded_builtin(gogo)))
631d5788 16082 go_error_at(name_expr->location(),
16083 "assignment of unexported field %qs in %qs literal",
16084 Gogo::message_name(sf->field_name()).c_str(),
16085 type->named_type()->message_name().c_str());
07daa4e7 16086
e440a328 16087 vals[index] = val;
e32de7ba 16088 traverse_order->push_back(static_cast<unsigned long>(index));
e440a328 16089 }
16090
62750cd5 16091 if (!this->all_are_names_)
16092 {
16093 // This is a weird case like bug462 in the testsuite.
16094 if (external_expr == NULL)
631d5788 16095 go_error_at(this->location(), "unknown field in %qs literal",
16096 (type->named_type() != NULL
16097 ? type->named_type()->message_name().c_str()
16098 : "unnamed struct"));
62750cd5 16099 else
631d5788 16100 go_error_at(external_expr->location(), "unknown field %qs in %qs",
16101 external_no->message_name().c_str(),
16102 (type->named_type() != NULL
16103 ? type->named_type()->message_name().c_str()
16104 : "unnamed struct"));
62750cd5 16105 return Expression::make_error(location);
16106 }
16107
e440a328 16108 Expression_list* list = new Expression_list;
16109 list->reserve(field_count);
16110 for (size_t i = 0; i < field_count; ++i)
16111 list->push_back(vals[i]);
16112
0c4f5a19 16113 Struct_construction_expression* ret =
16114 new Struct_construction_expression(type, list, location);
16115 ret->set_traverse_order(traverse_order);
16116 return ret;
e440a328 16117}
16118
e32de7ba 16119// Index/value/traversal-order triple.
00773463 16120
e32de7ba 16121struct IVT_triple {
16122 unsigned long index;
16123 unsigned long traversal_order;
16124 Expression* expr;
16125 IVT_triple(unsigned long i, unsigned long to, Expression *e)
16126 : index(i), traversal_order(to), expr(e) { }
16127 bool operator<(const IVT_triple& other) const
16128 { return this->index < other.index; }
00773463 16129};
16130
e440a328 16131// Lower an array composite literal.
16132
16133Expression*
113ef6a5 16134Composite_literal_expression::lower_array(Type* type)
e440a328 16135{
b13c66cd 16136 Location location = this->location();
e440a328 16137 if (this->vals_ == NULL || !this->has_keys_)
ffe743ca 16138 return this->make_array(type, NULL, this->vals_);
e440a328 16139
ffe743ca 16140 std::vector<unsigned long>* indexes = new std::vector<unsigned long>;
16141 indexes->reserve(this->vals_->size());
00773463 16142 bool indexes_out_of_order = false;
ffe743ca 16143 Expression_list* vals = new Expression_list();
16144 vals->reserve(this->vals_->size());
e440a328 16145 unsigned long index = 0;
16146 Expression_list::const_iterator p = this->vals_->begin();
16147 while (p != this->vals_->end())
16148 {
16149 Expression* index_expr = *p;
16150
16151 ++p;
c484d925 16152 go_assert(p != this->vals_->end());
e440a328 16153 Expression* val = *p;
16154
16155 ++p;
16156
ffe743ca 16157 if (index_expr == NULL)
16158 {
8f2ebee5 16159 if (std::find(indexes->begin(), indexes->end(), index)
16160 != indexes->end())
16161 {
16162 go_error_at(val->location(),
16163 "duplicate value for index %lu", index);
16164 return Expression::make_error(location);
16165 }
ffe743ca 16166 if (!indexes->empty())
16167 indexes->push_back(index);
16168 }
16169 else
e440a328 16170 {
ffe743ca 16171 if (indexes->empty() && !vals->empty())
16172 {
16173 for (size_t i = 0; i < vals->size(); ++i)
16174 indexes->push_back(i);
16175 }
16176
0c77715b 16177 Numeric_constant nc;
16178 if (!index_expr->numeric_constant_value(&nc))
e440a328 16179 {
631d5788 16180 go_error_at(index_expr->location(),
16181 "index expression is not integer constant");
e440a328 16182 return Expression::make_error(location);
16183 }
6f6d9955 16184
0c77715b 16185 switch (nc.to_unsigned_long(&index))
e440a328 16186 {
0c77715b 16187 case Numeric_constant::NC_UL_VALID:
16188 break;
16189 case Numeric_constant::NC_UL_NOTINT:
631d5788 16190 go_error_at(index_expr->location(),
16191 "index expression is not integer constant");
0c77715b 16192 return Expression::make_error(location);
16193 case Numeric_constant::NC_UL_NEGATIVE:
631d5788 16194 go_error_at(index_expr->location(),
16195 "index expression is negative");
e440a328 16196 return Expression::make_error(location);
0c77715b 16197 case Numeric_constant::NC_UL_BIG:
631d5788 16198 go_error_at(index_expr->location(), "index value overflow");
e440a328 16199 return Expression::make_error(location);
0c77715b 16200 default:
16201 go_unreachable();
e440a328 16202 }
6f6d9955 16203
16204 Named_type* ntype = Type::lookup_integer_type("int");
16205 Integer_type* inttype = ntype->integer_type();
0c77715b 16206 if (sizeof(index) <= static_cast<size_t>(inttype->bits() * 8)
16207 && index >> (inttype->bits() - 1) != 0)
6f6d9955 16208 {
631d5788 16209 go_error_at(index_expr->location(), "index value overflow");
6f6d9955 16210 return Expression::make_error(location);
16211 }
16212
ffe743ca 16213 if (std::find(indexes->begin(), indexes->end(), index)
16214 != indexes->end())
e440a328 16215 {
631d5788 16216 go_error_at(index_expr->location(),
16217 "duplicate value for index %lu",
16218 index);
e440a328 16219 return Expression::make_error(location);
16220 }
ffe743ca 16221
00773463 16222 if (!indexes->empty() && index < indexes->back())
16223 indexes_out_of_order = true;
16224
ffe743ca 16225 indexes->push_back(index);
e440a328 16226 }
16227
ffe743ca 16228 vals->push_back(val);
16229
e440a328 16230 ++index;
16231 }
16232
ffe743ca 16233 if (indexes->empty())
16234 {
16235 delete indexes;
16236 indexes = NULL;
16237 }
e440a328 16238
e32de7ba 16239 std::vector<unsigned long>* traverse_order = NULL;
00773463 16240 if (indexes_out_of_order)
16241 {
e32de7ba 16242 typedef std::vector<IVT_triple> V;
00773463 16243
16244 V v;
16245 v.reserve(indexes->size());
16246 std::vector<unsigned long>::const_iterator pi = indexes->begin();
e32de7ba 16247 unsigned long torder = 0;
00773463 16248 for (Expression_list::const_iterator pe = vals->begin();
16249 pe != vals->end();
e32de7ba 16250 ++pe, ++pi, ++torder)
16251 v.push_back(IVT_triple(*pi, torder, *pe));
00773463 16252
e32de7ba 16253 std::sort(v.begin(), v.end());
00773463 16254
16255 delete indexes;
16256 delete vals;
e32de7ba 16257
00773463 16258 indexes = new std::vector<unsigned long>();
16259 indexes->reserve(v.size());
16260 vals = new Expression_list();
16261 vals->reserve(v.size());
e32de7ba 16262 traverse_order = new std::vector<unsigned long>();
16263 traverse_order->reserve(v.size());
00773463 16264
16265 for (V::const_iterator p = v.begin(); p != v.end(); ++p)
16266 {
e32de7ba 16267 indexes->push_back(p->index);
16268 vals->push_back(p->expr);
16269 traverse_order->push_back(p->traversal_order);
00773463 16270 }
16271 }
16272
e32de7ba 16273 Expression* ret = this->make_array(type, indexes, vals);
16274 Array_construction_expression* ace = ret->array_literal();
16275 if (ace != NULL && traverse_order != NULL)
16276 ace->set_traverse_order(traverse_order);
16277 return ret;
e440a328 16278}
16279
16280// Actually build the array composite literal. This handles
16281// [...]{...}.
16282
16283Expression*
ffe743ca 16284Composite_literal_expression::make_array(
16285 Type* type,
16286 const std::vector<unsigned long>* indexes,
16287 Expression_list* vals)
e440a328 16288{
b13c66cd 16289 Location location = this->location();
e440a328 16290 Array_type* at = type->array_type();
ffe743ca 16291
e440a328 16292 if (at->length() != NULL && at->length()->is_nil_expression())
16293 {
ffe743ca 16294 size_t size;
16295 if (vals == NULL)
16296 size = 0;
00773463 16297 else if (indexes != NULL)
16298 size = indexes->back() + 1;
16299 else
ffe743ca 16300 {
16301 size = vals->size();
16302 Integer_type* it = Type::lookup_integer_type("int")->integer_type();
16303 if (sizeof(size) <= static_cast<size_t>(it->bits() * 8)
16304 && size >> (it->bits() - 1) != 0)
16305 {
631d5788 16306 go_error_at(location, "too many elements in composite literal");
ffe743ca 16307 return Expression::make_error(location);
16308 }
16309 }
ffe743ca 16310
e67508fa 16311 Expression* elen = Expression::make_integer_ul(size, NULL, location);
e440a328 16312 at = Type::make_array_type(at->element_type(), elen);
16313 type = at;
16314 }
ffe743ca 16315 else if (at->length() != NULL
16316 && !at->length()->is_error_expression()
16317 && this->vals_ != NULL)
16318 {
16319 Numeric_constant nc;
16320 unsigned long val;
16321 if (at->length()->numeric_constant_value(&nc)
16322 && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID)
16323 {
16324 if (indexes == NULL)
16325 {
16326 if (this->vals_->size() > val)
16327 {
631d5788 16328 go_error_at(location,
16329 "too many elements in composite literal");
ffe743ca 16330 return Expression::make_error(location);
16331 }
16332 }
16333 else
16334 {
00773463 16335 unsigned long max = indexes->back();
ffe743ca 16336 if (max >= val)
16337 {
631d5788 16338 go_error_at(location,
16339 ("some element keys in composite literal "
16340 "are out of range"));
ffe743ca 16341 return Expression::make_error(location);
16342 }
16343 }
16344 }
16345 }
16346
e440a328 16347 if (at->length() != NULL)
ffe743ca 16348 return new Fixed_array_construction_expression(type, indexes, vals,
16349 location);
e440a328 16350 else
2c809f8f 16351 return new Slice_construction_expression(type, indexes, vals, location);
e440a328 16352}
16353
16354// Lower a map composite literal.
16355
16356Expression*
a287720d 16357Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
ceeb4318 16358 Statement_inserter* inserter,
a287720d 16359 Type* type)
e440a328 16360{
b13c66cd 16361 Location location = this->location();
f03a9fbf 16362 Unordered_map(unsigned int, std::vector<Expression*>) st;
0ab32342 16363 Unordered_map(unsigned int, std::vector<Expression*>) nt;
e440a328 16364 if (this->vals_ != NULL)
16365 {
16366 if (!this->has_keys_)
16367 {
631d5788 16368 go_error_at(location, "map composite literal must have keys");
e440a328 16369 return Expression::make_error(location);
16370 }
16371
a287720d 16372 for (Expression_list::iterator p = this->vals_->begin();
e440a328 16373 p != this->vals_->end();
16374 p += 2)
16375 {
16376 if (*p == NULL)
16377 {
16378 ++p;
631d5788 16379 go_error_at((*p)->location(),
16380 ("map composite literal must "
16381 "have keys for every value"));
e440a328 16382 return Expression::make_error(location);
16383 }
a287720d 16384 // Make sure we have lowered the key; it may not have been
16385 // lowered in order to handle keys for struct composite
16386 // literals. Lower it now to get the right error message.
16387 if ((*p)->unknown_expression() != NULL)
16388 {
16389 (*p)->unknown_expression()->clear_is_composite_literal_key();
ceeb4318 16390 gogo->lower_expression(function, inserter, &*p);
c484d925 16391 go_assert((*p)->is_error_expression());
a287720d 16392 return Expression::make_error(location);
16393 }
f03a9fbf 16394 // Check if there are duplicate constant keys.
16395 if (!(*p)->is_constant())
16396 continue;
16397 std::string sval;
0ab32342 16398 Numeric_constant nval;
16399 if ((*p)->string_constant_value(&sval)) // Check string keys.
f03a9fbf 16400 {
16401 unsigned int h = Gogo::hash_string(sval, 0);
16402 // Search the index h in the hash map.
16403 Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
16404 mit = st.find(h);
16405 if (mit == st.end())
16406 {
16407 // No duplicate since h is a new index.
16408 // Create a new vector indexed by h and add it to the hash map.
16409 std::vector<Expression*> l;
16410 l.push_back(*p);
16411 std::pair<unsigned int, std::vector<Expression*> > val(h, l);
16412 st.insert(val);
16413 }
16414 else
16415 {
16416 // Do further check since index h already exists.
16417 for (std::vector<Expression*>::iterator lit =
16418 mit->second.begin();
16419 lit != mit->second.end();
16420 lit++)
16421 {
16422 std::string s;
16423 bool ok = (*lit)->string_constant_value(&s);
16424 go_assert(ok);
16425 if (s == sval)
16426 {
16427 go_error_at((*p)->location(), ("duplicate key "
16428 "in map literal"));
16429 return Expression::make_error(location);
16430 }
16431 }
16432 // Add this new string key to the vector indexed by h.
16433 mit->second.push_back(*p);
16434 }
16435 }
0ab32342 16436 else if ((*p)->numeric_constant_value(&nval)) // Check numeric keys.
16437 {
16438 unsigned int h = nval.hash(0);
16439 Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
16440 mit = nt.find(h);
16441 if (mit == nt.end())
16442 {
16443 // No duplicate since h is a new code.
16444 // Create a new vector indexed by h and add it to the hash map.
16445 std::vector<Expression*> l;
16446 l.push_back(*p);
16447 std::pair<unsigned int, std::vector<Expression*> > val(h, l);
16448 nt.insert(val);
16449 }
16450 else
16451 {
16452 // Do further check since h already exists.
16453 for (std::vector<Expression*>::iterator lit =
16454 mit->second.begin();
16455 lit != mit->second.end();
16456 lit++)
16457 {
16458 Numeric_constant rval;
16459 bool ok = (*lit)->numeric_constant_value(&rval);
16460 go_assert(ok);
16461 if (nval.equals(rval))
16462 {
16463 go_error_at((*p)->location(),
16464 "duplicate key in map literal");
16465 return Expression::make_error(location);
16466 }
16467 }
16468 // Add this new numeric key to the vector indexed by h.
16469 mit->second.push_back(*p);
16470 }
16471 }
e440a328 16472 }
16473 }
16474
16475 return new Map_construction_expression(type, this->vals_, location);
16476}
16477
de590a61 16478// Copy.
16479
16480Expression*
16481Composite_literal_expression::do_copy()
16482{
16483 Composite_literal_expression* ret =
16484 new Composite_literal_expression(this->type_->copy_expressions(),
16485 this->depth_, this->has_keys_,
16486 (this->vals_ == NULL
16487 ? NULL
16488 : this->vals_->copy()),
16489 this->all_are_names_,
16490 this->location());
16491 ret->key_path_ = this->key_path_;
16492 return ret;
16493}
16494
d751bb78 16495// Dump ast representation for a composite literal expression.
16496
16497void
16498Composite_literal_expression::do_dump_expression(
16499 Ast_dump_context* ast_dump_context) const
16500{
8b1c301d 16501 ast_dump_context->ostream() << "composite(";
d751bb78 16502 ast_dump_context->dump_type(this->type_);
16503 ast_dump_context->ostream() << ", {";
8b1c301d 16504 ast_dump_context->dump_expression_list(this->vals_, this->has_keys_);
d751bb78 16505 ast_dump_context->ostream() << "})";
16506}
16507
e440a328 16508// Make a composite literal expression.
16509
16510Expression*
16511Expression::make_composite_literal(Type* type, int depth, bool has_keys,
62750cd5 16512 Expression_list* vals, bool all_are_names,
b13c66cd 16513 Location location)
e440a328 16514{
16515 return new Composite_literal_expression(type, depth, has_keys, vals,
62750cd5 16516 all_are_names, location);
e440a328 16517}
16518
16519// Return whether this expression is a composite literal.
16520
16521bool
16522Expression::is_composite_literal() const
16523{
16524 switch (this->classification_)
16525 {
16526 case EXPRESSION_COMPOSITE_LITERAL:
16527 case EXPRESSION_STRUCT_CONSTRUCTION:
16528 case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
2c809f8f 16529 case EXPRESSION_SLICE_CONSTRUCTION:
e440a328 16530 case EXPRESSION_MAP_CONSTRUCTION:
16531 return true;
16532 default:
16533 return false;
16534 }
16535}
16536
16537// Return whether this expression is a composite literal which is not
16538// constant.
16539
16540bool
16541Expression::is_nonconstant_composite_literal() const
16542{
16543 switch (this->classification_)
16544 {
16545 case EXPRESSION_STRUCT_CONSTRUCTION:
16546 {
16547 const Struct_construction_expression *psce =
16548 static_cast<const Struct_construction_expression*>(this);
16549 return !psce->is_constant_struct();
16550 }
16551 case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
16552 {
16553 const Fixed_array_construction_expression *pace =
16554 static_cast<const Fixed_array_construction_expression*>(this);
16555 return !pace->is_constant_array();
16556 }
2c809f8f 16557 case EXPRESSION_SLICE_CONSTRUCTION:
e440a328 16558 {
2c809f8f 16559 const Slice_construction_expression *pace =
16560 static_cast<const Slice_construction_expression*>(this);
e440a328 16561 return !pace->is_constant_array();
16562 }
16563 case EXPRESSION_MAP_CONSTRUCTION:
16564 return true;
16565 default:
16566 return false;
16567 }
16568}
16569
35a54f17 16570// Return true if this is a variable or temporary_variable.
16571
16572bool
16573Expression::is_variable() const
16574{
16575 switch (this->classification_)
16576 {
16577 case EXPRESSION_VAR_REFERENCE:
16578 case EXPRESSION_TEMPORARY_REFERENCE:
16579 case EXPRESSION_SET_AND_USE_TEMPORARY:
b0c09712 16580 case EXPRESSION_ENCLOSED_VAR_REFERENCE:
35a54f17 16581 return true;
16582 default:
16583 return false;
16584 }
16585}
16586
e440a328 16587// Return true if this is a reference to a local variable.
16588
16589bool
16590Expression::is_local_variable() const
16591{
16592 const Var_expression* ve = this->var_expression();
16593 if (ve == NULL)
16594 return false;
16595 const Named_object* no = ve->named_object();
16596 return (no->is_result_variable()
16597 || (no->is_variable() && !no->var_value()->is_global()));
16598}
16599
16600// Class Type_guard_expression.
16601
16602// Traversal.
16603
16604int
16605Type_guard_expression::do_traverse(Traverse* traverse)
16606{
16607 if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
16608 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
16609 return TRAVERSE_EXIT;
16610 return TRAVERSE_CONTINUE;
16611}
16612
2c809f8f 16613Expression*
16614Type_guard_expression::do_flatten(Gogo*, Named_object*,
16615 Statement_inserter* inserter)
16616{
5bf8be8b 16617 if (this->expr_->is_error_expression()
16618 || this->expr_->type()->is_error_type())
16619 {
16620 go_assert(saw_errors());
16621 return Expression::make_error(this->location());
16622 }
16623
2c809f8f 16624 if (!this->expr_->is_variable())
16625 {
16626 Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_,
16627 this->location());
16628 inserter->insert(temp);
16629 this->expr_ =
16630 Expression::make_temporary_reference(temp, this->location());
16631 }
16632 return this;
16633}
16634
e440a328 16635// Check types of a type guard expression. The expression must have
16636// an interface type, but the actual type conversion is checked at run
16637// time.
16638
16639void
16640Type_guard_expression::do_check_types(Gogo*)
16641{
e440a328 16642 Type* expr_type = this->expr_->type();
7e9da23f 16643 if (expr_type->interface_type() == NULL)
f725ade8 16644 {
5c13bd80 16645 if (!expr_type->is_error() && !this->type_->is_error())
f725ade8 16646 this->report_error(_("type assertion only valid for interface types"));
16647 this->set_is_error();
16648 }
e440a328 16649 else if (this->type_->interface_type() == NULL)
16650 {
16651 std::string reason;
16652 if (!expr_type->interface_type()->implements_interface(this->type_,
16653 &reason))
16654 {
5c13bd80 16655 if (!this->type_->is_error())
e440a328 16656 {
f725ade8 16657 if (reason.empty())
16658 this->report_error(_("impossible type assertion: "
16659 "type does not implement interface"));
16660 else
631d5788 16661 go_error_at(this->location(),
16662 ("impossible type assertion: "
16663 "type does not implement interface (%s)"),
16664 reason.c_str());
e440a328 16665 }
f725ade8 16666 this->set_is_error();
e440a328 16667 }
16668 }
16669}
16670
de590a61 16671// Copy.
16672
16673Expression*
16674Type_guard_expression::do_copy()
16675{
16676 return new Type_guard_expression(this->expr_->copy(),
16677 this->type_->copy_expressions(),
16678 this->location());
16679}
16680
ea664253 16681// Return the backend representation for a type guard expression.
e440a328 16682
ea664253 16683Bexpression*
16684Type_guard_expression::do_get_backend(Translate_context* context)
e440a328 16685{
2c809f8f 16686 Expression* conversion;
7e9da23f 16687 if (this->type_->interface_type() != NULL)
2c809f8f 16688 conversion =
16689 Expression::convert_interface_to_interface(this->type_, this->expr_,
16690 true, this->location());
e440a328 16691 else
2c809f8f 16692 conversion =
16693 Expression::convert_for_assignment(context->gogo(), this->type_,
16694 this->expr_, this->location());
16695
21b70e8f 16696 Gogo* gogo = context->gogo();
16697 Btype* bt = this->type_->get_backend(gogo);
16698 Bexpression* bexpr = conversion->get_backend(context);
16699 return gogo->backend()->convert_expression(bt, bexpr, this->location());
e440a328 16700}
16701
d751bb78 16702// Dump ast representation for a type guard expression.
16703
16704void
2c809f8f 16705Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 16706 const
16707{
16708 this->expr_->dump_expression(ast_dump_context);
16709 ast_dump_context->ostream() << ".";
16710 ast_dump_context->dump_type(this->type_);
16711}
16712
e440a328 16713// Make a type guard expression.
16714
16715Expression*
16716Expression::make_type_guard(Expression* expr, Type* type,
b13c66cd 16717 Location location)
e440a328 16718{
16719 return new Type_guard_expression(expr, type, location);
16720}
16721
2c809f8f 16722// Class Heap_expression.
e440a328 16723
da244e59 16724// Return the type of the expression stored on the heap.
e440a328 16725
da244e59 16726Type*
16727Heap_expression::do_type()
16728{ return Type::make_pointer_type(this->expr_->type()); }
e440a328 16729
ea664253 16730// Return the backend representation for allocating an expression on the heap.
e440a328 16731
ea664253 16732Bexpression*
16733Heap_expression::do_get_backend(Translate_context* context)
e440a328 16734{
03118c21 16735 Type* etype = this->expr_->type();
16736 if (this->expr_->is_error_expression() || etype->is_error())
ea664253 16737 return context->backend()->error_expression();
2c809f8f 16738
02c19a1a 16739 Location loc = this->location();
2c809f8f 16740 Gogo* gogo = context->gogo();
02c19a1a 16741 Btype* btype = this->type()->get_backend(gogo);
45ff893b 16742
03118c21 16743 Expression* alloc = Expression::make_allocation(etype, loc);
5973ede0 16744 if (this->allocate_on_stack_)
45ff893b 16745 alloc->allocation_expression()->set_allocate_on_stack();
16746 Bexpression* space = alloc->get_backend(context);
02c19a1a 16747
16748 Bstatement* decl;
16749 Named_object* fn = context->function();
16750 go_assert(fn != NULL);
16751 Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
16752 Bvariable* space_temp =
16753 gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
16754 space, true, loc, &decl);
03118c21 16755 Btype* expr_btype = etype->get_backend(gogo);
02c19a1a 16756
ea664253 16757 Bexpression* bexpr = this->expr_->get_backend(context);
03118c21 16758
16759 // If this assignment needs a write barrier, call typedmemmove. We
16760 // don't do this in the write barrier pass because in some cases
16761 // backend conversion can introduce new Heap_expression values.
16762 Bstatement* assn;
06e83d10 16763 if (!etype->has_pointer() || this->allocate_on_stack_)
03118c21 16764 {
7af8e400 16765 space = gogo->backend()->var_expression(space_temp, loc);
03118c21 16766 Bexpression* ref =
16767 gogo->backend()->indirect_expression(expr_btype, space, true, loc);
16768 assn = gogo->backend()->assignment_statement(fndecl, ref, bexpr, loc);
16769 }
16770 else
16771 {
16772 Bstatement* edecl;
16773 Bvariable* btemp =
16774 gogo->backend()->temporary_variable(fndecl, context->bblock(),
16775 expr_btype, bexpr, true, loc,
16776 &edecl);
16777 Bexpression* btempref = gogo->backend()->var_expression(btemp,
7af8e400 16778 loc);
7af8e400 16779 space = gogo->backend()->var_expression(space_temp, loc);
d6eeba01 16780 Type* etype_ptr = Type::make_pointer_type(etype);
03118c21 16781 Expression* elhs = Expression::make_backend(space, etype_ptr, loc);
d6eeba01 16782 Expression* erhs;
16783 Expression* call;
16784 if (etype->is_direct_iface_type())
16785 {
16786 // Single pointer.
16787 Type* uintptr_type = Type::lookup_integer_type("uintptr");
16788 erhs = Expression::make_backend(btempref, etype, loc);
16789 erhs = Expression::unpack_direct_iface(erhs, loc);
16790 erhs = Expression::make_unsafe_cast(uintptr_type, erhs, loc);
16791 call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2,
16792 elhs, erhs);
16793 }
16794 else
16795 {
16796 Expression* td = Expression::make_type_descriptor(etype, loc);
16797 Bexpression* addr =
16798 gogo->backend()->address_expression(btempref, loc);
16799 erhs = Expression::make_backend(addr, etype_ptr, loc);
16800 call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
16801 td, elhs, erhs);
16802 }
16803 Statement* cs = Statement::make_statement(call, false);
16804
16805 space = gogo->backend()->var_expression(space_temp, loc);
16806 Bexpression* ref =
16807 gogo->backend()->indirect_expression(expr_btype, space, true, loc);
16808 Expression* eref = Expression::make_backend(ref, etype, loc);
16809 btempref = gogo->backend()->var_expression(btemp, loc);
16810 erhs = Expression::make_backend(btempref, etype, loc);
16811 Statement* as = Statement::make_assignment(eref, erhs, loc);
16812
16813 as = gogo->check_write_barrier(context->block(), as, cs);
16814 Bstatement* s = as->get_backend(context);
16815
03118c21 16816 assn = gogo->backend()->compound_statement(edecl, s);
16817 }
02c19a1a 16818 decl = gogo->backend()->compound_statement(decl, assn);
7af8e400 16819 space = gogo->backend()->var_expression(space_temp, loc);
ea664253 16820 return gogo->backend()->compound_expression(decl, space, loc);
e440a328 16821}
16822
2c809f8f 16823// Dump ast representation for a heap expression.
d751bb78 16824
16825void
2c809f8f 16826Heap_expression::do_dump_expression(
d751bb78 16827 Ast_dump_context* ast_dump_context) const
16828{
16829 ast_dump_context->ostream() << "&(";
16830 ast_dump_context->dump_expression(this->expr_);
16831 ast_dump_context->ostream() << ")";
16832}
16833
2c809f8f 16834// Allocate an expression on the heap.
e440a328 16835
16836Expression*
2c809f8f 16837Expression::make_heap_expression(Expression* expr, Location location)
e440a328 16838{
2c809f8f 16839 return new Heap_expression(expr, location);
e440a328 16840}
16841
16842// Class Receive_expression.
16843
16844// Return the type of a receive expression.
16845
16846Type*
16847Receive_expression::do_type()
16848{
e429e3bd 16849 if (this->is_error_expression())
16850 return Type::make_error_type();
e440a328 16851 Channel_type* channel_type = this->channel_->type()->channel_type();
16852 if (channel_type == NULL)
e429e3bd 16853 {
16854 this->report_error(_("expected channel"));
16855 return Type::make_error_type();
16856 }
e440a328 16857 return channel_type->element_type();
16858}
16859
16860// Check types for a receive expression.
16861
16862void
16863Receive_expression::do_check_types(Gogo*)
16864{
16865 Type* type = this->channel_->type();
5c13bd80 16866 if (type->is_error())
e440a328 16867 {
e429e3bd 16868 go_assert(saw_errors());
e440a328 16869 this->set_is_error();
16870 return;
16871 }
16872 if (type->channel_type() == NULL)
16873 {
16874 this->report_error(_("expected channel"));
16875 return;
16876 }
16877 if (!type->channel_type()->may_receive())
16878 {
16879 this->report_error(_("invalid receive on send-only channel"));
16880 return;
16881 }
16882}
16883
2c809f8f 16884// Flattening for receive expressions creates a temporary variable to store
16885// received data in for receives.
16886
16887Expression*
16888Receive_expression::do_flatten(Gogo*, Named_object*,
16889 Statement_inserter* inserter)
16890{
16891 Channel_type* channel_type = this->channel_->type()->channel_type();
16892 if (channel_type == NULL)
16893 {
16894 go_assert(saw_errors());
16895 return this;
16896 }
5bf8be8b 16897 else if (this->channel_->is_error_expression())
16898 {
16899 go_assert(saw_errors());
16900 return Expression::make_error(this->location());
16901 }
2c809f8f 16902
16903 Type* element_type = channel_type->element_type();
16904 if (this->temp_receiver_ == NULL)
16905 {
16906 this->temp_receiver_ = Statement::make_temporary(element_type, NULL,
16907 this->location());
16908 this->temp_receiver_->set_is_address_taken();
16909 inserter->insert(this->temp_receiver_);
16910 }
16911
16912 return this;
16913}
16914
ea664253 16915// Get the backend representation for a receive expression.
e440a328 16916
ea664253 16917Bexpression*
16918Receive_expression::do_get_backend(Translate_context* context)
e440a328 16919{
f24f10bb 16920 Location loc = this->location();
16921
e440a328 16922 Channel_type* channel_type = this->channel_->type()->channel_type();
5b8368f4 16923 if (channel_type == NULL)
16924 {
c484d925 16925 go_assert(this->channel_->type()->is_error());
ea664253 16926 return context->backend()->error_expression();
5b8368f4 16927 }
e440a328 16928
2c809f8f 16929 Expression* recv_ref =
16930 Expression::make_temporary_reference(this->temp_receiver_, loc);
16931 Expression* recv_addr =
16932 Expression::make_temporary_reference(this->temp_receiver_, loc);
16933 recv_addr = Expression::make_unary(OPERATOR_AND, recv_addr, loc);
e36a5ff5 16934 Expression* recv = Runtime::make_call(Runtime::CHANRECV1, loc, 2,
16935 this->channel_, recv_addr);
ea664253 16936 return Expression::make_compound(recv, recv_ref, loc)->get_backend(context);
e440a328 16937}
16938
0b2617a3 16939// Export a receive expression.
16940
16941void
16942Receive_expression::do_export(Export_function_body* efb) const
16943{
16944 efb->write_c_string("<-");
16945 this->channel_->export_expression(efb);
16946}
16947
d751bb78 16948// Dump ast representation for a receive expression.
16949
16950void
16951Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
16952{
16953 ast_dump_context->ostream() << " <- " ;
16954 ast_dump_context->dump_expression(channel_);
16955}
16956
0b2617a3 16957// Import a receive expression.
16958
16959Expression*
16960Receive_expression::do_import(Import_expression* imp, Location loc)
16961{
16962 imp->require_c_string("<-");
16963 Expression* expr = Expression::import_expression(imp, loc);
16964 return Expression::make_receive(expr, loc);
16965}
16966
e440a328 16967// Make a receive expression.
16968
16969Receive_expression*
b13c66cd 16970Expression::make_receive(Expression* channel, Location location)
e440a328 16971{
16972 return new Receive_expression(channel, location);
16973}
16974
e440a328 16975// An expression which evaluates to a pointer to the type descriptor
16976// of a type.
16977
16978class Type_descriptor_expression : public Expression
16979{
16980 public:
b13c66cd 16981 Type_descriptor_expression(Type* type, Location location)
e440a328 16982 : Expression(EXPRESSION_TYPE_DESCRIPTOR, location),
16983 type_(type)
16984 { }
16985
16986 protected:
4b686186 16987 int
16988 do_traverse(Traverse*);
16989
e440a328 16990 Type*
16991 do_type()
16992 { return Type::make_type_descriptor_ptr_type(); }
16993
f9ca30f9 16994 bool
3ae06f68 16995 do_is_static_initializer() const
f9ca30f9 16996 { return true; }
16997
e440a328 16998 void
16999 do_determine_type(const Type_context*)
17000 { }
17001
17002 Expression*
17003 do_copy()
17004 { return this; }
17005
ea664253 17006 Bexpression*
17007 do_get_backend(Translate_context* context)
a1d23b41 17008 {
ea664253 17009 return this->type_->type_descriptor_pointer(context->gogo(),
17010 this->location());
a1d23b41 17011 }
e440a328 17012
d751bb78 17013 void
17014 do_dump_expression(Ast_dump_context*) const;
17015
e440a328 17016 private:
17017 // The type for which this is the descriptor.
17018 Type* type_;
17019};
17020
4b686186 17021int
17022Type_descriptor_expression::do_traverse(Traverse* traverse)
17023{
17024 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
17025 return TRAVERSE_EXIT;
17026 return TRAVERSE_CONTINUE;
17027}
17028
d751bb78 17029// Dump ast representation for a type descriptor expression.
17030
17031void
17032Type_descriptor_expression::do_dump_expression(
17033 Ast_dump_context* ast_dump_context) const
17034{
17035 ast_dump_context->dump_type(this->type_);
17036}
17037
e440a328 17038// Make a type descriptor expression.
17039
17040Expression*
b13c66cd 17041Expression::make_type_descriptor(Type* type, Location location)
e440a328 17042{
17043 return new Type_descriptor_expression(type, location);
17044}
17045
aa5ae575 17046// An expression which evaluates to a pointer to the Garbage Collection symbol
17047// of a type.
17048
17049class GC_symbol_expression : public Expression
17050{
17051 public:
17052 GC_symbol_expression(Type* type)
17053 : Expression(EXPRESSION_GC_SYMBOL, Linemap::predeclared_location()),
17054 type_(type)
17055 {}
17056
17057 protected:
17058 Type*
17059 do_type()
03118c21 17060 { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
aa5ae575 17061
17062 bool
3ae06f68 17063 do_is_static_initializer() const
aa5ae575 17064 { return true; }
17065
17066 void
17067 do_determine_type(const Type_context*)
17068 { }
17069
17070 Expression*
17071 do_copy()
17072 { return this; }
17073
17074 Bexpression*
17075 do_get_backend(Translate_context* context)
17076 { return this->type_->gc_symbol_pointer(context->gogo()); }
17077
17078 void
17079 do_dump_expression(Ast_dump_context*) const;
17080
17081 private:
17082 // The type which this gc symbol describes.
17083 Type* type_;
17084};
17085
17086// Dump ast representation for a gc symbol expression.
17087
17088void
17089GC_symbol_expression::do_dump_expression(
17090 Ast_dump_context* ast_dump_context) const
17091{
17092 ast_dump_context->ostream() << "gcdata(";
17093 ast_dump_context->dump_type(this->type_);
17094 ast_dump_context->ostream() << ")";
17095}
17096
17097// Make a gc symbol expression.
17098
17099Expression*
17100Expression::make_gc_symbol(Type* type)
17101{
17102 return new GC_symbol_expression(type);
17103}
17104
03118c21 17105// An expression that evaluates to a pointer to a symbol holding the
17106// ptrmask data of a type.
17107
17108class Ptrmask_symbol_expression : public Expression
17109{
17110 public:
17111 Ptrmask_symbol_expression(Type* type)
17112 : Expression(EXPRESSION_PTRMASK_SYMBOL, Linemap::predeclared_location()),
17113 type_(type)
17114 {}
17115
17116 protected:
17117 Type*
17118 do_type()
17119 { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
17120
17121 bool
17122 do_is_static_initializer() const
17123 { return true; }
17124
17125 void
17126 do_determine_type(const Type_context*)
17127 { }
17128
17129 Expression*
17130 do_copy()
17131 { return this; }
17132
17133 Bexpression*
17134 do_get_backend(Translate_context*);
17135
17136 void
17137 do_dump_expression(Ast_dump_context*) const;
17138
17139 private:
17140 // The type that this ptrmask symbol describes.
17141 Type* type_;
17142};
17143
17144// Return the ptrmask variable.
17145
17146Bexpression*
17147Ptrmask_symbol_expression::do_get_backend(Translate_context* context)
17148{
17149 Gogo* gogo = context->gogo();
17150
17151 // If this type does not need a gcprog, then we can use the standard
17152 // GC symbol.
17153 int64_t ptrsize, ptrdata;
17154 if (!this->type_->needs_gcprog(gogo, &ptrsize, &ptrdata))
17155 return this->type_->gc_symbol_pointer(gogo);
17156
17157 // Otherwise we have to build a ptrmask variable, and return a
17158 // pointer to it.
17159
17160 Bvariable* bvar = this->type_->gc_ptrmask_var(gogo, ptrsize, ptrdata);
17161 Location bloc = Linemap::predeclared_location();
7af8e400 17162 Bexpression* bref = gogo->backend()->var_expression(bvar, bloc);
03118c21 17163 Bexpression* baddr = gogo->backend()->address_expression(bref, bloc);
17164
17165 Type* uint8_type = Type::lookup_integer_type("uint8");
17166 Type* pointer_uint8_type = Type::make_pointer_type(uint8_type);
17167 Btype* ubtype = pointer_uint8_type->get_backend(gogo);
17168 return gogo->backend()->convert_expression(ubtype, baddr, bloc);
17169}
17170
17171// Dump AST for a ptrmask symbol expression.
17172
17173void
17174Ptrmask_symbol_expression::do_dump_expression(
17175 Ast_dump_context* ast_dump_context) const
17176{
17177 ast_dump_context->ostream() << "ptrmask(";
17178 ast_dump_context->dump_type(this->type_);
17179 ast_dump_context->ostream() << ")";
17180}
17181
17182// Make a ptrmask symbol expression.
17183
17184Expression*
17185Expression::make_ptrmask_symbol(Type* type)
17186{
17187 return new Ptrmask_symbol_expression(type);
17188}
17189
e440a328 17190// An expression which evaluates to some characteristic of a type.
17191// This is only used to initialize fields of a type descriptor. Using
17192// a new expression class is slightly inefficient but gives us a good
17193// separation between the frontend and the middle-end with regard to
17194// how types are laid out.
17195
17196class Type_info_expression : public Expression
17197{
17198 public:
17199 Type_info_expression(Type* type, Type_info type_info)
b13c66cd 17200 : Expression(EXPRESSION_TYPE_INFO, Linemap::predeclared_location()),
e440a328 17201 type_(type), type_info_(type_info)
17202 { }
17203
17204 protected:
0e168074 17205 bool
3ae06f68 17206 do_is_static_initializer() const
0e168074 17207 { return true; }
17208
e440a328 17209 Type*
17210 do_type();
17211
17212 void
17213 do_determine_type(const Type_context*)
17214 { }
17215
17216 Expression*
17217 do_copy()
17218 { return this; }
17219
ea664253 17220 Bexpression*
17221 do_get_backend(Translate_context* context);
e440a328 17222
d751bb78 17223 void
17224 do_dump_expression(Ast_dump_context*) const;
17225
e440a328 17226 private:
17227 // The type for which we are getting information.
17228 Type* type_;
17229 // What information we want.
17230 Type_info type_info_;
17231};
17232
17233// The type is chosen to match what the type descriptor struct
17234// expects.
17235
17236Type*
17237Type_info_expression::do_type()
17238{
17239 switch (this->type_info_)
17240 {
17241 case TYPE_INFO_SIZE:
03118c21 17242 case TYPE_INFO_BACKEND_PTRDATA:
17243 case TYPE_INFO_DESCRIPTOR_PTRDATA:
e440a328 17244 return Type::lookup_integer_type("uintptr");
17245 case TYPE_INFO_ALIGNMENT:
17246 case TYPE_INFO_FIELD_ALIGNMENT:
17247 return Type::lookup_integer_type("uint8");
17248 default:
c3e6f413 17249 go_unreachable();
e440a328 17250 }
17251}
17252
ea664253 17253// Return the backend representation for type information.
e440a328 17254
ea664253 17255Bexpression*
17256Type_info_expression::do_get_backend(Translate_context* context)
e440a328 17257{
927a01eb 17258 Gogo* gogo = context->gogo();
2a305b85 17259 bool ok = true;
3f378015 17260 int64_t val;
927a01eb 17261 switch (this->type_info_)
e440a328 17262 {
927a01eb 17263 case TYPE_INFO_SIZE:
2a305b85 17264 ok = this->type_->backend_type_size(gogo, &val);
927a01eb 17265 break;
17266 case TYPE_INFO_ALIGNMENT:
2a305b85 17267 ok = this->type_->backend_type_align(gogo, &val);
927a01eb 17268 break;
17269 case TYPE_INFO_FIELD_ALIGNMENT:
2a305b85 17270 ok = this->type_->backend_type_field_align(gogo, &val);
927a01eb 17271 break;
03118c21 17272 case TYPE_INFO_BACKEND_PTRDATA:
17273 ok = this->type_->backend_type_ptrdata(gogo, &val);
17274 break;
17275 case TYPE_INFO_DESCRIPTOR_PTRDATA:
17276 ok = this->type_->descriptor_ptrdata(gogo, &val);
17277 break;
927a01eb 17278 default:
17279 go_unreachable();
e440a328 17280 }
2a305b85 17281 if (!ok)
17282 {
17283 go_assert(saw_errors());
17284 return gogo->backend()->error_expression();
17285 }
3f378015 17286 Expression* e = Expression::make_integer_int64(val, this->type(),
17287 this->location());
17288 return e->get_backend(context);
e440a328 17289}
17290
d751bb78 17291// Dump ast representation for a type info expression.
17292
17293void
17294Type_info_expression::do_dump_expression(
17295 Ast_dump_context* ast_dump_context) const
17296{
17297 ast_dump_context->ostream() << "typeinfo(";
17298 ast_dump_context->dump_type(this->type_);
17299 ast_dump_context->ostream() << ",";
f03a9fbf 17300 ast_dump_context->ostream() <<
17301 (this->type_info_ == TYPE_INFO_ALIGNMENT ? "alignment"
d751bb78 17302 : this->type_info_ == TYPE_INFO_FIELD_ALIGNMENT ? "field alignment"
03118c21 17303 : this->type_info_ == TYPE_INFO_SIZE ? "size"
17304 : this->type_info_ == TYPE_INFO_BACKEND_PTRDATA ? "backend_ptrdata"
17305 : this->type_info_ == TYPE_INFO_DESCRIPTOR_PTRDATA ? "descriptor_ptrdata"
d751bb78 17306 : "unknown");
17307 ast_dump_context->ostream() << ")";
17308}
17309
e440a328 17310// Make a type info expression.
17311
17312Expression*
17313Expression::make_type_info(Type* type, Type_info type_info)
17314{
17315 return new Type_info_expression(type, type_info);
17316}
17317
35a54f17 17318// An expression that evaluates to some characteristic of a slice.
17319// This is used when indexing, bound-checking, or nil checking a slice.
17320
17321class Slice_info_expression : public Expression
17322{
17323 public:
17324 Slice_info_expression(Expression* slice, Slice_info slice_info,
17325 Location location)
17326 : Expression(EXPRESSION_SLICE_INFO, location),
17327 slice_(slice), slice_info_(slice_info)
17328 { }
17329
17330 protected:
17331 Type*
17332 do_type();
17333
17334 void
17335 do_determine_type(const Type_context*)
17336 { }
17337
17338 Expression*
17339 do_copy()
17340 {
17341 return new Slice_info_expression(this->slice_->copy(), this->slice_info_,
17342 this->location());
17343 }
17344
ea664253 17345 Bexpression*
17346 do_get_backend(Translate_context* context);
35a54f17 17347
17348 void
17349 do_dump_expression(Ast_dump_context*) const;
17350
17351 void
17352 do_issue_nil_check()
17353 { this->slice_->issue_nil_check(); }
17354
17355 private:
17356 // The slice for which we are getting information.
17357 Expression* slice_;
17358 // What information we want.
17359 Slice_info slice_info_;
17360};
17361
17362// Return the type of the slice info.
17363
17364Type*
17365Slice_info_expression::do_type()
17366{
17367 switch (this->slice_info_)
17368 {
17369 case SLICE_INFO_VALUE_POINTER:
17370 return Type::make_pointer_type(
17371 this->slice_->type()->array_type()->element_type());
17372 case SLICE_INFO_LENGTH:
17373 case SLICE_INFO_CAPACITY:
17374 return Type::lookup_integer_type("int");
17375 default:
17376 go_unreachable();
17377 }
17378}
17379
ea664253 17380// Return the backend information for slice information.
35a54f17 17381
ea664253 17382Bexpression*
17383Slice_info_expression::do_get_backend(Translate_context* context)
35a54f17 17384{
17385 Gogo* gogo = context->gogo();
ea664253 17386 Bexpression* bslice = this->slice_->get_backend(context);
35a54f17 17387 switch (this->slice_info_)
17388 {
17389 case SLICE_INFO_VALUE_POINTER:
17390 case SLICE_INFO_LENGTH:
17391 case SLICE_INFO_CAPACITY:
ea664253 17392 return gogo->backend()->struct_field_expression(bslice, this->slice_info_,
17393 this->location());
35a54f17 17394 break;
17395 default:
17396 go_unreachable();
17397 }
35a54f17 17398}
17399
17400// Dump ast representation for a type info expression.
17401
17402void
17403Slice_info_expression::do_dump_expression(
17404 Ast_dump_context* ast_dump_context) const
17405{
17406 ast_dump_context->ostream() << "sliceinfo(";
17407 this->slice_->dump_expression(ast_dump_context);
17408 ast_dump_context->ostream() << ",";
f03a9fbf 17409 ast_dump_context->ostream() <<
17410 (this->slice_info_ == SLICE_INFO_VALUE_POINTER ? "values"
35a54f17 17411 : this->slice_info_ == SLICE_INFO_LENGTH ? "length"
17412 : this->slice_info_ == SLICE_INFO_CAPACITY ? "capacity "
17413 : "unknown");
17414 ast_dump_context->ostream() << ")";
17415}
17416
17417// Make a slice info expression.
17418
17419Expression*
17420Expression::make_slice_info(Expression* slice, Slice_info slice_info,
17421 Location location)
17422{
17423 return new Slice_info_expression(slice, slice_info, location);
17424}
17425
d633d0fb 17426// Class Slice_value_expression.
2c809f8f 17427
17428int
17429Slice_value_expression::do_traverse(Traverse* traverse)
17430{
55e8ba6a 17431 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT
d633d0fb 17432 || Expression::traverse(&this->valmem_, traverse) == TRAVERSE_EXIT
2c809f8f 17433 || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT
17434 || Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
17435 return TRAVERSE_EXIT;
17436 return TRAVERSE_CONTINUE;
17437}
17438
d633d0fb 17439Expression*
17440Slice_value_expression::do_copy()
17441{
17442 return new Slice_value_expression(this->type_->copy_expressions(),
17443 this->valmem_->copy(),
17444 this->len_->copy(), this->cap_->copy(),
17445 this->location());
17446}
17447
ea664253 17448Bexpression*
17449Slice_value_expression::do_get_backend(Translate_context* context)
2c809f8f 17450{
17451 std::vector<Bexpression*> vals(3);
d633d0fb 17452 vals[0] = this->valmem_->get_backend(context);
ea664253 17453 vals[1] = this->len_->get_backend(context);
17454 vals[2] = this->cap_->get_backend(context);
2c809f8f 17455
17456 Gogo* gogo = context->gogo();
17457 Btype* btype = this->type_->get_backend(gogo);
ea664253 17458 return gogo->backend()->constructor_expression(btype, vals, this->location());
2c809f8f 17459}
17460
17461void
17462Slice_value_expression::do_dump_expression(
17463 Ast_dump_context* ast_dump_context) const
17464{
17465 ast_dump_context->ostream() << "slicevalue(";
17466 ast_dump_context->ostream() << "values: ";
d633d0fb 17467 this->valmem_->dump_expression(ast_dump_context);
2c809f8f 17468 ast_dump_context->ostream() << ", length: ";
17469 this->len_->dump_expression(ast_dump_context);
17470 ast_dump_context->ostream() << ", capacity: ";
17471 this->cap_->dump_expression(ast_dump_context);
17472 ast_dump_context->ostream() << ")";
17473}
17474
17475Expression*
d633d0fb 17476Expression::make_slice_value(Type* at, Expression* valmem, Expression* len,
2c809f8f 17477 Expression* cap, Location location)
17478{
17479 go_assert(at->is_slice_type());
d633d0fb 17480 go_assert(valmem->is_nil_expression()
17481 || (at->array_type()->element_type()
17482 == valmem->type()->points_to()));
17483 return new Slice_value_expression(at, valmem, len, cap, location);
2c809f8f 17484}
2387f644 17485
38ba9eec 17486// Look through the expression of a Slice_value_expression's valmem to
17487// find an call to makeslice. If found, return the call expression and
17488// the containing temporary statement (if any).
17489
17490std::pair<Call_expression*, Temporary_statement*>
17491Expression::find_makeslice_call(Expression* expr)
17492{
17493 Unsafe_type_conversion_expression* utce =
17494 expr->unsafe_conversion_expression();
17495 if (utce != NULL)
17496 expr = utce->expr();
17497
17498 Slice_value_expression* sve = expr->slice_value_expression();
17499 if (sve == NULL)
17500 return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
17501 expr = sve->valmem();
17502
17503 utce = expr->unsafe_conversion_expression();
17504 if (utce != NULL)
17505 expr = utce->expr();
17506
17507 Temporary_reference_expression* tre = expr->temporary_reference_expression();
17508 Temporary_statement* ts = (tre != NULL ? tre->statement() : NULL);
17509 if (ts != NULL && ts->init() != NULL && !ts->assigned()
17510 && !ts->is_address_taken())
17511 expr = ts->init();
17512
17513 Call_expression* call = expr->call_expression();
17514 if (call == NULL)
17515 return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
17516
17517 Func_expression* fe = call->fn()->func_expression();
17518 if (fe != NULL
17519 && fe->runtime_code() == Runtime::MAKESLICE)
17520 return std::make_pair(call, ts);
17521
17522 return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
17523}
17524
2387f644 17525// An expression that evaluates to some characteristic of a non-empty interface.
17526// This is used to access the method table or underlying object of an interface.
17527
17528class Interface_info_expression : public Expression
17529{
17530 public:
17531 Interface_info_expression(Expression* iface, Interface_info iface_info,
2c809f8f 17532 Location location)
2387f644 17533 : Expression(EXPRESSION_INTERFACE_INFO, location),
17534 iface_(iface), iface_info_(iface_info)
17535 { }
17536
17537 protected:
17538 Type*
17539 do_type();
17540
17541 void
17542 do_determine_type(const Type_context*)
17543 { }
17544
17545 Expression*
17546 do_copy()
17547 {
17548 return new Interface_info_expression(this->iface_->copy(),
17549 this->iface_info_, this->location());
17550 }
17551
ea664253 17552 Bexpression*
17553 do_get_backend(Translate_context* context);
2387f644 17554
17555 void
17556 do_dump_expression(Ast_dump_context*) const;
17557
17558 void
17559 do_issue_nil_check()
17560 { this->iface_->issue_nil_check(); }
17561
17562 private:
17563 // The interface for which we are getting information.
17564 Expression* iface_;
17565 // What information we want.
17566 Interface_info iface_info_;
17567};
17568
17569// Return the type of the interface info.
17570
17571Type*
17572Interface_info_expression::do_type()
17573{
17574 switch (this->iface_info_)
17575 {
17576 case INTERFACE_INFO_METHODS:
17577 {
625d3118 17578 typedef Unordered_map(Interface_type*, Type*) Hashtable;
17579 static Hashtable result_types;
17580
17581 Interface_type* itype = this->iface_->type()->interface_type();
17582
17583 Hashtable::const_iterator p = result_types.find(itype);
17584 if (p != result_types.end())
17585 return p->second;
17586
2c809f8f 17587 Type* pdt = Type::make_type_descriptor_ptr_type();
625d3118 17588 if (itype->is_empty())
17589 {
17590 result_types[itype] = pdt;
17591 return pdt;
17592 }
2c809f8f 17593
2387f644 17594 Location loc = this->location();
17595 Struct_field_list* sfl = new Struct_field_list();
2387f644 17596 sfl->push_back(
17597 Struct_field(Typed_identifier("__type_descriptor", pdt, loc)));
17598
2387f644 17599 for (Typed_identifier_list::const_iterator p = itype->methods()->begin();
17600 p != itype->methods()->end();
17601 ++p)
17602 {
17603 Function_type* ft = p->type()->function_type();
17604 go_assert(ft->receiver() == NULL);
17605
17606 const Typed_identifier_list* params = ft->parameters();
17607 Typed_identifier_list* mparams = new Typed_identifier_list();
17608 if (params != NULL)
17609 mparams->reserve(params->size() + 1);
17610 Type* vt = Type::make_pointer_type(Type::make_void_type());
17611 mparams->push_back(Typed_identifier("", vt, ft->location()));
17612 if (params != NULL)
17613 {
17614 for (Typed_identifier_list::const_iterator pp = params->begin();
17615 pp != params->end();
17616 ++pp)
17617 mparams->push_back(*pp);
17618 }
17619
17620 Typed_identifier_list* mresults = (ft->results() == NULL
17621 ? NULL
17622 : ft->results()->copy());
17623 Backend_function_type* mft =
17624 Type::make_backend_function_type(NULL, mparams, mresults,
17625 ft->location());
17626
17627 std::string fname = Gogo::unpack_hidden_name(p->name());
17628 sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc)));
17629 }
17630
6bf4793c 17631 Struct_type* st = Type::make_struct_type(sfl, loc);
17632 st->set_is_struct_incomparable();
17633 Pointer_type *pt = Type::make_pointer_type(st);
625d3118 17634 result_types[itype] = pt;
17635 return pt;
2387f644 17636 }
17637 case INTERFACE_INFO_OBJECT:
17638 return Type::make_pointer_type(Type::make_void_type());
17639 default:
17640 go_unreachable();
17641 }
17642}
17643
ea664253 17644// Return the backend representation for interface information.
2387f644 17645
ea664253 17646Bexpression*
17647Interface_info_expression::do_get_backend(Translate_context* context)
2387f644 17648{
17649 Gogo* gogo = context->gogo();
ea664253 17650 Bexpression* biface = this->iface_->get_backend(context);
2387f644 17651 switch (this->iface_info_)
17652 {
17653 case INTERFACE_INFO_METHODS:
17654 case INTERFACE_INFO_OBJECT:
ea664253 17655 return gogo->backend()->struct_field_expression(biface, this->iface_info_,
17656 this->location());
2387f644 17657 break;
17658 default:
17659 go_unreachable();
17660 }
2387f644 17661}
17662
17663// Dump ast representation for an interface info expression.
17664
17665void
17666Interface_info_expression::do_dump_expression(
17667 Ast_dump_context* ast_dump_context) const
17668{
2c809f8f 17669 bool is_empty = this->iface_->type()->interface_type()->is_empty();
2387f644 17670 ast_dump_context->ostream() << "interfaceinfo(";
17671 this->iface_->dump_expression(ast_dump_context);
17672 ast_dump_context->ostream() << ",";
17673 ast_dump_context->ostream() <<
2c809f8f 17674 (this->iface_info_ == INTERFACE_INFO_METHODS && !is_empty ? "methods"
17675 : this->iface_info_ == INTERFACE_INFO_TYPE_DESCRIPTOR ? "type_descriptor"
2387f644 17676 : this->iface_info_ == INTERFACE_INFO_OBJECT ? "object"
17677 : "unknown");
17678 ast_dump_context->ostream() << ")";
17679}
17680
17681// Make an interface info expression.
17682
17683Expression*
17684Expression::make_interface_info(Expression* iface, Interface_info iface_info,
17685 Location location)
17686{
17687 return new Interface_info_expression(iface, iface_info, location);
17688}
17689
2c809f8f 17690// An expression that represents an interface value. The first field is either
17691// a type descriptor for an empty interface or a pointer to the interface method
17692// table for a non-empty interface. The second field is always the object.
17693
17694class Interface_value_expression : public Expression
17695{
17696 public:
17697 Interface_value_expression(Type* type, Expression* first_field,
17698 Expression* obj, Location location)
17699 : Expression(EXPRESSION_INTERFACE_VALUE, location),
17700 type_(type), first_field_(first_field), obj_(obj)
17701 { }
17702
17703 protected:
17704 int
17705 do_traverse(Traverse*);
17706
17707 Type*
17708 do_type()
17709 { return this->type_; }
17710
17711 void
17712 do_determine_type(const Type_context*)
17713 { go_unreachable(); }
17714
17715 Expression*
17716 do_copy()
17717 {
de590a61 17718 return new Interface_value_expression(this->type_->copy_expressions(),
2c809f8f 17719 this->first_field_->copy(),
17720 this->obj_->copy(), this->location());
17721 }
17722
ea664253 17723 Bexpression*
17724 do_get_backend(Translate_context* context);
2c809f8f 17725
17726 void
17727 do_dump_expression(Ast_dump_context*) const;
17728
17729 private:
17730 // The type of the interface value.
17731 Type* type_;
17732 // The first field of the interface (either a type descriptor or a pointer
17733 // to the method table.
17734 Expression* first_field_;
17735 // The underlying object of the interface.
17736 Expression* obj_;
17737};
17738
17739int
17740Interface_value_expression::do_traverse(Traverse* traverse)
17741{
17742 if (Expression::traverse(&this->first_field_, traverse) == TRAVERSE_EXIT
17743 || Expression::traverse(&this->obj_, traverse) == TRAVERSE_EXIT)
17744 return TRAVERSE_EXIT;
17745 return TRAVERSE_CONTINUE;
17746}
17747
ea664253 17748Bexpression*
17749Interface_value_expression::do_get_backend(Translate_context* context)
2c809f8f 17750{
17751 std::vector<Bexpression*> vals(2);
ea664253 17752 vals[0] = this->first_field_->get_backend(context);
17753 vals[1] = this->obj_->get_backend(context);
2c809f8f 17754
17755 Gogo* gogo = context->gogo();
17756 Btype* btype = this->type_->get_backend(gogo);
ea664253 17757 return gogo->backend()->constructor_expression(btype, vals, this->location());
2c809f8f 17758}
17759
17760void
17761Interface_value_expression::do_dump_expression(
17762 Ast_dump_context* ast_dump_context) const
17763{
17764 ast_dump_context->ostream() << "interfacevalue(";
17765 ast_dump_context->ostream() <<
17766 (this->type_->interface_type()->is_empty()
17767 ? "type_descriptor: "
17768 : "methods: ");
17769 this->first_field_->dump_expression(ast_dump_context);
17770 ast_dump_context->ostream() << ", object: ";
17771 this->obj_->dump_expression(ast_dump_context);
17772 ast_dump_context->ostream() << ")";
17773}
17774
17775Expression*
17776Expression::make_interface_value(Type* type, Expression* first_value,
17777 Expression* object, Location location)
17778{
17779 return new Interface_value_expression(type, first_value, object, location);
17780}
17781
17782// An interface method table for a pair of types: an interface type and a type
17783// that implements that interface.
17784
17785class Interface_mtable_expression : public Expression
17786{
17787 public:
17788 Interface_mtable_expression(Interface_type* itype, Type* type,
17789 bool is_pointer, Location location)
17790 : Expression(EXPRESSION_INTERFACE_MTABLE, location),
17791 itype_(itype), type_(type), is_pointer_(is_pointer),
17792 method_table_type_(NULL), bvar_(NULL)
17793 { }
17794
17795 protected:
17796 int
17797 do_traverse(Traverse*);
17798
17799 Type*
17800 do_type();
17801
17802 bool
3ae06f68 17803 do_is_static_initializer() const
2c809f8f 17804 { return true; }
17805
17806 void
17807 do_determine_type(const Type_context*)
17808 { go_unreachable(); }
17809
17810 Expression*
17811 do_copy()
17812 {
de590a61 17813 Interface_type* itype = this->itype_->copy_expressions()->interface_type();
17814 return new Interface_mtable_expression(itype,
17815 this->type_->copy_expressions(),
2c809f8f 17816 this->is_pointer_, this->location());
17817 }
17818
17819 bool
17820 do_is_addressable() const
17821 { return true; }
17822
ea664253 17823 Bexpression*
17824 do_get_backend(Translate_context* context);
2c809f8f 17825
17826 void
17827 do_dump_expression(Ast_dump_context*) const;
17828
17829 private:
17830 // The interface type for which the methods are defined.
17831 Interface_type* itype_;
17832 // The type to construct the interface method table for.
17833 Type* type_;
17834 // Whether this table contains the method set for the receiver type or the
17835 // pointer receiver type.
17836 bool is_pointer_;
17837 // The type of the method table.
17838 Type* method_table_type_;
17839 // The backend variable that refers to the interface method table.
17840 Bvariable* bvar_;
17841};
17842
17843int
17844Interface_mtable_expression::do_traverse(Traverse* traverse)
17845{
17846 if (Type::traverse(this->itype_, traverse) == TRAVERSE_EXIT
17847 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
17848 return TRAVERSE_EXIT;
17849 return TRAVERSE_CONTINUE;
17850}
17851
17852Type*
17853Interface_mtable_expression::do_type()
17854{
17855 if (this->method_table_type_ != NULL)
17856 return this->method_table_type_;
17857
17858 const Typed_identifier_list* interface_methods = this->itype_->methods();
17859 go_assert(!interface_methods->empty());
17860
17861 Struct_field_list* sfl = new Struct_field_list;
17862 Typed_identifier tid("__type_descriptor", Type::make_type_descriptor_ptr_type(),
17863 this->location());
17864 sfl->push_back(Struct_field(tid));
db122cb9 17865 Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
2c809f8f 17866 for (Typed_identifier_list::const_iterator p = interface_methods->begin();
17867 p != interface_methods->end();
17868 ++p)
db122cb9 17869 {
17870 // We want C function pointers here, not func descriptors; model
17871 // using void* pointers.
17872 Typed_identifier method(p->name(), unsafe_ptr_type, p->location());
17873 sfl->push_back(Struct_field(method));
17874 }
6bf4793c 17875 Struct_type* st = Type::make_struct_type(sfl, this->location());
17876 st->set_is_struct_incomparable();
17877 this->method_table_type_ = st;
2c809f8f 17878 return this->method_table_type_;
17879}
17880
ea664253 17881Bexpression*
17882Interface_mtable_expression::do_get_backend(Translate_context* context)
2c809f8f 17883{
17884 Gogo* gogo = context->gogo();
2c809f8f 17885 Location loc = Linemap::predeclared_location();
17886 if (this->bvar_ != NULL)
7af8e400 17887 return gogo->backend()->var_expression(this->bvar_, this->location());
2c809f8f 17888
17889 const Typed_identifier_list* interface_methods = this->itype_->methods();
17890 go_assert(!interface_methods->empty());
17891
19272321 17892 std::string mangled_name =
17893 gogo->interface_method_table_name(this->itype_, this->type_,
17894 this->is_pointer_);
2c809f8f 17895
1530c754 17896 // Set is_public if we are converting a named type to an interface
17897 // type that is defined in the same package as the named type, and
17898 // the interface has hidden methods. In that case the interface
17899 // method table will be defined by the package that defines the
17900 // types.
17901 bool is_public = false;
17902 if (this->type_->named_type() != NULL
17903 && (this->type_->named_type()->named_object()->package()
17904 == this->itype_->package()))
17905 {
17906 for (Typed_identifier_list::const_iterator p = interface_methods->begin();
17907 p != interface_methods->end();
17908 ++p)
2c809f8f 17909 {
1530c754 17910 if (Gogo::is_hidden_name(p->name()))
17911 {
17912 is_public = true;
17913 break;
17914 }
2c809f8f 17915 }
17916 }
17917
1530c754 17918 if (is_public
2c809f8f 17919 && this->type_->named_type()->named_object()->package() != NULL)
17920 {
1530c754 17921 // The interface conversion table is defined elsewhere.
2c809f8f 17922 Btype* btype = this->type()->get_backend(gogo);
438b4bec 17923 std::string asm_name(go_selectively_encode_id(mangled_name));
2c809f8f 17924 this->bvar_ =
438b4bec 17925 gogo->backend()->immutable_struct_reference(mangled_name, asm_name,
17926 btype, loc);
7af8e400 17927 return gogo->backend()->var_expression(this->bvar_, this->location());
2c809f8f 17928 }
17929
17930 // The first element is the type descriptor.
17931 Type* td_type;
17932 if (!this->is_pointer_)
17933 td_type = this->type_;
17934 else
17935 td_type = Type::make_pointer_type(this->type_);
17936
db122cb9 17937 std::vector<Backend::Btyped_identifier> bstructfields;
17938
2c809f8f 17939 // Build an interface method table for a type: a type descriptor followed by a
17940 // list of function pointers, one for each interface method. This is used for
17941 // interfaces.
17942 Expression_list* svals = new Expression_list();
db122cb9 17943 Expression* tdescriptor = Expression::make_type_descriptor(td_type, loc);
17944 svals->push_back(tdescriptor);
17945
17946 Btype* tdesc_btype = tdescriptor->type()->get_backend(gogo);
17947 Backend::Btyped_identifier btd("_type", tdesc_btype, loc);
17948 bstructfields.push_back(btd);
2c809f8f 17949
17950 Named_type* nt = this->type_->named_type();
17951 Struct_type* st = this->type_->struct_type();
17952 go_assert(nt != NULL || st != NULL);
17953
17954 for (Typed_identifier_list::const_iterator p = interface_methods->begin();
17955 p != interface_methods->end();
17956 ++p)
17957 {
17958 bool is_ambiguous;
17959 Method* m;
17960 if (nt != NULL)
17961 m = nt->method_function(p->name(), &is_ambiguous);
17962 else
17963 m = st->method_function(p->name(), &is_ambiguous);
17964 go_assert(m != NULL);
5b665222 17965 Named_object* no =
17966 (this->is_pointer_
17967 && this->type_->is_direct_iface_type()
17968 && m->is_value_method()
17969 ? m->iface_stub_object()
17970 : m->named_object());
2c809f8f 17971
17972 go_assert(no->is_function() || no->is_function_declaration());
db122cb9 17973
5b665222 17974 Function_type* fcn_type = (no->is_function()
17975 ? no->func_value()->type()
17976 : no->func_declaration_value()->type());
17977 Btype* fcn_btype = fcn_type->get_backend_fntype(gogo);
db122cb9 17978 Backend::Btyped_identifier bmtype(p->name(), fcn_btype, loc);
17979 bstructfields.push_back(bmtype);
17980
2c809f8f 17981 svals->push_back(Expression::make_func_code_reference(no, loc));
17982 }
17983
db122cb9 17984 Btype *btype = gogo->backend()->struct_type(bstructfields);
17985 std::vector<Bexpression*> ctor_bexprs;
17986 for (Expression_list::const_iterator pe = svals->begin();
17987 pe != svals->end();
17988 ++pe)
17989 {
17990 ctor_bexprs.push_back((*pe)->get_backend(context));
17991 }
17992 Bexpression* ctor =
17993 gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
2c809f8f 17994
438b4bec 17995 std::string asm_name(go_selectively_encode_id(mangled_name));
17996 this->bvar_ = gogo->backend()->immutable_struct(mangled_name, asm_name, false,
2c809f8f 17997 !is_public, btype, loc);
17998 gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false,
17999 !is_public, btype, loc, ctor);
7af8e400 18000 return gogo->backend()->var_expression(this->bvar_, loc);
2c809f8f 18001}
18002
18003void
18004Interface_mtable_expression::do_dump_expression(
18005 Ast_dump_context* ast_dump_context) const
18006{
18007 ast_dump_context->ostream() << "__go_"
18008 << (this->is_pointer_ ? "pimt__" : "imt_");
18009 ast_dump_context->dump_type(this->itype_);
18010 ast_dump_context->ostream() << "__";
18011 ast_dump_context->dump_type(this->type_);
18012}
18013
18014Expression*
18015Expression::make_interface_mtable_ref(Interface_type* itype, Type* type,
18016 bool is_pointer, Location location)
18017{
18018 return new Interface_mtable_expression(itype, type, is_pointer, location);
18019}
18020
e440a328 18021// An expression which evaluates to the offset of a field within a
18022// struct. This, like Type_info_expression, q.v., is only used to
18023// initialize fields of a type descriptor.
18024
18025class Struct_field_offset_expression : public Expression
18026{
18027 public:
18028 Struct_field_offset_expression(Struct_type* type, const Struct_field* field)
b13c66cd 18029 : Expression(EXPRESSION_STRUCT_FIELD_OFFSET,
18030 Linemap::predeclared_location()),
e440a328 18031 type_(type), field_(field)
18032 { }
18033
18034 protected:
f23d7786 18035 bool
3ae06f68 18036 do_is_static_initializer() const
f23d7786 18037 { return true; }
18038
e440a328 18039 Type*
18040 do_type()
18041 { return Type::lookup_integer_type("uintptr"); }
18042
18043 void
18044 do_determine_type(const Type_context*)
18045 { }
18046
18047 Expression*
18048 do_copy()
18049 { return this; }
18050
ea664253 18051 Bexpression*
18052 do_get_backend(Translate_context* context);
e440a328 18053
d751bb78 18054 void
18055 do_dump_expression(Ast_dump_context*) const;
f03a9fbf 18056
e440a328 18057 private:
18058 // The type of the struct.
18059 Struct_type* type_;
18060 // The field.
18061 const Struct_field* field_;
18062};
18063
ea664253 18064// Return the backend representation for a struct field offset.
e440a328 18065
ea664253 18066Bexpression*
18067Struct_field_offset_expression::do_get_backend(Translate_context* context)
e440a328 18068{
e440a328 18069 const Struct_field_list* fields = this->type_->fields();
e440a328 18070 Struct_field_list::const_iterator p;
2c8bda43 18071 unsigned i = 0;
e440a328 18072 for (p = fields->begin();
18073 p != fields->end();
2c8bda43 18074 ++p, ++i)
18075 if (&*p == this->field_)
18076 break;
c484d925 18077 go_assert(&*p == this->field_);
e440a328 18078
2c8bda43 18079 Gogo* gogo = context->gogo();
18080 Btype* btype = this->type_->get_backend(gogo);
18081
3f378015 18082 int64_t offset = gogo->backend()->type_field_offset(btype, i);
2c8bda43 18083 Type* uptr_type = Type::lookup_integer_type("uintptr");
e67508fa 18084 Expression* ret =
3f378015 18085 Expression::make_integer_int64(offset, uptr_type,
18086 Linemap::predeclared_location());
ea664253 18087 return ret->get_backend(context);
e440a328 18088}
18089
d751bb78 18090// Dump ast representation for a struct field offset expression.
18091
18092void
18093Struct_field_offset_expression::do_dump_expression(
18094 Ast_dump_context* ast_dump_context) const
18095{
18096 ast_dump_context->ostream() << "unsafe.Offsetof(";
2d29d278 18097 ast_dump_context->dump_type(this->type_);
18098 ast_dump_context->ostream() << '.';
18099 ast_dump_context->ostream() <<
18100 Gogo::message_name(this->field_->field_name());
d751bb78 18101 ast_dump_context->ostream() << ")";
18102}
18103
e440a328 18104// Make an expression for a struct field offset.
18105
18106Expression*
18107Expression::make_struct_field_offset(Struct_type* type,
18108 const Struct_field* field)
18109{
18110 return new Struct_field_offset_expression(type, field);
18111}
18112
18113// An expression which evaluates to the address of an unnamed label.
18114
18115class Label_addr_expression : public Expression
18116{
18117 public:
b13c66cd 18118 Label_addr_expression(Label* label, Location location)
e440a328 18119 : Expression(EXPRESSION_LABEL_ADDR, location),
18120 label_(label)
18121 { }
18122
18123 protected:
18124 Type*
18125 do_type()
18126 { return Type::make_pointer_type(Type::make_void_type()); }
18127
18128 void
18129 do_determine_type(const Type_context*)
18130 { }
18131
18132 Expression*
18133 do_copy()
18134 { return new Label_addr_expression(this->label_, this->location()); }
18135
ea664253 18136 Bexpression*
18137 do_get_backend(Translate_context* context)
18138 { return this->label_->get_addr(context, this->location()); }
e440a328 18139
d751bb78 18140 void
18141 do_dump_expression(Ast_dump_context* ast_dump_context) const
18142 { ast_dump_context->ostream() << this->label_->name(); }
f03a9fbf 18143
e440a328 18144 private:
18145 // The label whose address we are taking.
18146 Label* label_;
18147};
18148
18149// Make an expression for the address of an unnamed label.
18150
18151Expression*
b13c66cd 18152Expression::make_label_addr(Label* label, Location location)
e440a328 18153{
18154 return new Label_addr_expression(label, location);
18155}
18156
da244e59 18157// Class Conditional_expression.
283a177b 18158
2c809f8f 18159// Traversal.
18160
18161int
18162Conditional_expression::do_traverse(Traverse* traverse)
18163{
18164 if (Expression::traverse(&this->cond_, traverse) == TRAVERSE_EXIT
18165 || Expression::traverse(&this->then_, traverse) == TRAVERSE_EXIT
18166 || Expression::traverse(&this->else_, traverse) == TRAVERSE_EXIT)
18167 return TRAVERSE_EXIT;
18168 return TRAVERSE_CONTINUE;
18169}
18170
283a177b 18171// Return the type of the conditional expression.
18172
18173Type*
18174Conditional_expression::do_type()
18175{
18176 Type* result_type = Type::make_void_type();
3a522dcc 18177 if (Type::are_identical(this->then_->type(), this->else_->type(),
18178 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
2c809f8f 18179 NULL))
283a177b 18180 result_type = this->then_->type();
18181 else if (this->then_->is_nil_expression()
18182 || this->else_->is_nil_expression())
18183 result_type = (!this->then_->is_nil_expression()
18184 ? this->then_->type()
18185 : this->else_->type());
18186 return result_type;
18187}
18188
2c809f8f 18189// Determine type for a conditional expression.
18190
18191void
18192Conditional_expression::do_determine_type(const Type_context* context)
18193{
18194 this->cond_->determine_type_no_context();
18195 this->then_->determine_type(context);
18196 this->else_->determine_type(context);
18197}
18198
283a177b 18199// Get the backend representation of a conditional expression.
18200
ea664253 18201Bexpression*
18202Conditional_expression::do_get_backend(Translate_context* context)
283a177b 18203{
18204 Gogo* gogo = context->gogo();
18205 Btype* result_btype = this->type()->get_backend(gogo);
ea664253 18206 Bexpression* cond = this->cond_->get_backend(context);
18207 Bexpression* then = this->then_->get_backend(context);
18208 Bexpression* belse = this->else_->get_backend(context);
93715b75 18209 Bfunction* bfn = context->function()->func_value()->get_decl();
18210 return gogo->backend()->conditional_expression(bfn, result_btype, cond, then,
ea664253 18211 belse, this->location());
283a177b 18212}
18213
18214// Dump ast representation of a conditional expression.
18215
18216void
18217Conditional_expression::do_dump_expression(
18218 Ast_dump_context* ast_dump_context) const
18219{
18220 ast_dump_context->ostream() << "(";
18221 ast_dump_context->dump_expression(this->cond_);
18222 ast_dump_context->ostream() << " ? ";
18223 ast_dump_context->dump_expression(this->then_);
18224 ast_dump_context->ostream() << " : ";
18225 ast_dump_context->dump_expression(this->else_);
18226 ast_dump_context->ostream() << ") ";
18227}
18228
18229// Make a conditional expression.
18230
18231Expression*
18232Expression::make_conditional(Expression* cond, Expression* then,
18233 Expression* else_expr, Location location)
18234{
18235 return new Conditional_expression(cond, then, else_expr, location);
18236}
18237
da244e59 18238// Class Compound_expression.
2c809f8f 18239
18240// Traversal.
18241
18242int
18243Compound_expression::do_traverse(Traverse* traverse)
18244{
18245 if (Expression::traverse(&this->init_, traverse) == TRAVERSE_EXIT
18246 || Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT)
18247 return TRAVERSE_EXIT;
18248 return TRAVERSE_CONTINUE;
18249}
18250
18251// Return the type of the compound expression.
18252
18253Type*
18254Compound_expression::do_type()
18255{
18256 return this->expr_->type();
18257}
18258
18259// Determine type for a compound expression.
18260
18261void
18262Compound_expression::do_determine_type(const Type_context* context)
18263{
18264 this->init_->determine_type_no_context();
18265 this->expr_->determine_type(context);
18266}
18267
18268// Get the backend representation of a compound expression.
18269
ea664253 18270Bexpression*
18271Compound_expression::do_get_backend(Translate_context* context)
2c809f8f 18272{
18273 Gogo* gogo = context->gogo();
ea664253 18274 Bexpression* binit = this->init_->get_backend(context);
0ab48656 18275 Bfunction* bfunction = context->function()->func_value()->get_decl();
18276 Bstatement* init_stmt = gogo->backend()->expression_statement(bfunction,
18277 binit);
ea664253 18278 Bexpression* bexpr = this->expr_->get_backend(context);
18279 return gogo->backend()->compound_expression(init_stmt, bexpr,
18280 this->location());
2c809f8f 18281}
18282
18283// Dump ast representation of a conditional expression.
18284
18285void
18286Compound_expression::do_dump_expression(
18287 Ast_dump_context* ast_dump_context) const
18288{
18289 ast_dump_context->ostream() << "(";
18290 ast_dump_context->dump_expression(this->init_);
18291 ast_dump_context->ostream() << ",";
18292 ast_dump_context->dump_expression(this->expr_);
18293 ast_dump_context->ostream() << ") ";
18294}
18295
18296// Make a compound expression.
18297
18298Expression*
18299Expression::make_compound(Expression* init, Expression* expr, Location location)
18300{
18301 return new Compound_expression(init, expr, location);
18302}
18303
1b4fb1e0 18304// Class Backend_expression.
18305
18306int
18307Backend_expression::do_traverse(Traverse*)
18308{
18309 return TRAVERSE_CONTINUE;
18310}
18311
de590a61 18312Expression*
18313Backend_expression::do_copy()
18314{
18315 return new Backend_expression(this->bexpr_, this->type_->copy_expressions(),
18316 this->location());
18317}
18318
1b4fb1e0 18319void
18320Backend_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
18321{
18322 ast_dump_context->ostream() << "backend_expression<";
18323 ast_dump_context->dump_type(this->type_);
18324 ast_dump_context->ostream() << ">";
18325}
18326
18327Expression*
18328Expression::make_backend(Bexpression* bexpr, Type* type, Location location)
18329{
18330 return new Backend_expression(bexpr, type, location);
18331}
18332
e440a328 18333// Import an expression. This comes at the end in order to see the
18334// various class definitions.
18335
18336Expression*
bc8e2ef4 18337Expression::import_expression(Import_expression* imp, Location loc)
e3d09834 18338{
18339 Expression* expr = Expression::import_expression_without_suffix(imp, loc);
18340 while (true)
18341 {
18342 if (imp->match_c_string("("))
18343 {
18344 imp->advance(1);
18345 Expression_list* args = new Expression_list();
18346 bool is_varargs = false;
18347 while (!imp->match_c_string(")"))
18348 {
18349 Expression* arg = Expression::import_expression(imp, loc);
18350 if (arg->is_error_expression())
18351 return arg;
18352 args->push_back(arg);
18353 if (imp->match_c_string(")"))
18354 break;
18355 else if (imp->match_c_string("...)"))
18356 {
18357 imp->advance(3);
18358 is_varargs = true;
18359 break;
18360 }
18361 imp->require_c_string(", ");
18362 }
18363 imp->require_c_string(")");
18364 expr = Expression::make_call(expr, args, is_varargs, loc);
431a858a 18365 expr->call_expression()->set_varargs_are_lowered();
e3d09834 18366 }
171fd404 18367 else if (imp->match_c_string("["))
18368 {
18369 imp->advance(1);
18370 Expression* start = Expression::import_expression(imp, loc);
18371 Expression* end = NULL;
18372 Expression* cap = NULL;
18373 if (imp->match_c_string(":"))
18374 {
18375 imp->advance(1);
18376 int c = imp->peek_char();
18377 if (c == ':' || c == ']')
18378 end = Expression::make_nil(loc);
18379 else
18380 end = Expression::import_expression(imp, loc);
18381 if (imp->match_c_string(":"))
18382 {
18383 imp->advance(1);
18384 cap = Expression::import_expression(imp, loc);
18385 }
18386 }
18387 imp->require_c_string("]");
18388 expr = Expression::make_index(expr, start, end, cap, loc);
18389 }
e3d09834 18390 else
18391 break;
18392 }
18393
18394 return expr;
18395}
18396
18397// Import an expression without considering a suffix (function
18398// arguments, index operations, etc.).
18399
18400Expression*
18401Expression::import_expression_without_suffix(Import_expression* imp,
18402 Location loc)
e440a328 18403{
18404 int c = imp->peek_char();
5f6f5357 18405 if (c == '+' || c == '-' || c == '!' || c == '^' || c == '&' || c == '*')
9b92780c 18406 return Unary_expression::do_import(imp, loc);
e440a328 18407 else if (c == '(')
9b92780c 18408 return Binary_expression::do_import(imp, loc);
204d4af4 18409 else if (imp->match_c_string("$true")
18410 || imp->match_c_string("$false")
18411 || (imp->version() < EXPORT_FORMAT_V3
18412 && (imp->match_c_string("true")
18413 || imp->match_c_string("false"))))
9b92780c 18414 return Boolean_expression::do_import(imp, loc);
e440a328 18415 else if (c == '"')
9b92780c 18416 return String_expression::do_import(imp, loc);
e440a328 18417 else if (c == '-' || (c >= '0' && c <= '9'))
18418 {
18419 // This handles integers, floats and complex constants.
9b92780c 18420 return Integer_expression::do_import(imp, loc);
e440a328 18421 }
0b2617a3 18422 else if (imp->match_c_string("<-"))
18423 return Receive_expression::do_import(imp, loc);
204d4af4 18424 else if (imp->match_c_string("$nil")
18425 || (imp->version() < EXPORT_FORMAT_V3
18426 && imp->match_c_string("nil")))
9b92780c 18427 return Nil_expression::do_import(imp, loc);
204d4af4 18428 else if (imp->match_c_string("$convert")
18429 || (imp->version() < EXPORT_FORMAT_V3
18430 && imp->match_c_string("convert")))
9b92780c 18431 return Type_conversion_expression::do_import(imp, loc);
5f6f5357 18432
18433 Import_function_body* ifb = imp->ifb();
18434 if (ifb == NULL)
e440a328 18435 {
631d5788 18436 go_error_at(imp->location(), "import error: expected expression");
9b92780c 18437 return Expression::make_error(loc);
e440a328 18438 }
5f6f5357 18439 if (ifb->saw_error())
18440 return Expression::make_error(loc);
f6492beb 18441
18442 if (ifb->match_c_string("$t"))
18443 return Temporary_reference_expression::do_import(ifb, loc);
18444
015399f9 18445 return Expression::import_identifier(ifb, loc);
18446}
18447
18448// Import an identifier in an expression. This is a reference to a
18449// variable or function.
18450
18451Expression*
18452Expression::import_identifier(Import_function_body* ifb, Location loc)
18453{
18454 std::string id;
18455 Package* pkg;
18456 bool is_exported;
18457 if (!Import::read_qualified_identifier(ifb, &id, &pkg, &is_exported))
5f6f5357 18458 {
18459 if (!ifb->saw_error())
015399f9 18460 go_error_at(ifb->location(),
18461 "import error for %qs: bad qualified identifier at %lu",
18462 ifb->name().c_str(),
5f6f5357 18463 static_cast<unsigned long>(ifb->off()));
18464 ifb->set_saw_error();
18465 return Expression::make_error(loc);
18466 }
015399f9 18467
18468 Named_object* no = NULL;
18469 if (pkg == NULL && is_exported)
18470 no = ifb->block()->bindings()->lookup(id);
18471 if (no == NULL)
18472 {
18473 const Package* ipkg = pkg;
18474 if (ipkg == NULL)
18475 ipkg = ifb->function()->package();
18476 if (!is_exported)
18477 id = '.' + ipkg->pkgpath() + '.' + id;
18478 no = ipkg->bindings()->lookup(id);
18479 }
18480 if (no == NULL)
18481 no = ifb->gogo()->lookup_global(id.c_str());
18482
18483 if (no == NULL)
5f6f5357 18484 {
18485 if (!ifb->saw_error())
015399f9 18486 go_error_at(ifb->location(),
18487 "import error for %qs: lookup of %qs failed",
18488 ifb->name().c_str(), id.c_str());
5f6f5357 18489 ifb->set_saw_error();
18490 return Expression::make_error(loc);
18491 }
015399f9 18492
e3d09834 18493 if (no->is_variable() || no->is_result_variable())
18494 return Expression::make_var_reference(no, loc);
18495 else if (no->is_function() || no->is_function_declaration())
18496 return Expression::make_func_reference(no, NULL, loc);
18497 else
18498 {
18499 if (!ifb->saw_error())
18500 go_error_at(ifb->location(),
18501 ("import error for %qs: "
18502 "unexpected type of identifier %qs (%d)"),
18503 ifb->name().c_str(),
18504 id.c_str(), no->classification());
18505 ifb->set_saw_error();
18506 return Expression::make_error(loc);
18507 }
e440a328 18508}
18509
18510// Class Expression_list.
18511
18512// Traverse the list.
18513
18514int
18515Expression_list::traverse(Traverse* traverse)
18516{
18517 for (Expression_list::iterator p = this->begin();
18518 p != this->end();
18519 ++p)
18520 {
18521 if (*p != NULL)
18522 {
18523 if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
18524 return TRAVERSE_EXIT;
18525 }
18526 }
18527 return TRAVERSE_CONTINUE;
18528}
18529
18530// Copy the list.
18531
18532Expression_list*
18533Expression_list::copy()
18534{
18535 Expression_list* ret = new Expression_list();
18536 for (Expression_list::iterator p = this->begin();
18537 p != this->end();
18538 ++p)
18539 {
18540 if (*p == NULL)
18541 ret->push_back(NULL);
18542 else
18543 ret->push_back((*p)->copy());
18544 }
18545 return ret;
18546}
18547
18548// Return whether an expression list has an error expression.
18549
18550bool
18551Expression_list::contains_error() const
18552{
18553 for (Expression_list::const_iterator p = this->begin();
18554 p != this->end();
18555 ++p)
18556 if (*p != NULL && (*p)->is_error_expression())
18557 return true;
18558 return false;
18559}
0c77715b 18560
18561// Class Numeric_constant.
18562
18563// Destructor.
18564
18565Numeric_constant::~Numeric_constant()
18566{
18567 this->clear();
18568}
18569
18570// Copy constructor.
18571
18572Numeric_constant::Numeric_constant(const Numeric_constant& a)
18573 : classification_(a.classification_), type_(a.type_)
18574{
18575 switch (a.classification_)
18576 {
18577 case NC_INVALID:
18578 break;
18579 case NC_INT:
18580 case NC_RUNE:
18581 mpz_init_set(this->u_.int_val, a.u_.int_val);
18582 break;
18583 case NC_FLOAT:
18584 mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
18585 break;
18586 case NC_COMPLEX:
fcbea5e4 18587 mpc_init2(this->u_.complex_val, mpc_precision);
18588 mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
0c77715b 18589 break;
18590 default:
18591 go_unreachable();
18592 }
18593}
18594
18595// Assignment operator.
18596
18597Numeric_constant&
18598Numeric_constant::operator=(const Numeric_constant& a)
18599{
18600 this->clear();
18601 this->classification_ = a.classification_;
18602 this->type_ = a.type_;
18603 switch (a.classification_)
18604 {
18605 case NC_INVALID:
18606 break;
18607 case NC_INT:
18608 case NC_RUNE:
18609 mpz_init_set(this->u_.int_val, a.u_.int_val);
18610 break;
18611 case NC_FLOAT:
18612 mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
18613 break;
18614 case NC_COMPLEX:
fcbea5e4 18615 mpc_init2(this->u_.complex_val, mpc_precision);
18616 mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
0c77715b 18617 break;
18618 default:
18619 go_unreachable();
18620 }
18621 return *this;
18622}
18623
0ab32342 18624// Check equality with another numeric constant.
18625
18626bool
18627Numeric_constant::equals(const Numeric_constant& a) const
18628{
18629 if (this->classification_ != a.classification_)
18630 return false;
18631
18632 if (this->type_ != NULL && a.type_ != NULL
18633 && !Type::are_identical(this->type_, a.type_,
18634 Type::COMPARE_ALIASES, NULL))
18635 return false;
18636
18637 switch (a.classification_)
18638 {
18639 case NC_INVALID:
18640 break;
18641 case NC_INT:
18642 case NC_RUNE:
18643 return mpz_cmp(this->u_.int_val, a.u_.int_val) == 0;
18644 case NC_FLOAT:
18645 return mpfr_cmp(this->u_.float_val, a.u_.float_val) == 0;
18646 case NC_COMPLEX:
18647 return mpc_cmp(this->u_.complex_val, a.u_.complex_val) == 0;
18648 default:
18649 go_unreachable();
18650 }
18651 return false;
18652}
18653
0c77715b 18654// Clear the contents.
18655
18656void
18657Numeric_constant::clear()
18658{
18659 switch (this->classification_)
18660 {
18661 case NC_INVALID:
18662 break;
18663 case NC_INT:
18664 case NC_RUNE:
18665 mpz_clear(this->u_.int_val);
18666 break;
18667 case NC_FLOAT:
18668 mpfr_clear(this->u_.float_val);
18669 break;
18670 case NC_COMPLEX:
fcbea5e4 18671 mpc_clear(this->u_.complex_val);
0c77715b 18672 break;
18673 default:
18674 go_unreachable();
18675 }
18676 this->classification_ = NC_INVALID;
18677}
18678
18679// Set to an unsigned long value.
18680
18681void
18682Numeric_constant::set_unsigned_long(Type* type, unsigned long val)
18683{
18684 this->clear();
18685 this->classification_ = NC_INT;
18686 this->type_ = type;
18687 mpz_init_set_ui(this->u_.int_val, val);
18688}
18689
18690// Set to an integer value.
18691
18692void
18693Numeric_constant::set_int(Type* type, const mpz_t val)
18694{
18695 this->clear();
18696 this->classification_ = NC_INT;
18697 this->type_ = type;
18698 mpz_init_set(this->u_.int_val, val);
18699}
18700
18701// Set to a rune value.
18702
18703void
18704Numeric_constant::set_rune(Type* type, const mpz_t val)
18705{
18706 this->clear();
18707 this->classification_ = NC_RUNE;
18708 this->type_ = type;
18709 mpz_init_set(this->u_.int_val, val);
18710}
18711
18712// Set to a floating point value.
18713
18714void
18715Numeric_constant::set_float(Type* type, const mpfr_t val)
18716{
18717 this->clear();
18718 this->classification_ = NC_FLOAT;
18719 this->type_ = type;
d1d4ace3 18720
833b523c 18721 // Numeric constants do not have negative zero values, so remove
18722 // them here. They also don't have infinity or NaN values, but we
18723 // should never see them here.
d1d4ace3 18724 int bits = 0;
18725 if (type != NULL
18726 && type->float_type() != NULL
18727 && !type->float_type()->is_abstract())
18728 bits = type->float_type()->bits();
18729 if (Numeric_constant::is_float_neg_zero(val, bits))
833b523c 18730 mpfr_init_set_ui(this->u_.float_val, 0, GMP_RNDN);
18731 else
18732 mpfr_init_set(this->u_.float_val, val, GMP_RNDN);
0c77715b 18733}
18734
18735// Set to a complex value.
18736
18737void
fcbea5e4 18738Numeric_constant::set_complex(Type* type, const mpc_t val)
0c77715b 18739{
18740 this->clear();
18741 this->classification_ = NC_COMPLEX;
18742 this->type_ = type;
d1d4ace3 18743
18744 // Avoid negative zero as in set_float.
18745 int bits = 0;
18746 if (type != NULL
18747 && type->complex_type() != NULL
18748 && !type->complex_type()->is_abstract())
18749 bits = type->complex_type()->bits() / 2;
18750
18751 mpfr_t real;
18752 mpfr_init_set(real, mpc_realref(val), GMP_RNDN);
18753 if (Numeric_constant::is_float_neg_zero(real, bits))
18754 mpfr_set_ui(real, 0, GMP_RNDN);
18755
18756 mpfr_t imag;
18757 mpfr_init_set(imag, mpc_imagref(val), GMP_RNDN);
18758 if (Numeric_constant::is_float_neg_zero(imag, bits))
18759 mpfr_set_ui(imag, 0, GMP_RNDN);
18760
fcbea5e4 18761 mpc_init2(this->u_.complex_val, mpc_precision);
d1d4ace3 18762 mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN);
18763
18764 mpfr_clear(real);
18765 mpfr_clear(imag);
18766}
18767
18768// Return whether VAL, at a precision of BITS, is a negative zero.
18769// BITS may be zero in which case it is ignored.
18770
18771bool
18772Numeric_constant::is_float_neg_zero(const mpfr_t val, int bits)
18773{
18774 if (!mpfr_signbit(val))
18775 return false;
18776 if (mpfr_zero_p(val))
18777 return true;
18778 mp_exp_t min_exp;
18779 switch (bits)
18780 {
18781 case 0:
18782 return false;
18783 case 32:
18784 // In a denormalized float32 the exponent is -126, and there are
18785 // 24 bits of which at least the last must be 1, so the smallest
18786 // representable non-zero exponent is -126 - (24 - 1) == -149.
18787 min_exp = -149;
18788 break;
18789 case 64:
18790 // Minimum exponent is -1022, there are 53 bits.
18791 min_exp = -1074;
18792 break;
18793 default:
18794 go_unreachable();
18795 }
18796 return mpfr_get_exp(val) < min_exp;
0c77715b 18797}
18798
18799// Get an int value.
18800
18801void
18802Numeric_constant::get_int(mpz_t* val) const
18803{
18804 go_assert(this->is_int());
18805 mpz_init_set(*val, this->u_.int_val);
18806}
18807
18808// Get a rune value.
18809
18810void
18811Numeric_constant::get_rune(mpz_t* val) const
18812{
18813 go_assert(this->is_rune());
18814 mpz_init_set(*val, this->u_.int_val);
18815}
18816
18817// Get a floating point value.
18818
18819void
18820Numeric_constant::get_float(mpfr_t* val) const
18821{
18822 go_assert(this->is_float());
18823 mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
18824}
18825
18826// Get a complex value.
18827
18828void
fcbea5e4 18829Numeric_constant::get_complex(mpc_t* val) const
0c77715b 18830{
18831 go_assert(this->is_complex());
fcbea5e4 18832 mpc_init2(*val, mpc_precision);
18833 mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
0c77715b 18834}
18835
18836// Express value as unsigned long if possible.
18837
18838Numeric_constant::To_unsigned_long
18839Numeric_constant::to_unsigned_long(unsigned long* val) const
18840{
18841 switch (this->classification_)
18842 {
18843 case NC_INT:
18844 case NC_RUNE:
18845 return this->mpz_to_unsigned_long(this->u_.int_val, val);
18846 case NC_FLOAT:
18847 return this->mpfr_to_unsigned_long(this->u_.float_val, val);
18848 case NC_COMPLEX:
fcbea5e4 18849 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 18850 return NC_UL_NOTINT;
fcbea5e4 18851 return this->mpfr_to_unsigned_long(mpc_realref(this->u_.complex_val),
18852 val);
0c77715b 18853 default:
18854 go_unreachable();
18855 }
18856}
18857
18858// Express integer value as unsigned long if possible.
18859
18860Numeric_constant::To_unsigned_long
18861Numeric_constant::mpz_to_unsigned_long(const mpz_t ival,
18862 unsigned long *val) const
18863{
18864 if (mpz_sgn(ival) < 0)
18865 return NC_UL_NEGATIVE;
18866 unsigned long ui = mpz_get_ui(ival);
18867 if (mpz_cmp_ui(ival, ui) != 0)
18868 return NC_UL_BIG;
18869 *val = ui;
18870 return NC_UL_VALID;
18871}
18872
18873// Express floating point value as unsigned long if possible.
18874
18875Numeric_constant::To_unsigned_long
18876Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval,
18877 unsigned long *val) const
18878{
18879 if (!mpfr_integer_p(fval))
18880 return NC_UL_NOTINT;
18881 mpz_t ival;
18882 mpz_init(ival);
18883 mpfr_get_z(ival, fval, GMP_RNDN);
18884 To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val);
18885 mpz_clear(ival);
18886 return ret;
18887}
18888
03118c21 18889// Express value as memory size if possible.
18890
18891bool
18892Numeric_constant::to_memory_size(int64_t* val) const
18893{
18894 switch (this->classification_)
18895 {
18896 case NC_INT:
18897 case NC_RUNE:
18898 return this->mpz_to_memory_size(this->u_.int_val, val);
18899 case NC_FLOAT:
18900 return this->mpfr_to_memory_size(this->u_.float_val, val);
18901 case NC_COMPLEX:
18902 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
18903 return false;
18904 return this->mpfr_to_memory_size(mpc_realref(this->u_.complex_val), val);
18905 default:
18906 go_unreachable();
18907 }
18908}
18909
18910// Express integer as memory size if possible.
18911
18912bool
18913Numeric_constant::mpz_to_memory_size(const mpz_t ival, int64_t* val) const
18914{
18915 if (mpz_sgn(ival) < 0)
18916 return false;
18917 if (mpz_fits_slong_p(ival))
18918 {
18919 *val = static_cast<int64_t>(mpz_get_si(ival));
18920 return true;
18921 }
18922
18923 // Test >= 64, not > 64, because an int64_t can hold 63 bits of a
18924 // positive value.
18925 if (mpz_sizeinbase(ival, 2) >= 64)
18926 return false;
18927
18928 mpz_t q, r;
18929 mpz_init(q);
18930 mpz_init(r);
18931 mpz_tdiv_q_2exp(q, ival, 32);
18932 mpz_tdiv_r_2exp(r, ival, 32);
18933 go_assert(mpz_fits_ulong_p(q) && mpz_fits_ulong_p(r));
18934 *val = ((static_cast<int64_t>(mpz_get_ui(q)) << 32)
18935 + static_cast<int64_t>(mpz_get_ui(r)));
18936 mpz_clear(r);
18937 mpz_clear(q);
18938 return true;
18939}
18940
18941// Express floating point value as memory size if possible.
18942
18943bool
18944Numeric_constant::mpfr_to_memory_size(const mpfr_t fval, int64_t* val) const
18945{
18946 if (!mpfr_integer_p(fval))
18947 return false;
18948 mpz_t ival;
18949 mpz_init(ival);
18950 mpfr_get_z(ival, fval, GMP_RNDN);
18951 bool ret = this->mpz_to_memory_size(ival, val);
18952 mpz_clear(ival);
18953 return ret;
18954}
18955
0c77715b 18956// Convert value to integer if possible.
18957
18958bool
18959Numeric_constant::to_int(mpz_t* val) const
18960{
18961 switch (this->classification_)
18962 {
18963 case NC_INT:
18964 case NC_RUNE:
18965 mpz_init_set(*val, this->u_.int_val);
18966 return true;
18967 case NC_FLOAT:
18968 if (!mpfr_integer_p(this->u_.float_val))
18969 return false;
18970 mpz_init(*val);
18971 mpfr_get_z(*val, this->u_.float_val, GMP_RNDN);
18972 return true;
18973 case NC_COMPLEX:
fcbea5e4 18974 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val))
18975 || !mpfr_integer_p(mpc_realref(this->u_.complex_val)))
0c77715b 18976 return false;
18977 mpz_init(*val);
fcbea5e4 18978 mpfr_get_z(*val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 18979 return true;
18980 default:
18981 go_unreachable();
18982 }
18983}
18984
18985// Convert value to floating point if possible.
18986
18987bool
18988Numeric_constant::to_float(mpfr_t* val) const
18989{
18990 switch (this->classification_)
18991 {
18992 case NC_INT:
18993 case NC_RUNE:
18994 mpfr_init_set_z(*val, this->u_.int_val, GMP_RNDN);
18995 return true;
18996 case NC_FLOAT:
18997 mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
18998 return true;
18999 case NC_COMPLEX:
fcbea5e4 19000 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 19001 return false;
fcbea5e4 19002 mpfr_init_set(*val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 19003 return true;
19004 default:
19005 go_unreachable();
19006 }
19007}
19008
19009// Convert value to complex.
19010
19011bool
fcbea5e4 19012Numeric_constant::to_complex(mpc_t* val) const
0c77715b 19013{
fcbea5e4 19014 mpc_init2(*val, mpc_precision);
0c77715b 19015 switch (this->classification_)
19016 {
19017 case NC_INT:
19018 case NC_RUNE:
fcbea5e4 19019 mpc_set_z(*val, this->u_.int_val, MPC_RNDNN);
0c77715b 19020 return true;
19021 case NC_FLOAT:
fcbea5e4 19022 mpc_set_fr(*val, this->u_.float_val, MPC_RNDNN);
0c77715b 19023 return true;
19024 case NC_COMPLEX:
fcbea5e4 19025 mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
0c77715b 19026 return true;
19027 default:
19028 go_unreachable();
19029 }
19030}
19031
19032// Get the type.
19033
19034Type*
19035Numeric_constant::type() const
19036{
19037 if (this->type_ != NULL)
19038 return this->type_;
19039 switch (this->classification_)
19040 {
19041 case NC_INT:
19042 return Type::make_abstract_integer_type();
19043 case NC_RUNE:
19044 return Type::make_abstract_character_type();
19045 case NC_FLOAT:
19046 return Type::make_abstract_float_type();
19047 case NC_COMPLEX:
19048 return Type::make_abstract_complex_type();
19049 default:
19050 go_unreachable();
19051 }
19052}
19053
19054// If the constant can be expressed in TYPE, then set the type of the
19055// constant to TYPE and return true. Otherwise return false, and, if
19056// ISSUE_ERROR is true, report an appropriate error message.
19057
19058bool
19059Numeric_constant::set_type(Type* type, bool issue_error, Location loc)
19060{
19061 bool ret;
f11c2155 19062 if (type == NULL || type->is_error())
0c77715b 19063 ret = true;
19064 else if (type->integer_type() != NULL)
19065 ret = this->check_int_type(type->integer_type(), issue_error, loc);
19066 else if (type->float_type() != NULL)
19067 ret = this->check_float_type(type->float_type(), issue_error, loc);
19068 else if (type->complex_type() != NULL)
19069 ret = this->check_complex_type(type->complex_type(), issue_error, loc);
19070 else
5706ab68 19071 {
19072 ret = false;
19073 if (issue_error)
19074 go_assert(saw_errors());
19075 }
0c77715b 19076 if (ret)
19077 this->type_ = type;
19078 return ret;
19079}
19080
19081// Check whether the constant can be expressed in an integer type.
19082
19083bool
19084Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
71a45216 19085 Location location)
0c77715b 19086{
19087 mpz_t val;
19088 switch (this->classification_)
19089 {
19090 case NC_INT:
19091 case NC_RUNE:
19092 mpz_init_set(val, this->u_.int_val);
19093 break;
19094
19095 case NC_FLOAT:
19096 if (!mpfr_integer_p(this->u_.float_val))
19097 {
19098 if (issue_error)
71a45216 19099 {
631d5788 19100 go_error_at(location,
37423a84 19101 "floating-point constant truncated to integer");
71a45216 19102 this->set_invalid();
19103 }
0c77715b 19104 return false;
19105 }
19106 mpz_init(val);
19107 mpfr_get_z(val, this->u_.float_val, GMP_RNDN);
19108 break;
19109
19110 case NC_COMPLEX:
fcbea5e4 19111 if (!mpfr_integer_p(mpc_realref(this->u_.complex_val))
19112 || !mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 19113 {
19114 if (issue_error)
71a45216 19115 {
631d5788 19116 go_error_at(location, "complex constant truncated to integer");
71a45216 19117 this->set_invalid();
19118 }
0c77715b 19119 return false;
19120 }
19121 mpz_init(val);
fcbea5e4 19122 mpfr_get_z(val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 19123 break;
19124
19125 default:
19126 go_unreachable();
19127 }
19128
19129 bool ret;
19130 if (type->is_abstract())
19131 ret = true;
19132 else
19133 {
19134 int bits = mpz_sizeinbase(val, 2);
19135 if (type->is_unsigned())
19136 {
19137 // For an unsigned type we can only accept a nonnegative
19138 // number, and we must be able to represents at least BITS.
19139 ret = mpz_sgn(val) >= 0 && bits <= type->bits();
19140 }
19141 else
19142 {
19143 // For a signed type we need an extra bit to indicate the
19144 // sign. We have to handle the most negative integer
19145 // specially.
19146 ret = (bits + 1 <= type->bits()
19147 || (bits <= type->bits()
19148 && mpz_sgn(val) < 0
19149 && (mpz_scan1(val, 0)
19150 == static_cast<unsigned long>(type->bits() - 1))
19151 && mpz_scan0(val, type->bits()) == ULONG_MAX));
19152 }
19153 }
19154
19155 if (!ret && issue_error)
71a45216 19156 {
631d5788 19157 go_error_at(location, "integer constant overflow");
71a45216 19158 this->set_invalid();
19159 }
0c77715b 19160
19161 return ret;
19162}
19163
19164// Check whether the constant can be expressed in a floating point
19165// type.
19166
19167bool
19168Numeric_constant::check_float_type(Float_type* type, bool issue_error,
d0bcce51 19169 Location location)
0c77715b 19170{
19171 mpfr_t val;
19172 switch (this->classification_)
19173 {
19174 case NC_INT:
19175 case NC_RUNE:
19176 mpfr_init_set_z(val, this->u_.int_val, GMP_RNDN);
19177 break;
19178
19179 case NC_FLOAT:
19180 mpfr_init_set(val, this->u_.float_val, GMP_RNDN);
19181 break;
19182
19183 case NC_COMPLEX:
fcbea5e4 19184 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 19185 {
19186 if (issue_error)
71a45216 19187 {
19188 this->set_invalid();
37423a84 19189 go_error_at(location,
19190 "complex constant truncated to floating-point");
71a45216 19191 }
0c77715b 19192 return false;
19193 }
fcbea5e4 19194 mpfr_init_set(val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 19195 break;
19196
19197 default:
19198 go_unreachable();
19199 }
19200
19201 bool ret;
19202 if (type->is_abstract())
19203 ret = true;
19204 else if (mpfr_nan_p(val) || mpfr_inf_p(val) || mpfr_zero_p(val))
19205 {
19206 // A NaN or Infinity always fits in the range of the type.
19207 ret = true;
19208 }
19209 else
19210 {
19211 mp_exp_t exp = mpfr_get_exp(val);
19212 mp_exp_t max_exp;
19213 switch (type->bits())
19214 {
19215 case 32:
19216 max_exp = 128;
19217 break;
19218 case 64:
19219 max_exp = 1024;
19220 break;
19221 default:
19222 go_unreachable();
19223 }
19224
19225 ret = exp <= max_exp;
d0bcce51 19226
19227 if (ret)
19228 {
19229 // Round the constant to the desired type.
19230 mpfr_t t;
19231 mpfr_init(t);
19232 switch (type->bits())
19233 {
19234 case 32:
19235 mpfr_set_prec(t, 24);
19236 break;
19237 case 64:
19238 mpfr_set_prec(t, 53);
19239 break;
19240 default:
19241 go_unreachable();
19242 }
19243 mpfr_set(t, val, GMP_RNDN);
19244 mpfr_set(val, t, GMP_RNDN);
19245 mpfr_clear(t);
19246
19247 this->set_float(type, val);
19248 }
0c77715b 19249 }
19250
19251 mpfr_clear(val);
19252
19253 if (!ret && issue_error)
71a45216 19254 {
37423a84 19255 go_error_at(location, "floating-point constant overflow");
71a45216 19256 this->set_invalid();
19257 }
0c77715b 19258
19259 return ret;
f03a9fbf 19260}
0c77715b 19261
19262// Check whether the constant can be expressed in a complex type.
19263
19264bool
19265Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
d0bcce51 19266 Location location)
0c77715b 19267{
19268 if (type->is_abstract())
19269 return true;
19270
19271 mp_exp_t max_exp;
19272 switch (type->bits())
19273 {
19274 case 64:
19275 max_exp = 128;
19276 break;
19277 case 128:
19278 max_exp = 1024;
19279 break;
19280 default:
19281 go_unreachable();
19282 }
19283
fcbea5e4 19284 mpc_t val;
19285 mpc_init2(val, mpc_precision);
0c77715b 19286 switch (this->classification_)
19287 {
19288 case NC_INT:
19289 case NC_RUNE:
fcbea5e4 19290 mpc_set_z(val, this->u_.int_val, MPC_RNDNN);
0c77715b 19291 break;
19292
19293 case NC_FLOAT:
fcbea5e4 19294 mpc_set_fr(val, this->u_.float_val, MPC_RNDNN);
0c77715b 19295 break;
19296
19297 case NC_COMPLEX:
fcbea5e4 19298 mpc_set(val, this->u_.complex_val, MPC_RNDNN);
0c77715b 19299 break;
19300
19301 default:
19302 go_unreachable();
19303 }
19304
d0bcce51 19305 bool ret = true;
fcbea5e4 19306 if (!mpfr_nan_p(mpc_realref(val))
19307 && !mpfr_inf_p(mpc_realref(val))
19308 && !mpfr_zero_p(mpc_realref(val))
19309 && mpfr_get_exp(mpc_realref(val)) > max_exp)
d0bcce51 19310 {
19311 if (issue_error)
71a45216 19312 {
631d5788 19313 go_error_at(location, "complex real part overflow");
71a45216 19314 this->set_invalid();
19315 }
d0bcce51 19316 ret = false;
19317 }
0c77715b 19318
fcbea5e4 19319 if (!mpfr_nan_p(mpc_imagref(val))
19320 && !mpfr_inf_p(mpc_imagref(val))
19321 && !mpfr_zero_p(mpc_imagref(val))
19322 && mpfr_get_exp(mpc_imagref(val)) > max_exp)
d0bcce51 19323 {
19324 if (issue_error)
71a45216 19325 {
631d5788 19326 go_error_at(location, "complex imaginary part overflow");
71a45216 19327 this->set_invalid();
19328 }
d0bcce51 19329 ret = false;
19330 }
0c77715b 19331
d0bcce51 19332 if (ret)
19333 {
19334 // Round the constant to the desired type.
fcbea5e4 19335 mpc_t t;
d0bcce51 19336 switch (type->bits())
19337 {
19338 case 64:
fcbea5e4 19339 mpc_init2(t, 24);
d0bcce51 19340 break;
19341 case 128:
fcbea5e4 19342 mpc_init2(t, 53);
d0bcce51 19343 break;
19344 default:
19345 go_unreachable();
19346 }
fcbea5e4 19347 mpc_set(t, val, MPC_RNDNN);
19348 mpc_set(val, t, MPC_RNDNN);
19349 mpc_clear(t);
d0bcce51 19350
fcbea5e4 19351 this->set_complex(type, val);
d0bcce51 19352 }
19353
fcbea5e4 19354 mpc_clear(val);
0c77715b 19355
19356 return ret;
19357}
19358
19359// Return an Expression for this value.
19360
19361Expression*
19362Numeric_constant::expression(Location loc) const
19363{
19364 switch (this->classification_)
19365 {
19366 case NC_INT:
e67508fa 19367 return Expression::make_integer_z(&this->u_.int_val, this->type_, loc);
0c77715b 19368 case NC_RUNE:
19369 return Expression::make_character(&this->u_.int_val, this->type_, loc);
19370 case NC_FLOAT:
19371 return Expression::make_float(&this->u_.float_val, this->type_, loc);
19372 case NC_COMPLEX:
fcbea5e4 19373 return Expression::make_complex(&this->u_.complex_val, this->type_, loc);
71a45216 19374 case NC_INVALID:
19375 go_assert(saw_errors());
19376 return Expression::make_error(loc);
0c77715b 19377 default:
19378 go_unreachable();
19379 }
19380}
0ab32342 19381
19382// Calculate a hash code with a given seed.
19383
19384unsigned int
19385Numeric_constant::hash(unsigned int seed) const
19386{
19387 unsigned long val;
19388 const unsigned int PRIME = 97;
19389 long e = 0;
19390 double f = 1.0;
19391 mpfr_t m;
19392
19393 switch (this->classification_)
19394 {
19395 case NC_INVALID:
19396 return PRIME;
19397 case NC_INT:
19398 case NC_RUNE:
19399 val = mpz_get_ui(this->u_.int_val);
19400 break;
19401 case NC_COMPLEX:
19402 mpfr_init(m);
0570cb84 19403 mpc_abs(m, this->u_.complex_val, GMP_RNDN);
19404 val = mpfr_get_ui(m, GMP_RNDN);
0ab32342 19405 mpfr_clear(m);
19406 break;
19407 case NC_FLOAT:
29d43984 19408 f = mpfr_get_d_2exp(&e, this->u_.float_val, GMP_RNDN) * 4294967295.0;
0ab32342 19409 val = static_cast<unsigned long>(e + static_cast<long>(f));
19410 break;
19411 default:
19412 go_unreachable();
19413 }
19414
19415 return (static_cast<unsigned int>(val) + seed) * PRIME;
19416}