]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/go/gofrontend/expressions.cc
PR tree-optimization/89644 - false-positive -Warray-bounds on strncpy with unterminat...
[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
a7549a6a 90// Give an error saying that the value of the expression is not used.
e440a328 91
92void
a7549a6a 93Expression::unused_value_error()
e440a328 94{
4f2138d7 95 this->report_error(_("value computed is not used"));
e440a328 96}
97
98// Note that this expression is an error. This is called by children
99// when they discover an error.
100
101void
102Expression::set_is_error()
103{
104 this->classification_ = EXPRESSION_ERROR;
105}
106
107// For children to call to report an error conveniently.
108
109void
110Expression::report_error(const char* msg)
111{
631d5788 112 go_error_at(this->location_, "%s", msg);
e440a328 113 this->set_is_error();
114}
115
116// Set types of variables and constants. This is implemented by the
117// child class.
118
119void
120Expression::determine_type(const Type_context* context)
121{
122 this->do_determine_type(context);
123}
124
125// Set types when there is no context.
126
127void
128Expression::determine_type_no_context()
129{
130 Type_context context;
131 this->do_determine_type(&context);
132}
133
d3c55148 134// Return true if two expressions refer to the same variable or struct
135// field. This can only be true when there are no side effects.
136
137bool
138Expression::is_same_variable(Expression* a, Expression* b)
139{
140 if (a->classification() != b->classification())
141 return false;
142
143 Var_expression* av = a->var_expression();
144 if (av != NULL)
145 return av->named_object() == b->var_expression()->named_object();
146
147 Field_reference_expression* af = a->field_reference_expression();
148 if (af != NULL)
149 {
150 Field_reference_expression* bf = b->field_reference_expression();
151 return (af->field_index() == bf->field_index()
152 && Expression::is_same_variable(af->expr(), bf->expr()));
153 }
154
155 Unary_expression* au = a->unary_expression();
156 if (au != NULL)
157 {
158 Unary_expression* bu = b->unary_expression();
159 return (au->op() == OPERATOR_MULT
160 && bu->op() == OPERATOR_MULT
161 && Expression::is_same_variable(au->operand(),
162 bu->operand()));
163 }
164
165 return false;
166}
167
2c809f8f 168// Return an expression handling any conversions which must be done during
e440a328 169// assignment.
170
2c809f8f 171Expression*
b4a33049 172Expression::convert_for_assignment(Gogo*, Type* lhs_type,
2c809f8f 173 Expression* rhs, Location location)
e440a328 174{
2c809f8f 175 Type* rhs_type = rhs->type();
176 if (lhs_type->is_error()
177 || rhs_type->is_error()
178 || rhs->is_error_expression())
179 return Expression::make_error(location);
e440a328 180
3a522dcc 181 bool are_identical = Type::are_identical(lhs_type, rhs_type,
182 (Type::COMPARE_ERRORS
183 | Type::COMPARE_TAGS),
184 NULL);
22984631 185 if (!are_identical && lhs_type->interface_type() != NULL)
e440a328 186 {
187 if (rhs_type->interface_type() == NULL)
2c809f8f 188 return Expression::convert_type_to_interface(lhs_type, rhs, location);
e440a328 189 else
2c809f8f 190 return Expression::convert_interface_to_interface(lhs_type, rhs, false,
191 location);
e440a328 192 }
22984631 193 else if (!are_identical && rhs_type->interface_type() != NULL)
2c809f8f 194 return Expression::convert_interface_to_type(lhs_type, rhs, location);
411eb89e 195 else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
e440a328 196 {
2c809f8f 197 // Assigning nil to a slice.
2c809f8f 198 Expression* nil = Expression::make_nil(location);
e67508fa 199 Expression* zero = Expression::make_integer_ul(0, NULL, location);
2c809f8f 200 return Expression::make_slice_value(lhs_type, nil, zero, zero, location);
e440a328 201 }
202 else if (rhs_type->is_nil_type())
2c809f8f 203 return Expression::make_nil(location);
22984631 204 else if (are_identical)
e440a328 205 {
22984631 206 if (lhs_type->forwarded() != rhs_type->forwarded())
207 {
208 // Different but identical types require an explicit
209 // conversion. This happens with type aliases.
210 return Expression::make_cast(lhs_type, rhs, location);
211 }
212
e440a328 213 // No conversion is needed.
2c809f8f 214 return rhs;
215 }
216 else if (lhs_type->points_to() != NULL)
217 return Expression::make_unsafe_cast(lhs_type, rhs, location);
218 else if (lhs_type->is_numeric_type())
219 return Expression::make_cast(lhs_type, rhs, location);
220 else if ((lhs_type->struct_type() != NULL
221 && rhs_type->struct_type() != NULL)
222 || (lhs_type->array_type() != NULL
223 && rhs_type->array_type() != NULL))
e440a328 224 {
225 // This conversion must be permitted by Go, or we wouldn't have
226 // gotten here.
2c809f8f 227 return Expression::make_unsafe_cast(lhs_type, rhs, location);
e440a328 228 }
229 else
2c809f8f 230 return rhs;
e440a328 231}
232
2c809f8f 233// Return an expression for a conversion from a non-interface type to an
e440a328 234// interface type.
235
2c809f8f 236Expression*
237Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
238 Location location)
e440a328 239{
e440a328 240 Interface_type* lhs_interface_type = lhs_type->interface_type();
241 bool lhs_is_empty = lhs_interface_type->is_empty();
242
243 // Since RHS_TYPE is a static type, we can create the interface
244 // method table at compile time.
245
246 // When setting an interface to nil, we just set both fields to
247 // NULL.
2c809f8f 248 Type* rhs_type = rhs->type();
e440a328 249 if (rhs_type->is_nil_type())
63697958 250 {
2c809f8f 251 Expression* nil = Expression::make_nil(location);
252 return Expression::make_interface_value(lhs_type, nil, nil, location);
63697958 253 }
e440a328 254
255 // This should have been checked already.
2b8629dd 256 if (!lhs_interface_type->implements_interface(rhs_type, NULL))
257 {
258 go_assert(saw_errors());
259 return Expression::make_error(location);
260 }
e440a328 261
e440a328 262 // An interface is a tuple. If LHS_TYPE is an empty interface type,
263 // then the first field is the type descriptor for RHS_TYPE.
264 // Otherwise it is the interface method table for RHS_TYPE.
2c809f8f 265 Expression* first_field;
e440a328 266 if (lhs_is_empty)
2c809f8f 267 first_field = Expression::make_type_descriptor(rhs_type, location);
e440a328 268 else
269 {
270 // Build the interface method table for this interface and this
271 // object type: a list of function pointers for each interface
272 // method.
273 Named_type* rhs_named_type = rhs_type->named_type();
c0cab2ec 274 Struct_type* rhs_struct_type = rhs_type->struct_type();
e440a328 275 bool is_pointer = false;
c0cab2ec 276 if (rhs_named_type == NULL && rhs_struct_type == NULL)
e440a328 277 {
278 rhs_named_type = rhs_type->deref()->named_type();
c0cab2ec 279 rhs_struct_type = rhs_type->deref()->struct_type();
e440a328 280 is_pointer = true;
281 }
c0cab2ec 282 if (rhs_named_type != NULL)
2c809f8f 283 first_field =
284 rhs_named_type->interface_method_table(lhs_interface_type,
285 is_pointer);
c0cab2ec 286 else if (rhs_struct_type != NULL)
2c809f8f 287 first_field =
288 rhs_struct_type->interface_method_table(lhs_interface_type,
289 is_pointer);
c0cab2ec 290 else
2c809f8f 291 first_field = Expression::make_nil(location);
e440a328 292 }
e440a328 293
2c809f8f 294 Expression* obj;
e440a328 295 if (rhs_type->points_to() != NULL)
296 {
2c809f8f 297 // We are assigning a pointer to the interface; the interface
e440a328 298 // holds the pointer itself.
2c809f8f 299 obj = rhs;
300 }
301 else
302 {
303 // We are assigning a non-pointer value to the interface; the
45ff893b 304 // interface gets a copy of the value in the heap if it escapes.
305 // TODO(cmang): Associate escape state state of RHS with newly
306 // created OBJ.
2c809f8f 307 obj = Expression::make_heap_expression(rhs, location);
e440a328 308 }
309
2c809f8f 310 return Expression::make_interface_value(lhs_type, first_field, obj, location);
311}
e440a328 312
2c809f8f 313// Return an expression for the type descriptor of RHS.
e440a328 314
2c809f8f 315Expression*
316Expression::get_interface_type_descriptor(Expression* rhs)
317{
318 go_assert(rhs->type()->interface_type() != NULL);
319 Location location = rhs->location();
e440a328 320
2c809f8f 321 // The type descriptor is the first field of an empty interface.
322 if (rhs->type()->interface_type()->is_empty())
323 return Expression::make_interface_info(rhs, INTERFACE_INFO_TYPE_DESCRIPTOR,
324 location);
325
326 Expression* mtable =
327 Expression::make_interface_info(rhs, INTERFACE_INFO_METHODS, location);
e440a328 328
2c809f8f 329 Expression* descriptor =
f614ea8b 330 Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, location);
2c809f8f 331 descriptor = Expression::make_field_reference(descriptor, 0, location);
332 Expression* nil = Expression::make_nil(location);
e440a328 333
2c809f8f 334 Expression* eq =
335 Expression::make_binary(OPERATOR_EQEQ, mtable, nil, location);
336 return Expression::make_conditional(eq, nil, descriptor, location);
e440a328 337}
338
2c809f8f 339// Return an expression for the conversion of an interface type to an
e440a328 340// interface type.
341
2c809f8f 342Expression*
343Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
344 bool for_type_guard,
345 Location location)
e440a328 346{
3a522dcc 347 if (Type::are_identical(lhs_type, rhs->type(),
348 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
349 NULL))
8ba8cc87 350 return rhs;
351
e440a328 352 Interface_type* lhs_interface_type = lhs_type->interface_type();
353 bool lhs_is_empty = lhs_interface_type->is_empty();
354
e440a328 355 // In the general case this requires runtime examination of the type
356 // method table to match it up with the interface methods.
357
358 // FIXME: If all of the methods in the right hand side interface
359 // also appear in the left hand side interface, then we don't need
360 // to do a runtime check, although we still need to build a new
361 // method table.
362
8ba8cc87 363 // We are going to evaluate RHS multiple times.
364 go_assert(rhs->is_variable());
365
e440a328 366 // Get the type descriptor for the right hand side. This will be
367 // NULL for a nil interface.
2c809f8f 368 Expression* rhs_type_expr = Expression::get_interface_type_descriptor(rhs);
369 Expression* lhs_type_expr =
370 Expression::make_type_descriptor(lhs_type, location);
e440a328 371
2c809f8f 372 Expression* first_field;
e440a328 373 if (for_type_guard)
374 {
375 // A type assertion fails when converting a nil interface.
6098d6cb 376 first_field = Runtime::make_call(Runtime::ASSERTITAB, location, 2,
377 lhs_type_expr, rhs_type_expr);
e440a328 378 }
379 else if (lhs_is_empty)
380 {
2c809f8f 381 // A conversion to an empty interface always succeeds, and the
e440a328 382 // first field is just the type descriptor of the object.
2c809f8f 383 first_field = rhs_type_expr;
e440a328 384 }
385 else
386 {
387 // A conversion to a non-empty interface may fail, but unlike a
388 // type assertion converting nil will always succeed.
6098d6cb 389 first_field = Runtime::make_call(Runtime::REQUIREITAB, location, 2,
390 lhs_type_expr, rhs_type_expr);
e440a328 391 }
392
393 // The second field is simply the object pointer.
2c809f8f 394 Expression* obj =
395 Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT, location);
396 return Expression::make_interface_value(lhs_type, first_field, obj, location);
e440a328 397}
398
2c809f8f 399// Return an expression for the conversion of an interface type to a
e440a328 400// non-interface type.
401
2c809f8f 402Expression*
403Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs,
404 Location location)
e440a328 405{
8ba8cc87 406 // We are going to evaluate RHS multiple times.
407 go_assert(rhs->is_variable());
408
e440a328 409 // Call a function to check that the type is valid. The function
410 // will panic with an appropriate runtime type error if the type is
411 // not valid.
2c809f8f 412 Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type,
413 location);
414 Expression* rhs_descriptor =
415 Expression::get_interface_type_descriptor(rhs);
416
417 Type* rhs_type = rhs->type();
418 Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
419 location);
420
6098d6cb 421 Expression* check_iface = Runtime::make_call(Runtime::ASSERTI2T,
2c809f8f 422 location, 3, lhs_type_expr,
423 rhs_descriptor, rhs_inter_expr);
e440a328 424
425 // If the call succeeds, pull out the value.
2c809f8f 426 Expression* obj = Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT,
427 location);
e440a328 428
429 // If the value is a pointer, then it is the value we want.
430 // Otherwise it points to the value.
431 if (lhs_type->points_to() == NULL)
432 {
2c809f8f 433 obj = Expression::make_unsafe_cast(Type::make_pointer_type(lhs_type), obj,
434 location);
f614ea8b 435 obj = Expression::make_dereference(obj, NIL_CHECK_NOT_NEEDED,
436 location);
e440a328 437 }
2c809f8f 438 return Expression::make_compound(check_iface, obj, location);
e440a328 439}
440
ea664253 441// Convert an expression to its backend representation. This is implemented by
442// the child class. Not that it is not in general safe to call this multiple
e440a328 443// times for a single expression, but that we don't catch such errors.
444
ea664253 445Bexpression*
446Expression::get_backend(Translate_context* context)
e440a328 447{
448 // The child may have marked this expression as having an error.
449 if (this->classification_ == EXPRESSION_ERROR)
ea664253 450 return context->backend()->error_expression();
e440a328 451
ea664253 452 return this->do_get_backend(context);
e440a328 453}
454
48c2a53a 455// Return a backend expression for VAL.
456Bexpression*
457Expression::backend_numeric_constant_expression(Translate_context* context,
458 Numeric_constant* val)
e440a328 459{
48c2a53a 460 Gogo* gogo = context->gogo();
461 Type* type = val->type();
462 if (type == NULL)
463 return gogo->backend()->error_expression();
e440a328 464
48c2a53a 465 Btype* btype = type->get_backend(gogo);
466 Bexpression* ret;
467 if (type->integer_type() != NULL)
e440a328 468 {
469 mpz_t ival;
48c2a53a 470 if (!val->to_int(&ival))
471 {
472 go_assert(saw_errors());
473 return gogo->backend()->error_expression();
474 }
475 ret = gogo->backend()->integer_constant_expression(btype, ival);
e440a328 476 mpz_clear(ival);
e440a328 477 }
48c2a53a 478 else if (type->float_type() != NULL)
e440a328 479 {
48c2a53a 480 mpfr_t fval;
481 if (!val->to_float(&fval))
482 {
483 go_assert(saw_errors());
484 return gogo->backend()->error_expression();
485 }
486 ret = gogo->backend()->float_constant_expression(btype, fval);
487 mpfr_clear(fval);
e440a328 488 }
48c2a53a 489 else if (type->complex_type() != NULL)
e440a328 490 {
fcbea5e4 491 mpc_t cval;
492 if (!val->to_complex(&cval))
48c2a53a 493 {
494 go_assert(saw_errors());
495 return gogo->backend()->error_expression();
496 }
fcbea5e4 497 ret = gogo->backend()->complex_constant_expression(btype, cval);
498 mpc_clear(cval);
e440a328 499 }
500 else
c3e6f413 501 go_unreachable();
e440a328 502
48c2a53a 503 return ret;
e440a328 504}
505
2c809f8f 506// Return an expression which evaluates to true if VAL, of arbitrary integer
507// type, is negative or is more than the maximum value of the Go type "int".
e440a328 508
2c809f8f 509Expression*
510Expression::check_bounds(Expression* val, Location loc)
e440a328 511{
2c809f8f 512 Type* val_type = val->type();
513 Type* bound_type = Type::lookup_integer_type("int");
514
515 int val_type_size;
516 bool val_is_unsigned = false;
517 if (val_type->integer_type() != NULL)
518 {
519 val_type_size = val_type->integer_type()->bits();
520 val_is_unsigned = val_type->integer_type()->is_unsigned();
521 }
522 else
523 {
524 if (!val_type->is_numeric_type()
525 || !Type::are_convertible(bound_type, val_type, NULL))
526 {
527 go_assert(saw_errors());
528 return Expression::make_boolean(true, loc);
529 }
e440a328 530
2c809f8f 531 if (val_type->complex_type() != NULL)
532 val_type_size = val_type->complex_type()->bits();
533 else
534 val_type_size = val_type->float_type()->bits();
535 }
536
537 Expression* negative_index = Expression::make_boolean(false, loc);
538 Expression* index_overflows = Expression::make_boolean(false, loc);
539 if (!val_is_unsigned)
e440a328 540 {
e67508fa 541 Expression* zero = Expression::make_integer_ul(0, val_type, loc);
2c809f8f 542 negative_index = Expression::make_binary(OPERATOR_LT, val, zero, loc);
e440a328 543 }
544
2c809f8f 545 int bound_type_size = bound_type->integer_type()->bits();
c3068ac0 546 if (val_type_size > bound_type_size
547 || (val_type_size == bound_type_size
2c809f8f 548 && val_is_unsigned))
549 {
550 mpz_t one;
551 mpz_init_set_ui(one, 1UL);
552
553 // maxval = 2^(bound_type_size - 1) - 1
554 mpz_t maxval;
555 mpz_init(maxval);
556 mpz_mul_2exp(maxval, one, bound_type_size - 1);
557 mpz_sub_ui(maxval, maxval, 1);
e67508fa 558 Expression* max = Expression::make_integer_z(&maxval, val_type, loc);
2c809f8f 559 mpz_clear(one);
560 mpz_clear(maxval);
561
562 index_overflows = Expression::make_binary(OPERATOR_GT, val, max, loc);
e440a328 563 }
564
2c809f8f 565 return Expression::make_binary(OPERATOR_OROR, negative_index, index_overflows,
566 loc);
e440a328 567}
568
d751bb78 569void
570Expression::dump_expression(Ast_dump_context* ast_dump_context) const
571{
572 this->do_dump_expression(ast_dump_context);
573}
574
e440a328 575// Error expressions. This are used to avoid cascading errors.
576
577class Error_expression : public Expression
578{
579 public:
b13c66cd 580 Error_expression(Location location)
e440a328 581 : Expression(EXPRESSION_ERROR, location)
582 { }
583
584 protected:
585 bool
586 do_is_constant() const
587 { return true; }
588
589 bool
0c77715b 590 do_numeric_constant_value(Numeric_constant* nc) const
e440a328 591 {
0c77715b 592 nc->set_unsigned_long(NULL, 0);
e440a328 593 return true;
594 }
595
4f2138d7 596 bool
e440a328 597 do_discarding_value()
4f2138d7 598 { return true; }
e440a328 599
600 Type*
601 do_type()
602 { return Type::make_error_type(); }
603
604 void
605 do_determine_type(const Type_context*)
606 { }
607
608 Expression*
609 do_copy()
610 { return this; }
611
612 bool
613 do_is_addressable() const
614 { return true; }
615
ea664253 616 Bexpression*
617 do_get_backend(Translate_context* context)
618 { return context->backend()->error_expression(); }
d751bb78 619
620 void
621 do_dump_expression(Ast_dump_context*) const;
e440a328 622};
623
d751bb78 624// Dump the ast representation for an error expression to a dump context.
625
626void
627Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
628{
629 ast_dump_context->ostream() << "_Error_" ;
630}
631
e440a328 632Expression*
b13c66cd 633Expression::make_error(Location location)
e440a328 634{
635 return new Error_expression(location);
636}
637
638// An expression which is really a type. This is used during parsing.
639// It is an error if these survive after lowering.
640
641class
642Type_expression : public Expression
643{
644 public:
b13c66cd 645 Type_expression(Type* type, Location location)
e440a328 646 : Expression(EXPRESSION_TYPE, location),
647 type_(type)
648 { }
649
650 protected:
651 int
652 do_traverse(Traverse* traverse)
653 { return Type::traverse(this->type_, traverse); }
654
655 Type*
656 do_type()
657 { return this->type_; }
658
659 void
660 do_determine_type(const Type_context*)
661 { }
662
663 void
664 do_check_types(Gogo*)
665 { this->report_error(_("invalid use of type")); }
666
667 Expression*
668 do_copy()
669 { return this; }
670
ea664253 671 Bexpression*
672 do_get_backend(Translate_context*)
c3e6f413 673 { go_unreachable(); }
e440a328 674
d751bb78 675 void do_dump_expression(Ast_dump_context*) const;
f03a9fbf 676
e440a328 677 private:
678 // The type which we are representing as an expression.
679 Type* type_;
680};
681
d751bb78 682void
683Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
684{
685 ast_dump_context->dump_type(this->type_);
686}
687
e440a328 688Expression*
b13c66cd 689Expression::make_type(Type* type, Location location)
e440a328 690{
691 return new Type_expression(type, location);
692}
693
e03bdf36 694// Class Parser_expression.
695
696Type*
697Parser_expression::do_type()
698{
699 // We should never really ask for the type of a Parser_expression.
700 // However, it can happen, at least when we have an invalid const
701 // whose initializer refers to the const itself. In that case we
702 // may ask for the type when lowering the const itself.
c484d925 703 go_assert(saw_errors());
e03bdf36 704 return Type::make_error_type();
705}
706
e440a328 707// Class Var_expression.
708
709// Lower a variable expression. Here we just make sure that the
710// initialization expression of the variable has been lowered. This
711// ensures that we will be able to determine the type of the variable
712// if necessary.
713
714Expression*
ceeb4318 715Var_expression::do_lower(Gogo* gogo, Named_object* function,
716 Statement_inserter* inserter, int)
e440a328 717{
718 if (this->variable_->is_variable())
719 {
720 Variable* var = this->variable_->var_value();
721 // This is either a local variable or a global variable. A
722 // reference to a variable which is local to an enclosing
723 // function will be a reference to a field in a closure.
724 if (var->is_global())
ceeb4318 725 {
726 function = NULL;
727 inserter = NULL;
728 }
729 var->lower_init_expression(gogo, function, inserter);
e440a328 730 }
731 return this;
732}
733
e440a328 734// Return the type of a reference to a variable.
735
736Type*
737Var_expression::do_type()
738{
739 if (this->variable_->is_variable())
740 return this->variable_->var_value()->type();
741 else if (this->variable_->is_result_variable())
742 return this->variable_->result_var_value()->type();
743 else
c3e6f413 744 go_unreachable();
e440a328 745}
746
0ab09e06 747// Determine the type of a reference to a variable.
748
749void
750Var_expression::do_determine_type(const Type_context*)
751{
752 if (this->variable_->is_variable())
753 this->variable_->var_value()->determine_type();
754}
755
e440a328 756// Something takes the address of this variable. This means that we
757// may want to move the variable onto the heap.
758
759void
760Var_expression::do_address_taken(bool escapes)
761{
762 if (!escapes)
f325319b 763 {
764 if (this->variable_->is_variable())
765 this->variable_->var_value()->set_non_escaping_address_taken();
766 else if (this->variable_->is_result_variable())
767 this->variable_->result_var_value()->set_non_escaping_address_taken();
768 else
769 go_unreachable();
770 }
e440a328 771 else
f325319b 772 {
773 if (this->variable_->is_variable())
774 this->variable_->var_value()->set_address_taken();
775 else if (this->variable_->is_result_variable())
776 this->variable_->result_var_value()->set_address_taken();
777 else
778 go_unreachable();
779 }
45ff893b 780
781 if (this->variable_->is_variable()
782 && this->variable_->var_value()->is_in_heap())
783 {
784 Node::make_node(this)->set_encoding(Node::ESCAPE_HEAP);
785 Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
786 }
e440a328 787}
788
5f6f5357 789// The cost to inline a variable reference. We currently only support
790// references to parameters.
791
792int
793Var_expression::do_inlining_cost() const
794{
795 if (this->variable_->is_variable())
796 {
797 if (this->variable_->var_value()->is_parameter())
798 return 1;
799 }
800 else if (this->variable_->is_result_variable())
801 return 1;
802
803 return 0x100000;
804}
805
806// Export a reference to a variable.
807
808void
809Var_expression::do_export(Export_function_body* efb) const
810{
811 efb->write_string(Gogo::unpack_hidden_name(this->variable_->name()));
812}
813
ea664253 814// Get the backend representation for a reference to a variable.
e440a328 815
ea664253 816Bexpression*
817Var_expression::do_get_backend(Translate_context* context)
e440a328 818{
fe2f84cf 819 Bvariable* bvar = this->variable_->get_backend_variable(context->gogo(),
820 context->function());
fe2f84cf 821 bool is_in_heap;
c6777780 822 Location loc = this->location();
9b27b43c 823 Btype* btype;
824 Gogo* gogo = context->gogo();
fe2f84cf 825 if (this->variable_->is_variable())
9b27b43c 826 {
827 is_in_heap = this->variable_->var_value()->is_in_heap();
828 btype = this->variable_->var_value()->type()->get_backend(gogo);
829 }
fe2f84cf 830 else if (this->variable_->is_result_variable())
9b27b43c 831 {
832 is_in_heap = this->variable_->result_var_value()->is_in_heap();
833 btype = this->variable_->result_var_value()->type()->get_backend(gogo);
834 }
fe2f84cf 835 else
c3e6f413 836 go_unreachable();
c6777780 837
d4e6573e 838 Bexpression* ret =
7af8e400 839 context->backend()->var_expression(bvar, loc);
fe2f84cf 840 if (is_in_heap)
9b27b43c 841 ret = context->backend()->indirect_expression(btype, ret, true, loc);
ea664253 842 return ret;
e440a328 843}
844
d751bb78 845// Ast dump for variable expression.
846
847void
848Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
849{
cd5e24c1 850 ast_dump_context->ostream() << this->variable_->message_name() ;
d751bb78 851}
852
e440a328 853// Make a reference to a variable in an expression.
854
855Expression*
b13c66cd 856Expression::make_var_reference(Named_object* var, Location location)
e440a328 857{
858 if (var->is_sink())
859 return Expression::make_sink(location);
860
861 // FIXME: Creating a new object for each reference to a variable is
862 // wasteful.
863 return new Var_expression(var, location);
864}
865
b0c09712 866// Class Enclosed_var_expression.
867
868int
869Enclosed_var_expression::do_traverse(Traverse*)
870{
871 return TRAVERSE_CONTINUE;
872}
873
874// Lower the reference to the enclosed variable.
875
876Expression*
877Enclosed_var_expression::do_lower(Gogo* gogo, Named_object* function,
878 Statement_inserter* inserter, int)
879{
880 gogo->lower_expression(function, inserter, &this->reference_);
881 return this;
882}
883
884// Flatten the reference to the enclosed variable.
885
886Expression*
887Enclosed_var_expression::do_flatten(Gogo* gogo, Named_object* function,
888 Statement_inserter* inserter)
889{
890 gogo->flatten_expression(function, inserter, &this->reference_);
891 return this;
892}
893
894void
895Enclosed_var_expression::do_address_taken(bool escapes)
896{
897 if (!escapes)
898 {
899 if (this->variable_->is_variable())
900 this->variable_->var_value()->set_non_escaping_address_taken();
901 else if (this->variable_->is_result_variable())
902 this->variable_->result_var_value()->set_non_escaping_address_taken();
903 else
904 go_unreachable();
905 }
906 else
907 {
908 if (this->variable_->is_variable())
909 this->variable_->var_value()->set_address_taken();
910 else if (this->variable_->is_result_variable())
911 this->variable_->result_var_value()->set_address_taken();
912 else
913 go_unreachable();
914 }
45ff893b 915
916 if (this->variable_->is_variable()
917 && this->variable_->var_value()->is_in_heap())
918 Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
b0c09712 919}
920
921// Ast dump for enclosed variable expression.
922
923void
924Enclosed_var_expression::do_dump_expression(Ast_dump_context* adc) const
925{
cd5e24c1 926 adc->ostream() << this->variable_->message_name();
b0c09712 927}
928
929// Make a reference to a variable within an enclosing function.
930
931Expression*
932Expression::make_enclosing_var_reference(Expression* reference,
933 Named_object* var, Location location)
934{
935 return new Enclosed_var_expression(reference, var, location);
936}
937
e440a328 938// Class Temporary_reference_expression.
939
940// The type.
941
942Type*
943Temporary_reference_expression::do_type()
944{
945 return this->statement_->type();
946}
947
948// Called if something takes the address of this temporary variable.
949// We never have to move temporary variables to the heap, but we do
950// need to know that they must live in the stack rather than in a
951// register.
952
953void
954Temporary_reference_expression::do_address_taken(bool)
955{
956 this->statement_->set_is_address_taken();
957}
958
ea664253 959// Get a backend expression referring to the variable.
e440a328 960
ea664253 961Bexpression*
962Temporary_reference_expression::do_get_backend(Translate_context* context)
e440a328 963{
cd440cff 964 Gogo* gogo = context->gogo();
eefc1ed3 965 Bvariable* bvar = this->statement_->get_backend_variable(context);
7af8e400 966 Bexpression* ret = gogo->backend()->var_expression(bvar, this->location());
eefc1ed3 967
cd440cff 968 // The backend can't always represent the same set of recursive types
eefc1ed3 969 // that the Go frontend can. In some cases this means that a
970 // temporary variable won't have the right backend type. Correct
971 // that here by adding a type cast. We need to use base() to push
972 // the circularity down one level.
cd440cff 973 Type* stype = this->statement_->type();
ceeb4318 974 if (!this->is_lvalue_
03118c21 975 && stype->points_to() != NULL
976 && stype->points_to()->is_void_type())
eefc1ed3 977 {
cd440cff 978 Btype* btype = this->type()->base()->get_backend(gogo);
979 ret = gogo->backend()->convert_expression(btype, ret, this->location());
eefc1ed3 980 }
ea664253 981 return ret;
e440a328 982}
983
d751bb78 984// Ast dump for temporary reference.
985
986void
987Temporary_reference_expression::do_dump_expression(
988 Ast_dump_context* ast_dump_context) const
989{
990 ast_dump_context->dump_temp_variable_name(this->statement_);
991}
992
e440a328 993// Make a reference to a temporary variable.
994
ceeb4318 995Temporary_reference_expression*
e440a328 996Expression::make_temporary_reference(Temporary_statement* statement,
b13c66cd 997 Location location)
e440a328 998{
999 return new Temporary_reference_expression(statement, location);
1000}
1001
e9d3367e 1002// Class Set_and_use_temporary_expression.
1003
1004// Return the type.
1005
1006Type*
1007Set_and_use_temporary_expression::do_type()
1008{
1009 return this->statement_->type();
1010}
1011
0afbb937 1012// Determine the type of the expression.
1013
1014void
1015Set_and_use_temporary_expression::do_determine_type(
1016 const Type_context* context)
1017{
1018 this->expr_->determine_type(context);
1019}
1020
e9d3367e 1021// Take the address.
1022
1023void
1024Set_and_use_temporary_expression::do_address_taken(bool)
1025{
1026 this->statement_->set_is_address_taken();
1027}
1028
1029// Return the backend representation.
1030
ea664253 1031Bexpression*
1032Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
e9d3367e 1033{
e9d3367e 1034 Location loc = this->location();
a302c105 1035 Gogo* gogo = context->gogo();
1036 Bvariable* bvar = this->statement_->get_backend_variable(context);
7af8e400 1037 Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, loc);
a302c105 1038
0ab48656 1039 Named_object* fn = context->function();
1040 go_assert(fn != NULL);
1041 Bfunction* bfn = fn->func_value()->get_or_make_decl(gogo, fn);
ea664253 1042 Bexpression* bexpr = this->expr_->get_backend(context);
0ab48656 1043 Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref,
1044 bexpr, loc);
7af8e400 1045 Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc);
a302c105 1046 Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
ea664253 1047 return ret;
e9d3367e 1048}
1049
1050// Dump.
1051
1052void
1053Set_and_use_temporary_expression::do_dump_expression(
1054 Ast_dump_context* ast_dump_context) const
1055{
1056 ast_dump_context->ostream() << '(';
1057 ast_dump_context->dump_temp_variable_name(this->statement_);
1058 ast_dump_context->ostream() << " = ";
1059 this->expr_->dump_expression(ast_dump_context);
1060 ast_dump_context->ostream() << ')';
1061}
1062
1063// Make a set-and-use temporary.
1064
1065Set_and_use_temporary_expression*
1066Expression::make_set_and_use_temporary(Temporary_statement* statement,
1067 Expression* expr, Location location)
1068{
1069 return new Set_and_use_temporary_expression(statement, expr, location);
1070}
1071
e440a328 1072// A sink expression--a use of the blank identifier _.
1073
1074class Sink_expression : public Expression
1075{
1076 public:
b13c66cd 1077 Sink_expression(Location location)
e440a328 1078 : Expression(EXPRESSION_SINK, location),
aa93217a 1079 type_(NULL), bvar_(NULL)
e440a328 1080 { }
1081
1082 protected:
4f2138d7 1083 bool
e440a328 1084 do_discarding_value()
4f2138d7 1085 { return true; }
e440a328 1086
1087 Type*
1088 do_type();
1089
1090 void
1091 do_determine_type(const Type_context*);
1092
1093 Expression*
1094 do_copy()
1095 { return new Sink_expression(this->location()); }
1096
ea664253 1097 Bexpression*
1098 do_get_backend(Translate_context*);
e440a328 1099
d751bb78 1100 void
1101 do_dump_expression(Ast_dump_context*) const;
1102
e440a328 1103 private:
1104 // The type of this sink variable.
1105 Type* type_;
1106 // The temporary variable we generate.
aa93217a 1107 Bvariable* bvar_;
e440a328 1108};
1109
1110// Return the type of a sink expression.
1111
1112Type*
1113Sink_expression::do_type()
1114{
1115 if (this->type_ == NULL)
1116 return Type::make_sink_type();
1117 return this->type_;
1118}
1119
1120// Determine the type of a sink expression.
1121
1122void
1123Sink_expression::do_determine_type(const Type_context* context)
1124{
1125 if (context->type != NULL)
1126 this->type_ = context->type;
1127}
1128
1129// Return a temporary variable for a sink expression. This will
1130// presumably be a write-only variable which the middle-end will drop.
1131
ea664253 1132Bexpression*
1133Sink_expression::do_get_backend(Translate_context* context)
e440a328 1134{
aa93217a 1135 Location loc = this->location();
1136 Gogo* gogo = context->gogo();
1137 if (this->bvar_ == NULL)
e440a328 1138 {
c484d925 1139 go_assert(this->type_ != NULL && !this->type_->is_sink_type());
aa93217a 1140 Named_object* fn = context->function();
1141 go_assert(fn != NULL);
1142 Bfunction* fn_ctx = fn->func_value()->get_or_make_decl(gogo, fn);
9f0e0513 1143 Btype* bt = this->type_->get_backend(context->gogo());
aa93217a 1144 Bstatement* decl;
1145 this->bvar_ =
1146 gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL,
1147 false, loc, &decl);
d4e6573e 1148 Bexpression* var_ref =
7af8e400 1149 gogo->backend()->var_expression(this->bvar_, loc);
aa93217a 1150 var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
ea664253 1151 return var_ref;
e440a328 1152 }
7af8e400 1153 return gogo->backend()->var_expression(this->bvar_, loc);
e440a328 1154}
1155
d751bb78 1156// Ast dump for sink expression.
1157
1158void
1159Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1160{
1161 ast_dump_context->ostream() << "_" ;
1162}
1163
e440a328 1164// Make a sink expression.
1165
1166Expression*
b13c66cd 1167Expression::make_sink(Location location)
e440a328 1168{
1169 return new Sink_expression(location);
1170}
1171
1172// Class Func_expression.
1173
1174// FIXME: Can a function expression appear in a constant expression?
1175// The value is unchanging. Initializing a constant to the address of
1176// a function seems like it could work, though there might be little
1177// point to it.
1178
e440a328 1179// Traversal.
1180
1181int
1182Func_expression::do_traverse(Traverse* traverse)
1183{
1184 return (this->closure_ == NULL
1185 ? TRAVERSE_CONTINUE
1186 : Expression::traverse(&this->closure_, traverse));
1187}
1188
1189// Return the type of a function expression.
1190
1191Type*
1192Func_expression::do_type()
1193{
1194 if (this->function_->is_function())
1195 return this->function_->func_value()->type();
1196 else if (this->function_->is_function_declaration())
1197 return this->function_->func_declaration_value()->type();
1198 else
c3e6f413 1199 go_unreachable();
e440a328 1200}
1201
ea664253 1202// Get the backend representation for the code of a function expression.
e440a328 1203
97267c39 1204Bexpression*
8381eda7 1205Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc)
e440a328 1206{
1207 Function_type* fntype;
8381eda7 1208 if (no->is_function())
1209 fntype = no->func_value()->type();
1210 else if (no->is_function_declaration())
1211 fntype = no->func_declaration_value()->type();
e440a328 1212 else
c3e6f413 1213 go_unreachable();
e440a328 1214
1215 // Builtin functions are handled specially by Call_expression. We
1216 // can't take their address.
1217 if (fntype->is_builtin())
1218 {
631d5788 1219 go_error_at(loc,
1220 "invalid use of special builtin function %qs; must be called",
1221 no->message_name().c_str());
97267c39 1222 return gogo->backend()->error_expression();
e440a328 1223 }
1224
97267c39 1225 Bfunction* fndecl;
e440a328 1226 if (no->is_function())
cf3cae55 1227 fndecl = no->func_value()->get_or_make_decl(gogo, no);
e440a328 1228 else if (no->is_function_declaration())
cf3cae55 1229 fndecl = no->func_declaration_value()->get_or_make_decl(gogo, no);
e440a328 1230 else
c3e6f413 1231 go_unreachable();
e440a328 1232
97267c39 1233 return gogo->backend()->function_code_expression(fndecl, loc);
e440a328 1234}
1235
ea664253 1236// Get the backend representation for a function expression. This is used when
1237// we take the address of a function rather than simply calling it. A func
8381eda7 1238// value is represented as a pointer to a block of memory. The first
1239// word of that memory is a pointer to the function code. The
1240// remaining parts of that memory are the addresses of variables that
1241// the function closes over.
e440a328 1242
ea664253 1243Bexpression*
1244Func_expression::do_get_backend(Translate_context* context)
e440a328 1245{
8381eda7 1246 // If there is no closure, just use the function descriptor.
2010c17a 1247 if (this->closure_ == NULL)
8381eda7 1248 {
1249 Gogo* gogo = context->gogo();
1250 Named_object* no = this->function_;
1251 Expression* descriptor;
1252 if (no->is_function())
1253 descriptor = no->func_value()->descriptor(gogo, no);
1254 else if (no->is_function_declaration())
1255 {
1256 if (no->func_declaration_value()->type()->is_builtin())
1257 {
631d5788 1258 go_error_at(this->location(),
1259 ("invalid use of special builtin function %qs; "
1260 "must be called"),
1261 no->message_name().c_str());
ea664253 1262 return gogo->backend()->error_expression();
8381eda7 1263 }
1264 descriptor = no->func_declaration_value()->descriptor(gogo, no);
1265 }
1266 else
1267 go_unreachable();
2010c17a 1268
ea664253 1269 Bexpression* bdesc = descriptor->get_backend(context);
1270 return gogo->backend()->address_expression(bdesc, this->location());
8381eda7 1271 }
e440a328 1272
8381eda7 1273 go_assert(this->function_->func_value()->enclosing() != NULL);
e440a328 1274
8381eda7 1275 // If there is a closure, then the closure is itself the function
1276 // expression. It is a pointer to a struct whose first field points
1277 // to the function code and whose remaining fields are the addresses
1278 // of the closed-over variables.
76818e19 1279 Bexpression *bexpr = this->closure_->get_backend(context);
1280
1281 // Introduce a backend type conversion, to account for any differences
1282 // between the argument type (function descriptor, struct with a
1283 // single field) and the closure (struct with multiple fields).
1284 Gogo* gogo = context->gogo();
1285 Btype *btype = this->type()->get_backend(gogo);
1286 return gogo->backend()->convert_expression(btype, bexpr, this->location());
e440a328 1287}
1288
d751bb78 1289// Ast dump for function.
1290
1291void
1292Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1293{
8b1c301d 1294 ast_dump_context->ostream() << this->function_->name();
1295 if (this->closure_ != NULL)
1296 {
1297 ast_dump_context->ostream() << " {closure = ";
1298 this->closure_->dump_expression(ast_dump_context);
1299 ast_dump_context->ostream() << "}";
1300 }
d751bb78 1301}
1302
e440a328 1303// Make a reference to a function in an expression.
1304
1305Expression*
1306Expression::make_func_reference(Named_object* function, Expression* closure,
b13c66cd 1307 Location location)
e440a328 1308{
b1d7ecfa 1309 Func_expression* fe = new Func_expression(function, closure, location);
1310
1311 // Detect references to builtin functions and set the runtime code if
1312 // appropriate.
1313 if (function->is_function_declaration())
1314 fe->set_runtime_code(Runtime::name_to_code(function->name()));
1315 return fe;
e440a328 1316}
1317
c6837989 1318// Class Func_descriptor_expression.
8381eda7 1319
c6837989 1320// Constructor.
8381eda7 1321
c6837989 1322Func_descriptor_expression::Func_descriptor_expression(Named_object* fn)
1323 : Expression(EXPRESSION_FUNC_DESCRIPTOR, fn->location()),
f8bdf81a 1324 fn_(fn), dvar_(NULL)
c6837989 1325{
1326 go_assert(!fn->is_function() || !fn->func_value()->needs_closure());
1327}
8381eda7 1328
c6837989 1329// Traversal.
8381eda7 1330
c6837989 1331int
1332Func_descriptor_expression::do_traverse(Traverse*)
1333{
1334 return TRAVERSE_CONTINUE;
1335}
8381eda7 1336
1337// All function descriptors have the same type.
1338
1339Type* Func_descriptor_expression::descriptor_type;
1340
1341void
1342Func_descriptor_expression::make_func_descriptor_type()
1343{
1344 if (Func_descriptor_expression::descriptor_type != NULL)
1345 return;
1346 Type* uintptr_type = Type::lookup_integer_type("uintptr");
81487fff 1347 Type* struct_type = Type::make_builtin_struct_type(1, "fn", uintptr_type);
8381eda7 1348 Func_descriptor_expression::descriptor_type =
1349 Type::make_builtin_named_type("functionDescriptor", struct_type);
1350}
1351
1352Type*
1353Func_descriptor_expression::do_type()
1354{
1355 Func_descriptor_expression::make_func_descriptor_type();
1356 return Func_descriptor_expression::descriptor_type;
1357}
1358
ea664253 1359// The backend representation for a function descriptor.
8381eda7 1360
ea664253 1361Bexpression*
1362Func_descriptor_expression::do_get_backend(Translate_context* context)
8381eda7 1363{
8381eda7 1364 Named_object* no = this->fn_;
1365 Location loc = no->location();
ea664253 1366 if (this->dvar_ != NULL)
7af8e400 1367 return context->backend()->var_expression(this->dvar_, loc);
8381eda7 1368
ea664253 1369 Gogo* gogo = context->gogo();
19272321 1370 std::string var_name(gogo->function_descriptor_name(no));
09e57698 1371 bool is_descriptor = false;
1372 if (no->is_function_declaration()
1373 && !no->func_declaration_value()->asm_name().empty()
1374 && Linemap::is_predeclared_location(no->location()))
19272321 1375 is_descriptor = true;
8381eda7 1376
13f2fdb8 1377 // The runtime package implements some functions defined in the
1378 // syscall package. Let the syscall package define the descriptor
1379 // in this case.
1380 if (gogo->compiling_runtime()
1381 && gogo->package_name() == "runtime"
1382 && no->is_function()
1383 && !no->func_value()->asm_name().empty()
1384 && no->func_value()->asm_name().compare(0, 8, "syscall.") == 0)
1385 is_descriptor = true;
1386
8381eda7 1387 Btype* btype = this->type()->get_backend(gogo);
1388
1389 Bvariable* bvar;
438b4bec 1390 std::string asm_name(go_selectively_encode_id(var_name));
09e57698 1391 if (no->package() != NULL || is_descriptor)
438b4bec 1392 bvar = context->backend()->immutable_struct_reference(var_name, asm_name,
1393 btype, loc);
8381eda7 1394 else
1395 {
1396 Location bloc = Linemap::predeclared_location();
80efb81d 1397
1398 // The runtime package has hash/equality functions that are
1399 // referenced by type descriptors outside of the runtime, so the
1400 // function descriptors must be visible even though they are not
1401 // exported.
1402 bool is_exported_runtime = false;
1403 if (gogo->compiling_runtime()
1404 && gogo->package_name() == "runtime"
1405 && (no->name().find("hash") != std::string::npos
1406 || no->name().find("equal") != std::string::npos))
1407 is_exported_runtime = true;
1408
8381eda7 1409 bool is_hidden = ((no->is_function()
1410 && no->func_value()->enclosing() != NULL)
80efb81d 1411 || (Gogo::is_hidden_name(no->name())
1412 && !is_exported_runtime)
8381eda7 1413 || Gogo::is_thunk(no));
80efb81d 1414
438b4bec 1415 bvar = context->backend()->immutable_struct(var_name, asm_name,
1416 is_hidden, false,
8381eda7 1417 btype, bloc);
1418 Expression_list* vals = new Expression_list();
f8bdf81a 1419 vals->push_back(Expression::make_func_code_reference(this->fn_, bloc));
8381eda7 1420 Expression* init =
1421 Expression::make_struct_composite_literal(this->type(), vals, bloc);
1422 Translate_context bcontext(gogo, NULL, NULL, NULL);
1423 bcontext.set_is_const();
ea664253 1424 Bexpression* binit = init->get_backend(&bcontext);
8381eda7 1425 context->backend()->immutable_struct_set_init(bvar, var_name, is_hidden,
1426 false, btype, bloc, binit);
1427 }
1428
1429 this->dvar_ = bvar;
7af8e400 1430 return gogo->backend()->var_expression(bvar, loc);
8381eda7 1431}
1432
c6837989 1433// Print a function descriptor expression.
1434
1435void
1436Func_descriptor_expression::do_dump_expression(Ast_dump_context* context) const
1437{
1438 context->ostream() << "[descriptor " << this->fn_->name() << "]";
1439}
1440
8381eda7 1441// Make a function descriptor expression.
1442
c6837989 1443Func_descriptor_expression*
1444Expression::make_func_descriptor(Named_object* fn)
8381eda7 1445{
c6837989 1446 return new Func_descriptor_expression(fn);
8381eda7 1447}
1448
1449// Make the function descriptor type, so that it can be converted.
1450
1451void
1452Expression::make_func_descriptor_type()
1453{
1454 Func_descriptor_expression::make_func_descriptor_type();
1455}
1456
1457// A reference to just the code of a function.
1458
1459class Func_code_reference_expression : public Expression
1460{
1461 public:
1462 Func_code_reference_expression(Named_object* function, Location location)
1463 : Expression(EXPRESSION_FUNC_CODE_REFERENCE, location),
1464 function_(function)
1465 { }
1466
1467 protected:
1468 int
1469 do_traverse(Traverse*)
1470 { return TRAVERSE_CONTINUE; }
1471
f9ca30f9 1472 bool
3ae06f68 1473 do_is_static_initializer() const
f9ca30f9 1474 { return true; }
1475
8381eda7 1476 Type*
1477 do_type()
1478 { return Type::make_pointer_type(Type::make_void_type()); }
1479
1480 void
1481 do_determine_type(const Type_context*)
1482 { }
1483
1484 Expression*
1485 do_copy()
1486 {
1487 return Expression::make_func_code_reference(this->function_,
1488 this->location());
1489 }
1490
ea664253 1491 Bexpression*
1492 do_get_backend(Translate_context*);
8381eda7 1493
1494 void
1495 do_dump_expression(Ast_dump_context* context) const
1496 { context->ostream() << "[raw " << this->function_->name() << "]" ; }
1497
1498 private:
1499 // The function.
1500 Named_object* function_;
1501};
1502
ea664253 1503// Get the backend representation for a reference to function code.
8381eda7 1504
ea664253 1505Bexpression*
1506Func_code_reference_expression::do_get_backend(Translate_context* context)
8381eda7 1507{
ea664253 1508 return Func_expression::get_code_pointer(context->gogo(), this->function_,
1509 this->location());
8381eda7 1510}
1511
1512// Make a reference to the code of a function.
1513
1514Expression*
1515Expression::make_func_code_reference(Named_object* function, Location location)
1516{
1517 return new Func_code_reference_expression(function, location);
1518}
1519
e440a328 1520// Class Unknown_expression.
1521
1522// Return the name of an unknown expression.
1523
1524const std::string&
1525Unknown_expression::name() const
1526{
1527 return this->named_object_->name();
1528}
1529
1530// Lower a reference to an unknown name.
1531
1532Expression*
ceeb4318 1533Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
e440a328 1534{
b13c66cd 1535 Location location = this->location();
e440a328 1536 Named_object* no = this->named_object_;
deded542 1537 Named_object* real;
1538 if (!no->is_unknown())
1539 real = no;
1540 else
e440a328 1541 {
deded542 1542 real = no->unknown_value()->real_named_object();
1543 if (real == NULL)
1544 {
1545 if (this->is_composite_literal_key_)
1546 return this;
acf8e158 1547 if (!this->no_error_message_)
631d5788 1548 go_error_at(location, "reference to undefined name %qs",
1549 this->named_object_->message_name().c_str());
deded542 1550 return Expression::make_error(location);
1551 }
e440a328 1552 }
1553 switch (real->classification())
1554 {
1555 case Named_object::NAMED_OBJECT_CONST:
1556 return Expression::make_const_reference(real, location);
1557 case Named_object::NAMED_OBJECT_TYPE:
1558 return Expression::make_type(real->type_value(), location);
1559 case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
1560 if (this->is_composite_literal_key_)
1561 return this;
acf8e158 1562 if (!this->no_error_message_)
631d5788 1563 go_error_at(location, "reference to undefined type %qs",
1564 real->message_name().c_str());
e440a328 1565 return Expression::make_error(location);
1566 case Named_object::NAMED_OBJECT_VAR:
7d834090 1567 real->var_value()->set_is_used();
e440a328 1568 return Expression::make_var_reference(real, location);
1569 case Named_object::NAMED_OBJECT_FUNC:
1570 case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
1571 return Expression::make_func_reference(real, NULL, location);
1572 case Named_object::NAMED_OBJECT_PACKAGE:
1573 if (this->is_composite_literal_key_)
1574 return this;
acf8e158 1575 if (!this->no_error_message_)
631d5788 1576 go_error_at(location, "unexpected reference to package");
e440a328 1577 return Expression::make_error(location);
1578 default:
c3e6f413 1579 go_unreachable();
e440a328 1580 }
1581}
1582
d751bb78 1583// Dump the ast representation for an unknown expression to a dump context.
1584
1585void
1586Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1587{
1588 ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
1589 << ")";
d751bb78 1590}
1591
e440a328 1592// Make a reference to an unknown name.
1593
acf8e158 1594Unknown_expression*
b13c66cd 1595Expression::make_unknown_reference(Named_object* no, Location location)
e440a328 1596{
e440a328 1597 return new Unknown_expression(no, location);
1598}
1599
1600// A boolean expression.
1601
1602class Boolean_expression : public Expression
1603{
1604 public:
b13c66cd 1605 Boolean_expression(bool val, Location location)
e440a328 1606 : Expression(EXPRESSION_BOOLEAN, location),
1607 val_(val), type_(NULL)
1608 { }
1609
1610 static Expression*
bc8e2ef4 1611 do_import(Import_expression*, Location);
e440a328 1612
1613 protected:
1614 bool
1615 do_is_constant() const
1616 { return true; }
1617
0e168074 1618 bool
3ae06f68 1619 do_is_static_initializer() const
0e168074 1620 { return true; }
1621
e440a328 1622 Type*
1623 do_type();
1624
1625 void
1626 do_determine_type(const Type_context*);
1627
1628 Expression*
1629 do_copy()
1630 { return this; }
1631
ea664253 1632 Bexpression*
1633 do_get_backend(Translate_context* context)
1634 { return context->backend()->boolean_constant_expression(this->val_); }
e440a328 1635
5f6f5357 1636 int
1637 do_inlining_cost() const
1638 { return 1; }
1639
e440a328 1640 void
548be246 1641 do_export(Export_function_body* efb) const
204d4af4 1642 { efb->write_c_string(this->val_ ? "$true" : "$false"); }
e440a328 1643
d751bb78 1644 void
1645 do_dump_expression(Ast_dump_context* ast_dump_context) const
1646 { ast_dump_context->ostream() << (this->val_ ? "true" : "false"); }
1647
e440a328 1648 private:
1649 // The constant.
1650 bool val_;
1651 // The type as determined by context.
1652 Type* type_;
1653};
1654
1655// Get the type.
1656
1657Type*
1658Boolean_expression::do_type()
1659{
1660 if (this->type_ == NULL)
1661 this->type_ = Type::make_boolean_type();
1662 return this->type_;
1663}
1664
1665// Set the type from the context.
1666
1667void
1668Boolean_expression::do_determine_type(const Type_context* context)
1669{
1670 if (this->type_ != NULL && !this->type_->is_abstract())
1671 ;
1672 else if (context->type != NULL && context->type->is_boolean_type())
1673 this->type_ = context->type;
1674 else if (!context->may_be_abstract)
1675 this->type_ = Type::lookup_bool_type();
1676}
1677
1678// Import a boolean constant.
1679
1680Expression*
bc8e2ef4 1681Boolean_expression::do_import(Import_expression* imp, Location loc)
e440a328 1682{
204d4af4 1683 if (imp->version() >= EXPORT_FORMAT_V3)
1684 imp->require_c_string("$");
e440a328 1685 if (imp->peek_char() == 't')
1686 {
1687 imp->require_c_string("true");
9b92780c 1688 return Expression::make_boolean(true, loc);
e440a328 1689 }
1690 else
1691 {
1692 imp->require_c_string("false");
9b92780c 1693 return Expression::make_boolean(false, loc);
e440a328 1694 }
1695}
1696
1697// Make a boolean expression.
1698
1699Expression*
b13c66cd 1700Expression::make_boolean(bool val, Location location)
e440a328 1701{
1702 return new Boolean_expression(val, location);
1703}
1704
1705// Class String_expression.
1706
1707// Get the type.
1708
1709Type*
1710String_expression::do_type()
1711{
1712 if (this->type_ == NULL)
1713 this->type_ = Type::make_string_type();
1714 return this->type_;
1715}
1716
1717// Set the type from the context.
1718
1719void
1720String_expression::do_determine_type(const Type_context* context)
1721{
1722 if (this->type_ != NULL && !this->type_->is_abstract())
1723 ;
1724 else if (context->type != NULL && context->type->is_string_type())
1725 this->type_ = context->type;
1726 else if (!context->may_be_abstract)
1727 this->type_ = Type::lookup_string_type();
1728}
1729
1730// Build a string constant.
1731
ea664253 1732Bexpression*
1733String_expression::do_get_backend(Translate_context* context)
e440a328 1734{
2c809f8f 1735 Gogo* gogo = context->gogo();
1736 Btype* btype = Type::make_string_type()->get_backend(gogo);
1737
1738 Location loc = this->location();
1739 std::vector<Bexpression*> init(2);
1740 Bexpression* str_cst =
1741 gogo->backend()->string_constant_expression(this->val_);
1742 init[0] = gogo->backend()->address_expression(str_cst, loc);
1743
1744 Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo);
1745 mpz_t lenval;
1746 mpz_init_set_ui(lenval, this->val_.length());
1747 init[1] = gogo->backend()->integer_constant_expression(int_btype, lenval);
1748 mpz_clear(lenval);
1749
ea664253 1750 return gogo->backend()->constructor_expression(btype, init, loc);
e440a328 1751}
1752
8b1c301d 1753 // Write string literal to string dump.
e440a328 1754
1755void
8b1c301d 1756String_expression::export_string(String_dump* exp,
1757 const String_expression* str)
e440a328 1758{
1759 std::string s;
8b1c301d 1760 s.reserve(str->val_.length() * 4 + 2);
e440a328 1761 s += '"';
8b1c301d 1762 for (std::string::const_iterator p = str->val_.begin();
1763 p != str->val_.end();
e440a328 1764 ++p)
1765 {
1766 if (*p == '\\' || *p == '"')
1767 {
1768 s += '\\';
1769 s += *p;
1770 }
1771 else if (*p >= 0x20 && *p < 0x7f)
1772 s += *p;
1773 else if (*p == '\n')
1774 s += "\\n";
1775 else if (*p == '\t')
1776 s += "\\t";
1777 else
1778 {
1779 s += "\\x";
1780 unsigned char c = *p;
1781 unsigned int dig = c >> 4;
1782 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
1783 dig = c & 0xf;
1784 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
1785 }
1786 }
1787 s += '"';
1788 exp->write_string(s);
1789}
1790
8b1c301d 1791// Export a string expression.
1792
1793void
548be246 1794String_expression::do_export(Export_function_body* efb) const
8b1c301d 1795{
548be246 1796 String_expression::export_string(efb, this);
8b1c301d 1797}
1798
e440a328 1799// Import a string expression.
1800
1801Expression*
bc8e2ef4 1802String_expression::do_import(Import_expression* imp, Location loc)
e440a328 1803{
1804 imp->require_c_string("\"");
1805 std::string val;
1806 while (true)
1807 {
1808 int c = imp->get_char();
1809 if (c == '"' || c == -1)
1810 break;
1811 if (c != '\\')
1812 val += static_cast<char>(c);
1813 else
1814 {
1815 c = imp->get_char();
1816 if (c == '\\' || c == '"')
1817 val += static_cast<char>(c);
1818 else if (c == 'n')
1819 val += '\n';
1820 else if (c == 't')
1821 val += '\t';
1822 else if (c == 'x')
1823 {
1824 c = imp->get_char();
1825 unsigned int vh = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
1826 c = imp->get_char();
1827 unsigned int vl = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
1828 char v = (vh << 4) | vl;
1829 val += v;
1830 }
1831 else
1832 {
631d5788 1833 go_error_at(imp->location(), "bad string constant");
9b92780c 1834 return Expression::make_error(loc);
e440a328 1835 }
1836 }
1837 }
9b92780c 1838 return Expression::make_string(val, loc);
e440a328 1839}
1840
d751bb78 1841// Ast dump for string expression.
1842
1843void
1844String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1845{
8b1c301d 1846 String_expression::export_string(ast_dump_context, this);
d751bb78 1847}
1848
e440a328 1849// Make a string expression.
1850
1851Expression*
b13c66cd 1852Expression::make_string(const std::string& val, Location location)
e440a328 1853{
1854 return new String_expression(val, location);
1855}
1856
2c809f8f 1857// An expression that evaluates to some characteristic of a string.
1858// This is used when indexing, bound-checking, or nil checking a string.
1859
1860class String_info_expression : public Expression
1861{
1862 public:
1863 String_info_expression(Expression* string, String_info string_info,
1864 Location location)
1865 : Expression(EXPRESSION_STRING_INFO, location),
1866 string_(string), string_info_(string_info)
1867 { }
1868
1869 protected:
1870 Type*
1871 do_type();
1872
1873 void
1874 do_determine_type(const Type_context*)
1875 { go_unreachable(); }
1876
1877 Expression*
1878 do_copy()
1879 {
1880 return new String_info_expression(this->string_->copy(), this->string_info_,
1881 this->location());
1882 }
1883
ea664253 1884 Bexpression*
1885 do_get_backend(Translate_context* context);
2c809f8f 1886
1887 void
1888 do_dump_expression(Ast_dump_context*) const;
1889
1890 void
1891 do_issue_nil_check()
1892 { this->string_->issue_nil_check(); }
1893
1894 private:
1895 // The string for which we are getting information.
1896 Expression* string_;
1897 // What information we want.
1898 String_info string_info_;
1899};
1900
1901// Return the type of the string info.
1902
1903Type*
1904String_info_expression::do_type()
1905{
1906 switch (this->string_info_)
1907 {
1908 case STRING_INFO_DATA:
1909 {
1910 Type* byte_type = Type::lookup_integer_type("uint8");
1911 return Type::make_pointer_type(byte_type);
1912 }
1913 case STRING_INFO_LENGTH:
1914 return Type::lookup_integer_type("int");
1915 default:
1916 go_unreachable();
1917 }
1918}
1919
1920// Return string information in GENERIC.
1921
ea664253 1922Bexpression*
1923String_info_expression::do_get_backend(Translate_context* context)
2c809f8f 1924{
1925 Gogo* gogo = context->gogo();
1926
ea664253 1927 Bexpression* bstring = this->string_->get_backend(context);
2c809f8f 1928 switch (this->string_info_)
1929 {
1930 case STRING_INFO_DATA:
1931 case STRING_INFO_LENGTH:
ea664253 1932 return gogo->backend()->struct_field_expression(bstring,
1933 this->string_info_,
1934 this->location());
2c809f8f 1935 break;
1936 default:
1937 go_unreachable();
1938 }
2c809f8f 1939}
1940
1941// Dump ast representation for a type info expression.
1942
1943void
1944String_info_expression::do_dump_expression(
1945 Ast_dump_context* ast_dump_context) const
1946{
1947 ast_dump_context->ostream() << "stringinfo(";
1948 this->string_->dump_expression(ast_dump_context);
1949 ast_dump_context->ostream() << ",";
1950 ast_dump_context->ostream() <<
1951 (this->string_info_ == STRING_INFO_DATA ? "data"
1952 : this->string_info_ == STRING_INFO_LENGTH ? "length"
1953 : "unknown");
1954 ast_dump_context->ostream() << ")";
1955}
1956
1957// Make a string info expression.
1958
1959Expression*
1960Expression::make_string_info(Expression* string, String_info string_info,
1961 Location location)
1962{
1963 return new String_info_expression(string, string_info, location);
1964}
1965
e440a328 1966// Make an integer expression.
1967
1968class Integer_expression : public Expression
1969{
1970 public:
5d4b8566 1971 Integer_expression(const mpz_t* val, Type* type, bool is_character_constant,
1972 Location location)
e440a328 1973 : Expression(EXPRESSION_INTEGER, location),
5d4b8566 1974 type_(type), is_character_constant_(is_character_constant)
e440a328 1975 { mpz_init_set(this->val_, *val); }
1976
1977 static Expression*
bc8e2ef4 1978 do_import(Import_expression*, Location);
e440a328 1979
8b1c301d 1980 // Write VAL to string dump.
e440a328 1981 static void
8b1c301d 1982 export_integer(String_dump* exp, const mpz_t val);
e440a328 1983
d751bb78 1984 // Write VAL to dump context.
1985 static void
1986 dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val);
1987
e440a328 1988 protected:
1989 bool
1990 do_is_constant() const
1991 { return true; }
1992
0e168074 1993 bool
3ae06f68 1994 do_is_static_initializer() const
0e168074 1995 { return true; }
1996
e440a328 1997 bool
0c77715b 1998 do_numeric_constant_value(Numeric_constant* nc) const;
e440a328 1999
2000 Type*
2001 do_type();
2002
2003 void
2004 do_determine_type(const Type_context* context);
2005
2006 void
2007 do_check_types(Gogo*);
2008
ea664253 2009 Bexpression*
2010 do_get_backend(Translate_context*);
e440a328 2011
2012 Expression*
2013 do_copy()
5d4b8566 2014 {
2015 if (this->is_character_constant_)
de590a61 2016 return Expression::make_character(&this->val_,
2017 (this->type_ == NULL
2018 ? NULL
2019 : this->type_->copy_expressions()),
5d4b8566 2020 this->location());
2021 else
de590a61 2022 return Expression::make_integer_z(&this->val_,
2023 (this->type_ == NULL
2024 ? NULL
2025 : this->type_->copy_expressions()),
e67508fa 2026 this->location());
5d4b8566 2027 }
e440a328 2028
5f6f5357 2029 int
2030 do_inlining_cost() const
2031 { return 1; }
2032
e440a328 2033 void
548be246 2034 do_export(Export_function_body*) const;
e440a328 2035
d751bb78 2036 void
2037 do_dump_expression(Ast_dump_context*) const;
2038
e440a328 2039 private:
2040 // The integer value.
2041 mpz_t val_;
2042 // The type so far.
2043 Type* type_;
5d4b8566 2044 // Whether this is a character constant.
2045 bool is_character_constant_;
e440a328 2046};
2047
0c77715b 2048// Return a numeric constant for this expression. We have to mark
2049// this as a character when appropriate.
e440a328 2050
2051bool
0c77715b 2052Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 2053{
0c77715b 2054 if (this->is_character_constant_)
2055 nc->set_rune(this->type_, this->val_);
2056 else
2057 nc->set_int(this->type_, this->val_);
e440a328 2058 return true;
2059}
2060
2061// Return the current type. If we haven't set the type yet, we return
2062// an abstract integer type.
2063
2064Type*
2065Integer_expression::do_type()
2066{
2067 if (this->type_ == NULL)
5d4b8566 2068 {
2069 if (this->is_character_constant_)
2070 this->type_ = Type::make_abstract_character_type();
2071 else
2072 this->type_ = Type::make_abstract_integer_type();
2073 }
e440a328 2074 return this->type_;
2075}
2076
2077// Set the type of the integer value. Here we may switch from an
2078// abstract type to a real type.
2079
2080void
2081Integer_expression::do_determine_type(const Type_context* context)
2082{
2083 if (this->type_ != NULL && !this->type_->is_abstract())
2084 ;
0c77715b 2085 else if (context->type != NULL && context->type->is_numeric_type())
e440a328 2086 this->type_ = context->type;
2087 else if (!context->may_be_abstract)
5d4b8566 2088 {
2089 if (this->is_character_constant_)
2090 this->type_ = Type::lookup_integer_type("int32");
2091 else
2092 this->type_ = Type::lookup_integer_type("int");
2093 }
e440a328 2094}
2095
e440a328 2096// Check the type of an integer constant.
2097
2098void
2099Integer_expression::do_check_types(Gogo*)
2100{
0c77715b 2101 Type* type = this->type_;
2102 if (type == NULL)
e440a328 2103 return;
0c77715b 2104 Numeric_constant nc;
2105 if (this->is_character_constant_)
2106 nc.set_rune(NULL, this->val_);
2107 else
2108 nc.set_int(NULL, this->val_);
2109 if (!nc.set_type(type, true, this->location()))
e440a328 2110 this->set_is_error();
2111}
2112
ea664253 2113// Get the backend representation for an integer constant.
e440a328 2114
ea664253 2115Bexpression*
2116Integer_expression::do_get_backend(Translate_context* context)
e440a328 2117{
12373dd5 2118 if (this->is_error_expression()
2119 || (this->type_ != NULL && this->type_->is_error_type()))
2120 {
2121 go_assert(saw_errors());
2122 return context->gogo()->backend()->error_expression();
2123 }
2124
48c2a53a 2125 Type* resolved_type = NULL;
e440a328 2126 if (this->type_ != NULL && !this->type_->is_abstract())
48c2a53a 2127 resolved_type = this->type_;
e440a328 2128 else if (this->type_ != NULL && this->type_->float_type() != NULL)
2129 {
2130 // We are converting to an abstract floating point type.
48c2a53a 2131 resolved_type = Type::lookup_float_type("float64");
e440a328 2132 }
2133 else if (this->type_ != NULL && this->type_->complex_type() != NULL)
2134 {
2135 // We are converting to an abstract complex type.
48c2a53a 2136 resolved_type = Type::lookup_complex_type("complex128");
e440a328 2137 }
2138 else
2139 {
2140 // If we still have an abstract type here, then this is being
2141 // used in a constant expression which didn't get reduced for
2142 // some reason. Use a type which will fit the value. We use <,
2143 // not <=, because we need an extra bit for the sign bit.
2144 int bits = mpz_sizeinbase(this->val_, 2);
1b1f2abf 2145 Type* int_type = Type::lookup_integer_type("int");
2146 if (bits < int_type->integer_type()->bits())
48c2a53a 2147 resolved_type = int_type;
e440a328 2148 else if (bits < 64)
48c2a53a 2149 resolved_type = Type::lookup_integer_type("int64");
e440a328 2150 else
48c2a53a 2151 {
2152 if (!saw_errors())
631d5788 2153 go_error_at(this->location(),
2154 "unknown type for large integer constant");
ea664253 2155 return context->gogo()->backend()->error_expression();
48c2a53a 2156 }
e440a328 2157 }
48c2a53a 2158 Numeric_constant nc;
2159 nc.set_int(resolved_type, this->val_);
ea664253 2160 return Expression::backend_numeric_constant_expression(context, &nc);
e440a328 2161}
2162
2163// Write VAL to export data.
2164
2165void
8b1c301d 2166Integer_expression::export_integer(String_dump* exp, const mpz_t val)
e440a328 2167{
2168 char* s = mpz_get_str(NULL, 10, val);
2169 exp->write_c_string(s);
2170 free(s);
2171}
2172
2173// Export an integer in a constant expression.
2174
2175void
548be246 2176Integer_expression::do_export(Export_function_body* efb) const
e440a328 2177{
69f634cc 2178 bool added_type = false;
2179 if (this->type_ != NULL
2180 && !this->type_->is_abstract()
2181 && this->type_ != efb->type_context())
2182 {
2183 efb->write_c_string("$convert(");
2184 efb->write_type(this->type_);
2185 efb->write_c_string(", ");
2186 added_type = true;
2187 }
2188
548be246 2189 Integer_expression::export_integer(efb, this->val_);
5d4b8566 2190 if (this->is_character_constant_)
548be246 2191 efb->write_c_string("'");
e440a328 2192 // A trailing space lets us reliably identify the end of the number.
548be246 2193 efb->write_c_string(" ");
69f634cc 2194
2195 if (added_type)
2196 efb->write_c_string(")");
e440a328 2197}
2198
2199// Import an integer, floating point, or complex value. This handles
2200// all these types because they all start with digits.
2201
2202Expression*
bc8e2ef4 2203Integer_expression::do_import(Import_expression* imp, Location loc)
e440a328 2204{
2205 std::string num = imp->read_identifier();
2206 imp->require_c_string(" ");
2207 if (!num.empty() && num[num.length() - 1] == 'i')
2208 {
2209 mpfr_t real;
2210 size_t plus_pos = num.find('+', 1);
2211 size_t minus_pos = num.find('-', 1);
2212 size_t pos;
2213 if (plus_pos == std::string::npos)
2214 pos = minus_pos;
2215 else if (minus_pos == std::string::npos)
2216 pos = plus_pos;
2217 else
2218 {
631d5788 2219 go_error_at(imp->location(), "bad number in import data: %qs",
2220 num.c_str());
9b92780c 2221 return Expression::make_error(loc);
e440a328 2222 }
2223 if (pos == std::string::npos)
2224 mpfr_set_ui(real, 0, GMP_RNDN);
2225 else
2226 {
2227 std::string real_str = num.substr(0, pos);
2228 if (mpfr_init_set_str(real, real_str.c_str(), 10, GMP_RNDN) != 0)
2229 {
631d5788 2230 go_error_at(imp->location(), "bad number in import data: %qs",
2231 real_str.c_str());
9b92780c 2232 return Expression::make_error(loc);
e440a328 2233 }
2234 }
2235
2236 std::string imag_str;
2237 if (pos == std::string::npos)
2238 imag_str = num;
2239 else
2240 imag_str = num.substr(pos);
2241 imag_str = imag_str.substr(0, imag_str.size() - 1);
2242 mpfr_t imag;
2243 if (mpfr_init_set_str(imag, imag_str.c_str(), 10, GMP_RNDN) != 0)
2244 {
631d5788 2245 go_error_at(imp->location(), "bad number in import data: %qs",
2246 imag_str.c_str());
9b92780c 2247 return Expression::make_error(loc);
e440a328 2248 }
fcbea5e4 2249 mpc_t cval;
2250 mpc_init2(cval, mpc_precision);
2251 mpc_set_fr_fr(cval, real, imag, MPC_RNDNN);
e440a328 2252 mpfr_clear(real);
2253 mpfr_clear(imag);
9b92780c 2254 Expression* ret = Expression::make_complex(&cval, NULL, loc);
fcbea5e4 2255 mpc_clear(cval);
e440a328 2256 return ret;
2257 }
2258 else if (num.find('.') == std::string::npos
2259 && num.find('E') == std::string::npos)
2260 {
5d4b8566 2261 bool is_character_constant = (!num.empty()
2262 && num[num.length() - 1] == '\'');
2263 if (is_character_constant)
2264 num = num.substr(0, num.length() - 1);
e440a328 2265 mpz_t val;
2266 if (mpz_init_set_str(val, num.c_str(), 10) != 0)
2267 {
631d5788 2268 go_error_at(imp->location(), "bad number in import data: %qs",
2269 num.c_str());
9b92780c 2270 return Expression::make_error(loc);
e440a328 2271 }
5d4b8566 2272 Expression* ret;
2273 if (is_character_constant)
9b92780c 2274 ret = Expression::make_character(&val, NULL, loc);
5d4b8566 2275 else
9b92780c 2276 ret = Expression::make_integer_z(&val, NULL, loc);
e440a328 2277 mpz_clear(val);
2278 return ret;
2279 }
2280 else
2281 {
2282 mpfr_t val;
2283 if (mpfr_init_set_str(val, num.c_str(), 10, GMP_RNDN) != 0)
2284 {
631d5788 2285 go_error_at(imp->location(), "bad number in import data: %qs",
2286 num.c_str());
9b92780c 2287 return Expression::make_error(loc);
e440a328 2288 }
9b92780c 2289 Expression* ret = Expression::make_float(&val, NULL, loc);
e440a328 2290 mpfr_clear(val);
2291 return ret;
2292 }
2293}
d751bb78 2294// Ast dump for integer expression.
2295
2296void
2297Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2298{
5d4b8566 2299 if (this->is_character_constant_)
2300 ast_dump_context->ostream() << '\'';
8b1c301d 2301 Integer_expression::export_integer(ast_dump_context, this->val_);
5d4b8566 2302 if (this->is_character_constant_)
2303 ast_dump_context->ostream() << '\'';
d751bb78 2304}
2305
e67508fa 2306// Build a new integer value from a multi-precision integer.
e440a328 2307
2308Expression*
e67508fa 2309Expression::make_integer_z(const mpz_t* val, Type* type, Location location)
5d4b8566 2310{
2311 return new Integer_expression(val, type, false, location);
2312}
2313
e67508fa 2314// Build a new integer value from an unsigned long.
2315
2316Expression*
2317Expression::make_integer_ul(unsigned long val, Type *type, Location location)
2318{
2319 mpz_t zval;
2320 mpz_init_set_ui(zval, val);
2321 Expression* ret = Expression::make_integer_z(&zval, type, location);
2322 mpz_clear(zval);
2323 return ret;
2324}
2325
2326// Build a new integer value from a signed long.
2327
2328Expression*
2329Expression::make_integer_sl(long val, Type *type, Location location)
2330{
2331 mpz_t zval;
2332 mpz_init_set_si(zval, val);
2333 Expression* ret = Expression::make_integer_z(&zval, type, location);
2334 mpz_clear(zval);
2335 return ret;
2336}
2337
3f378015 2338// Store an int64_t in an uninitialized mpz_t.
2339
2340static void
2341set_mpz_from_int64(mpz_t* zval, int64_t val)
2342{
2343 if (val >= 0)
2344 {
2345 unsigned long ul = static_cast<unsigned long>(val);
2346 if (static_cast<int64_t>(ul) == val)
2347 {
2348 mpz_init_set_ui(*zval, ul);
2349 return;
2350 }
2351 }
2352 uint64_t uv;
2353 if (val >= 0)
2354 uv = static_cast<uint64_t>(val);
2355 else
2356 uv = static_cast<uint64_t>(- val);
2357 unsigned long ul = uv & 0xffffffffUL;
2358 mpz_init_set_ui(*zval, ul);
2359 mpz_t hval;
2360 mpz_init_set_ui(hval, static_cast<unsigned long>(uv >> 32));
2361 mpz_mul_2exp(hval, hval, 32);
2362 mpz_add(*zval, *zval, hval);
2363 mpz_clear(hval);
2364 if (val < 0)
2365 mpz_neg(*zval, *zval);
2366}
2367
2368// Build a new integer value from an int64_t.
2369
2370Expression*
2371Expression::make_integer_int64(int64_t val, Type* type, Location location)
2372{
2373 mpz_t zval;
2374 set_mpz_from_int64(&zval, val);
2375 Expression* ret = Expression::make_integer_z(&zval, type, location);
2376 mpz_clear(zval);
2377 return ret;
2378}
2379
5d4b8566 2380// Build a new character constant value.
2381
2382Expression*
2383Expression::make_character(const mpz_t* val, Type* type, Location location)
e440a328 2384{
5d4b8566 2385 return new Integer_expression(val, type, true, location);
e440a328 2386}
2387
2388// Floats.
2389
2390class Float_expression : public Expression
2391{
2392 public:
b13c66cd 2393 Float_expression(const mpfr_t* val, Type* type, Location location)
e440a328 2394 : Expression(EXPRESSION_FLOAT, location),
2395 type_(type)
2396 {
2397 mpfr_init_set(this->val_, *val, GMP_RNDN);
2398 }
2399
e440a328 2400 // Write VAL to export data.
2401 static void
8b1c301d 2402 export_float(String_dump* exp, const mpfr_t val);
2403
d751bb78 2404 // Write VAL to dump file.
2405 static void
2406 dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
e440a328 2407
2408 protected:
2409 bool
2410 do_is_constant() const
2411 { return true; }
2412
0e168074 2413 bool
3ae06f68 2414 do_is_static_initializer() const
0e168074 2415 { return true; }
2416
e440a328 2417 bool
0c77715b 2418 do_numeric_constant_value(Numeric_constant* nc) const
2419 {
2420 nc->set_float(this->type_, this->val_);
2421 return true;
2422 }
e440a328 2423
2424 Type*
2425 do_type();
2426
2427 void
2428 do_determine_type(const Type_context*);
2429
2430 void
2431 do_check_types(Gogo*);
2432
2433 Expression*
2434 do_copy()
de590a61 2435 { return Expression::make_float(&this->val_,
2436 (this->type_ == NULL
2437 ? NULL
2438 : this->type_->copy_expressions()),
e440a328 2439 this->location()); }
2440
ea664253 2441 Bexpression*
2442 do_get_backend(Translate_context*);
e440a328 2443
5f6f5357 2444 int
2445 do_inlining_cost() const
2446 { return 1; }
2447
e440a328 2448 void
548be246 2449 do_export(Export_function_body*) const;
e440a328 2450
d751bb78 2451 void
2452 do_dump_expression(Ast_dump_context*) const;
2453
e440a328 2454 private:
2455 // The floating point value.
2456 mpfr_t val_;
2457 // The type so far.
2458 Type* type_;
2459};
2460
e440a328 2461// Return the current type. If we haven't set the type yet, we return
2462// an abstract float type.
2463
2464Type*
2465Float_expression::do_type()
2466{
2467 if (this->type_ == NULL)
2468 this->type_ = Type::make_abstract_float_type();
2469 return this->type_;
2470}
2471
2472// Set the type of the float value. Here we may switch from an
2473// abstract type to a real type.
2474
2475void
2476Float_expression::do_determine_type(const Type_context* context)
2477{
2478 if (this->type_ != NULL && !this->type_->is_abstract())
2479 ;
2480 else if (context->type != NULL
2481 && (context->type->integer_type() != NULL
2482 || context->type->float_type() != NULL
2483 || context->type->complex_type() != NULL))
2484 this->type_ = context->type;
2485 else if (!context->may_be_abstract)
48080209 2486 this->type_ = Type::lookup_float_type("float64");
e440a328 2487}
2488
e440a328 2489// Check the type of a float value.
2490
2491void
2492Float_expression::do_check_types(Gogo*)
2493{
0c77715b 2494 Type* type = this->type_;
2495 if (type == NULL)
e440a328 2496 return;
0c77715b 2497 Numeric_constant nc;
2498 nc.set_float(NULL, this->val_);
2499 if (!nc.set_type(this->type_, true, this->location()))
e440a328 2500 this->set_is_error();
e440a328 2501}
2502
ea664253 2503// Get the backend representation for a float constant.
e440a328 2504
ea664253 2505Bexpression*
2506Float_expression::do_get_backend(Translate_context* context)
e440a328 2507{
12373dd5 2508 if (this->is_error_expression()
2509 || (this->type_ != NULL && this->type_->is_error_type()))
2510 {
2511 go_assert(saw_errors());
2512 return context->gogo()->backend()->error_expression();
2513 }
2514
48c2a53a 2515 Type* resolved_type;
e440a328 2516 if (this->type_ != NULL && !this->type_->is_abstract())
48c2a53a 2517 resolved_type = this->type_;
e440a328 2518 else if (this->type_ != NULL && this->type_->integer_type() != NULL)
2519 {
2520 // We have an abstract integer type. We just hope for the best.
48c2a53a 2521 resolved_type = Type::lookup_integer_type("int");
2522 }
2523 else if (this->type_ != NULL && this->type_->complex_type() != NULL)
2524 {
2525 // We are converting to an abstract complex type.
2526 resolved_type = Type::lookup_complex_type("complex128");
e440a328 2527 }
2528 else
2529 {
2530 // If we still have an abstract type here, then this is being
2531 // used in a constant expression which didn't get reduced. We
2532 // just use float64 and hope for the best.
48c2a53a 2533 resolved_type = Type::lookup_float_type("float64");
e440a328 2534 }
48c2a53a 2535
2536 Numeric_constant nc;
2537 nc.set_float(resolved_type, this->val_);
ea664253 2538 return Expression::backend_numeric_constant_expression(context, &nc);
e440a328 2539}
2540
8b1c301d 2541// Write a floating point number to a string dump.
e440a328 2542
2543void
8b1c301d 2544Float_expression::export_float(String_dump *exp, const mpfr_t val)
e440a328 2545{
2546 mp_exp_t exponent;
2547 char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
2548 if (*s == '-')
2549 exp->write_c_string("-");
2550 exp->write_c_string("0.");
2551 exp->write_c_string(*s == '-' ? s + 1 : s);
2552 mpfr_free_str(s);
2553 char buf[30];
2554 snprintf(buf, sizeof buf, "E%ld", exponent);
2555 exp->write_c_string(buf);
2556}
2557
2558// Export a floating point number in a constant expression.
2559
2560void
548be246 2561Float_expression::do_export(Export_function_body* efb) const
e440a328 2562{
69f634cc 2563 bool added_type = false;
2564 if (this->type_ != NULL
2565 && !this->type_->is_abstract()
2566 && this->type_ != efb->type_context())
2567 {
2568 efb->write_c_string("$convert(");
2569 efb->write_type(this->type_);
2570 efb->write_c_string(", ");
2571 added_type = true;
2572 }
2573
548be246 2574 Float_expression::export_float(efb, this->val_);
e440a328 2575 // A trailing space lets us reliably identify the end of the number.
548be246 2576 efb->write_c_string(" ");
69f634cc 2577
2578 if (added_type)
2579 efb->write_c_string(")");
e440a328 2580}
2581
d751bb78 2582// Dump a floating point number to the dump file.
2583
2584void
2585Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2586{
8b1c301d 2587 Float_expression::export_float(ast_dump_context, this->val_);
d751bb78 2588}
2589
e440a328 2590// Make a float expression.
2591
2592Expression*
b13c66cd 2593Expression::make_float(const mpfr_t* val, Type* type, Location location)
e440a328 2594{
2595 return new Float_expression(val, type, location);
2596}
2597
2598// Complex numbers.
2599
2600class Complex_expression : public Expression
2601{
2602 public:
fcbea5e4 2603 Complex_expression(const mpc_t* val, Type* type, Location location)
e440a328 2604 : Expression(EXPRESSION_COMPLEX, location),
2605 type_(type)
2606 {
fcbea5e4 2607 mpc_init2(this->val_, mpc_precision);
2608 mpc_set(this->val_, *val, MPC_RNDNN);
e440a328 2609 }
2610
fcbea5e4 2611 // Write VAL to string dump.
e440a328 2612 static void
fcbea5e4 2613 export_complex(String_dump* exp, const mpc_t val);
e440a328 2614
d751bb78 2615 // Write REAL/IMAG to dump context.
2616 static void
fcbea5e4 2617 dump_complex(Ast_dump_context* ast_dump_context, const mpc_t val);
d751bb78 2618
e440a328 2619 protected:
2620 bool
2621 do_is_constant() const
2622 { return true; }
2623
0e168074 2624 bool
3ae06f68 2625 do_is_static_initializer() const
0e168074 2626 { return true; }
2627
e440a328 2628 bool
0c77715b 2629 do_numeric_constant_value(Numeric_constant* nc) const
2630 {
fcbea5e4 2631 nc->set_complex(this->type_, this->val_);
0c77715b 2632 return true;
2633 }
e440a328 2634
2635 Type*
2636 do_type();
2637
2638 void
2639 do_determine_type(const Type_context*);
2640
2641 void
2642 do_check_types(Gogo*);
2643
2644 Expression*
2645 do_copy()
2646 {
de590a61 2647 return Expression::make_complex(&this->val_,
2648 (this->type_ == NULL
2649 ? NULL
2650 : this->type_->copy_expressions()),
e440a328 2651 this->location());
2652 }
2653
ea664253 2654 Bexpression*
2655 do_get_backend(Translate_context*);
e440a328 2656
5f6f5357 2657 int
2658 do_inlining_cost() const
2659 { return 2; }
2660
e440a328 2661 void
548be246 2662 do_export(Export_function_body*) const;
e440a328 2663
d751bb78 2664 void
2665 do_dump_expression(Ast_dump_context*) const;
abd26de0 2666
e440a328 2667 private:
fcbea5e4 2668 // The complex value.
2669 mpc_t val_;
e440a328 2670 // The type if known.
2671 Type* type_;
2672};
2673
e440a328 2674// Return the current type. If we haven't set the type yet, we return
2675// an abstract complex type.
2676
2677Type*
2678Complex_expression::do_type()
2679{
2680 if (this->type_ == NULL)
2681 this->type_ = Type::make_abstract_complex_type();
2682 return this->type_;
2683}
2684
2685// Set the type of the complex value. Here we may switch from an
2686// abstract type to a real type.
2687
2688void
2689Complex_expression::do_determine_type(const Type_context* context)
2690{
2691 if (this->type_ != NULL && !this->type_->is_abstract())
2692 ;
abd26de0 2693 else if (context->type != NULL && context->type->is_numeric_type())
e440a328 2694 this->type_ = context->type;
2695 else if (!context->may_be_abstract)
48080209 2696 this->type_ = Type::lookup_complex_type("complex128");
e440a328 2697}
2698
e440a328 2699// Check the type of a complex value.
2700
2701void
2702Complex_expression::do_check_types(Gogo*)
2703{
0c77715b 2704 Type* type = this->type_;
2705 if (type == NULL)
e440a328 2706 return;
0c77715b 2707 Numeric_constant nc;
fcbea5e4 2708 nc.set_complex(NULL, this->val_);
0c77715b 2709 if (!nc.set_type(this->type_, true, this->location()))
e440a328 2710 this->set_is_error();
2711}
2712
ea664253 2713// Get the backend representation for a complex constant.
e440a328 2714
ea664253 2715Bexpression*
2716Complex_expression::do_get_backend(Translate_context* context)
e440a328 2717{
12373dd5 2718 if (this->is_error_expression()
2719 || (this->type_ != NULL && this->type_->is_error_type()))
2720 {
2721 go_assert(saw_errors());
2722 return context->gogo()->backend()->error_expression();
2723 }
2724
48c2a53a 2725 Type* resolved_type;
e440a328 2726 if (this->type_ != NULL && !this->type_->is_abstract())
48c2a53a 2727 resolved_type = this->type_;
2728 else if (this->type_ != NULL && this->type_->integer_type() != NULL)
2729 {
2730 // We are converting to an abstract integer type.
2731 resolved_type = Type::lookup_integer_type("int");
2732 }
2733 else if (this->type_ != NULL && this->type_->float_type() != NULL)
2734 {
2735 // We are converting to an abstract float type.
2736 resolved_type = Type::lookup_float_type("float64");
2737 }
e440a328 2738 else
2739 {
47ae02b7 2740 // If we still have an abstract type here, this is being
e440a328 2741 // used in a constant expression which didn't get reduced. We
2742 // just use complex128 and hope for the best.
48c2a53a 2743 resolved_type = Type::lookup_complex_type("complex128");
e440a328 2744 }
48c2a53a 2745
2746 Numeric_constant nc;
fcbea5e4 2747 nc.set_complex(resolved_type, this->val_);
ea664253 2748 return Expression::backend_numeric_constant_expression(context, &nc);
e440a328 2749}
2750
2751// Write REAL/IMAG to export data.
2752
2753void
fcbea5e4 2754Complex_expression::export_complex(String_dump* exp, const mpc_t val)
e440a328 2755{
fcbea5e4 2756 if (!mpfr_zero_p(mpc_realref(val)))
e440a328 2757 {
fcbea5e4 2758 Float_expression::export_float(exp, mpc_realref(val));
d1db782d 2759 if (mpfr_sgn(mpc_imagref(val)) >= 0)
e440a328 2760 exp->write_c_string("+");
2761 }
fcbea5e4 2762 Float_expression::export_float(exp, mpc_imagref(val));
e440a328 2763 exp->write_c_string("i");
2764}
2765
2766// Export a complex number in a constant expression.
2767
2768void
548be246 2769Complex_expression::do_export(Export_function_body* efb) const
e440a328 2770{
69f634cc 2771 bool added_type = false;
2772 if (this->type_ != NULL
2773 && !this->type_->is_abstract()
2774 && this->type_ != efb->type_context())
2775 {
2776 efb->write_c_string("$convert(");
2777 efb->write_type(this->type_);
2778 efb->write_c_string(", ");
2779 added_type = true;
2780 }
2781
548be246 2782 Complex_expression::export_complex(efb, this->val_);
e440a328 2783 // A trailing space lets us reliably identify the end of the number.
548be246 2784 efb->write_c_string(" ");
69f634cc 2785
2786 if (added_type)
2787 efb->write_c_string(")");
e440a328 2788}
2789
d751bb78 2790// Dump a complex expression to the dump file.
2791
2792void
2793Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2794{
fcbea5e4 2795 Complex_expression::export_complex(ast_dump_context, this->val_);
d751bb78 2796}
2797
e440a328 2798// Make a complex expression.
2799
2800Expression*
fcbea5e4 2801Expression::make_complex(const mpc_t* val, Type* type, Location location)
e440a328 2802{
fcbea5e4 2803 return new Complex_expression(val, type, location);
e440a328 2804}
2805
d5b605df 2806// Find a named object in an expression.
2807
2808class Find_named_object : public Traverse
2809{
2810 public:
2811 Find_named_object(Named_object* no)
2812 : Traverse(traverse_expressions),
2813 no_(no), found_(false)
2814 { }
2815
2816 // Whether we found the object.
2817 bool
2818 found() const
2819 { return this->found_; }
2820
2821 protected:
2822 int
2823 expression(Expression**);
2824
2825 private:
2826 // The object we are looking for.
2827 Named_object* no_;
2828 // Whether we found it.
2829 bool found_;
2830};
2831
e440a328 2832// A reference to a const in an expression.
2833
2834class Const_expression : public Expression
2835{
2836 public:
b13c66cd 2837 Const_expression(Named_object* constant, Location location)
e440a328 2838 : Expression(EXPRESSION_CONST_REFERENCE, location),
13e818f5 2839 constant_(constant), type_(NULL), seen_(false)
e440a328 2840 { }
2841
d5b605df 2842 Named_object*
2843 named_object()
2844 { return this->constant_; }
2845
a7f064d5 2846 // Check that the initializer does not refer to the constant itself.
2847 void
2848 check_for_init_loop();
2849
e440a328 2850 protected:
ba4aedd4 2851 int
2852 do_traverse(Traverse*);
2853
e440a328 2854 Expression*
ceeb4318 2855 do_lower(Gogo*, Named_object*, Statement_inserter*, int);
e440a328 2856
2857 bool
2858 do_is_constant() const
2859 { return true; }
2860
0e168074 2861 bool
3ae06f68 2862 do_is_static_initializer() const
0e168074 2863 { return true; }
2864
e440a328 2865 bool
0c77715b 2866 do_numeric_constant_value(Numeric_constant* nc) const;
e440a328 2867
2868 bool
af6b489a 2869 do_string_constant_value(std::string* val) const;
e440a328 2870
2871 Type*
2872 do_type();
2873
2874 // The type of a const is set by the declaration, not the use.
2875 void
2876 do_determine_type(const Type_context*);
2877
2878 void
2879 do_check_types(Gogo*);
2880
2881 Expression*
2882 do_copy()
2883 { return this; }
2884
ea664253 2885 Bexpression*
2886 do_get_backend(Translate_context* context);
e440a328 2887
2888 // When exporting a reference to a const as part of a const
2889 // expression, we export the value. We ignore the fact that it has
2890 // a name.
2891 void
548be246 2892 do_export(Export_function_body* efb) const
2893 { this->constant_->const_value()->expr()->export_expression(efb); }
e440a328 2894
d751bb78 2895 void
2896 do_dump_expression(Ast_dump_context*) const;
2897
e440a328 2898 private:
2899 // The constant.
2900 Named_object* constant_;
2901 // The type of this reference. This is used if the constant has an
2902 // abstract type.
2903 Type* type_;
13e818f5 2904 // Used to prevent infinite recursion when a constant incorrectly
2905 // refers to itself.
2906 mutable bool seen_;
e440a328 2907};
2908
ba4aedd4 2909// Traversal.
2910
2911int
2912Const_expression::do_traverse(Traverse* traverse)
2913{
2914 if (this->type_ != NULL)
2915 return Type::traverse(this->type_, traverse);
2916 return TRAVERSE_CONTINUE;
2917}
2918
e440a328 2919// Lower a constant expression. This is where we convert the
2920// predeclared constant iota into an integer value.
2921
2922Expression*
ceeb4318 2923Const_expression::do_lower(Gogo* gogo, Named_object*,
2924 Statement_inserter*, int iota_value)
e440a328 2925{
2926 if (this->constant_->const_value()->expr()->classification()
2927 == EXPRESSION_IOTA)
2928 {
2929 if (iota_value == -1)
2930 {
631d5788 2931 go_error_at(this->location(),
2932 "iota is only defined in const declarations");
e440a328 2933 iota_value = 0;
2934 }
e67508fa 2935 return Expression::make_integer_ul(iota_value, NULL, this->location());
e440a328 2936 }
2937
2938 // Make sure that the constant itself has been lowered.
2939 gogo->lower_constant(this->constant_);
2940
2941 return this;
2942}
2943
0c77715b 2944// Return a numeric constant value.
e440a328 2945
2946bool
0c77715b 2947Const_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 2948{
13e818f5 2949 if (this->seen_)
2950 return false;
2951
e440a328 2952 Expression* e = this->constant_->const_value()->expr();
f03a9fbf 2953
13e818f5 2954 this->seen_ = true;
2955
0c77715b 2956 bool r = e->numeric_constant_value(nc);
e440a328 2957
13e818f5 2958 this->seen_ = false;
2959
e440a328 2960 Type* ctype;
2961 if (this->type_ != NULL)
2962 ctype = this->type_;
2963 else
2964 ctype = this->constant_->const_value()->type();
e440a328 2965 if (r && ctype != NULL)
2966 {
0c77715b 2967 if (!nc->set_type(ctype, false, this->location()))
e440a328 2968 return false;
e440a328 2969 }
e440a328 2970
e440a328 2971 return r;
2972}
2973
af6b489a 2974bool
2975Const_expression::do_string_constant_value(std::string* val) const
2976{
2977 if (this->seen_)
2978 return false;
2979
2980 Expression* e = this->constant_->const_value()->expr();
2981
2982 this->seen_ = true;
2983 bool ok = e->string_constant_value(val);
2984 this->seen_ = false;
2985
2986 return ok;
2987}
2988
e440a328 2989// Return the type of the const reference.
2990
2991Type*
2992Const_expression::do_type()
2993{
2994 if (this->type_ != NULL)
2995 return this->type_;
13e818f5 2996
2f78f012 2997 Named_constant* nc = this->constant_->const_value();
2998
2999 if (this->seen_ || nc->lowering())
13e818f5 3000 {
4b2ab536 3001 if (nc->type() == NULL || !nc->type()->is_error_type())
3002 {
3003 Location loc = this->location();
3004 if (!this->seen_)
3005 loc = nc->location();
3006 go_error_at(loc, "constant refers to itself");
3007 }
3008 this->set_is_error();
13e818f5 3009 this->type_ = Type::make_error_type();
4b2ab536 3010 nc->set_type(this->type_);
13e818f5 3011 return this->type_;
3012 }
3013
3014 this->seen_ = true;
3015
e440a328 3016 Type* ret = nc->type();
13e818f5 3017
e440a328 3018 if (ret != NULL)
13e818f5 3019 {
3020 this->seen_ = false;
3021 return ret;
3022 }
3023
e440a328 3024 // During parsing, a named constant may have a NULL type, but we
3025 // must not return a NULL type here.
13e818f5 3026 ret = nc->expr()->type();
3027
3028 this->seen_ = false;
3029
4b2ab536 3030 if (ret->is_error_type())
3031 nc->set_type(ret);
3032
13e818f5 3033 return ret;
e440a328 3034}
3035
3036// Set the type of the const reference.
3037
3038void
3039Const_expression::do_determine_type(const Type_context* context)
3040{
3041 Type* ctype = this->constant_->const_value()->type();
3042 Type* cetype = (ctype != NULL
3043 ? ctype
3044 : this->constant_->const_value()->expr()->type());
3045 if (ctype != NULL && !ctype->is_abstract())
3046 ;
3047 else if (context->type != NULL
0c77715b 3048 && context->type->is_numeric_type()
3049 && cetype->is_numeric_type())
e440a328 3050 this->type_ = context->type;
3051 else if (context->type != NULL
3052 && context->type->is_string_type()
3053 && cetype->is_string_type())
3054 this->type_ = context->type;
3055 else if (context->type != NULL
3056 && context->type->is_boolean_type()
3057 && cetype->is_boolean_type())
3058 this->type_ = context->type;
3059 else if (!context->may_be_abstract)
3060 {
3061 if (cetype->is_abstract())
3062 cetype = cetype->make_non_abstract_type();
3063 this->type_ = cetype;
3064 }
3065}
3066
a7f064d5 3067// Check for a loop in which the initializer of a constant refers to
3068// the constant itself.
e440a328 3069
3070void
a7f064d5 3071Const_expression::check_for_init_loop()
e440a328 3072{
5c13bd80 3073 if (this->type_ != NULL && this->type_->is_error())
d5b605df 3074 return;
3075
a7f064d5 3076 if (this->seen_)
3077 {
3078 this->report_error(_("constant refers to itself"));
3079 this->type_ = Type::make_error_type();
3080 return;
3081 }
3082
d5b605df 3083 Expression* init = this->constant_->const_value()->expr();
3084 Find_named_object find_named_object(this->constant_);
a7f064d5 3085
3086 this->seen_ = true;
d5b605df 3087 Expression::traverse(&init, &find_named_object);
a7f064d5 3088 this->seen_ = false;
3089
d5b605df 3090 if (find_named_object.found())
3091 {
5c13bd80 3092 if (this->type_ == NULL || !this->type_->is_error())
a7f064d5 3093 {
3094 this->report_error(_("constant refers to itself"));
3095 this->type_ = Type::make_error_type();
3096 }
d5b605df 3097 return;
3098 }
a7f064d5 3099}
3100
3101// Check types of a const reference.
3102
3103void
3104Const_expression::do_check_types(Gogo*)
3105{
5c13bd80 3106 if (this->type_ != NULL && this->type_->is_error())
a7f064d5 3107 return;
3108
3109 this->check_for_init_loop();
d5b605df 3110
0c77715b 3111 // Check that numeric constant fits in type.
3112 if (this->type_ != NULL && this->type_->is_numeric_type())
e440a328 3113 {
0c77715b 3114 Numeric_constant nc;
3115 if (this->constant_->const_value()->expr()->numeric_constant_value(&nc))
e440a328 3116 {
0c77715b 3117 if (!nc.set_type(this->type_, true, this->location()))
3118 this->set_is_error();
e440a328 3119 }
e440a328 3120 }
3121}
3122
ea664253 3123// Return the backend representation for a const reference.
e440a328 3124
ea664253 3125Bexpression*
3126Const_expression::do_get_backend(Translate_context* context)
e440a328 3127{
12373dd5 3128 if (this->is_error_expression()
3129 || (this->type_ != NULL && this->type_->is_error()))
3130 {
3131 go_assert(saw_errors());
3132 return context->backend()->error_expression();
3133 }
e440a328 3134
3135 // If the type has been set for this expression, but the underlying
3136 // object is an abstract int or float, we try to get the abstract
3137 // value. Otherwise we may lose something in the conversion.
f2de4532 3138 Expression* expr = this->constant_->const_value()->expr();
e440a328 3139 if (this->type_ != NULL
0c77715b 3140 && this->type_->is_numeric_type()
a68492b4 3141 && (this->constant_->const_value()->type() == NULL
3142 || this->constant_->const_value()->type()->is_abstract()))
e440a328 3143 {
0c77715b 3144 Numeric_constant nc;
3145 if (expr->numeric_constant_value(&nc)
3146 && nc.set_type(this->type_, false, this->location()))
e440a328 3147 {
0c77715b 3148 Expression* e = nc.expression(this->location());
ea664253 3149 return e->get_backend(context);
e440a328 3150 }
e440a328 3151 }
3152
2c809f8f 3153 if (this->type_ != NULL)
f2de4532 3154 expr = Expression::make_cast(this->type_, expr, this->location());
ea664253 3155 return expr->get_backend(context);
e440a328 3156}
3157
d751bb78 3158// Dump ast representation for constant expression.
3159
3160void
3161Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3162{
3163 ast_dump_context->ostream() << this->constant_->name();
3164}
3165
e440a328 3166// Make a reference to a constant in an expression.
3167
3168Expression*
3169Expression::make_const_reference(Named_object* constant,
b13c66cd 3170 Location location)
e440a328 3171{
3172 return new Const_expression(constant, location);
3173}
3174
d5b605df 3175// Find a named object in an expression.
3176
3177int
3178Find_named_object::expression(Expression** pexpr)
3179{
3180 switch ((*pexpr)->classification())
3181 {
3182 case Expression::EXPRESSION_CONST_REFERENCE:
a7f064d5 3183 {
3184 Const_expression* ce = static_cast<Const_expression*>(*pexpr);
3185 if (ce->named_object() == this->no_)
3186 break;
3187
3188 // We need to check a constant initializer explicitly, as
3189 // loops here will not be caught by the loop checking for
3190 // variable initializers.
3191 ce->check_for_init_loop();
3192
3193 return TRAVERSE_CONTINUE;
3194 }
3195
d5b605df 3196 case Expression::EXPRESSION_VAR_REFERENCE:
3197 if ((*pexpr)->var_expression()->named_object() == this->no_)
3198 break;
3199 return TRAVERSE_CONTINUE;
3200 case Expression::EXPRESSION_FUNC_REFERENCE:
3201 if ((*pexpr)->func_expression()->named_object() == this->no_)
3202 break;
3203 return TRAVERSE_CONTINUE;
3204 default:
3205 return TRAVERSE_CONTINUE;
3206 }
3207 this->found_ = true;
3208 return TRAVERSE_EXIT;
3209}
3210
e440a328 3211// The nil value.
3212
3213class Nil_expression : public Expression
3214{
3215 public:
b13c66cd 3216 Nil_expression(Location location)
e440a328 3217 : Expression(EXPRESSION_NIL, location)
3218 { }
3219
3220 static Expression*
bc8e2ef4 3221 do_import(Import_expression*, Location);
e440a328 3222
3223 protected:
3224 bool
3225 do_is_constant() const
3226 { return true; }
3227
f9ca30f9 3228 bool
3ae06f68 3229 do_is_static_initializer() const
f9ca30f9 3230 { return true; }
3231
e440a328 3232 Type*
3233 do_type()
3234 { return Type::make_nil_type(); }
3235
3236 void
3237 do_determine_type(const Type_context*)
3238 { }
3239
3240 Expression*
3241 do_copy()
3242 { return this; }
3243
ea664253 3244 Bexpression*
3245 do_get_backend(Translate_context* context)
3246 { return context->backend()->nil_pointer_expression(); }
e440a328 3247
5f6f5357 3248 int
3249 do_inlining_cost() const
3250 { return 1; }
3251
e440a328 3252 void
548be246 3253 do_export(Export_function_body* efb) const
204d4af4 3254 { efb->write_c_string("$nil"); }
d751bb78 3255
3256 void
3257 do_dump_expression(Ast_dump_context* ast_dump_context) const
3258 { ast_dump_context->ostream() << "nil"; }
e440a328 3259};
3260
3261// Import a nil expression.
3262
3263Expression*
bc8e2ef4 3264Nil_expression::do_import(Import_expression* imp, Location loc)
e440a328 3265{
204d4af4 3266 if (imp->version() >= EXPORT_FORMAT_V3)
3267 imp->require_c_string("$");
e440a328 3268 imp->require_c_string("nil");
9b92780c 3269 return Expression::make_nil(loc);
e440a328 3270}
3271
3272// Make a nil expression.
3273
3274Expression*
b13c66cd 3275Expression::make_nil(Location location)
e440a328 3276{
3277 return new Nil_expression(location);
3278}
3279
3280// The value of the predeclared constant iota. This is little more
3281// than a marker. This will be lowered to an integer in
3282// Const_expression::do_lower, which is where we know the value that
3283// it should have.
3284
3285class Iota_expression : public Parser_expression
3286{
3287 public:
b13c66cd 3288 Iota_expression(Location location)
e440a328 3289 : Parser_expression(EXPRESSION_IOTA, location)
3290 { }
3291
3292 protected:
3293 Expression*
ceeb4318 3294 do_lower(Gogo*, Named_object*, Statement_inserter*, int)
c3e6f413 3295 { go_unreachable(); }
e440a328 3296
3297 // There should only ever be one of these.
3298 Expression*
3299 do_copy()
c3e6f413 3300 { go_unreachable(); }
f03a9fbf 3301
d751bb78 3302 void
3303 do_dump_expression(Ast_dump_context* ast_dump_context) const
f03a9fbf 3304 { ast_dump_context->ostream() << "iota"; }
e440a328 3305};
3306
3307// Make an iota expression. This is only called for one case: the
3308// value of the predeclared constant iota.
3309
3310Expression*
3311Expression::make_iota()
3312{
b13c66cd 3313 static Iota_expression iota_expression(Linemap::unknown_location());
e440a328 3314 return &iota_expression;
3315}
3316
da244e59 3317// Class Type_conversion_expression.
e440a328 3318
3319// Traversal.
3320
3321int
3322Type_conversion_expression::do_traverse(Traverse* traverse)
3323{
3324 if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
3325 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
3326 return TRAVERSE_EXIT;
3327 return TRAVERSE_CONTINUE;
3328}
3329
3330// Convert to a constant at lowering time.
3331
3332Expression*
ceeb4318 3333Type_conversion_expression::do_lower(Gogo*, Named_object*,
3334 Statement_inserter*, int)
e440a328 3335{
3336 Type* type = this->type_;
3337 Expression* val = this->expr_;
b13c66cd 3338 Location location = this->location();
e440a328 3339
0c77715b 3340 if (type->is_numeric_type())
e440a328 3341 {
0c77715b 3342 Numeric_constant nc;
3343 if (val->numeric_constant_value(&nc))
e440a328 3344 {
0c77715b 3345 if (!nc.set_type(type, true, location))
3346 return Expression::make_error(location);
3347 return nc.expression(location);
e440a328 3348 }
e440a328 3349 }
3350
d7739c9a 3351 // According to the language specification on string conversions
3352 // (http://golang.org/ref/spec#Conversions_to_and_from_a_string_type):
3353 // When converting an integer into a string, the string will be a UTF-8
3354 // representation of the integer and integers "outside the range of valid
3355 // Unicode code points are converted to '\uFFFD'."
3356 if (type->is_string_type())
3357 {
3358 Numeric_constant nc;
3359 if (val->numeric_constant_value(&nc) && nc.is_int())
3360 {
3361 // An integer value doesn't fit in the Unicode code point range if it
3362 // overflows the Go "int" type or is negative.
3363 unsigned long ul;
3364 if (!nc.set_type(Type::lookup_integer_type("int"), false, location)
3365 || nc.to_unsigned_long(&ul) == Numeric_constant::NC_UL_NEGATIVE)
3366 return Expression::make_string("\ufffd", location);
3367 }
3368 }
3369
55072f2b 3370 if (type->is_slice_type())
e440a328 3371 {
3372 Type* element_type = type->array_type()->element_type()->forwarded();
60963afd 3373 bool is_byte = (element_type->integer_type() != NULL
3374 && element_type->integer_type()->is_byte());
3375 bool is_rune = (element_type->integer_type() != NULL
3376 && element_type->integer_type()->is_rune());
3377 if (is_byte || is_rune)
e440a328 3378 {
3379 std::string s;
3380 if (val->string_constant_value(&s))
3381 {
3382 Expression_list* vals = new Expression_list();
3383 if (is_byte)
3384 {
3385 for (std::string::const_iterator p = s.begin();
3386 p != s.end();
3387 p++)
3388 {
e67508fa 3389 unsigned char c = static_cast<unsigned char>(*p);
3390 vals->push_back(Expression::make_integer_ul(c,
3391 element_type,
3392 location));
e440a328 3393 }
3394 }
3395 else
3396 {
3397 const char *p = s.data();
3398 const char *pend = s.data() + s.length();
3399 while (p < pend)
3400 {
3401 unsigned int c;
3402 int adv = Lex::fetch_char(p, &c);
3403 if (adv == 0)
3404 {
631d5788 3405 go_warning_at(this->location(), 0,
e440a328 3406 "invalid UTF-8 encoding");
3407 adv = 1;
3408 }
3409 p += adv;
e67508fa 3410 vals->push_back(Expression::make_integer_ul(c,
3411 element_type,
3412 location));
e440a328 3413 }
3414 }
3415
3416 return Expression::make_slice_composite_literal(type, vals,
3417 location);
3418 }
3419 }
3420 }
3421
3422 return this;
3423}
3424
35a54f17 3425// Flatten a type conversion by using a temporary variable for the slice
3426// in slice to string conversions.
3427
3428Expression*
3429Type_conversion_expression::do_flatten(Gogo*, Named_object*,
3430 Statement_inserter* inserter)
3431{
5bf8be8b 3432 if (this->type()->is_error_type() || this->expr_->is_error_expression())
3433 {
3434 go_assert(saw_errors());
3435 return Expression::make_error(this->location());
3436 }
3437
2c809f8f 3438 if (((this->type()->is_string_type()
3439 && this->expr_->type()->is_slice_type())
8ba8cc87 3440 || this->expr_->type()->interface_type() != NULL)
35a54f17 3441 && !this->expr_->is_variable())
3442 {
3443 Temporary_statement* temp =
3444 Statement::make_temporary(NULL, this->expr_, this->location());
3445 inserter->insert(temp);
3446 this->expr_ = Expression::make_temporary_reference(temp, this->location());
3447 }
3448 return this;
3449}
3450
1ca01a59 3451// Return whether a type conversion is a constant.
3452
3453bool
3454Type_conversion_expression::do_is_constant() const
3455{
3456 if (!this->expr_->is_constant())
3457 return false;
3458
3459 // A conversion to a type that may not be used as a constant is not
3460 // a constant. For example, []byte(nil).
3461 Type* type = this->type_;
3462 if (type->integer_type() == NULL
3463 && type->float_type() == NULL
3464 && type->complex_type() == NULL
3465 && !type->is_boolean_type()
3466 && !type->is_string_type())
3467 return false;
3468
3469 return true;
3470}
3471
3ae06f68 3472// Return whether a type conversion can be used in a constant
3473// initializer.
0e168074 3474
3475bool
3ae06f68 3476Type_conversion_expression::do_is_static_initializer() const
0e168074 3477{
3478 Type* type = this->type_;
3479 Type* expr_type = this->expr_->type();
3480
3481 if (type->interface_type() != NULL
3482 || expr_type->interface_type() != NULL)
3483 return false;
3484
3ae06f68 3485 if (!this->expr_->is_static_initializer())
0e168074 3486 return false;
3487
3a522dcc 3488 if (Type::are_identical(type, expr_type,
3489 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
3490 NULL))
0e168074 3491 return true;
3492
03118c21 3493 if (type->is_string_type() && expr_type->is_string_type())
3494 return true;
3495
3496 if ((type->is_numeric_type()
3497 || type->is_boolean_type()
3498 || type->points_to() != NULL)
3499 && (expr_type->is_numeric_type()
3500 || expr_type->is_boolean_type()
3501 || expr_type->points_to() != NULL))
3502 return true;
3503
3504 return false;
0e168074 3505}
3506
0c77715b 3507// Return the constant numeric value if there is one.
e440a328 3508
3509bool
0c77715b 3510Type_conversion_expression::do_numeric_constant_value(
3511 Numeric_constant* nc) const
e440a328 3512{
0c77715b 3513 if (!this->type_->is_numeric_type())
e440a328 3514 return false;
0c77715b 3515 if (!this->expr_->numeric_constant_value(nc))
e440a328 3516 return false;
0c77715b 3517 return nc->set_type(this->type_, false, this->location());
e440a328 3518}
3519
3520// Return the constant string value if there is one.
3521
3522bool
3523Type_conversion_expression::do_string_constant_value(std::string* val) const
3524{
3525 if (this->type_->is_string_type()
3526 && this->expr_->type()->integer_type() != NULL)
3527 {
0c77715b 3528 Numeric_constant nc;
3529 if (this->expr_->numeric_constant_value(&nc))
e440a328 3530 {
0c77715b 3531 unsigned long ival;
3532 if (nc.to_unsigned_long(&ival) == Numeric_constant::NC_UL_VALID)
e440a328 3533 {
0c77715b 3534 val->clear();
3535 Lex::append_char(ival, true, val, this->location());
e440a328 3536 return true;
3537 }
3538 }
e440a328 3539 }
3540
3541 // FIXME: Could handle conversion from const []int here.
3542
3543 return false;
3544}
3545
da244e59 3546// Determine the resulting type of the conversion.
3547
3548void
3549Type_conversion_expression::do_determine_type(const Type_context*)
3550{
3551 Type_context subcontext(this->type_, false);
3552 this->expr_->determine_type(&subcontext);
3553}
3554
e440a328 3555// Check that types are convertible.
3556
3557void
3558Type_conversion_expression::do_check_types(Gogo*)
3559{
3560 Type* type = this->type_;
3561 Type* expr_type = this->expr_->type();
3562 std::string reason;
3563
5c13bd80 3564 if (type->is_error() || expr_type->is_error())
842f6425 3565 {
842f6425 3566 this->set_is_error();
3567 return;
3568 }
3569
e440a328 3570 if (this->may_convert_function_types_
3571 && type->function_type() != NULL
3572 && expr_type->function_type() != NULL)
3573 return;
3574
3575 if (Type::are_convertible(type, expr_type, &reason))
3576 return;
3577
631d5788 3578 go_error_at(this->location(), "%s", reason.c_str());
e440a328 3579 this->set_is_error();
3580}
3581
de590a61 3582// Copy.
3583
3584Expression*
3585Type_conversion_expression::do_copy()
3586{
3587 return new Type_conversion_expression(this->type_->copy_expressions(),
3588 this->expr_->copy(),
3589 this->location());
3590}
3591
ea664253 3592// Get the backend representation for a type conversion.
e440a328 3593
ea664253 3594Bexpression*
3595Type_conversion_expression::do_get_backend(Translate_context* context)
e440a328 3596{
e440a328 3597 Type* type = this->type_;
3598 Type* expr_type = this->expr_->type();
2c809f8f 3599
3600 Gogo* gogo = context->gogo();
3601 Btype* btype = type->get_backend(gogo);
2c809f8f 3602 Location loc = this->location();
3603
3a522dcc 3604 if (Type::are_identical(type, expr_type,
3605 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
3606 NULL))
859cdc93 3607 {
3608 Bexpression* bexpr = this->expr_->get_backend(context);
3609 return gogo->backend()->convert_expression(btype, bexpr, loc);
3610 }
2c809f8f 3611 else if (type->interface_type() != NULL
3612 || expr_type->interface_type() != NULL)
e440a328 3613 {
2c809f8f 3614 Expression* conversion =
3615 Expression::convert_for_assignment(gogo, type, this->expr_,
3616 this->location());
ea664253 3617 return conversion->get_backend(context);
e440a328 3618 }
3619 else if (type->is_string_type()
3620 && expr_type->integer_type() != NULL)
3621 {
2c809f8f 3622 mpz_t intval;
3623 Numeric_constant nc;
3624 if (this->expr_->numeric_constant_value(&nc)
3625 && nc.to_int(&intval)
3626 && mpz_fits_ushort_p(intval))
e440a328 3627 {
e440a328 3628 std::string s;
2c809f8f 3629 Lex::append_char(mpz_get_ui(intval), true, &s, loc);
3630 mpz_clear(intval);
3631 Expression* se = Expression::make_string(s, loc);
ea664253 3632 return se->get_backend(context);
e440a328 3633 }
3634
f16ab008 3635 Expression* i2s_expr =
736a16ba 3636 Runtime::make_call(Runtime::INTSTRING, loc, 2,
3637 Expression::make_nil(loc), this->expr_);
ea664253 3638 return Expression::make_cast(type, i2s_expr, loc)->get_backend(context);
e440a328 3639 }
55072f2b 3640 else if (type->is_string_type() && expr_type->is_slice_type())
e440a328 3641 {
55072f2b 3642 Array_type* a = expr_type->array_type();
e440a328 3643 Type* e = a->element_type()->forwarded();
c484d925 3644 go_assert(e->integer_type() != NULL);
35a54f17 3645 go_assert(this->expr_->is_variable());
3646
3647 Runtime::Function code;
60963afd 3648 if (e->integer_type()->is_byte())
736a16ba 3649 code = Runtime::SLICEBYTETOSTRING;
e440a328 3650 else
35a54f17 3651 {
3652 go_assert(e->integer_type()->is_rune());
736a16ba 3653 code = Runtime::SLICERUNETOSTRING;
35a54f17 3654 }
736a16ba 3655 return Runtime::make_call(code, loc, 2, Expression::make_nil(loc),
3656 this->expr_)->get_backend(context);
e440a328 3657 }
411eb89e 3658 else if (type->is_slice_type() && expr_type->is_string_type())
e440a328 3659 {
3660 Type* e = type->array_type()->element_type()->forwarded();
c484d925 3661 go_assert(e->integer_type() != NULL);
6c252e42 3662
2c809f8f 3663 Runtime::Function code;
60963afd 3664 if (e->integer_type()->is_byte())
736a16ba 3665 code = Runtime::STRINGTOSLICEBYTE;
e440a328 3666 else
3667 {
60963afd 3668 go_assert(e->integer_type()->is_rune());
736a16ba 3669 code = Runtime::STRINGTOSLICERUNE;
e440a328 3670 }
736a16ba 3671 Expression* s2a = Runtime::make_call(code, loc, 2,
3672 Expression::make_nil(loc),
3673 this->expr_);
ea664253 3674 return Expression::make_unsafe_cast(type, s2a, loc)->get_backend(context);
2c809f8f 3675 }
3676 else if (type->is_numeric_type())
3677 {
3678 go_assert(Type::are_convertible(type, expr_type, NULL));
859cdc93 3679 Bexpression* bexpr = this->expr_->get_backend(context);
ea664253 3680 return gogo->backend()->convert_expression(btype, bexpr, loc);
e440a328 3681 }
3682 else if ((type->is_unsafe_pointer_type()
2c809f8f 3683 && (expr_type->points_to() != NULL
3684 || expr_type->integer_type()))
3685 || (expr_type->is_unsafe_pointer_type()
3686 && type->points_to() != NULL)
3687 || (this->may_convert_function_types_
3688 && type->function_type() != NULL
3689 && expr_type->function_type() != NULL))
859cdc93 3690 {
3691 Bexpression* bexpr = this->expr_->get_backend(context);
3692 return gogo->backend()->convert_expression(btype, bexpr, loc);
3693 }
e440a328 3694 else
2c809f8f 3695 {
3696 Expression* conversion =
3697 Expression::convert_for_assignment(gogo, type, this->expr_, loc);
ea664253 3698 return conversion->get_backend(context);
2c809f8f 3699 }
e440a328 3700}
3701
5f6f5357 3702// Cost of inlining a type conversion.
3703
3704int
3705Type_conversion_expression::do_inlining_cost() const
3706{
3707 Type* type = this->type_;
3708 Type* expr_type = this->expr_->type();
3709 if (type->interface_type() != NULL || expr_type->interface_type() != NULL)
3710 return 10;
3711 else if (type->is_string_type() && expr_type->integer_type() != NULL)
3712 return 10;
3713 else if (type->is_string_type() && expr_type->is_slice_type())
3714 return 10;
3715 else if (type->is_slice_type() && expr_type->is_string_type())
3716 return 10;
3717 else
3718 return 1;
3719}
3720
e440a328 3721// Output a type conversion in a constant expression.
3722
3723void
548be246 3724Type_conversion_expression::do_export(Export_function_body* efb) const
e440a328 3725{
204d4af4 3726 efb->write_c_string("$convert(");
548be246 3727 efb->write_type(this->type_);
3728 efb->write_c_string(", ");
69f634cc 3729
3730 Type* old_context = efb->type_context();
3731 efb->set_type_context(this->type_);
3732
548be246 3733 this->expr_->export_expression(efb);
69f634cc 3734
3735 efb->set_type_context(old_context);
3736
548be246 3737 efb->write_c_string(")");
e440a328 3738}
3739
3740// Import a type conversion or a struct construction.
3741
3742Expression*
bc8e2ef4 3743Type_conversion_expression::do_import(Import_expression* imp, Location loc)
e440a328 3744{
204d4af4 3745 imp->require_c_string("$convert(");
e440a328 3746 Type* type = imp->read_type();
3747 imp->require_c_string(", ");
9b92780c 3748 Expression* val = Expression::import_expression(imp, loc);
e440a328 3749 imp->require_c_string(")");
9b92780c 3750 return Expression::make_cast(type, val, loc);
e440a328 3751}
3752
d751bb78 3753// Dump ast representation for a type conversion expression.
3754
3755void
3756Type_conversion_expression::do_dump_expression(
3757 Ast_dump_context* ast_dump_context) const
3758{
3759 ast_dump_context->dump_type(this->type_);
3760 ast_dump_context->ostream() << "(";
3761 ast_dump_context->dump_expression(this->expr_);
3762 ast_dump_context->ostream() << ") ";
3763}
3764
e440a328 3765// Make a type cast expression.
3766
3767Expression*
b13c66cd 3768Expression::make_cast(Type* type, Expression* val, Location location)
e440a328 3769{
3770 if (type->is_error_type() || val->is_error_expression())
3771 return Expression::make_error(location);
3772 return new Type_conversion_expression(type, val, location);
3773}
3774
98f62f7a 3775// Class Unsafe_type_conversion_expression.
9581e91d 3776
3777// Traversal.
3778
3779int
3780Unsafe_type_conversion_expression::do_traverse(Traverse* traverse)
3781{
3782 if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
3783 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
3784 return TRAVERSE_EXIT;
3785 return TRAVERSE_CONTINUE;
3786}
3787
3ae06f68 3788// Return whether an unsafe type conversion can be used as a constant
3789// initializer.
aa5ae575 3790
3791bool
3ae06f68 3792Unsafe_type_conversion_expression::do_is_static_initializer() const
aa5ae575 3793{
3794 Type* type = this->type_;
3795 Type* expr_type = this->expr_->type();
3796
3797 if (type->interface_type() != NULL
3798 || expr_type->interface_type() != NULL)
3799 return false;
3800
3ae06f68 3801 if (!this->expr_->is_static_initializer())
aa5ae575 3802 return false;
3803
3804 if (Type::are_convertible(type, expr_type, NULL))
3805 return true;
3806
03118c21 3807 if (type->is_string_type() && expr_type->is_string_type())
3808 return true;
3809
3810 if ((type->is_numeric_type()
3811 || type->is_boolean_type()
3812 || type->points_to() != NULL)
3813 && (expr_type->is_numeric_type()
3814 || expr_type->is_boolean_type()
3815 || expr_type->points_to() != NULL))
3816 return true;
3817
3818 return false;
aa5ae575 3819}
3820
de590a61 3821// Copy.
3822
3823Expression*
3824Unsafe_type_conversion_expression::do_copy()
3825{
3826 return new Unsafe_type_conversion_expression(this->type_->copy_expressions(),
3827 this->expr_->copy(),
3828 this->location());
3829}
3830
9581e91d 3831// Convert to backend representation.
3832
ea664253 3833Bexpression*
3834Unsafe_type_conversion_expression::do_get_backend(Translate_context* context)
9581e91d 3835{
3836 // We are only called for a limited number of cases.
3837
3838 Type* t = this->type_;
3839 Type* et = this->expr_->type();
5c4802f1 3840
3841 if (t->is_error_type()
3842 || this->expr_->is_error_expression()
3843 || et->is_error_type())
3844 {
3845 go_assert(saw_errors());
3846 return context->backend()->error_expression();
3847 }
3848
2c809f8f 3849 if (t->array_type() != NULL)
3850 go_assert(et->array_type() != NULL
3851 && t->is_slice_type() == et->is_slice_type());
3852 else if (t->struct_type() != NULL)
9581e91d 3853 {
2c809f8f 3854 if (t->named_type() != NULL
3855 && et->named_type() != NULL
3856 && !Type::are_convertible(t, et, NULL))
3857 {
3858 go_assert(saw_errors());
ea664253 3859 return context->backend()->error_expression();
2c809f8f 3860 }
3861
3862 go_assert(et->struct_type() != NULL
3863 && Type::are_convertible(t, et, NULL));
3864 }
3865 else if (t->map_type() != NULL)
c484d925 3866 go_assert(et->map_type() != NULL);
9581e91d 3867 else if (t->channel_type() != NULL)
c484d925 3868 go_assert(et->channel_type() != NULL);
09ea332d 3869 else if (t->points_to() != NULL)
2c809f8f 3870 go_assert(et->points_to() != NULL
3871 || et->channel_type() != NULL
3872 || et->map_type() != NULL
3873 || et->function_type() != NULL
132ed071 3874 || et->integer_type() != NULL
2c809f8f 3875 || et->is_nil_type());
9581e91d 3876 else if (et->is_unsafe_pointer_type())
81487fff 3877 go_assert(t->points_to() != NULL
3878 || (t->integer_type() != NULL
3879 && t->integer_type() == Type::lookup_integer_type("uintptr")->real_type()));
2c809f8f 3880 else if (t->interface_type() != NULL)
9581e91d 3881 {
2c809f8f 3882 bool empty_iface = t->interface_type()->is_empty();
c484d925 3883 go_assert(et->interface_type() != NULL
2c809f8f 3884 && et->interface_type()->is_empty() == empty_iface);
9581e91d 3885 }
588e3cf9 3886 else if (t->integer_type() != NULL)
2c809f8f 3887 go_assert(et->is_boolean_type()
3888 || et->integer_type() != NULL
3889 || et->function_type() != NULL
3890 || et->points_to() != NULL
3891 || et->map_type() != NULL
8ba8cc87 3892 || et->channel_type() != NULL
3893 || et->is_nil_type());
cd39797e 3894 else if (t->function_type() != NULL)
3895 go_assert(et->points_to() != NULL);
9581e91d 3896 else
c3e6f413 3897 go_unreachable();
9581e91d 3898
2c809f8f 3899 Gogo* gogo = context->gogo();
3900 Btype* btype = t->get_backend(gogo);
ea664253 3901 Bexpression* bexpr = this->expr_->get_backend(context);
2c809f8f 3902 Location loc = this->location();
ea664253 3903 return gogo->backend()->convert_expression(btype, bexpr, loc);
9581e91d 3904}
3905
d751bb78 3906// Dump ast representation for an unsafe type conversion expression.
3907
3908void
3909Unsafe_type_conversion_expression::do_dump_expression(
3910 Ast_dump_context* ast_dump_context) const
3911{
3912 ast_dump_context->dump_type(this->type_);
3913 ast_dump_context->ostream() << "(";
3914 ast_dump_context->dump_expression(this->expr_);
3915 ast_dump_context->ostream() << ") ";
3916}
3917
9581e91d 3918// Make an unsafe type conversion expression.
3919
3920Expression*
3921Expression::make_unsafe_cast(Type* type, Expression* expr,
b13c66cd 3922 Location location)
9581e91d 3923{
3924 return new Unsafe_type_conversion_expression(type, expr, location);
3925}
3926
76f85fd6 3927// Class Unary_expression.
e440a328 3928
03118c21 3929// Call the address_taken method of the operand if needed. This is
3930// called after escape analysis but before inserting write barriers.
3931
3932void
c1177ba4 3933Unary_expression::check_operand_address_taken(Gogo*)
03118c21 3934{
3935 if (this->op_ != OPERATOR_AND)
3936 return;
3937
3938 // If this->escapes_ is false at this point, then it was set to
3939 // false by an explicit call to set_does_not_escape, and the value
3940 // does not escape. If this->escapes_ is true, we may be able to
2f86af0a 3941 // set it to false based on the escape analysis pass.
3942 if (this->escapes_)
3943 {
3944 Node* n = Node::make_node(this);
3945 if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
3946 this->escapes_ = false;
03118c21 3947 }
3948
3949 this->expr_->address_taken(this->escapes_);
3950}
3951
e440a328 3952// If we are taking the address of a composite literal, and the
2c809f8f 3953// contents are not constant, then we want to make a heap expression
e440a328 3954// instead.
3955
3956Expression*
ceeb4318 3957Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
e440a328 3958{
b13c66cd 3959 Location loc = this->location();
e440a328 3960 Operator op = this->op_;
3961 Expression* expr = this->expr_;
3962
3963 if (op == OPERATOR_MULT && expr->is_type_expression())
3964 return Expression::make_type(Type::make_pointer_type(expr->type()), loc);
3965
3966 // *&x simplifies to x. *(*T)(unsafe.Pointer)(&x) does not require
3967 // moving x to the heap. FIXME: Is it worth doing a real escape
3968 // analysis here? This case is found in math/unsafe.go and is
3969 // therefore worth special casing.
3970 if (op == OPERATOR_MULT)
3971 {
3972 Expression* e = expr;
3973 while (e->classification() == EXPRESSION_CONVERSION)
3974 {
3975 Type_conversion_expression* te
3976 = static_cast<Type_conversion_expression*>(e);
3977 e = te->expr();
3978 }
3979
3980 if (e->classification() == EXPRESSION_UNARY)
3981 {
3982 Unary_expression* ue = static_cast<Unary_expression*>(e);
3983 if (ue->op_ == OPERATOR_AND)
3984 {
3985 if (e == expr)
3986 {
3987 // *&x == x.
f4dea966 3988 if (!ue->expr_->is_addressable() && !ue->create_temp_)
3989 {
631d5788 3990 go_error_at(ue->location(),
3991 "invalid operand for unary %<&%>");
f4dea966 3992 this->set_is_error();
3993 }
e440a328 3994 return ue->expr_;
3995 }
3996 ue->set_does_not_escape();
3997 }
3998 }
3999 }
4000
55661ce9 4001 // Catching an invalid indirection of unsafe.Pointer here avoid
4002 // having to deal with TYPE_VOID in other places.
4003 if (op == OPERATOR_MULT && expr->type()->is_unsafe_pointer_type())
4004 {
631d5788 4005 go_error_at(this->location(), "invalid indirect of %<unsafe.Pointer%>");
55661ce9 4006 return Expression::make_error(this->location());
4007 }
4008
d9f3743a 4009 // Check for an invalid pointer dereference. We need to do this
4010 // here because Unary_expression::do_type will return an error type
4011 // in this case. That can cause code to appear erroneous, and
4012 // therefore disappear at lowering time, without any error message.
4013 if (op == OPERATOR_MULT && expr->type()->points_to() == NULL)
4014 {
4015 this->report_error(_("expected pointer"));
4016 return Expression::make_error(this->location());
4017 }
4018
59a401fe 4019 if (op == OPERATOR_PLUS || op == OPERATOR_MINUS || op == OPERATOR_XOR)
e440a328 4020 {
0c77715b 4021 Numeric_constant nc;
4022 if (expr->numeric_constant_value(&nc))
e440a328 4023 {
0c77715b 4024 Numeric_constant result;
af7a5274 4025 bool issued_error;
4026 if (Unary_expression::eval_constant(op, &nc, loc, &result,
4027 &issued_error))
0c77715b 4028 return result.expression(loc);
af7a5274 4029 else if (issued_error)
4030 return Expression::make_error(this->location());
e440a328 4031 }
4032 }
4033
4034 return this;
4035}
4036
f9ca30f9 4037// Flatten expression if a nil check must be performed and create temporary
4038// variables if necessary.
4039
4040Expression*
4041Unary_expression::do_flatten(Gogo* gogo, Named_object*,
4042 Statement_inserter* inserter)
4043{
5bf8be8b 4044 if (this->is_error_expression()
4045 || this->expr_->is_error_expression()
4046 || this->expr_->type()->is_error_type())
4047 {
4048 go_assert(saw_errors());
4049 return Expression::make_error(this->location());
4050 }
f4dea966 4051
f9ca30f9 4052 Location location = this->location();
4053 if (this->op_ == OPERATOR_MULT
4054 && !this->expr_->is_variable())
4055 {
4056 go_assert(this->expr_->type()->points_to() != NULL);
f614ea8b 4057 switch (this->requires_nil_check(gogo))
f9ca30f9 4058 {
f614ea8b 4059 case NIL_CHECK_ERROR_ENCOUNTERED:
2a305b85 4060 {
4061 go_assert(saw_errors());
4062 return Expression::make_error(this->location());
4063 }
f614ea8b 4064 case NIL_CHECK_NOT_NEEDED:
4065 break;
4066 case NIL_CHECK_NEEDED:
4067 this->create_temp_ = true;
4068 break;
4069 case NIL_CHECK_DEFAULT:
4070 go_unreachable();
f9ca30f9 4071 }
4072 }
4073
4074 if (this->create_temp_ && !this->expr_->is_variable())
4075 {
4076 Temporary_statement* temp =
4077 Statement::make_temporary(NULL, this->expr_, location);
4078 inserter->insert(temp);
4079 this->expr_ = Expression::make_temporary_reference(temp, location);
4080 }
4081
4082 return this;
4083}
4084
e440a328 4085// Return whether a unary expression is a constant.
4086
4087bool
4088Unary_expression::do_is_constant() const
4089{
4090 if (this->op_ == OPERATOR_MULT)
4091 {
4092 // Indirecting through a pointer is only constant if the object
4093 // to which the expression points is constant, but we currently
4094 // have no way to determine that.
4095 return false;
4096 }
4097 else if (this->op_ == OPERATOR_AND)
4098 {
4099 // Taking the address of a variable is constant if it is a
f9ca30f9 4100 // global variable, not constant otherwise. In other cases taking the
4101 // address is probably not a constant.
e440a328 4102 Var_expression* ve = this->expr_->var_expression();
4103 if (ve != NULL)
4104 {
4105 Named_object* no = ve->named_object();
4106 return no->is_variable() && no->var_value()->is_global();
4107 }
4108 return false;
4109 }
4110 else
4111 return this->expr_->is_constant();
4112}
4113
3ae06f68 4114// Return whether a unary expression can be used as a constant
4115// initializer.
4116
4117bool
4118Unary_expression::do_is_static_initializer() const
4119{
4120 if (this->op_ == OPERATOR_MULT)
4121 return false;
4122 else if (this->op_ == OPERATOR_AND)
de048538 4123 return Unary_expression::base_is_static_initializer(this->expr_);
4124 else
4125 return this->expr_->is_static_initializer();
4126}
3ae06f68 4127
de048538 4128// Return whether the address of EXPR can be used as a static
4129// initializer.
3ae06f68 4130
de048538 4131bool
4132Unary_expression::base_is_static_initializer(Expression* expr)
4133{
4134 // The address of a field reference can be a static initializer if
4135 // the base can be a static initializer.
4136 Field_reference_expression* fre = expr->field_reference_expression();
4137 if (fre != NULL)
4138 return Unary_expression::base_is_static_initializer(fre->expr());
4139
4140 // The address of an index expression can be a static initializer if
4141 // the base can be a static initializer and the index is constant.
4142 Array_index_expression* aind = expr->array_index_expression();
4143 if (aind != NULL)
4144 return (aind->end() == NULL
4145 && aind->start()->is_constant()
4146 && Unary_expression::base_is_static_initializer(aind->array()));
4147
4148 // The address of a global variable can be a static initializer.
4149 Var_expression* ve = expr->var_expression();
4150 if (ve != NULL)
4151 {
4152 Named_object* no = ve->named_object();
4153 return no->is_variable() && no->var_value()->is_global();
4154 }
4155
4156 // The address of a composite literal can be used as a static
4157 // initializer if the composite literal is itself usable as a
4158 // static initializer.
4159 if (expr->is_composite_literal() && expr->is_static_initializer())
4160 return true;
3ae06f68 4161
de048538 4162 // The address of a string constant can be used as a static
4163 // initializer. This can not be written in Go itself but this is
4164 // used when building a type descriptor.
4165 if (expr->string_expression() != NULL)
4166 return true;
4167
4168 return false;
3ae06f68 4169}
4170
f614ea8b 4171// Return whether this dereference expression requires an explicit nil
4172// check. If we are dereferencing the pointer to a large struct
4173// (greater than the specified size threshold), we need to check for
4174// nil. We don't bother to check for small structs because we expect
4175// the system to crash on a nil pointer dereference. However, if we
4176// know the address of this expression is being taken, we must always
4177// check for nil.
4178Unary_expression::Nil_check_classification
f03a9fbf 4179Unary_expression::requires_nil_check(Gogo* gogo)
f614ea8b 4180{
4181 go_assert(this->op_ == OPERATOR_MULT);
4182 go_assert(this->expr_->type()->points_to() != NULL);
4183
4184 if (this->issue_nil_check_ == NIL_CHECK_NEEDED)
4185 return NIL_CHECK_NEEDED;
4186 else if (this->issue_nil_check_ == NIL_CHECK_NOT_NEEDED)
4187 return NIL_CHECK_NOT_NEEDED;
4188
4189 Type* ptype = this->expr_->type()->points_to();
4190 int64_t type_size = -1;
4191 if (!ptype->is_void_type())
4192 {
4193 bool ok = ptype->backend_type_size(gogo, &type_size);
4194 if (!ok)
4195 return NIL_CHECK_ERROR_ENCOUNTERED;
4196 }
4197
4198 int64_t size_cutoff = gogo->nil_check_size_threshold();
4199 if (size_cutoff == -1 || (type_size != -1 && type_size >= size_cutoff))
4200 this->issue_nil_check_ = NIL_CHECK_NEEDED;
4201 else
4202 this->issue_nil_check_ = NIL_CHECK_NOT_NEEDED;
4203 return this->issue_nil_check_;
4204}
4205
0c77715b 4206// Apply unary opcode OP to UNC, setting NC. Return true if this
af7a5274 4207// could be done, false if not. On overflow, issues an error and sets
4208// *ISSUED_ERROR.
e440a328 4209
4210bool
0c77715b 4211Unary_expression::eval_constant(Operator op, const Numeric_constant* unc,
af7a5274 4212 Location location, Numeric_constant* nc,
4213 bool* issued_error)
e440a328 4214{
af7a5274 4215 *issued_error = false;
e440a328 4216 switch (op)
4217 {
4218 case OPERATOR_PLUS:
0c77715b 4219 *nc = *unc;
e440a328 4220 return true;
0c77715b 4221
e440a328 4222 case OPERATOR_MINUS:
0c77715b 4223 if (unc->is_int() || unc->is_rune())
4224 break;
4225 else if (unc->is_float())
4226 {
4227 mpfr_t uval;
4228 unc->get_float(&uval);
4229 mpfr_t val;
4230 mpfr_init(val);
4231 mpfr_neg(val, uval, GMP_RNDN);
4232 nc->set_float(unc->type(), val);
4233 mpfr_clear(uval);
4234 mpfr_clear(val);
4235 return true;
4236 }
4237 else if (unc->is_complex())
4238 {
fcbea5e4 4239 mpc_t uval;
4240 unc->get_complex(&uval);
4241 mpc_t val;
4242 mpc_init2(val, mpc_precision);
4243 mpc_neg(val, uval, MPC_RNDNN);
4244 nc->set_complex(unc->type(), val);
4245 mpc_clear(uval);
4246 mpc_clear(val);
0c77715b 4247 return true;
4248 }
e440a328 4249 else
0c77715b 4250 go_unreachable();
e440a328 4251
0c77715b 4252 case OPERATOR_XOR:
4253 break;
68448d53 4254
59a401fe 4255 case OPERATOR_NOT:
e440a328 4256 case OPERATOR_AND:
4257 case OPERATOR_MULT:
4258 return false;
0c77715b 4259
e440a328 4260 default:
c3e6f413 4261 go_unreachable();
e440a328 4262 }
e440a328 4263
0c77715b 4264 if (!unc->is_int() && !unc->is_rune())
4265 return false;
4266
4267 mpz_t uval;
8387e1df 4268 if (unc->is_rune())
4269 unc->get_rune(&uval);
4270 else
4271 unc->get_int(&uval);
0c77715b 4272 mpz_t val;
4273 mpz_init(val);
e440a328 4274
e440a328 4275 switch (op)
4276 {
e440a328 4277 case OPERATOR_MINUS:
0c77715b 4278 mpz_neg(val, uval);
4279 break;
4280
e440a328 4281 case OPERATOR_NOT:
0c77715b 4282 mpz_set_ui(val, mpz_cmp_si(uval, 0) == 0 ? 1 : 0);
4283 break;
4284
e440a328 4285 case OPERATOR_XOR:
0c77715b 4286 {
4287 Type* utype = unc->type();
4288 if (utype->integer_type() == NULL
4289 || utype->integer_type()->is_abstract())
4290 mpz_com(val, uval);
4291 else
4292 {
4293 // The number of HOST_WIDE_INTs that it takes to represent
4294 // UVAL.
4295 size_t count = ((mpz_sizeinbase(uval, 2)
4296 + HOST_BITS_PER_WIDE_INT
4297 - 1)
4298 / HOST_BITS_PER_WIDE_INT);
e440a328 4299
0c77715b 4300 unsigned HOST_WIDE_INT* phwi = new unsigned HOST_WIDE_INT[count];
4301 memset(phwi, 0, count * sizeof(HOST_WIDE_INT));
4302
4303 size_t obits = utype->integer_type()->bits();
4304
4305 if (!utype->integer_type()->is_unsigned() && mpz_sgn(uval) < 0)
4306 {
4307 mpz_t adj;
4308 mpz_init_set_ui(adj, 1);
4309 mpz_mul_2exp(adj, adj, obits);
4310 mpz_add(uval, uval, adj);
4311 mpz_clear(adj);
4312 }
4313
4314 size_t ecount;
4315 mpz_export(phwi, &ecount, -1, sizeof(HOST_WIDE_INT), 0, 0, uval);
4316 go_assert(ecount <= count);
4317
4318 // Trim down to the number of words required by the type.
4319 size_t ocount = ((obits + HOST_BITS_PER_WIDE_INT - 1)
4320 / HOST_BITS_PER_WIDE_INT);
4321 go_assert(ocount <= count);
4322
4323 for (size_t i = 0; i < ocount; ++i)
4324 phwi[i] = ~phwi[i];
4325
4326 size_t clearbits = ocount * HOST_BITS_PER_WIDE_INT - obits;
4327 if (clearbits != 0)
4328 phwi[ocount - 1] &= (((unsigned HOST_WIDE_INT) (HOST_WIDE_INT) -1)
4329 >> clearbits);
4330
4331 mpz_import(val, ocount, -1, sizeof(HOST_WIDE_INT), 0, 0, phwi);
4332
4333 if (!utype->integer_type()->is_unsigned()
4334 && mpz_tstbit(val, obits - 1))
4335 {
4336 mpz_t adj;
4337 mpz_init_set_ui(adj, 1);
4338 mpz_mul_2exp(adj, adj, obits);
4339 mpz_sub(val, val, adj);
4340 mpz_clear(adj);
4341 }
4342
4343 delete[] phwi;
4344 }
4345 }
4346 break;
e440a328 4347
e440a328 4348 default:
c3e6f413 4349 go_unreachable();
e440a328 4350 }
e440a328 4351
0c77715b 4352 if (unc->is_rune())
4353 nc->set_rune(NULL, val);
e440a328 4354 else
0c77715b 4355 nc->set_int(NULL, val);
e440a328 4356
0c77715b 4357 mpz_clear(uval);
4358 mpz_clear(val);
e440a328 4359
af7a5274 4360 if (!nc->set_type(unc->type(), true, location))
4361 {
4362 *issued_error = true;
4363 return false;
4364 }
4365 return true;
e440a328 4366}
4367
0c77715b 4368// Return the integral constant value of a unary expression, if it has one.
e440a328 4369
4370bool
0c77715b 4371Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 4372{
0c77715b 4373 Numeric_constant unc;
4374 if (!this->expr_->numeric_constant_value(&unc))
4375 return false;
af7a5274 4376 bool issued_error;
0c77715b 4377 return Unary_expression::eval_constant(this->op_, &unc, this->location(),
af7a5274 4378 nc, &issued_error);
e440a328 4379}
4380
4381// Return the type of a unary expression.
4382
4383Type*
4384Unary_expression::do_type()
4385{
4386 switch (this->op_)
4387 {
4388 case OPERATOR_PLUS:
4389 case OPERATOR_MINUS:
4390 case OPERATOR_NOT:
4391 case OPERATOR_XOR:
4392 return this->expr_->type();
4393
4394 case OPERATOR_AND:
4395 return Type::make_pointer_type(this->expr_->type());
4396
4397 case OPERATOR_MULT:
4398 {
4399 Type* subtype = this->expr_->type();
4400 Type* points_to = subtype->points_to();
4401 if (points_to == NULL)
4402 return Type::make_error_type();
4403 return points_to;
4404 }
4405
4406 default:
c3e6f413 4407 go_unreachable();
e440a328 4408 }
4409}
4410
4411// Determine abstract types for a unary expression.
4412
4413void
4414Unary_expression::do_determine_type(const Type_context* context)
4415{
4416 switch (this->op_)
4417 {
4418 case OPERATOR_PLUS:
4419 case OPERATOR_MINUS:
4420 case OPERATOR_NOT:
4421 case OPERATOR_XOR:
4422 this->expr_->determine_type(context);
4423 break;
4424
4425 case OPERATOR_AND:
4426 // Taking the address of something.
4427 {
4428 Type* subtype = (context->type == NULL
4429 ? NULL
4430 : context->type->points_to());
4431 Type_context subcontext(subtype, false);
4432 this->expr_->determine_type(&subcontext);
4433 }
4434 break;
4435
4436 case OPERATOR_MULT:
4437 // Indirecting through a pointer.
4438 {
4439 Type* subtype = (context->type == NULL
4440 ? NULL
4441 : Type::make_pointer_type(context->type));
4442 Type_context subcontext(subtype, false);
4443 this->expr_->determine_type(&subcontext);
4444 }
4445 break;
4446
4447 default:
c3e6f413 4448 go_unreachable();
e440a328 4449 }
4450}
4451
4452// Check types for a unary expression.
4453
4454void
4455Unary_expression::do_check_types(Gogo*)
4456{
9fe897ef 4457 Type* type = this->expr_->type();
5c13bd80 4458 if (type->is_error())
9fe897ef 4459 {
4460 this->set_is_error();
4461 return;
4462 }
4463
e440a328 4464 switch (this->op_)
4465 {
4466 case OPERATOR_PLUS:
4467 case OPERATOR_MINUS:
9fe897ef 4468 if (type->integer_type() == NULL
4469 && type->float_type() == NULL
4470 && type->complex_type() == NULL)
4471 this->report_error(_("expected numeric type"));
e440a328 4472 break;
4473
4474 case OPERATOR_NOT:
59a401fe 4475 if (!type->is_boolean_type())
4476 this->report_error(_("expected boolean type"));
4477 break;
4478
e440a328 4479 case OPERATOR_XOR:
b3b1474e 4480 if (type->integer_type() == NULL)
4481 this->report_error(_("expected integer"));
e440a328 4482 break;
4483
4484 case OPERATOR_AND:
4485 if (!this->expr_->is_addressable())
09ea332d 4486 {
4487 if (!this->create_temp_)
f4dea966 4488 {
631d5788 4489 go_error_at(this->location(), "invalid operand for unary %<&%>");
f4dea966 4490 this->set_is_error();
4491 }
09ea332d 4492 }
e440a328 4493 else
da244e59 4494 this->expr_->issue_nil_check();
e440a328 4495 break;
4496
4497 case OPERATOR_MULT:
4498 // Indirecting through a pointer.
9fe897ef 4499 if (type->points_to() == NULL)
4500 this->report_error(_("expected pointer"));
7661d702 4501 if (type->points_to()->is_error())
4502 this->set_is_error();
e440a328 4503 break;
4504
4505 default:
c3e6f413 4506 go_unreachable();
e440a328 4507 }
4508}
4509
ea664253 4510// Get the backend representation for a unary expression.
e440a328 4511
ea664253 4512Bexpression*
4513Unary_expression::do_get_backend(Translate_context* context)
e440a328 4514{
1b1f2abf 4515 Gogo* gogo = context->gogo();
e9d3367e 4516 Location loc = this->location();
4517
4518 // Taking the address of a set-and-use-temporary expression requires
4519 // setting the temporary and then taking the address.
4520 if (this->op_ == OPERATOR_AND)
4521 {
4522 Set_and_use_temporary_expression* sut =
4523 this->expr_->set_and_use_temporary_expression();
4524 if (sut != NULL)
4525 {
4526 Temporary_statement* temp = sut->temporary();
4527 Bvariable* bvar = temp->get_backend_variable(context);
d4e6573e 4528 Bexpression* bvar_expr =
7af8e400 4529 gogo->backend()->var_expression(bvar, loc);
ea664253 4530 Bexpression* bval = sut->expression()->get_backend(context);
f9ca30f9 4531
0ab48656 4532 Named_object* fn = context->function();
4533 go_assert(fn != NULL);
4534 Bfunction* bfn =
4535 fn->func_value()->get_or_make_decl(gogo, fn);
f9ca30f9 4536 Bstatement* bassign =
0ab48656 4537 gogo->backend()->assignment_statement(bfn, bvar_expr, bval, loc);
f9ca30f9 4538 Bexpression* bvar_addr =
4539 gogo->backend()->address_expression(bvar_expr, loc);
ea664253 4540 return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
e9d3367e 4541 }
4542 }
4543
f9ca30f9 4544 Bexpression* ret;
ea664253 4545 Bexpression* bexpr = this->expr_->get_backend(context);
f9ca30f9 4546 Btype* btype = this->expr_->type()->get_backend(gogo);
e440a328 4547 switch (this->op_)
4548 {
4549 case OPERATOR_PLUS:
f9ca30f9 4550 ret = bexpr;
4551 break;
e440a328 4552
4553 case OPERATOR_MINUS:
f9ca30f9 4554 ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
4555 ret = gogo->backend()->convert_expression(btype, ret, loc);
4556 break;
e440a328 4557
4558 case OPERATOR_NOT:
e440a328 4559 case OPERATOR_XOR:
f9ca30f9 4560 ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
4561 break;
e440a328 4562
4563 case OPERATOR_AND:
09ea332d 4564 if (!this->create_temp_)
4565 {
4566 // We should not see a non-constant constructor here; cases
4567 // where we would see one should have been moved onto the
4568 // heap at parse time. Taking the address of a nonconstant
4569 // constructor will not do what the programmer expects.
f9ca30f9 4570
4571 go_assert(!this->expr_->is_composite_literal()
3ae06f68 4572 || this->expr_->is_static_initializer());
24060bf9 4573 if (this->expr_->classification() == EXPRESSION_UNARY)
4574 {
4575 Unary_expression* ue =
4576 static_cast<Unary_expression*>(this->expr_);
4577 go_assert(ue->op() != OPERATOR_AND);
4578 }
09ea332d 4579 }
e440a328 4580
f23d7786 4581 if (this->is_gc_root_ || this->is_slice_init_)
76f85fd6 4582 {
19272321 4583 std::string var_name;
f23d7786 4584 bool copy_to_heap = false;
4585 if (this->is_gc_root_)
4586 {
4587 // Build a decl for a GC root variable. GC roots are mutable, so
4588 // they cannot be represented as an immutable_struct in the
4589 // backend.
19272321 4590 var_name = gogo->gc_root_name();
f23d7786 4591 }
4592 else
4593 {
4594 // Build a decl for a slice value initializer. An immutable slice
4595 // value initializer may have to be copied to the heap if it
4596 // contains pointers in a non-constant context.
19272321 4597 var_name = gogo->initializer_name();
f23d7786 4598
4599 Array_type* at = this->expr_->type()->array_type();
4600 go_assert(at != NULL);
4601
4602 // If we are not copying the value to the heap, we will only
4603 // initialize the value once, so we can use this directly
4604 // rather than copying it. In that case we can't make it
4605 // read-only, because the program is permitted to change it.
ee200713 4606 copy_to_heap = (context->function() != NULL
4607 || context->is_const());
f23d7786 4608 }
19272321 4609 std::string asm_name(go_selectively_encode_id(var_name));
f23d7786 4610 Bvariable* implicit =
19272321 4611 gogo->backend()->implicit_variable(var_name, asm_name,
438b4bec 4612 btype, true, copy_to_heap,
4613 false, 0);
19272321 4614 gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
aa5ae575 4615 true, copy_to_heap, false,
4616 bexpr);
7af8e400 4617 bexpr = gogo->backend()->var_expression(implicit, loc);
1b4fb1e0 4618
4619 // If we are not copying a slice initializer to the heap,
4620 // then it can be changed by the program, so if it can
4621 // contain pointers we must register it as a GC root.
4622 if (this->is_slice_init_
4623 && !copy_to_heap
4624 && this->expr_->type()->has_pointer())
4625 {
4626 Bexpression* root =
7af8e400 4627 gogo->backend()->var_expression(implicit, loc);
1b4fb1e0 4628 root = gogo->backend()->address_expression(root, loc);
4629 Type* type = Type::make_pointer_type(this->expr_->type());
4630 gogo->add_gc_root(Expression::make_backend(root, type, loc));
4631 }
76f85fd6 4632 }
4633 else if ((this->expr_->is_composite_literal()
3ae06f68 4634 || this->expr_->string_expression() != NULL)
4635 && this->expr_->is_static_initializer())
f9ca30f9 4636 {
19272321 4637 std::string var_name(gogo->initializer_name());
4638 std::string asm_name(go_selectively_encode_id(var_name));
f9ca30f9 4639 Bvariable* decl =
19272321 4640 gogo->backend()->immutable_struct(var_name, asm_name,
438b4bec 4641 true, false, btype, loc);
19272321 4642 gogo->backend()->immutable_struct_set_init(decl, var_name, true,
4643 false, btype, loc, bexpr);
7af8e400 4644 bexpr = gogo->backend()->var_expression(decl, loc);
f9ca30f9 4645 }
09ea332d 4646
f9ca30f9 4647 go_assert(!this->create_temp_ || this->expr_->is_variable());
4648 ret = gogo->backend()->address_expression(bexpr, loc);
4649 break;
e440a328 4650
4651 case OPERATOR_MULT:
4652 {
f9ca30f9 4653 go_assert(this->expr_->type()->points_to() != NULL);
e440a328 4654
f614ea8b 4655 bool known_valid = false;
f9ca30f9 4656 Type* ptype = this->expr_->type()->points_to();
4657 Btype* pbtype = ptype->get_backend(gogo);
f614ea8b 4658 switch (this->requires_nil_check(gogo))
4659 {
4660 case NIL_CHECK_NOT_NEEDED:
4661 break;
4662 case NIL_CHECK_ERROR_ENCOUNTERED:
2a305b85 4663 {
4664 go_assert(saw_errors());
4665 return gogo->backend()->error_expression();
4666 }
f614ea8b 4667 case NIL_CHECK_NEEDED:
4668 {
f9ca30f9 4669 go_assert(this->expr_->is_variable());
2dd89704 4670
4671 // If we're nil-checking the result of a set-and-use-temporary
4672 // expression, then pick out the target temp and use that
4673 // for the final result of the conditional.
4674 Bexpression* tbexpr = bexpr;
4675 Bexpression* ubexpr = bexpr;
4676 Set_and_use_temporary_expression* sut =
4677 this->expr_->set_and_use_temporary_expression();
4678 if (sut != NULL) {
4679 Temporary_statement* temp = sut->temporary();
4680 Bvariable* bvar = temp->get_backend_variable(context);
4681 ubexpr = gogo->backend()->var_expression(bvar, loc);
4682 }
ea664253 4683 Bexpression* nil =
f614ea8b 4684 Expression::make_nil(loc)->get_backend(context);
f9ca30f9 4685 Bexpression* compare =
2dd89704 4686 gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr,
f9ca30f9 4687 nil, loc);
f9ca30f9 4688 Bexpression* crash =
f614ea8b 4689 gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
4690 loc)->get_backend(context);
93715b75 4691 Bfunction* bfn = context->function()->func_value()->get_decl();
4692 bexpr = gogo->backend()->conditional_expression(bfn, btype,
4693 compare,
2dd89704 4694 crash, ubexpr,
f9ca30f9 4695 loc);
f614ea8b 4696 known_valid = true;
4697 break;
4698 }
4699 case NIL_CHECK_DEFAULT:
4700 go_unreachable();
4701 }
4702 ret = gogo->backend()->indirect_expression(pbtype, bexpr,
4703 known_valid, loc);
e440a328 4704 }
f9ca30f9 4705 break;
e440a328 4706
4707 default:
c3e6f413 4708 go_unreachable();
e440a328 4709 }
f9ca30f9 4710
ea664253 4711 return ret;
e440a328 4712}
4713
4714// Export a unary expression.
4715
4716void
548be246 4717Unary_expression::do_export(Export_function_body* efb) const
e440a328 4718{
4719 switch (this->op_)
4720 {
4721 case OPERATOR_PLUS:
204d4af4 4722 efb->write_c_string("+");
e440a328 4723 break;
4724 case OPERATOR_MINUS:
204d4af4 4725 efb->write_c_string("-");
e440a328 4726 break;
4727 case OPERATOR_NOT:
204d4af4 4728 efb->write_c_string("!");
e440a328 4729 break;
4730 case OPERATOR_XOR:
204d4af4 4731 efb->write_c_string("^");
e440a328 4732 break;
4733 case OPERATOR_AND:
5f6f5357 4734 efb->write_c_string("&");
4735 break;
e440a328 4736 case OPERATOR_MULT:
5f6f5357 4737 efb->write_c_string("*");
4738 break;
e440a328 4739 default:
c3e6f413 4740 go_unreachable();
e440a328 4741 }
548be246 4742 this->expr_->export_expression(efb);
e440a328 4743}
4744
4745// Import a unary expression.
4746
4747Expression*
bc8e2ef4 4748Unary_expression::do_import(Import_expression* imp, Location loc)
e440a328 4749{
4750 Operator op;
4751 switch (imp->get_char())
4752 {
4753 case '+':
4754 op = OPERATOR_PLUS;
4755 break;
4756 case '-':
4757 op = OPERATOR_MINUS;
4758 break;
4759 case '!':
4760 op = OPERATOR_NOT;
4761 break;
4762 case '^':
4763 op = OPERATOR_XOR;
4764 break;
5f6f5357 4765 case '&':
4766 op = OPERATOR_AND;
4767 break;
4768 case '*':
4769 op = OPERATOR_MULT;
4770 break;
e440a328 4771 default:
c3e6f413 4772 go_unreachable();
e440a328 4773 }
204d4af4 4774 if (imp->version() < EXPORT_FORMAT_V3)
4775 imp->require_c_string(" ");
9b92780c 4776 Expression* expr = Expression::import_expression(imp, loc);
4777 return Expression::make_unary(op, expr, loc);
e440a328 4778}
4779
d751bb78 4780// Dump ast representation of an unary expression.
4781
4782void
4783Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
4784{
4785 ast_dump_context->dump_operator(this->op_);
4786 ast_dump_context->ostream() << "(";
4787 ast_dump_context->dump_expression(this->expr_);
4788 ast_dump_context->ostream() << ") ";
4789}
4790
e440a328 4791// Make a unary expression.
4792
4793Expression*
b13c66cd 4794Expression::make_unary(Operator op, Expression* expr, Location location)
e440a328 4795{
4796 return new Unary_expression(op, expr, location);
4797}
4798
f614ea8b 4799Expression*
4800Expression::make_dereference(Expression* ptr,
4801 Nil_check_classification docheck,
4802 Location location)
4803{
4804 Expression* deref = Expression::make_unary(OPERATOR_MULT, ptr, location);
4805 if (docheck == NIL_CHECK_NEEDED)
4806 deref->unary_expression()->set_requires_nil_check(true);
4807 else if (docheck == NIL_CHECK_NOT_NEEDED)
4808 deref->unary_expression()->set_requires_nil_check(false);
4809 return deref;
4810}
4811
e440a328 4812// If this is an indirection through a pointer, return the expression
4813// being pointed through. Otherwise return this.
4814
4815Expression*
4816Expression::deref()
4817{
4818 if (this->classification_ == EXPRESSION_UNARY)
4819 {
4820 Unary_expression* ue = static_cast<Unary_expression*>(this);
4821 if (ue->op() == OPERATOR_MULT)
4822 return ue->operand();
4823 }
4824 return this;
4825}
4826
4827// Class Binary_expression.
4828
4829// Traversal.
4830
4831int
4832Binary_expression::do_traverse(Traverse* traverse)
4833{
4834 int t = Expression::traverse(&this->left_, traverse);
4835 if (t == TRAVERSE_EXIT)
4836 return TRAVERSE_EXIT;
4837 return Expression::traverse(&this->right_, traverse);
4838}
4839
3ae06f68 4840// Return whether this expression may be used as a static initializer.
4841
4842bool
4843Binary_expression::do_is_static_initializer() const
4844{
4845 if (!this->left_->is_static_initializer()
4846 || !this->right_->is_static_initializer())
4847 return false;
4848
4849 // Addresses can be static initializers, but we can't implement
4850 // arbitray binary expressions of them.
4851 Unary_expression* lu = this->left_->unary_expression();
4852 Unary_expression* ru = this->right_->unary_expression();
4853 if (lu != NULL && lu->op() == OPERATOR_AND)
4854 {
4855 if (ru != NULL && ru->op() == OPERATOR_AND)
4856 return this->op_ == OPERATOR_MINUS;
4857 else
4858 return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
4859 }
4860 else if (ru != NULL && ru->op() == OPERATOR_AND)
4861 return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
4862
4863 // Other cases should resolve in the backend.
4864 return true;
4865}
4866
0c77715b 4867// Return the type to use for a binary operation on operands of
4868// LEFT_TYPE and RIGHT_TYPE. These are the types of constants and as
4869// such may be NULL or abstract.
4870
4871bool
4872Binary_expression::operation_type(Operator op, Type* left_type,
4873 Type* right_type, Type** result_type)
4874{
4875 if (left_type != right_type
4876 && !left_type->is_abstract()
4877 && !right_type->is_abstract()
4878 && left_type->base() != right_type->base()
4879 && op != OPERATOR_LSHIFT
4880 && op != OPERATOR_RSHIFT)
4881 {
4882 // May be a type error--let it be diagnosed elsewhere.
4883 return false;
4884 }
4885
4886 if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
4887 {
4888 if (left_type->integer_type() != NULL)
4889 *result_type = left_type;
4890 else
4891 *result_type = Type::make_abstract_integer_type();
4892 }
4893 else if (!left_type->is_abstract() && left_type->named_type() != NULL)
4894 *result_type = left_type;
4895 else if (!right_type->is_abstract() && right_type->named_type() != NULL)
4896 *result_type = right_type;
4897 else if (!left_type->is_abstract())
4898 *result_type = left_type;
4899 else if (!right_type->is_abstract())
4900 *result_type = right_type;
4901 else if (left_type->complex_type() != NULL)
4902 *result_type = left_type;
4903 else if (right_type->complex_type() != NULL)
4904 *result_type = right_type;
4905 else if (left_type->float_type() != NULL)
4906 *result_type = left_type;
4907 else if (right_type->float_type() != NULL)
4908 *result_type = right_type;
4909 else if (left_type->integer_type() != NULL
4910 && left_type->integer_type()->is_rune())
4911 *result_type = left_type;
4912 else if (right_type->integer_type() != NULL
4913 && right_type->integer_type()->is_rune())
4914 *result_type = right_type;
4915 else
4916 *result_type = left_type;
4917
4918 return true;
4919}
4920
4921// Convert an integer comparison code and an operator to a boolean
4922// value.
e440a328 4923
4924bool
0c77715b 4925Binary_expression::cmp_to_bool(Operator op, int cmp)
e440a328 4926{
e440a328 4927 switch (op)
4928 {
4929 case OPERATOR_EQEQ:
0c77715b 4930 return cmp == 0;
4931 break;
e440a328 4932 case OPERATOR_NOTEQ:
0c77715b 4933 return cmp != 0;
4934 break;
e440a328 4935 case OPERATOR_LT:
0c77715b 4936 return cmp < 0;
4937 break;
e440a328 4938 case OPERATOR_LE:
0c77715b 4939 return cmp <= 0;
e440a328 4940 case OPERATOR_GT:
0c77715b 4941 return cmp > 0;
e440a328 4942 case OPERATOR_GE:
0c77715b 4943 return cmp >= 0;
e440a328 4944 default:
c3e6f413 4945 go_unreachable();
e440a328 4946 }
4947}
4948
0c77715b 4949// Compare constants according to OP.
e440a328 4950
4951bool
0c77715b 4952Binary_expression::compare_constant(Operator op, Numeric_constant* left_nc,
4953 Numeric_constant* right_nc,
4954 Location location, bool* result)
e440a328 4955{
0c77715b 4956 Type* left_type = left_nc->type();
4957 Type* right_type = right_nc->type();
4958
4959 Type* type;
4960 if (!Binary_expression::operation_type(op, left_type, right_type, &type))
4961 return false;
4962
4963 // When comparing an untyped operand to a typed operand, we are
4964 // effectively coercing the untyped operand to the other operand's
4965 // type, so make sure that is valid.
4966 if (!left_nc->set_type(type, true, location)
4967 || !right_nc->set_type(type, true, location))
4968 return false;
4969
4970 bool ret;
4971 int cmp;
4972 if (type->complex_type() != NULL)
4973 {
4974 if (op != OPERATOR_EQEQ && op != OPERATOR_NOTEQ)
4975 return false;
4976 ret = Binary_expression::compare_complex(left_nc, right_nc, &cmp);
4977 }
4978 else if (type->float_type() != NULL)
4979 ret = Binary_expression::compare_float(left_nc, right_nc, &cmp);
e440a328 4980 else
0c77715b 4981 ret = Binary_expression::compare_integer(left_nc, right_nc, &cmp);
4982
4983 if (ret)
4984 *result = Binary_expression::cmp_to_bool(op, cmp);
4985
4986 return ret;
4987}
4988
4989// Compare integer constants.
4990
4991bool
4992Binary_expression::compare_integer(const Numeric_constant* left_nc,
4993 const Numeric_constant* right_nc,
4994 int* cmp)
4995{
4996 mpz_t left_val;
4997 if (!left_nc->to_int(&left_val))
4998 return false;
4999 mpz_t right_val;
5000 if (!right_nc->to_int(&right_val))
e440a328 5001 {
0c77715b 5002 mpz_clear(left_val);
5003 return false;
e440a328 5004 }
0c77715b 5005
5006 *cmp = mpz_cmp(left_val, right_val);
5007
5008 mpz_clear(left_val);
5009 mpz_clear(right_val);
5010
5011 return true;
5012}
5013
5014// Compare floating point constants.
5015
5016bool
5017Binary_expression::compare_float(const Numeric_constant* left_nc,
5018 const Numeric_constant* right_nc,
5019 int* cmp)
5020{
5021 mpfr_t left_val;
5022 if (!left_nc->to_float(&left_val))
5023 return false;
5024 mpfr_t right_val;
5025 if (!right_nc->to_float(&right_val))
e440a328 5026 {
0c77715b 5027 mpfr_clear(left_val);
5028 return false;
5029 }
5030
5031 // We already coerced both operands to the same type. If that type
5032 // is not an abstract type, we need to round the values accordingly.
5033 Type* type = left_nc->type();
5034 if (!type->is_abstract() && type->float_type() != NULL)
5035 {
5036 int bits = type->float_type()->bits();
5037 mpfr_prec_round(left_val, bits, GMP_RNDN);
5038 mpfr_prec_round(right_val, bits, GMP_RNDN);
e440a328 5039 }
0c77715b 5040
5041 *cmp = mpfr_cmp(left_val, right_val);
5042
5043 mpfr_clear(left_val);
5044 mpfr_clear(right_val);
5045
5046 return true;
e440a328 5047}
5048
0c77715b 5049// Compare complex constants. Complex numbers may only be compared
5050// for equality.
e440a328 5051
5052bool
0c77715b 5053Binary_expression::compare_complex(const Numeric_constant* left_nc,
5054 const Numeric_constant* right_nc,
5055 int* cmp)
e440a328 5056{
fcbea5e4 5057 mpc_t left_val;
5058 if (!left_nc->to_complex(&left_val))
0c77715b 5059 return false;
fcbea5e4 5060 mpc_t right_val;
5061 if (!right_nc->to_complex(&right_val))
e440a328 5062 {
fcbea5e4 5063 mpc_clear(left_val);
0c77715b 5064 return false;
e440a328 5065 }
0c77715b 5066
5067 // We already coerced both operands to the same type. If that type
5068 // is not an abstract type, we need to round the values accordingly.
5069 Type* type = left_nc->type();
5070 if (!type->is_abstract() && type->complex_type() != NULL)
e440a328 5071 {
0c77715b 5072 int bits = type->complex_type()->bits();
fcbea5e4 5073 mpfr_prec_round(mpc_realref(left_val), bits / 2, GMP_RNDN);
5074 mpfr_prec_round(mpc_imagref(left_val), bits / 2, GMP_RNDN);
5075 mpfr_prec_round(mpc_realref(right_val), bits / 2, GMP_RNDN);
5076 mpfr_prec_round(mpc_imagref(right_val), bits / 2, GMP_RNDN);
e440a328 5077 }
0c77715b 5078
fcbea5e4 5079 *cmp = mpc_cmp(left_val, right_val) != 0;
0c77715b 5080
fcbea5e4 5081 mpc_clear(left_val);
5082 mpc_clear(right_val);
0c77715b 5083
5084 return true;
e440a328 5085}
5086
0c77715b 5087// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. Return
5088// true if this could be done, false if not. Issue errors at LOCATION
af7a5274 5089// as appropriate, and sets *ISSUED_ERROR if it did.
e440a328 5090
5091bool
0c77715b 5092Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
5093 Numeric_constant* right_nc,
af7a5274 5094 Location location, Numeric_constant* nc,
5095 bool* issued_error)
e440a328 5096{
af7a5274 5097 *issued_error = false;
e440a328 5098 switch (op)
5099 {
5100 case OPERATOR_OROR:
5101 case OPERATOR_ANDAND:
5102 case OPERATOR_EQEQ:
5103 case OPERATOR_NOTEQ:
5104 case OPERATOR_LT:
5105 case OPERATOR_LE:
5106 case OPERATOR_GT:
5107 case OPERATOR_GE:
9767e2d3 5108 // These return boolean values, not numeric.
5109 return false;
0c77715b 5110 default:
5111 break;
5112 }
5113
5114 Type* left_type = left_nc->type();
5115 Type* right_type = right_nc->type();
5116
5117 Type* type;
5118 if (!Binary_expression::operation_type(op, left_type, right_type, &type))
5119 return false;
5120
5121 bool is_shift = op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT;
5122
5123 // When combining an untyped operand with a typed operand, we are
5124 // effectively coercing the untyped operand to the other operand's
5125 // type, so make sure that is valid.
5126 if (!left_nc->set_type(type, true, location))
5127 return false;
5128 if (!is_shift && !right_nc->set_type(type, true, location))
5129 return false;
85334a21 5130 if (is_shift
5131 && ((left_type->integer_type() == NULL
5132 && !left_type->is_abstract())
5133 || (right_type->integer_type() == NULL
5134 && !right_type->is_abstract())))
5135 return false;
0c77715b 5136
5137 bool r;
5138 if (type->complex_type() != NULL)
5139 r = Binary_expression::eval_complex(op, left_nc, right_nc, location, nc);
5140 else if (type->float_type() != NULL)
5141 r = Binary_expression::eval_float(op, left_nc, right_nc, location, nc);
5142 else
5143 r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc);
5144
5145 if (r)
af7a5274 5146 {
5147 r = nc->set_type(type, true, location);
5148 if (!r)
5149 *issued_error = true;
5150 }
0c77715b 5151
5152 return r;
5153}
5154
5155// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
5156// integer operations. Return true if this could be done, false if
5157// not.
5158
5159bool
5160Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
5161 const Numeric_constant* right_nc,
5162 Location location, Numeric_constant* nc)
5163{
5164 mpz_t left_val;
5165 if (!left_nc->to_int(&left_val))
5166 return false;
5167 mpz_t right_val;
5168 if (!right_nc->to_int(&right_val))
5169 {
5170 mpz_clear(left_val);
e440a328 5171 return false;
0c77715b 5172 }
5173
5174 mpz_t val;
5175 mpz_init(val);
5176
5177 switch (op)
5178 {
e440a328 5179 case OPERATOR_PLUS:
5180 mpz_add(val, left_val, right_val);
2c809f8f 5181 if (mpz_sizeinbase(val, 2) > 0x100000)
5182 {
631d5788 5183 go_error_at(location, "constant addition overflow");
71a45216 5184 nc->set_invalid();
2c809f8f 5185 mpz_set_ui(val, 1);
5186 }
e440a328 5187 break;
5188 case OPERATOR_MINUS:
5189 mpz_sub(val, left_val, right_val);
2c809f8f 5190 if (mpz_sizeinbase(val, 2) > 0x100000)
5191 {
631d5788 5192 go_error_at(location, "constant subtraction overflow");
71a45216 5193 nc->set_invalid();
2c809f8f 5194 mpz_set_ui(val, 1);
5195 }
e440a328 5196 break;
5197 case OPERATOR_OR:
5198 mpz_ior(val, left_val, right_val);
5199 break;
5200 case OPERATOR_XOR:
5201 mpz_xor(val, left_val, right_val);
5202 break;
5203 case OPERATOR_MULT:
5204 mpz_mul(val, left_val, right_val);
2c809f8f 5205 if (mpz_sizeinbase(val, 2) > 0x100000)
5206 {
631d5788 5207 go_error_at(location, "constant multiplication overflow");
71a45216 5208 nc->set_invalid();
2c809f8f 5209 mpz_set_ui(val, 1);
5210 }
e440a328 5211 break;
5212 case OPERATOR_DIV:
5213 if (mpz_sgn(right_val) != 0)
5214 mpz_tdiv_q(val, left_val, right_val);
5215 else
5216 {
631d5788 5217 go_error_at(location, "division by zero");
71a45216 5218 nc->set_invalid();
e440a328 5219 mpz_set_ui(val, 0);
e440a328 5220 }
5221 break;
5222 case OPERATOR_MOD:
5223 if (mpz_sgn(right_val) != 0)
5224 mpz_tdiv_r(val, left_val, right_val);
5225 else
5226 {
631d5788 5227 go_error_at(location, "division by zero");
71a45216 5228 nc->set_invalid();
e440a328 5229 mpz_set_ui(val, 0);
e440a328 5230 }
5231 break;
5232 case OPERATOR_LSHIFT:
5233 {
5234 unsigned long shift = mpz_get_ui(right_val);
0c77715b 5235 if (mpz_cmp_ui(right_val, shift) == 0 && shift <= 0x100000)
5236 mpz_mul_2exp(val, left_val, shift);
5237 else
e440a328 5238 {
631d5788 5239 go_error_at(location, "shift count overflow");
71a45216 5240 nc->set_invalid();
2c809f8f 5241 mpz_set_ui(val, 1);
e440a328 5242 }
e440a328 5243 break;
5244 }
5245 break;
5246 case OPERATOR_RSHIFT:
5247 {
5248 unsigned long shift = mpz_get_ui(right_val);
5249 if (mpz_cmp_ui(right_val, shift) != 0)
5250 {
631d5788 5251 go_error_at(location, "shift count overflow");
71a45216 5252 nc->set_invalid();
2c809f8f 5253 mpz_set_ui(val, 1);
e440a328 5254 }
e440a328 5255 else
0c77715b 5256 {
5257 if (mpz_cmp_ui(left_val, 0) >= 0)
5258 mpz_tdiv_q_2exp(val, left_val, shift);
5259 else
5260 mpz_fdiv_q_2exp(val, left_val, shift);
5261 }
e440a328 5262 break;
5263 }
5264 break;
5265 case OPERATOR_AND:
5266 mpz_and(val, left_val, right_val);
5267 break;
5268 case OPERATOR_BITCLEAR:
5269 {
5270 mpz_t tval;
5271 mpz_init(tval);
5272 mpz_com(tval, right_val);
5273 mpz_and(val, left_val, tval);
5274 mpz_clear(tval);
5275 }
5276 break;
5277 default:
c3e6f413 5278 go_unreachable();
e440a328 5279 }
5280
0c77715b 5281 mpz_clear(left_val);
5282 mpz_clear(right_val);
e440a328 5283
0c77715b 5284 if (left_nc->is_rune()
5285 || (op != OPERATOR_LSHIFT
5286 && op != OPERATOR_RSHIFT
5287 && right_nc->is_rune()))
5288 nc->set_rune(NULL, val);
5289 else
5290 nc->set_int(NULL, val);
5291
5292 mpz_clear(val);
e440a328 5293
5294 return true;
5295}
5296
0c77715b 5297// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
5298// floating point operations. Return true if this could be done,
5299// false if not.
e440a328 5300
5301bool
0c77715b 5302Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
5303 const Numeric_constant* right_nc,
5304 Location location, Numeric_constant* nc)
e440a328 5305{
0c77715b 5306 mpfr_t left_val;
5307 if (!left_nc->to_float(&left_val))
5308 return false;
5309 mpfr_t right_val;
5310 if (!right_nc->to_float(&right_val))
e440a328 5311 {
0c77715b 5312 mpfr_clear(left_val);
e440a328 5313 return false;
0c77715b 5314 }
5315
5316 mpfr_t val;
5317 mpfr_init(val);
5318
5319 bool ret = true;
5320 switch (op)
5321 {
e440a328 5322 case OPERATOR_PLUS:
5323 mpfr_add(val, left_val, right_val, GMP_RNDN);
5324 break;
5325 case OPERATOR_MINUS:
5326 mpfr_sub(val, left_val, right_val, GMP_RNDN);
5327 break;
5328 case OPERATOR_OR:
5329 case OPERATOR_XOR:
5330 case OPERATOR_AND:
5331 case OPERATOR_BITCLEAR:
0c77715b 5332 case OPERATOR_MOD:
5333 case OPERATOR_LSHIFT:
5334 case OPERATOR_RSHIFT:
5335 mpfr_set_ui(val, 0, GMP_RNDN);
5336 ret = false;
5337 break;
e440a328 5338 case OPERATOR_MULT:
5339 mpfr_mul(val, left_val, right_val, GMP_RNDN);
5340 break;
5341 case OPERATOR_DIV:
0c77715b 5342 if (!mpfr_zero_p(right_val))
5343 mpfr_div(val, left_val, right_val, GMP_RNDN);
5344 else
5345 {
631d5788 5346 go_error_at(location, "division by zero");
71a45216 5347 nc->set_invalid();
0c77715b 5348 mpfr_set_ui(val, 0, GMP_RNDN);
5349 }
e440a328 5350 break;
e440a328 5351 default:
c3e6f413 5352 go_unreachable();
e440a328 5353 }
5354
0c77715b 5355 mpfr_clear(left_val);
5356 mpfr_clear(right_val);
e440a328 5357
0c77715b 5358 nc->set_float(NULL, val);
5359 mpfr_clear(val);
e440a328 5360
0c77715b 5361 return ret;
e440a328 5362}
5363
0c77715b 5364// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
5365// complex operations. Return true if this could be done, false if
5366// not.
e440a328 5367
5368bool
0c77715b 5369Binary_expression::eval_complex(Operator op, const Numeric_constant* left_nc,
5370 const Numeric_constant* right_nc,
5371 Location location, Numeric_constant* nc)
e440a328 5372{
fcbea5e4 5373 mpc_t left_val;
5374 if (!left_nc->to_complex(&left_val))
0c77715b 5375 return false;
fcbea5e4 5376 mpc_t right_val;
5377 if (!right_nc->to_complex(&right_val))
e440a328 5378 {
fcbea5e4 5379 mpc_clear(left_val);
e440a328 5380 return false;
0c77715b 5381 }
5382
fcbea5e4 5383 mpc_t val;
5384 mpc_init2(val, mpc_precision);
0c77715b 5385
5386 bool ret = true;
5387 switch (op)
5388 {
e440a328 5389 case OPERATOR_PLUS:
fcbea5e4 5390 mpc_add(val, left_val, right_val, MPC_RNDNN);
e440a328 5391 break;
5392 case OPERATOR_MINUS:
fcbea5e4 5393 mpc_sub(val, left_val, right_val, MPC_RNDNN);
e440a328 5394 break;
5395 case OPERATOR_OR:
5396 case OPERATOR_XOR:
5397 case OPERATOR_AND:
5398 case OPERATOR_BITCLEAR:
0c77715b 5399 case OPERATOR_MOD:
5400 case OPERATOR_LSHIFT:
5401 case OPERATOR_RSHIFT:
fcbea5e4 5402 mpc_set_ui(val, 0, MPC_RNDNN);
0c77715b 5403 ret = false;
5404 break;
e440a328 5405 case OPERATOR_MULT:
fcbea5e4 5406 mpc_mul(val, left_val, right_val, MPC_RNDNN);
e440a328 5407 break;
5408 case OPERATOR_DIV:
fcbea5e4 5409 if (mpc_cmp_si(right_val, 0) == 0)
5410 {
631d5788 5411 go_error_at(location, "division by zero");
71a45216 5412 nc->set_invalid();
fcbea5e4 5413 mpc_set_ui(val, 0, MPC_RNDNN);
5414 break;
5415 }
5416 mpc_div(val, left_val, right_val, MPC_RNDNN);
e440a328 5417 break;
e440a328 5418 default:
c3e6f413 5419 go_unreachable();
e440a328 5420 }
5421
fcbea5e4 5422 mpc_clear(left_val);
5423 mpc_clear(right_val);
e440a328 5424
fcbea5e4 5425 nc->set_complex(NULL, val);
5426 mpc_clear(val);
e440a328 5427
0c77715b 5428 return ret;
e440a328 5429}
5430
5431// Lower a binary expression. We have to evaluate constant
5432// expressions now, in order to implement Go's unlimited precision
5433// constants.
5434
5435Expression*
e9d3367e 5436Binary_expression::do_lower(Gogo* gogo, Named_object*,
5437 Statement_inserter* inserter, int)
e440a328 5438{
b13c66cd 5439 Location location = this->location();
e440a328 5440 Operator op = this->op_;
5441 Expression* left = this->left_;
5442 Expression* right = this->right_;
5443
5444 const bool is_comparison = (op == OPERATOR_EQEQ
5445 || op == OPERATOR_NOTEQ
5446 || op == OPERATOR_LT
5447 || op == OPERATOR_LE
5448 || op == OPERATOR_GT
5449 || op == OPERATOR_GE);
5450
0c77715b 5451 // Numeric constant expressions.
e440a328 5452 {
0c77715b 5453 Numeric_constant left_nc;
5454 Numeric_constant right_nc;
5455 if (left->numeric_constant_value(&left_nc)
5456 && right->numeric_constant_value(&right_nc))
e440a328 5457 {
0c77715b 5458 if (is_comparison)
e440a328 5459 {
0c77715b 5460 bool result;
5461 if (!Binary_expression::compare_constant(op, &left_nc,
5462 &right_nc, location,
5463 &result))
5464 return this;
e90c9dfc 5465 return Expression::make_cast(Type::make_boolean_type(),
0c77715b 5466 Expression::make_boolean(result,
5467 location),
5468 location);
e440a328 5469 }
5470 else
5471 {
0c77715b 5472 Numeric_constant nc;
af7a5274 5473 bool issued_error;
0c77715b 5474 if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
af7a5274 5475 location, &nc,
5476 &issued_error))
5477 {
5478 if (issued_error)
5479 return Expression::make_error(location);
71a45216 5480 return this;
af7a5274 5481 }
0c77715b 5482 return nc.expression(location);
e440a328 5483 }
5484 }
e440a328 5485 }
5486
5487 // String constant expressions.
315fa98d 5488 if (left->type()->is_string_type() && right->type()->is_string_type())
e440a328 5489 {
5490 std::string left_string;
5491 std::string right_string;
5492 if (left->string_constant_value(&left_string)
5493 && right->string_constant_value(&right_string))
315fa98d 5494 {
5495 if (op == OPERATOR_PLUS)
5496 return Expression::make_string(left_string + right_string,
5497 location);
5498 else if (is_comparison)
5499 {
5500 int cmp = left_string.compare(right_string);
0c77715b 5501 bool r = Binary_expression::cmp_to_bool(op, cmp);
e90c9dfc 5502 return Expression::make_boolean(r, location);
b40dc774 5503 }
5504 }
b40dc774 5505 }
5506
ceeb12d7 5507 // Lower struct, array, and some interface comparisons.
e9d3367e 5508 if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
5509 {
b79832ca 5510 if (left->type()->struct_type() != NULL
5511 && right->type()->struct_type() != NULL)
e9d3367e 5512 return this->lower_struct_comparison(gogo, inserter);
5513 else if (left->type()->array_type() != NULL
b79832ca 5514 && !left->type()->is_slice_type()
5515 && right->type()->array_type() != NULL
5516 && !right->type()->is_slice_type())
e9d3367e 5517 return this->lower_array_comparison(gogo, inserter);
ceeb12d7 5518 else if ((left->type()->interface_type() != NULL
5519 && right->type()->interface_type() == NULL)
5520 || (left->type()->interface_type() == NULL
5521 && right->type()->interface_type() != NULL))
5522 return this->lower_interface_value_comparison(gogo, inserter);
e9d3367e 5523 }
5524
736a16ba 5525 // Lower string concatenation to String_concat_expression, so that
5526 // we can group sequences of string additions.
5527 if (this->left_->type()->is_string_type() && this->op_ == OPERATOR_PLUS)
5528 {
5529 Expression_list* exprs;
5530 String_concat_expression* left_sce =
5531 this->left_->string_concat_expression();
5532 if (left_sce != NULL)
5533 exprs = left_sce->exprs();
5534 else
5535 {
5536 exprs = new Expression_list();
5537 exprs->push_back(this->left_);
5538 }
5539
5540 String_concat_expression* right_sce =
5541 this->right_->string_concat_expression();
5542 if (right_sce != NULL)
5543 exprs->append(right_sce->exprs());
5544 else
5545 exprs->push_back(this->right_);
5546
5547 return Expression::make_string_concat(exprs);
5548 }
5549
e440a328 5550 return this;
5551}
5552
e9d3367e 5553// Lower a struct comparison.
5554
5555Expression*
5556Binary_expression::lower_struct_comparison(Gogo* gogo,
5557 Statement_inserter* inserter)
5558{
5559 Struct_type* st = this->left_->type()->struct_type();
5560 Struct_type* st2 = this->right_->type()->struct_type();
5561 if (st2 == NULL)
5562 return this;
3a522dcc 5563 if (st != st2
5564 && !Type::are_identical(st, st2,
5565 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
5566 NULL))
e9d3367e 5567 return this;
5568 if (!Type::are_compatible_for_comparison(true, this->left_->type(),
5569 this->right_->type(), NULL))
5570 return this;
5571
5572 // See if we can compare using memcmp. As a heuristic, we use
5573 // memcmp rather than field references and comparisons if there are
5574 // more than two fields.
113ef6a5 5575 if (st->compare_is_identity(gogo) && st->total_field_count() > 2)
e9d3367e 5576 return this->lower_compare_to_memcmp(gogo, inserter);
5577
5578 Location loc = this->location();
5579
5580 Expression* left = this->left_;
5581 Temporary_statement* left_temp = NULL;
5582 if (left->var_expression() == NULL
5583 && left->temporary_reference_expression() == NULL)
5584 {
5585 left_temp = Statement::make_temporary(left->type(), NULL, loc);
5586 inserter->insert(left_temp);
5587 left = Expression::make_set_and_use_temporary(left_temp, left, loc);
5588 }
5589
5590 Expression* right = this->right_;
5591 Temporary_statement* right_temp = NULL;
5592 if (right->var_expression() == NULL
5593 && right->temporary_reference_expression() == NULL)
5594 {
5595 right_temp = Statement::make_temporary(right->type(), NULL, loc);
5596 inserter->insert(right_temp);
5597 right = Expression::make_set_and_use_temporary(right_temp, right, loc);
5598 }
5599
5600 Expression* ret = Expression::make_boolean(true, loc);
5601 const Struct_field_list* fields = st->fields();
5602 unsigned int field_index = 0;
5603 for (Struct_field_list::const_iterator pf = fields->begin();
5604 pf != fields->end();
5605 ++pf, ++field_index)
5606 {
f5165c05 5607 if (Gogo::is_sink_name(pf->field_name()))
5608 continue;
5609
e9d3367e 5610 if (field_index > 0)
5611 {
5612 if (left_temp == NULL)
5613 left = left->copy();
5614 else
5615 left = Expression::make_temporary_reference(left_temp, loc);
5616 if (right_temp == NULL)
5617 right = right->copy();
5618 else
5619 right = Expression::make_temporary_reference(right_temp, loc);
5620 }
5621 Expression* f1 = Expression::make_field_reference(left, field_index,
5622 loc);
5623 Expression* f2 = Expression::make_field_reference(right, field_index,
5624 loc);
5625 Expression* cond = Expression::make_binary(OPERATOR_EQEQ, f1, f2, loc);
5626 ret = Expression::make_binary(OPERATOR_ANDAND, ret, cond, loc);
5627 }
5628
5629 if (this->op_ == OPERATOR_NOTEQ)
5630 ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
5631
5632 return ret;
5633}
5634
5635// Lower an array comparison.
5636
5637Expression*
5638Binary_expression::lower_array_comparison(Gogo* gogo,
5639 Statement_inserter* inserter)
5640{
5641 Array_type* at = this->left_->type()->array_type();
5642 Array_type* at2 = this->right_->type()->array_type();
5643 if (at2 == NULL)
5644 return this;
3a522dcc 5645 if (at != at2
5646 && !Type::are_identical(at, at2,
5647 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
5648 NULL))
e9d3367e 5649 return this;
5650 if (!Type::are_compatible_for_comparison(true, this->left_->type(),
5651 this->right_->type(), NULL))
5652 return this;
5653
5654 // Call memcmp directly if possible. This may let the middle-end
5655 // optimize the call.
113ef6a5 5656 if (at->compare_is_identity(gogo))
e9d3367e 5657 return this->lower_compare_to_memcmp(gogo, inserter);
5658
5659 // Call the array comparison function.
5660 Named_object* hash_fn;
5661 Named_object* equal_fn;
5662 at->type_functions(gogo, this->left_->type()->named_type(), NULL, NULL,
5663 &hash_fn, &equal_fn);
5664
5665 Location loc = this->location();
5666
5667 Expression* func = Expression::make_func_reference(equal_fn, NULL, loc);
5668
5669 Expression_list* args = new Expression_list();
5670 args->push_back(this->operand_address(inserter, this->left_));
5671 args->push_back(this->operand_address(inserter, this->right_));
e9d3367e 5672
5673 Expression* ret = Expression::make_call(func, args, false, loc);
5674
5675 if (this->op_ == OPERATOR_NOTEQ)
5676 ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
5677
5678 return ret;
5679}
5680
ceeb12d7 5681// Lower an interface to value comparison.
5682
5683Expression*
5684Binary_expression::lower_interface_value_comparison(Gogo*,
5685 Statement_inserter* inserter)
5686{
5687 Type* left_type = this->left_->type();
5688 Type* right_type = this->right_->type();
5689 Interface_type* ift;
5690 if (left_type->interface_type() != NULL)
5691 {
5692 ift = left_type->interface_type();
5693 if (!ift->implements_interface(right_type, NULL))
5694 return this;
5695 }
5696 else
5697 {
5698 ift = right_type->interface_type();
5699 if (!ift->implements_interface(left_type, NULL))
5700 return this;
5701 }
5702 if (!Type::are_compatible_for_comparison(true, left_type, right_type, NULL))
5703 return this;
5704
5705 Location loc = this->location();
5706
5707 if (left_type->interface_type() == NULL
5708 && left_type->points_to() == NULL
5709 && !this->left_->is_addressable())
5710 {
5711 Temporary_statement* temp =
5712 Statement::make_temporary(left_type, NULL, loc);
5713 inserter->insert(temp);
5714 this->left_ =
5715 Expression::make_set_and_use_temporary(temp, this->left_, loc);
5716 }
5717
5718 if (right_type->interface_type() == NULL
5719 && right_type->points_to() == NULL
5720 && !this->right_->is_addressable())
5721 {
5722 Temporary_statement* temp =
5723 Statement::make_temporary(right_type, NULL, loc);
5724 inserter->insert(temp);
5725 this->right_ =
5726 Expression::make_set_and_use_temporary(temp, this->right_, loc);
5727 }
5728
5729 return this;
5730}
5731
e9d3367e 5732// Lower a struct or array comparison to a call to memcmp.
5733
5734Expression*
5735Binary_expression::lower_compare_to_memcmp(Gogo*, Statement_inserter* inserter)
5736{
5737 Location loc = this->location();
5738
5739 Expression* a1 = this->operand_address(inserter, this->left_);
5740 Expression* a2 = this->operand_address(inserter, this->right_);
5741 Expression* len = Expression::make_type_info(this->left_->type(),
5742 TYPE_INFO_SIZE);
5743
5744 Expression* call = Runtime::make_call(Runtime::MEMCMP, loc, 3, a1, a2, len);
e67508fa 5745 Expression* zero = Expression::make_integer_ul(0, NULL, loc);
e9d3367e 5746 return Expression::make_binary(this->op_, call, zero, loc);
5747}
5748
a32698ee 5749Expression*
5c3f3470 5750Binary_expression::do_flatten(Gogo* gogo, Named_object*,
a32698ee 5751 Statement_inserter* inserter)
5752{
5753 Location loc = this->location();
5bf8be8b 5754 if (this->left_->type()->is_error_type()
5755 || this->right_->type()->is_error_type()
5756 || this->left_->is_error_expression()
5757 || this->right_->is_error_expression())
5758 {
5759 go_assert(saw_errors());
5760 return Expression::make_error(loc);
5761 }
5762
a32698ee 5763 Temporary_statement* temp;
a32698ee 5764
5765 Type* left_type = this->left_->type();
5766 bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
5767 || this->op_ == OPERATOR_RSHIFT);
5768 bool is_idiv_op = ((this->op_ == OPERATOR_DIV &&
5769 left_type->integer_type() != NULL)
5770 || this->op_ == OPERATOR_MOD);
5771
a32698ee 5772 if (is_shift_op
5c3f3470 5773 || (is_idiv_op
5774 && (gogo->check_divide_by_zero() || gogo->check_divide_overflow())))
a32698ee 5775 {
545ab43b 5776 if (!this->left_->is_variable() && !this->left_->is_constant())
a32698ee 5777 {
5778 temp = Statement::make_temporary(NULL, this->left_, loc);
5779 inserter->insert(temp);
5780 this->left_ = Expression::make_temporary_reference(temp, loc);
5781 }
545ab43b 5782 if (!this->right_->is_variable() && !this->right_->is_constant())
a32698ee 5783 {
5784 temp =
5785 Statement::make_temporary(NULL, this->right_, loc);
5786 this->right_ = Expression::make_temporary_reference(temp, loc);
5787 inserter->insert(temp);
5788 }
5789 }
5790 return this;
5791}
5792
5793
e9d3367e 5794// Return the address of EXPR, cast to unsafe.Pointer.
5795
5796Expression*
5797Binary_expression::operand_address(Statement_inserter* inserter,
5798 Expression* expr)
5799{
5800 Location loc = this->location();
5801
5802 if (!expr->is_addressable())
5803 {
5804 Temporary_statement* temp = Statement::make_temporary(expr->type(), NULL,
5805 loc);
5806 inserter->insert(temp);
5807 expr = Expression::make_set_and_use_temporary(temp, expr, loc);
5808 }
5809 expr = Expression::make_unary(OPERATOR_AND, expr, loc);
5810 static_cast<Unary_expression*>(expr)->set_does_not_escape();
5811 Type* void_type = Type::make_void_type();
5812 Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
5813 return Expression::make_cast(unsafe_pointer_type, expr, loc);
5814}
5815
0c77715b 5816// Return the numeric constant value, if it has one.
e440a328 5817
5818bool
0c77715b 5819Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 5820{
0c77715b 5821 Numeric_constant left_nc;
5822 if (!this->left_->numeric_constant_value(&left_nc))
5823 return false;
5824 Numeric_constant right_nc;
5825 if (!this->right_->numeric_constant_value(&right_nc))
5826 return false;
af7a5274 5827 bool issued_error;
9767e2d3 5828 return Binary_expression::eval_constant(this->op_, &left_nc, &right_nc,
af7a5274 5829 this->location(), nc, &issued_error);
e440a328 5830}
5831
5832// Note that the value is being discarded.
5833
4f2138d7 5834bool
e440a328 5835Binary_expression::do_discarding_value()
5836{
5837 if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
4f2138d7 5838 return this->right_->discarding_value();
e440a328 5839 else
4f2138d7 5840 {
5841 this->unused_value_error();
5842 return false;
5843 }
e440a328 5844}
5845
5846// Get type.
5847
5848Type*
5849Binary_expression::do_type()
5850{
5f5fea79 5851 if (this->classification() == EXPRESSION_ERROR)
5852 return Type::make_error_type();
5853
e440a328 5854 switch (this->op_)
5855 {
e440a328 5856 case OPERATOR_EQEQ:
5857 case OPERATOR_NOTEQ:
5858 case OPERATOR_LT:
5859 case OPERATOR_LE:
5860 case OPERATOR_GT:
5861 case OPERATOR_GE:
e90c9dfc 5862 if (this->type_ == NULL)
5863 this->type_ = Type::make_boolean_type();
5864 return this->type_;
e440a328 5865
5866 case OPERATOR_PLUS:
5867 case OPERATOR_MINUS:
5868 case OPERATOR_OR:
5869 case OPERATOR_XOR:
5870 case OPERATOR_MULT:
5871 case OPERATOR_DIV:
5872 case OPERATOR_MOD:
5873 case OPERATOR_AND:
5874 case OPERATOR_BITCLEAR:
e90c9dfc 5875 case OPERATOR_OROR:
5876 case OPERATOR_ANDAND:
e440a328 5877 {
0c77715b 5878 Type* type;
5879 if (!Binary_expression::operation_type(this->op_,
5880 this->left_->type(),
5881 this->right_->type(),
5882 &type))
5883 return Type::make_error_type();
5884 return type;
e440a328 5885 }
5886
5887 case OPERATOR_LSHIFT:
5888 case OPERATOR_RSHIFT:
5889 return this->left_->type();
5890
5891 default:
c3e6f413 5892 go_unreachable();
e440a328 5893 }
5894}
5895
5896// Set type for a binary expression.
5897
5898void
5899Binary_expression::do_determine_type(const Type_context* context)
5900{
5901 Type* tleft = this->left_->type();
5902 Type* tright = this->right_->type();
5903
5904 // Both sides should have the same type, except for the shift
5905 // operations. For a comparison, we should ignore the incoming
5906 // type.
5907
5908 bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
5909 || this->op_ == OPERATOR_RSHIFT);
5910
5911 bool is_comparison = (this->op_ == OPERATOR_EQEQ
5912 || this->op_ == OPERATOR_NOTEQ
5913 || this->op_ == OPERATOR_LT
5914 || this->op_ == OPERATOR_LE
5915 || this->op_ == OPERATOR_GT
5916 || this->op_ == OPERATOR_GE);
5917
c999c2a7 5918 // For constant expressions, the context of the result is not useful in
5919 // determining the types of the operands. It is only legal to use abstract
5920 // boolean, numeric, and string constants as operands where it is legal to
5921 // use non-abstract boolean, numeric, and string constants, respectively.
5922 // Any issues with the operation will be resolved in the check_types pass.
5923 bool is_constant_expr = (this->left_->is_constant()
5924 && this->right_->is_constant());
5925
e440a328 5926 Type_context subcontext(*context);
5927
9c4ff2ce 5928 if (is_constant_expr && !is_shift_op)
af7a5274 5929 {
5930 subcontext.type = NULL;
5931 subcontext.may_be_abstract = true;
5932 }
5933 else if (is_comparison)
e440a328 5934 {
5935 // In a comparison, the context does not determine the types of
5936 // the operands.
5937 subcontext.type = NULL;
5938 }
5939
5940 // Set the context for the left hand operand.
5941 if (is_shift_op)
5942 {
b40dc774 5943 // The right hand operand of a shift plays no role in
5944 // determining the type of the left hand operand.
e440a328 5945 }
5946 else if (!tleft->is_abstract())
5947 subcontext.type = tleft;
5948 else if (!tright->is_abstract())
5949 subcontext.type = tright;
5950 else if (subcontext.type == NULL)
5951 {
5952 if ((tleft->integer_type() != NULL && tright->integer_type() != NULL)
5953 || (tleft->float_type() != NULL && tright->float_type() != NULL)
5954 || (tleft->complex_type() != NULL && tright->complex_type() != NULL))
5955 {
5956 // Both sides have an abstract integer, abstract float, or
5957 // abstract complex type. Just let CONTEXT determine
5958 // whether they may remain abstract or not.
5959 }
5960 else if (tleft->complex_type() != NULL)
5961 subcontext.type = tleft;
5962 else if (tright->complex_type() != NULL)
5963 subcontext.type = tright;
5964 else if (tleft->float_type() != NULL)
5965 subcontext.type = tleft;
5966 else if (tright->float_type() != NULL)
5967 subcontext.type = tright;
5968 else
5969 subcontext.type = tleft;
f58a23ae 5970
5971 if (subcontext.type != NULL && !context->may_be_abstract)
5972 subcontext.type = subcontext.type->make_non_abstract_type();
e440a328 5973 }
5974
af7a5274 5975 this->left_->determine_type(&subcontext);
e440a328 5976
e440a328 5977 if (is_shift_op)
5978 {
b40dc774 5979 // We may have inherited an unusable type for the shift operand.
5980 // Give a useful error if that happened.
5981 if (tleft->is_abstract()
5982 && subcontext.type != NULL
8ab6effb 5983 && !subcontext.may_be_abstract
f6bc81e6 5984 && subcontext.type->interface_type() == NULL
8ab6effb 5985 && subcontext.type->integer_type() == NULL)
b40dc774 5986 this->report_error(("invalid context-determined non-integer type "
8ab6effb 5987 "for left operand of shift"));
b40dc774 5988
5989 // The context for the right hand operand is the same as for the
5990 // left hand operand, except for a shift operator.
e440a328 5991 subcontext.type = Type::lookup_integer_type("uint");
5992 subcontext.may_be_abstract = false;
5993 }
5994
af7a5274 5995 this->right_->determine_type(&subcontext);
e90c9dfc 5996
5997 if (is_comparison)
5998 {
5999 if (this->type_ != NULL && !this->type_->is_abstract())
6000 ;
6001 else if (context->type != NULL && context->type->is_boolean_type())
6002 this->type_ = context->type;
6003 else if (!context->may_be_abstract)
6004 this->type_ = Type::lookup_bool_type();
6005 }
e440a328 6006}
6007
6008// Report an error if the binary operator OP does not support TYPE.
be8b5eee 6009// OTYPE is the type of the other operand. Return whether the
6010// operation is OK. This should not be used for shift.
e440a328 6011
6012bool
be8b5eee 6013Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
b13c66cd 6014 Location location)
e440a328 6015{
6016 switch (op)
6017 {
6018 case OPERATOR_OROR:
6019 case OPERATOR_ANDAND:
c999c2a7 6020 if (!type->is_boolean_type()
6021 || !otype->is_boolean_type())
e440a328 6022 {
631d5788 6023 go_error_at(location, "expected boolean type");
e440a328 6024 return false;
6025 }
6026 break;
6027
6028 case OPERATOR_EQEQ:
6029 case OPERATOR_NOTEQ:
e9d3367e 6030 {
6031 std::string reason;
6032 if (!Type::are_compatible_for_comparison(true, type, otype, &reason))
6033 {
631d5788 6034 go_error_at(location, "%s", reason.c_str());
e9d3367e 6035 return false;
6036 }
6037 }
e440a328 6038 break;
6039
6040 case OPERATOR_LT:
6041 case OPERATOR_LE:
6042 case OPERATOR_GT:
6043 case OPERATOR_GE:
e9d3367e 6044 {
6045 std::string reason;
6046 if (!Type::are_compatible_for_comparison(false, type, otype, &reason))
6047 {
631d5788 6048 go_error_at(location, "%s", reason.c_str());
e9d3367e 6049 return false;
6050 }
6051 }
e440a328 6052 break;
6053
6054 case OPERATOR_PLUS:
6055 case OPERATOR_PLUSEQ:
c999c2a7 6056 if ((!type->is_numeric_type() && !type->is_string_type())
6057 || (!otype->is_numeric_type() && !otype->is_string_type()))
e440a328 6058 {
631d5788 6059 go_error_at(location,
e440a328 6060 "expected integer, floating, complex, or string type");
6061 return false;
6062 }
6063 break;
6064
6065 case OPERATOR_MINUS:
6066 case OPERATOR_MINUSEQ:
6067 case OPERATOR_MULT:
6068 case OPERATOR_MULTEQ:
6069 case OPERATOR_DIV:
6070 case OPERATOR_DIVEQ:
c999c2a7 6071 if (!type->is_numeric_type() || !otype->is_numeric_type())
e440a328 6072 {
631d5788 6073 go_error_at(location, "expected integer, floating, or complex type");
e440a328 6074 return false;
6075 }
6076 break;
6077
6078 case OPERATOR_MOD:
6079 case OPERATOR_MODEQ:
6080 case OPERATOR_OR:
6081 case OPERATOR_OREQ:
6082 case OPERATOR_AND:
6083 case OPERATOR_ANDEQ:
6084 case OPERATOR_XOR:
6085 case OPERATOR_XOREQ:
6086 case OPERATOR_BITCLEAR:
6087 case OPERATOR_BITCLEAREQ:
c999c2a7 6088 if (type->integer_type() == NULL || otype->integer_type() == NULL)
e440a328 6089 {
631d5788 6090 go_error_at(location, "expected integer type");
e440a328 6091 return false;
6092 }
6093 break;
6094
6095 default:
c3e6f413 6096 go_unreachable();
e440a328 6097 }
6098
6099 return true;
6100}
6101
6102// Check types.
6103
6104void
6105Binary_expression::do_check_types(Gogo*)
6106{
5f5fea79 6107 if (this->classification() == EXPRESSION_ERROR)
6108 return;
6109
e440a328 6110 Type* left_type = this->left_->type();
6111 Type* right_type = this->right_->type();
5c13bd80 6112 if (left_type->is_error() || right_type->is_error())
9fe897ef 6113 {
6114 this->set_is_error();
6115 return;
6116 }
e440a328 6117
6118 if (this->op_ == OPERATOR_EQEQ
6119 || this->op_ == OPERATOR_NOTEQ
6120 || this->op_ == OPERATOR_LT
6121 || this->op_ == OPERATOR_LE
6122 || this->op_ == OPERATOR_GT
6123 || this->op_ == OPERATOR_GE)
6124 {
907c5ecd 6125 if (left_type->is_nil_type() && right_type->is_nil_type())
6126 {
6127 this->report_error(_("invalid comparison of nil with nil"));
6128 return;
6129 }
e440a328 6130 if (!Type::are_assignable(left_type, right_type, NULL)
6131 && !Type::are_assignable(right_type, left_type, NULL))
6132 {
6133 this->report_error(_("incompatible types in binary expression"));
6134 return;
6135 }
6136 if (!Binary_expression::check_operator_type(this->op_, left_type,
be8b5eee 6137 right_type,
e440a328 6138 this->location())
6139 || !Binary_expression::check_operator_type(this->op_, right_type,
be8b5eee 6140 left_type,
e440a328 6141 this->location()))
6142 {
6143 this->set_is_error();
6144 return;
6145 }
6146 }
6147 else if (this->op_ != OPERATOR_LSHIFT && this->op_ != OPERATOR_RSHIFT)
6148 {
6149 if (!Type::are_compatible_for_binop(left_type, right_type))
6150 {
6151 this->report_error(_("incompatible types in binary expression"));
6152 return;
6153 }
6154 if (!Binary_expression::check_operator_type(this->op_, left_type,
be8b5eee 6155 right_type,
e440a328 6156 this->location()))
6157 {
6158 this->set_is_error();
6159 return;
6160 }
5c65b19d 6161 if (this->op_ == OPERATOR_DIV || this->op_ == OPERATOR_MOD)
6162 {
6163 // Division by a zero integer constant is an error.
6164 Numeric_constant rconst;
6165 unsigned long rval;
6166 if (left_type->integer_type() != NULL
6167 && this->right_->numeric_constant_value(&rconst)
6168 && rconst.to_unsigned_long(&rval) == Numeric_constant::NC_UL_VALID
6169 && rval == 0)
6170 {
6171 this->report_error(_("integer division by zero"));
6172 return;
6173 }
6174 }
e440a328 6175 }
6176 else
6177 {
6178 if (left_type->integer_type() == NULL)
6179 this->report_error(_("shift of non-integer operand"));
6180
6b5e0fac 6181 if (right_type->is_string_type())
6182 this->report_error(_("shift count not unsigned integer"));
6183 else if (!right_type->is_abstract()
e440a328 6184 && (right_type->integer_type() == NULL
6185 || !right_type->integer_type()->is_unsigned()))
6186 this->report_error(_("shift count not unsigned integer"));
6187 else
6188 {
0c77715b 6189 Numeric_constant nc;
6190 if (this->right_->numeric_constant_value(&nc))
e440a328 6191 {
0c77715b 6192 mpz_t val;
6193 if (!nc.to_int(&val))
6194 this->report_error(_("shift count not unsigned integer"));
6195 else
a4eba91b 6196 {
0c77715b 6197 if (mpz_sgn(val) < 0)
6198 {
6199 this->report_error(_("negative shift count"));
0c77715b 6200 Location rloc = this->right_->location();
e67508fa 6201 this->right_ = Expression::make_integer_ul(0, right_type,
6202 rloc);
0c77715b 6203 }
6204 mpz_clear(val);
a4eba91b 6205 }
e440a328 6206 }
e440a328 6207 }
6208 }
6209}
6210
ea664253 6211// Get the backend representation for a binary expression.
e440a328 6212
ea664253 6213Bexpression*
6214Binary_expression::do_get_backend(Translate_context* context)
e440a328 6215{
1b1f2abf 6216 Gogo* gogo = context->gogo();
a32698ee 6217 Location loc = this->location();
6218 Type* left_type = this->left_->type();
6219 Type* right_type = this->right_->type();
1b1f2abf 6220
e440a328 6221 bool use_left_type = true;
6222 bool is_shift_op = false;
29a2d1d8 6223 bool is_idiv_op = false;
e440a328 6224 switch (this->op_)
6225 {
6226 case OPERATOR_EQEQ:
6227 case OPERATOR_NOTEQ:
6228 case OPERATOR_LT:
6229 case OPERATOR_LE:
6230 case OPERATOR_GT:
6231 case OPERATOR_GE:
ea664253 6232 return Expression::comparison(context, this->type_, this->op_,
6233 this->left_, this->right_, loc);
e440a328 6234
6235 case OPERATOR_OROR:
e440a328 6236 case OPERATOR_ANDAND:
e440a328 6237 use_left_type = false;
6238 break;
6239 case OPERATOR_PLUS:
e440a328 6240 case OPERATOR_MINUS:
e440a328 6241 case OPERATOR_OR:
e440a328 6242 case OPERATOR_XOR:
e440a328 6243 case OPERATOR_MULT:
e440a328 6244 break;
6245 case OPERATOR_DIV:
a32698ee 6246 if (left_type->float_type() != NULL || left_type->complex_type() != NULL)
6247 break;
729f8831 6248 // Fall through.
e440a328 6249 case OPERATOR_MOD:
29a2d1d8 6250 is_idiv_op = true;
e440a328 6251 break;
6252 case OPERATOR_LSHIFT:
e440a328 6253 case OPERATOR_RSHIFT:
e440a328 6254 is_shift_op = true;
6255 break;
e440a328 6256 case OPERATOR_BITCLEAR:
a32698ee 6257 this->right_ = Expression::make_unary(OPERATOR_XOR, this->right_, loc);
6258 case OPERATOR_AND:
e440a328 6259 break;
6260 default:
c3e6f413 6261 go_unreachable();
e440a328 6262 }
6263
736a16ba 6264 // The only binary operation for string is +, and that should have
6265 // been converted to a String_concat_expression in do_lower.
6266 go_assert(!left_type->is_string_type());
a32698ee 6267
6268 // For complex division Go might want slightly different results than the
6269 // backend implementation provides, so we have our own runtime routine.
1850e20c 6270 if (this->op_ == OPERATOR_DIV && this->left_->type()->complex_type() != NULL)
6271 {
a32698ee 6272 Runtime::Function complex_code;
1850e20c 6273 switch (this->left_->type()->complex_type()->bits())
6274 {
6275 case 64:
a32698ee 6276 complex_code = Runtime::COMPLEX64_DIV;
1850e20c 6277 break;
6278 case 128:
a32698ee 6279 complex_code = Runtime::COMPLEX128_DIV;
1850e20c 6280 break;
6281 default:
6282 go_unreachable();
6283 }
a32698ee 6284 Expression* complex_div =
6285 Runtime::make_call(complex_code, loc, 2, this->left_, this->right_);
ea664253 6286 return complex_div->get_backend(context);
1850e20c 6287 }
6288
ea664253 6289 Bexpression* left = this->left_->get_backend(context);
6290 Bexpression* right = this->right_->get_backend(context);
e440a328 6291
a32698ee 6292 Type* type = use_left_type ? left_type : right_type;
6293 Btype* btype = type->get_backend(gogo);
6294
6295 Bexpression* ret =
6296 gogo->backend()->binary_expression(this->op_, left, right, loc);
6297 ret = gogo->backend()->convert_expression(btype, ret, loc);
e440a328 6298
a32698ee 6299 // Initialize overflow constants.
6300 Bexpression* overflow;
6301 mpz_t zero;
6302 mpz_init_set_ui(zero, 0UL);
6303 mpz_t one;
6304 mpz_init_set_ui(one, 1UL);
6305 mpz_t neg_one;
6306 mpz_init_set_si(neg_one, -1);
e440a328 6307
a32698ee 6308 Btype* left_btype = left_type->get_backend(gogo);
6309 Btype* right_btype = right_type->get_backend(gogo);
e440a328 6310
6311 // In Go, a shift larger than the size of the type is well-defined.
a32698ee 6312 // This is not true in C, so we need to insert a conditional.
e440a328 6313 if (is_shift_op)
6314 {
a32698ee 6315 go_assert(left_type->integer_type() != NULL);
e440a328 6316
a32698ee 6317 int bits = left_type->integer_type()->bits();
a7c5b619 6318
6319 Numeric_constant nc;
6320 unsigned long ul;
6321 if (!this->right_->numeric_constant_value(&nc)
6322 || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID
6323 || ul >= static_cast<unsigned long>(bits))
e440a328 6324 {
a7c5b619 6325 mpz_t bitsval;
6326 mpz_init_set_ui(bitsval, bits);
6327 Bexpression* bits_expr =
6328 gogo->backend()->integer_constant_expression(right_btype, bitsval);
6329 Bexpression* compare =
6330 gogo->backend()->binary_expression(OPERATOR_LT,
6331 right, bits_expr, loc);
6332
6333 Bexpression* zero_expr =
6334 gogo->backend()->integer_constant_expression(left_btype, zero);
6335 overflow = zero_expr;
6336 Bfunction* bfn = context->function()->func_value()->get_decl();
6337 if (this->op_ == OPERATOR_RSHIFT
6338 && !left_type->integer_type()->is_unsigned())
6339 {
6340 Bexpression* neg_expr =
6341 gogo->backend()->binary_expression(OPERATOR_LT, left,
6342 zero_expr, loc);
6343 Bexpression* neg_one_expr =
6344 gogo->backend()->integer_constant_expression(left_btype,
6345 neg_one);
6346 overflow = gogo->backend()->conditional_expression(bfn,
6347 btype,
6348 neg_expr,
6349 neg_one_expr,
6350 zero_expr,
6351 loc);
6352 }
6353 ret = gogo->backend()->conditional_expression(bfn, btype, compare,
6354 ret, overflow, loc);
6355 mpz_clear(bitsval);
29a2d1d8 6356 }
29a2d1d8 6357 }
6358
6359 // Add checks for division by zero and division overflow as needed.
6360 if (is_idiv_op)
6361 {
5c3f3470 6362 if (gogo->check_divide_by_zero())
29a2d1d8 6363 {
6364 // right == 0
a32698ee 6365 Bexpression* zero_expr =
6366 gogo->backend()->integer_constant_expression(right_btype, zero);
6367 Bexpression* check =
6368 gogo->backend()->binary_expression(OPERATOR_EQEQ,
6369 right, zero_expr, loc);
29a2d1d8 6370
a32698ee 6371 // __go_runtime_error(RUNTIME_ERROR_DIVISION_BY_ZERO)
29a2d1d8 6372 int errcode = RUNTIME_ERROR_DIVISION_BY_ZERO;
ea664253 6373 Bexpression* crash = gogo->runtime_error(errcode,
6374 loc)->get_backend(context);
29a2d1d8 6375
6376 // right == 0 ? (__go_runtime_error(...), 0) : ret
93715b75 6377 Bfunction* bfn = context->function()->func_value()->get_decl();
6378 ret = gogo->backend()->conditional_expression(bfn, btype,
6379 check, crash,
ea664253 6380 ret, loc);
b13c66cd 6381 }
6382
5c3f3470 6383 if (gogo->check_divide_overflow())
29a2d1d8 6384 {
6385 // right == -1
6386 // FIXME: It would be nice to say that this test is expected
6387 // to return false.
a32698ee 6388
6389 Bexpression* neg_one_expr =
6390 gogo->backend()->integer_constant_expression(right_btype, neg_one);
6391 Bexpression* check =
6392 gogo->backend()->binary_expression(OPERATOR_EQEQ,
6393 right, neg_one_expr, loc);
6394
6395 Bexpression* zero_expr =
6396 gogo->backend()->integer_constant_expression(btype, zero);
6397 Bexpression* one_expr =
6398 gogo->backend()->integer_constant_expression(btype, one);
93715b75 6399 Bfunction* bfn = context->function()->func_value()->get_decl();
a32698ee 6400
6401 if (type->integer_type()->is_unsigned())
29a2d1d8 6402 {
6403 // An unsigned -1 is the largest possible number, so
6404 // dividing is always 1 or 0.
a32698ee 6405
6406 Bexpression* cmp =
6407 gogo->backend()->binary_expression(OPERATOR_EQEQ,
6408 left, right, loc);
29a2d1d8 6409 if (this->op_ == OPERATOR_DIV)
a32698ee 6410 overflow =
93715b75 6411 gogo->backend()->conditional_expression(bfn, btype, cmp,
a32698ee 6412 one_expr, zero_expr,
6413 loc);
29a2d1d8 6414 else
a32698ee 6415 overflow =
93715b75 6416 gogo->backend()->conditional_expression(bfn, btype, cmp,
a32698ee 6417 zero_expr, left,
6418 loc);
29a2d1d8 6419 }
6420 else
6421 {
6422 // Computing left / -1 is the same as computing - left,
6423 // which does not overflow since Go sets -fwrapv.
6424 if (this->op_ == OPERATOR_DIV)
a32698ee 6425 {
6426 Expression* negate_expr =
6427 Expression::make_unary(OPERATOR_MINUS, this->left_, loc);
ea664253 6428 overflow = negate_expr->get_backend(context);
a32698ee 6429 }
29a2d1d8 6430 else
a32698ee 6431 overflow = zero_expr;
29a2d1d8 6432 }
a32698ee 6433 overflow = gogo->backend()->convert_expression(btype, overflow, loc);
29a2d1d8 6434
6435 // right == -1 ? - left : ret
93715b75 6436 ret = gogo->backend()->conditional_expression(bfn, btype,
6437 check, overflow,
a32698ee 6438 ret, loc);
29a2d1d8 6439 }
e440a328 6440 }
6441
a32698ee 6442 mpz_clear(zero);
6443 mpz_clear(one);
6444 mpz_clear(neg_one);
ea664253 6445 return ret;
e440a328 6446}
6447
6448// Export a binary expression.
6449
6450void
548be246 6451Binary_expression::do_export(Export_function_body* efb) const
e440a328 6452{
548be246 6453 efb->write_c_string("(");
6454 this->left_->export_expression(efb);
e440a328 6455 switch (this->op_)
6456 {
6457 case OPERATOR_OROR:
548be246 6458 efb->write_c_string(" || ");
e440a328 6459 break;
6460 case OPERATOR_ANDAND:
548be246 6461 efb->write_c_string(" && ");
e440a328 6462 break;
6463 case OPERATOR_EQEQ:
548be246 6464 efb->write_c_string(" == ");
e440a328 6465 break;
6466 case OPERATOR_NOTEQ:
548be246 6467 efb->write_c_string(" != ");
e440a328 6468 break;
6469 case OPERATOR_LT:
548be246 6470 efb->write_c_string(" < ");
e440a328 6471 break;
6472 case OPERATOR_LE:
548be246 6473 efb->write_c_string(" <= ");
e440a328 6474 break;
6475 case OPERATOR_GT:
548be246 6476 efb->write_c_string(" > ");
e440a328 6477 break;
6478 case OPERATOR_GE:
548be246 6479 efb->write_c_string(" >= ");
e440a328 6480 break;
6481 case OPERATOR_PLUS:
548be246 6482 efb->write_c_string(" + ");
e440a328 6483 break;
6484 case OPERATOR_MINUS:
548be246 6485 efb->write_c_string(" - ");
e440a328 6486 break;
6487 case OPERATOR_OR:
548be246 6488 efb->write_c_string(" | ");
e440a328 6489 break;
6490 case OPERATOR_XOR:
548be246 6491 efb->write_c_string(" ^ ");
e440a328 6492 break;
6493 case OPERATOR_MULT:
548be246 6494 efb->write_c_string(" * ");
e440a328 6495 break;
6496 case OPERATOR_DIV:
548be246 6497 efb->write_c_string(" / ");
e440a328 6498 break;
6499 case OPERATOR_MOD:
548be246 6500 efb->write_c_string(" % ");
e440a328 6501 break;
6502 case OPERATOR_LSHIFT:
548be246 6503 efb->write_c_string(" << ");
e440a328 6504 break;
6505 case OPERATOR_RSHIFT:
548be246 6506 efb->write_c_string(" >> ");
e440a328 6507 break;
6508 case OPERATOR_AND:
548be246 6509 efb->write_c_string(" & ");
e440a328 6510 break;
6511 case OPERATOR_BITCLEAR:
548be246 6512 efb->write_c_string(" &^ ");
e440a328 6513 break;
6514 default:
c3e6f413 6515 go_unreachable();
e440a328 6516 }
548be246 6517 this->right_->export_expression(efb);
6518 efb->write_c_string(")");
e440a328 6519}
6520
6521// Import a binary expression.
6522
6523Expression*
bc8e2ef4 6524Binary_expression::do_import(Import_expression* imp, Location loc)
e440a328 6525{
6526 imp->require_c_string("(");
6527
9b92780c 6528 Expression* left = Expression::import_expression(imp, loc);
e440a328 6529
6530 Operator op;
6531 if (imp->match_c_string(" || "))
6532 {
6533 op = OPERATOR_OROR;
6534 imp->advance(4);
6535 }
6536 else if (imp->match_c_string(" && "))
6537 {
6538 op = OPERATOR_ANDAND;
6539 imp->advance(4);
6540 }
6541 else if (imp->match_c_string(" == "))
6542 {
6543 op = OPERATOR_EQEQ;
6544 imp->advance(4);
6545 }
6546 else if (imp->match_c_string(" != "))
6547 {
6548 op = OPERATOR_NOTEQ;
6549 imp->advance(4);
6550 }
6551 else if (imp->match_c_string(" < "))
6552 {
6553 op = OPERATOR_LT;
6554 imp->advance(3);
6555 }
6556 else if (imp->match_c_string(" <= "))
6557 {
6558 op = OPERATOR_LE;
6559 imp->advance(4);
6560 }
6561 else if (imp->match_c_string(" > "))
6562 {
6563 op = OPERATOR_GT;
6564 imp->advance(3);
6565 }
6566 else if (imp->match_c_string(" >= "))
6567 {
6568 op = OPERATOR_GE;
6569 imp->advance(4);
6570 }
6571 else if (imp->match_c_string(" + "))
6572 {
6573 op = OPERATOR_PLUS;
6574 imp->advance(3);
6575 }
6576 else if (imp->match_c_string(" - "))
6577 {
6578 op = OPERATOR_MINUS;
6579 imp->advance(3);
6580 }
6581 else if (imp->match_c_string(" | "))
6582 {
6583 op = OPERATOR_OR;
6584 imp->advance(3);
6585 }
6586 else if (imp->match_c_string(" ^ "))
6587 {
6588 op = OPERATOR_XOR;
6589 imp->advance(3);
6590 }
6591 else if (imp->match_c_string(" * "))
6592 {
6593 op = OPERATOR_MULT;
6594 imp->advance(3);
6595 }
6596 else if (imp->match_c_string(" / "))
6597 {
6598 op = OPERATOR_DIV;
6599 imp->advance(3);
6600 }
6601 else if (imp->match_c_string(" % "))
6602 {
6603 op = OPERATOR_MOD;
6604 imp->advance(3);
6605 }
6606 else if (imp->match_c_string(" << "))
6607 {
6608 op = OPERATOR_LSHIFT;
6609 imp->advance(4);
6610 }
6611 else if (imp->match_c_string(" >> "))
6612 {
6613 op = OPERATOR_RSHIFT;
6614 imp->advance(4);
6615 }
6616 else if (imp->match_c_string(" & "))
6617 {
6618 op = OPERATOR_AND;
6619 imp->advance(3);
6620 }
6621 else if (imp->match_c_string(" &^ "))
6622 {
6623 op = OPERATOR_BITCLEAR;
6624 imp->advance(4);
6625 }
6626 else
6627 {
631d5788 6628 go_error_at(imp->location(), "unrecognized binary operator");
9b92780c 6629 return Expression::make_error(loc);
e440a328 6630 }
6631
9b92780c 6632 Expression* right = Expression::import_expression(imp, loc);
e440a328 6633
6634 imp->require_c_string(")");
6635
9b92780c 6636 return Expression::make_binary(op, left, right, loc);
e440a328 6637}
6638
d751bb78 6639// Dump ast representation of a binary expression.
6640
6641void
6642Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
6643{
6644 ast_dump_context->ostream() << "(";
6645 ast_dump_context->dump_expression(this->left_);
6646 ast_dump_context->ostream() << " ";
6647 ast_dump_context->dump_operator(this->op_);
6648 ast_dump_context->ostream() << " ";
6649 ast_dump_context->dump_expression(this->right_);
6650 ast_dump_context->ostream() << ") ";
6651}
6652
e440a328 6653// Make a binary expression.
6654
6655Expression*
6656Expression::make_binary(Operator op, Expression* left, Expression* right,
b13c66cd 6657 Location location)
e440a328 6658{
6659 return new Binary_expression(op, left, right, location);
6660}
6661
6662// Implement a comparison.
6663
a32698ee 6664Bexpression*
6665Expression::comparison(Translate_context* context, Type* result_type,
6666 Operator op, Expression* left, Expression* right,
6667 Location location)
e440a328 6668{
2387f644 6669 Type* left_type = left->type();
6670 Type* right_type = right->type();
ceeb12d7 6671
e67508fa 6672 Expression* zexpr = Expression::make_integer_ul(0, NULL, location);
1b1f2abf 6673
15c67ee2 6674 if (left_type->is_string_type() && right_type->is_string_type())
e440a328 6675 {
6098d6cb 6676 if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
6677 {
6678 left = Runtime::make_call(Runtime::EQSTRING, location, 2,
6679 left, right);
6680 right = Expression::make_boolean(true, location);
6681 }
6682 else
6683 {
6684 left = Runtime::make_call(Runtime::CMPSTRING, location, 2,
6685 left, right);
6686 right = zexpr;
6687 }
e440a328 6688 }
15c67ee2 6689 else if ((left_type->interface_type() != NULL
6690 && right_type->interface_type() == NULL
6691 && !right_type->is_nil_type())
6692 || (left_type->interface_type() == NULL
6693 && !left_type->is_nil_type()
6694 && right_type->interface_type() != NULL))
e440a328 6695 {
6696 // Comparing an interface value to a non-interface value.
6697 if (left_type->interface_type() == NULL)
6698 {
6699 std::swap(left_type, right_type);
2387f644 6700 std::swap(left, right);
e440a328 6701 }
6702
6703 // The right operand is not an interface. We need to take its
6704 // address if it is not a pointer.
ceeb12d7 6705 Expression* pointer_arg = NULL;
e440a328 6706 if (right_type->points_to() != NULL)
2387f644 6707 pointer_arg = right;
e440a328 6708 else
6709 {
2387f644 6710 go_assert(right->is_addressable());
6711 pointer_arg = Expression::make_unary(OPERATOR_AND, right,
ceeb12d7 6712 location);
e440a328 6713 }
e440a328 6714
2387f644 6715 Expression* descriptor =
6716 Expression::make_type_descriptor(right_type, location);
6717 left =
ceeb12d7 6718 Runtime::make_call((left_type->interface_type()->is_empty()
6098d6cb 6719 ? Runtime::EFACEVALEQ
6720 : Runtime::IFACEVALEQ),
2387f644 6721 location, 3, left, descriptor,
ceeb12d7 6722 pointer_arg);
6098d6cb 6723 go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
6724 right = Expression::make_boolean(true, location);
e440a328 6725 }
6726 else if (left_type->interface_type() != NULL
6727 && right_type->interface_type() != NULL)
6728 {
ceeb12d7 6729 Runtime::Function compare_function;
739bad04 6730 if (left_type->interface_type()->is_empty()
6731 && right_type->interface_type()->is_empty())
6098d6cb 6732 compare_function = Runtime::EFACEEQ;
739bad04 6733 else if (!left_type->interface_type()->is_empty()
6734 && !right_type->interface_type()->is_empty())
6098d6cb 6735 compare_function = Runtime::IFACEEQ;
739bad04 6736 else
6737 {
6738 if (left_type->interface_type()->is_empty())
6739 {
739bad04 6740 std::swap(left_type, right_type);
2387f644 6741 std::swap(left, right);
739bad04 6742 }
c484d925 6743 go_assert(!left_type->interface_type()->is_empty());
6744 go_assert(right_type->interface_type()->is_empty());
6098d6cb 6745 compare_function = Runtime::IFACEEFACEEQ;
739bad04 6746 }
6747
2387f644 6748 left = Runtime::make_call(compare_function, location, 2, left, right);
6098d6cb 6749 go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
6750 right = Expression::make_boolean(true, location);
e440a328 6751 }
6752
6753 if (left_type->is_nil_type()
6754 && (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ))
6755 {
6756 std::swap(left_type, right_type);
2387f644 6757 std::swap(left, right);
e440a328 6758 }
6759
6760 if (right_type->is_nil_type())
6761 {
2387f644 6762 right = Expression::make_nil(location);
e440a328 6763 if (left_type->array_type() != NULL
6764 && left_type->array_type()->length() == NULL)
6765 {
6766 Array_type* at = left_type->array_type();
44dbe1d7 6767 bool is_lvalue = false;
6768 left = at->get_value_pointer(context->gogo(), left, is_lvalue);
e440a328 6769 }
6770 else if (left_type->interface_type() != NULL)
6771 {
6772 // An interface is nil if the first field is nil.
2387f644 6773 left = Expression::make_field_reference(left, 0, location);
e440a328 6774 }
6775 }
6776
ea664253 6777 Bexpression* left_bexpr = left->get_backend(context);
6778 Bexpression* right_bexpr = right->get_backend(context);
e90c9dfc 6779
a32698ee 6780 Gogo* gogo = context->gogo();
6781 Bexpression* ret = gogo->backend()->binary_expression(op, left_bexpr,
6782 right_bexpr, location);
6783 if (result_type != NULL)
6784 ret = gogo->backend()->convert_expression(result_type->get_backend(gogo),
6785 ret, location);
e440a328 6786 return ret;
6787}
6788
736a16ba 6789// Class String_concat_expression.
6790
6791bool
6792String_concat_expression::do_is_constant() const
6793{
6794 for (Expression_list::const_iterator pe = this->exprs_->begin();
6795 pe != this->exprs_->end();
6796 ++pe)
6797 {
6798 if (!(*pe)->is_constant())
6799 return false;
6800 }
6801 return true;
6802}
6803
6804bool
3ae06f68 6805String_concat_expression::do_is_static_initializer() const
736a16ba 6806{
6807 for (Expression_list::const_iterator pe = this->exprs_->begin();
6808 pe != this->exprs_->end();
6809 ++pe)
6810 {
3ae06f68 6811 if (!(*pe)->is_static_initializer())
736a16ba 6812 return false;
6813 }
6814 return true;
6815}
6816
6817Type*
6818String_concat_expression::do_type()
6819{
6820 Type* t = this->exprs_->front()->type();
6821 Expression_list::iterator pe = this->exprs_->begin();
6822 ++pe;
6823 for (; pe != this->exprs_->end(); ++pe)
6824 {
6825 Type* t1;
6826 if (!Binary_expression::operation_type(OPERATOR_PLUS, t,
6827 (*pe)->type(),
6828 &t1))
6829 return Type::make_error_type();
6830 t = t1;
6831 }
6832 return t;
6833}
6834
6835void
6836String_concat_expression::do_determine_type(const Type_context* context)
6837{
6838 Type_context subcontext(*context);
6839 for (Expression_list::iterator pe = this->exprs_->begin();
6840 pe != this->exprs_->end();
6841 ++pe)
6842 {
6843 Type* t = (*pe)->type();
6844 if (!t->is_abstract())
6845 {
6846 subcontext.type = t;
6847 break;
6848 }
6849 }
6850 if (subcontext.type == NULL)
6851 subcontext.type = this->exprs_->front()->type();
6852 for (Expression_list::iterator pe = this->exprs_->begin();
6853 pe != this->exprs_->end();
6854 ++pe)
6855 (*pe)->determine_type(&subcontext);
6856}
6857
6858void
6859String_concat_expression::do_check_types(Gogo*)
6860{
6861 if (this->is_error_expression())
6862 return;
6863 Type* t = this->exprs_->front()->type();
6864 if (t->is_error())
6865 {
6866 this->set_is_error();
6867 return;
6868 }
6869 Expression_list::iterator pe = this->exprs_->begin();
6870 ++pe;
6871 for (; pe != this->exprs_->end(); ++pe)
6872 {
6873 Type* t1 = (*pe)->type();
6874 if (!Type::are_compatible_for_binop(t, t1))
6875 {
6876 this->report_error("incompatible types in binary expression");
6877 return;
6878 }
6879 if (!Binary_expression::check_operator_type(OPERATOR_PLUS, t, t1,
6880 this->location()))
6881 {
6882 this->set_is_error();
6883 return;
6884 }
6885 }
6886}
6887
6888Expression*
6889String_concat_expression::do_flatten(Gogo*, Named_object*,
6890 Statement_inserter*)
6891{
6892 if (this->is_error_expression())
6893 return this;
6894 Location loc = this->location();
6895 Type* type = this->type();
6896 Expression* nil_arg = Expression::make_nil(loc);
6897 Expression* call;
6898 switch (this->exprs_->size())
6899 {
6900 case 0: case 1:
6901 go_unreachable();
6902
6903 case 2: case 3: case 4: case 5:
6904 {
6905 Expression* len = Expression::make_integer_ul(this->exprs_->size(),
6906 NULL, loc);
6907 Array_type* arg_type = Type::make_array_type(type, len);
6908 arg_type->set_is_array_incomparable();
6909 Expression* arg =
6910 Expression::make_array_composite_literal(arg_type, this->exprs_,
6911 loc);
6912 Runtime::Function code;
6913 switch (this->exprs_->size())
6914 {
6915 default:
6916 go_unreachable();
6917 case 2:
6918 code = Runtime::CONCATSTRING2;
6919 break;
6920 case 3:
6921 code = Runtime::CONCATSTRING3;
6922 break;
6923 case 4:
6924 code = Runtime::CONCATSTRING4;
6925 break;
6926 case 5:
6927 code = Runtime::CONCATSTRING5;
6928 break;
6929 }
6930 call = Runtime::make_call(code, loc, 2, nil_arg, arg);
6931 }
6932 break;
6933
6934 default:
6935 {
6936 Type* arg_type = Type::make_array_type(type, NULL);
6937 Slice_construction_expression* sce =
6938 Expression::make_slice_composite_literal(arg_type, this->exprs_,
6939 loc);
6940 sce->set_storage_does_not_escape();
6941 call = Runtime::make_call(Runtime::CONCATSTRINGS, loc, 2, nil_arg,
6942 sce);
6943 }
6944 break;
6945 }
6946
6947 return Expression::make_cast(type, call, loc);
6948}
6949
6950void
6951String_concat_expression::do_dump_expression(
6952 Ast_dump_context* ast_dump_context) const
6953{
6954 ast_dump_context->ostream() << "concat(";
6955 ast_dump_context->dump_expression_list(this->exprs_, false);
6956 ast_dump_context->ostream() << ")";
6957}
6958
6959Expression*
6960Expression::make_string_concat(Expression_list* exprs)
6961{
6962 return new String_concat_expression(exprs);
6963}
6964
e440a328 6965// Class Bound_method_expression.
6966
6967// Traversal.
6968
6969int
6970Bound_method_expression::do_traverse(Traverse* traverse)
6971{
e0659c9e 6972 return Expression::traverse(&this->expr_, traverse);
e440a328 6973}
6974
6975// Return the type of a bound method expression. The type of this
0afbb937 6976// object is simply the type of the method with no receiver.
e440a328 6977
6978Type*
6979Bound_method_expression::do_type()
6980{
0afbb937 6981 Named_object* fn = this->method_->named_object();
6982 Function_type* fntype;
6983 if (fn->is_function())
6984 fntype = fn->func_value()->type();
6985 else if (fn->is_function_declaration())
6986 fntype = fn->func_declaration_value()->type();
e0659c9e 6987 else
6988 return Type::make_error_type();
0afbb937 6989 return fntype->copy_without_receiver();
e440a328 6990}
6991
6992// Determine the types of a method expression.
6993
6994void
6995Bound_method_expression::do_determine_type(const Type_context*)
6996{
0afbb937 6997 Named_object* fn = this->method_->named_object();
6998 Function_type* fntype;
6999 if (fn->is_function())
7000 fntype = fn->func_value()->type();
7001 else if (fn->is_function_declaration())
7002 fntype = fn->func_declaration_value()->type();
7003 else
7004 fntype = NULL;
e440a328 7005 if (fntype == NULL || !fntype->is_method())
7006 this->expr_->determine_type_no_context();
7007 else
7008 {
7009 Type_context subcontext(fntype->receiver()->type(), false);
7010 this->expr_->determine_type(&subcontext);
7011 }
7012}
7013
7014// Check the types of a method expression.
7015
7016void
7017Bound_method_expression::do_check_types(Gogo*)
7018{
0afbb937 7019 Named_object* fn = this->method_->named_object();
7020 if (!fn->is_function() && !fn->is_function_declaration())
7021 {
7022 this->report_error(_("object is not a method"));
7023 return;
7024 }
7025
7026 Function_type* fntype;
7027 if (fn->is_function())
7028 fntype = fn->func_value()->type();
7029 else if (fn->is_function_declaration())
7030 fntype = fn->func_declaration_value()->type();
e440a328 7031 else
0afbb937 7032 go_unreachable();
7033 Type* rtype = fntype->receiver()->type()->deref();
7034 Type* etype = (this->expr_type_ != NULL
7035 ? this->expr_type_
7036 : this->expr_->type());
7037 etype = etype->deref();
3a522dcc 7038 if (!Type::are_identical(rtype, etype, Type::COMPARE_TAGS, NULL))
0afbb937 7039 this->report_error(_("method type does not match object type"));
7040}
7041
7042// If a bound method expression is not simply called, then it is
7043// represented as a closure. The closure will hold a single variable,
7044// the receiver to pass to the method. The function will be a simple
7045// thunk that pulls that value from the closure and calls the method
7046// with the remaining arguments.
7047//
7048// Because method values are not common, we don't build all thunks for
7049// every methods, but instead only build them as we need them. In
7050// particular, we even build them on demand for methods defined in
7051// other packages.
7052
7053Bound_method_expression::Method_value_thunks
7054 Bound_method_expression::method_value_thunks;
7055
7056// Find or create the thunk for METHOD.
7057
7058Named_object*
7059Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
7060 Named_object* fn)
7061{
7062 std::pair<Named_object*, Named_object*> val(fn, NULL);
7063 std::pair<Method_value_thunks::iterator, bool> ins =
7064 Bound_method_expression::method_value_thunks.insert(val);
7065 if (!ins.second)
7066 {
7067 // We have seen this method before.
7068 go_assert(ins.first->second != NULL);
7069 return ins.first->second;
7070 }
7071
7072 Location loc = fn->location();
7073
7074 Function_type* orig_fntype;
7075 if (fn->is_function())
7076 orig_fntype = fn->func_value()->type();
7077 else if (fn->is_function_declaration())
7078 orig_fntype = fn->func_declaration_value()->type();
7079 else
7080 orig_fntype = NULL;
7081
7082 if (orig_fntype == NULL || !orig_fntype->is_method())
e440a328 7083 {
13f2fdb8 7084 ins.first->second =
7085 Named_object::make_erroneous_name(gogo->thunk_name());
0afbb937 7086 return ins.first->second;
e440a328 7087 }
0afbb937 7088
7089 Struct_field_list* sfl = new Struct_field_list();
f8bdf81a 7090 // The type here is wrong--it should be the C function type. But it
7091 // doesn't really matter.
0afbb937 7092 Type* vt = Type::make_pointer_type(Type::make_void_type());
13f2fdb8 7093 sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
7094 sfl->push_back(Struct_field(Typed_identifier("val",
0afbb937 7095 orig_fntype->receiver()->type(),
7096 loc)));
6bf4793c 7097 Struct_type* st = Type::make_struct_type(sfl, loc);
7098 st->set_is_struct_incomparable();
7099 Type* closure_type = Type::make_pointer_type(st);
0afbb937 7100
f8bdf81a 7101 Function_type* new_fntype = orig_fntype->copy_with_names();
0afbb937 7102
13f2fdb8 7103 std::string thunk_name = gogo->thunk_name();
da244e59 7104 Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
0afbb937 7105 false, loc);
7106
f8bdf81a 7107 Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
7108 cvar->set_is_used();
1ecc6157 7109 cvar->set_is_closure();
da244e59 7110 Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
7111 NULL, cvar);
f8bdf81a 7112 new_no->func_value()->set_closure_var(cp);
0afbb937 7113
f8bdf81a 7114 gogo->start_block(loc);
0afbb937 7115
7116 // Field 0 of the closure is the function code pointer, field 1 is
7117 // the value on which to invoke the method.
7118 Expression* arg = Expression::make_var_reference(cp, loc);
f614ea8b 7119 arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
0afbb937 7120 arg = Expression::make_field_reference(arg, 1, loc);
7121
7122 Expression* bme = Expression::make_bound_method(arg, method, fn, loc);
7123
7124 const Typed_identifier_list* orig_params = orig_fntype->parameters();
7125 Expression_list* args;
7126 if (orig_params == NULL || orig_params->empty())
7127 args = NULL;
7128 else
7129 {
7130 const Typed_identifier_list* new_params = new_fntype->parameters();
7131 args = new Expression_list();
7132 for (Typed_identifier_list::const_iterator p = new_params->begin();
f8bdf81a 7133 p != new_params->end();
0afbb937 7134 ++p)
7135 {
7136 Named_object* p_no = gogo->lookup(p->name(), NULL);
7137 go_assert(p_no != NULL
7138 && p_no->is_variable()
7139 && p_no->var_value()->is_parameter());
7140 args->push_back(Expression::make_var_reference(p_no, loc));
7141 }
7142 }
7143
7144 Call_expression* call = Expression::make_call(bme, args,
7145 orig_fntype->is_varargs(),
7146 loc);
7147 call->set_varargs_are_lowered();
7148
7149 Statement* s = Statement::make_return_from_call(call, loc);
7150 gogo->add_statement(s);
7151 Block* b = gogo->finish_block(loc);
7152 gogo->add_block(b, loc);
7153 gogo->lower_block(new_no, b);
a32698ee 7154 gogo->flatten_block(new_no, b);
0afbb937 7155 gogo->finish_function(loc);
7156
7157 ins.first->second = new_no;
7158 return new_no;
7159}
7160
7161// Return an expression to check *REF for nil while dereferencing
7162// according to FIELD_INDEXES. Update *REF to build up the field
7163// reference. This is a static function so that we don't have to
7164// worry about declaring Field_indexes in expressions.h.
7165
7166static Expression*
7167bme_check_nil(const Method::Field_indexes* field_indexes, Location loc,
7168 Expression** ref)
7169{
7170 if (field_indexes == NULL)
7171 return Expression::make_boolean(false, loc);
7172 Expression* cond = bme_check_nil(field_indexes->next, loc, ref);
7173 Struct_type* stype = (*ref)->type()->deref()->struct_type();
7174 go_assert(stype != NULL
7175 && field_indexes->field_index < stype->field_count());
7176 if ((*ref)->type()->struct_type() == NULL)
7177 {
7178 go_assert((*ref)->type()->points_to() != NULL);
7179 Expression* n = Expression::make_binary(OPERATOR_EQEQ, *ref,
7180 Expression::make_nil(loc),
7181 loc);
7182 cond = Expression::make_binary(OPERATOR_OROR, cond, n, loc);
f614ea8b 7183 *ref = Expression::make_dereference(*ref, Expression::NIL_CHECK_DEFAULT,
7184 loc);
0afbb937 7185 go_assert((*ref)->type()->struct_type() == stype);
7186 }
7187 *ref = Expression::make_field_reference(*ref, field_indexes->field_index,
7188 loc);
7189 return cond;
e440a328 7190}
7191
cd39797e 7192// Flatten a method value into a struct with nil checks. We can't do
7193// this in the lowering phase, because if the method value is called
7194// directly we don't need a thunk. That case will have been handled
7195// by Call_expression::do_lower, so if we get here then we do need a
7196// thunk.
e440a328 7197
cd39797e 7198Expression*
7199Bound_method_expression::do_flatten(Gogo* gogo, Named_object*,
7200 Statement_inserter* inserter)
e440a328 7201{
cd39797e 7202 Location loc = this->location();
7203
7204 Named_object* thunk = Bound_method_expression::create_thunk(gogo,
0afbb937 7205 this->method_,
7206 this->function_);
7207 if (thunk->is_erroneous())
7208 {
7209 go_assert(saw_errors());
cd39797e 7210 return Expression::make_error(loc);
0afbb937 7211 }
7212
cd39797e 7213 // Force the expression into a variable. This is only necessary if
7214 // we are going to do nil checks below, but it's easy enough to
7215 // always do it.
7216 Expression* expr = this->expr_;
7217 if (!expr->is_variable())
7218 {
7219 Temporary_statement* etemp = Statement::make_temporary(NULL, expr, loc);
7220 inserter->insert(etemp);
7221 expr = Expression::make_temporary_reference(etemp, loc);
7222 }
0afbb937 7223
7224 // If the method expects a value, and we have a pointer, we need to
7225 // dereference the pointer.
7226
7227 Named_object* fn = this->method_->named_object();
cd39797e 7228 Function_type *fntype;
0afbb937 7229 if (fn->is_function())
7230 fntype = fn->func_value()->type();
7231 else if (fn->is_function_declaration())
7232 fntype = fn->func_declaration_value()->type();
7233 else
7234 go_unreachable();
7235
cd39797e 7236 Expression* val = expr;
0afbb937 7237 if (fntype->receiver()->type()->points_to() == NULL
7238 && val->type()->points_to() != NULL)
f614ea8b 7239 val = Expression::make_dereference(val, NIL_CHECK_DEFAULT, loc);
0afbb937 7240
7241 // Note that we are ignoring this->expr_type_ here. The thunk will
7242 // expect a closure whose second field has type this->expr_type_ (if
7243 // that is not NULL). We are going to pass it a closure whose
7244 // second field has type this->expr_->type(). Since
7245 // this->expr_type_ is only not-NULL for pointer types, we can get
7246 // away with this.
7247
7248 Struct_field_list* fields = new Struct_field_list();
13f2fdb8 7249 fields->push_back(Struct_field(Typed_identifier("fn",
0afbb937 7250 thunk->func_value()->type(),
7251 loc)));
13f2fdb8 7252 fields->push_back(Struct_field(Typed_identifier("val", val->type(), loc)));
0afbb937 7253 Struct_type* st = Type::make_struct_type(fields, loc);
6bf4793c 7254 st->set_is_struct_incomparable();
0afbb937 7255
7256 Expression_list* vals = new Expression_list();
7257 vals->push_back(Expression::make_func_code_reference(thunk, loc));
7258 vals->push_back(val);
7259
7260 Expression* ret = Expression::make_struct_composite_literal(st, vals, loc);
c1177ba4 7261 ret = Expression::make_heap_expression(ret, loc);
0afbb937 7262
c1177ba4 7263 Node* n = Node::make_node(this);
7264 if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
7265 ret->heap_expression()->set_allocate_on_stack();
7266 else if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
7267 go_error_at(loc, "%s escapes to heap, not allowed in runtime",
7268 n->ast_format(gogo).c_str());
cd39797e 7269
7270 // If necessary, check whether the expression or any embedded
7271 // pointers are nil.
0afbb937 7272
df7ef1fd 7273 Expression* nil_check = NULL;
0afbb937 7274 if (this->method_->field_indexes() != NULL)
7275 {
0afbb937 7276 Expression* ref = expr;
7277 nil_check = bme_check_nil(this->method_->field_indexes(), loc, &ref);
7278 expr = ref;
7279 }
7280
7281 if (this->method_->is_value_method() && expr->type()->points_to() != NULL)
7282 {
7283 Expression* n = Expression::make_binary(OPERATOR_EQEQ, expr,
7284 Expression::make_nil(loc),
7285 loc);
7286 if (nil_check == NULL)
7287 nil_check = n;
7288 else
7289 nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc);
7290 }
7291
7292 if (nil_check != NULL)
7293 {
cd39797e 7294 Expression* crash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
7295 loc);
7296 // Fix the type of the conditional expression by pretending to
7297 // evaluate to RET either way through the conditional.
7298 crash = Expression::make_compound(crash, ret, loc);
7299 ret = Expression::make_conditional(nil_check, crash, ret, loc);
7300 }
7301
7302 // RET is a pointer to a struct, but we want a function type.
7303 ret = Expression::make_unsafe_cast(this->type(), ret, loc);
7304
7305 return ret;
e440a328 7306}
7307
d751bb78 7308// Dump ast representation of a bound method expression.
7309
7310void
7311Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
7312 const
7313{
7314 if (this->expr_type_ != NULL)
7315 ast_dump_context->ostream() << "(";
f03a9fbf 7316 ast_dump_context->dump_expression(this->expr_);
7317 if (this->expr_type_ != NULL)
d751bb78 7318 {
7319 ast_dump_context->ostream() << ":";
7320 ast_dump_context->dump_type(this->expr_type_);
7321 ast_dump_context->ostream() << ")";
7322 }
f03a9fbf 7323
0afbb937 7324 ast_dump_context->ostream() << "." << this->function_->name();
d751bb78 7325}
7326
e440a328 7327// Make a method expression.
7328
7329Bound_method_expression*
0afbb937 7330Expression::make_bound_method(Expression* expr, const Method* method,
7331 Named_object* function, Location location)
e440a328 7332{
0afbb937 7333 return new Bound_method_expression(expr, method, function, location);
e440a328 7334}
7335
7336// Class Builtin_call_expression. This is used for a call to a
7337// builtin function.
7338
e440a328 7339Builtin_call_expression::Builtin_call_expression(Gogo* gogo,
7340 Expression* fn,
7341 Expression_list* args,
7342 bool is_varargs,
b13c66cd 7343 Location location)
e440a328 7344 : Call_expression(fn, args, is_varargs, location),
6334270b 7345 gogo_(gogo), code_(BUILTIN_INVALID), seen_(false),
7346 recover_arg_is_set_(false)
e440a328 7347{
7348 Func_expression* fnexp = this->fn()->func_expression();
79651b1f 7349 if (fnexp == NULL)
7350 {
7351 this->code_ = BUILTIN_INVALID;
7352 return;
7353 }
e440a328 7354 const std::string& name(fnexp->named_object()->name());
7355 if (name == "append")
7356 this->code_ = BUILTIN_APPEND;
7357 else if (name == "cap")
7358 this->code_ = BUILTIN_CAP;
7359 else if (name == "close")
7360 this->code_ = BUILTIN_CLOSE;
48080209 7361 else if (name == "complex")
7362 this->code_ = BUILTIN_COMPLEX;
e440a328 7363 else if (name == "copy")
7364 this->code_ = BUILTIN_COPY;
1cce762f 7365 else if (name == "delete")
7366 this->code_ = BUILTIN_DELETE;
e440a328 7367 else if (name == "imag")
7368 this->code_ = BUILTIN_IMAG;
7369 else if (name == "len")
7370 this->code_ = BUILTIN_LEN;
7371 else if (name == "make")
7372 this->code_ = BUILTIN_MAKE;
7373 else if (name == "new")
7374 this->code_ = BUILTIN_NEW;
7375 else if (name == "panic")
7376 this->code_ = BUILTIN_PANIC;
7377 else if (name == "print")
7378 this->code_ = BUILTIN_PRINT;
7379 else if (name == "println")
7380 this->code_ = BUILTIN_PRINTLN;
7381 else if (name == "real")
7382 this->code_ = BUILTIN_REAL;
7383 else if (name == "recover")
7384 this->code_ = BUILTIN_RECOVER;
7385 else if (name == "Alignof")
7386 this->code_ = BUILTIN_ALIGNOF;
7387 else if (name == "Offsetof")
7388 this->code_ = BUILTIN_OFFSETOF;
7389 else if (name == "Sizeof")
7390 this->code_ = BUILTIN_SIZEOF;
7391 else
c3e6f413 7392 go_unreachable();
e440a328 7393}
7394
7395// Return whether this is a call to recover. This is a virtual
7396// function called from the parent class.
7397
7398bool
7399Builtin_call_expression::do_is_recover_call() const
7400{
7401 if (this->classification() == EXPRESSION_ERROR)
7402 return false;
7403 return this->code_ == BUILTIN_RECOVER;
7404}
7405
7406// Set the argument for a call to recover.
7407
7408void
7409Builtin_call_expression::do_set_recover_arg(Expression* arg)
7410{
7411 const Expression_list* args = this->args();
c484d925 7412 go_assert(args == NULL || args->empty());
e440a328 7413 Expression_list* new_args = new Expression_list();
7414 new_args->push_back(arg);
7415 this->set_args(new_args);
6334270b 7416 this->recover_arg_is_set_ = true;
e440a328 7417}
7418
e440a328 7419// Lower a builtin call expression. This turns new and make into
7420// specific expressions. We also convert to a constant if we can.
7421
7422Expression*
321e5ad2 7423Builtin_call_expression::do_lower(Gogo*, Named_object* function,
ceeb4318 7424 Statement_inserter* inserter, int)
e440a328 7425{
79651b1f 7426 if (this->is_error_expression())
a9182619 7427 return this;
7428
b13c66cd 7429 Location loc = this->location();
1cce762f 7430
a8725655 7431 if (this->is_varargs() && this->code_ != BUILTIN_APPEND)
7432 {
7433 this->report_error(_("invalid use of %<...%> with builtin function"));
1cce762f 7434 return Expression::make_error(loc);
a8725655 7435 }
7436
393ba00b 7437 if (this->code_ == BUILTIN_OFFSETOF)
7438 {
7439 Expression* arg = this->one_arg();
12e69faa 7440
7441 if (arg->bound_method_expression() != NULL
7442 || arg->interface_field_reference_expression() != NULL)
7443 {
7444 this->report_error(_("invalid use of method value as argument "
7445 "of Offsetof"));
7446 return this;
7447 }
7448
393ba00b 7449 Field_reference_expression* farg = arg->field_reference_expression();
7450 while (farg != NULL)
7451 {
7452 if (!farg->implicit())
7453 break;
7454 // When the selector refers to an embedded field,
7455 // it must not be reached through pointer indirections.
7456 if (farg->expr()->deref() != farg->expr())
7457 {
12e69faa 7458 this->report_error(_("argument of Offsetof implies "
7459 "indirection of an embedded field"));
393ba00b 7460 return this;
7461 }
7462 // Go up until we reach the original base.
7463 farg = farg->expr()->field_reference_expression();
7464 }
7465 }
f03a9fbf 7466
1cce762f 7467 if (this->is_constant())
e440a328 7468 {
0c77715b 7469 Numeric_constant nc;
7470 if (this->numeric_constant_value(&nc))
7471 return nc.expression(loc);
e440a328 7472 }
1cce762f 7473
7474 switch (this->code_)
e440a328 7475 {
1cce762f 7476 default:
7477 break;
7478
7479 case BUILTIN_NEW:
7480 {
7481 const Expression_list* args = this->args();
7482 if (args == NULL || args->size() < 1)
7483 this->report_error(_("not enough arguments"));
7484 else if (args->size() > 1)
7485 this->report_error(_("too many arguments"));
7486 else
7487 {
7488 Expression* arg = args->front();
7489 if (!arg->is_type_expression())
7490 {
631d5788 7491 go_error_at(arg->location(), "expected type");
1cce762f 7492 this->set_is_error();
7493 }
7494 else
7495 return Expression::make_allocation(arg->type(), loc);
7496 }
7497 }
7498 break;
7499
7500 case BUILTIN_MAKE:
321e5ad2 7501 return this->lower_make(inserter);
1cce762f 7502
7503 case BUILTIN_RECOVER:
e440a328 7504 if (function != NULL)
7505 function->func_value()->set_calls_recover();
7506 else
7507 {
7508 // Calling recover outside of a function always returns the
7509 // nil empty interface.
823c7e3d 7510 Type* eface = Type::make_empty_interface_type(loc);
1cce762f 7511 return Expression::make_cast(eface, Expression::make_nil(loc), loc);
e440a328 7512 }
1cce762f 7513 break;
7514
1cce762f 7515 case BUILTIN_DELETE:
7516 {
7517 // Lower to a runtime function call.
7518 const Expression_list* args = this->args();
7519 if (args == NULL || args->size() < 2)
7520 this->report_error(_("not enough arguments"));
7521 else if (args->size() > 2)
7522 this->report_error(_("too many arguments"));
7523 else if (args->front()->type()->map_type() == NULL)
7524 this->report_error(_("argument 1 must be a map"));
7525 else
7526 {
7527 // Since this function returns no value it must appear in
7528 // a statement by itself, so we don't have to worry about
7529 // order of evaluation of values around it. Evaluate the
7530 // map first to get order of evaluation right.
7531 Map_type* mt = args->front()->type()->map_type();
7532 Temporary_statement* map_temp =
7533 Statement::make_temporary(mt, args->front(), loc);
7534 inserter->insert(map_temp);
7535
7536 Temporary_statement* key_temp =
7537 Statement::make_temporary(mt->key_type(), args->back(), loc);
7538 inserter->insert(key_temp);
7539
0d5530d9 7540 Expression* e1 = Expression::make_type_descriptor(mt, loc);
7541 Expression* e2 = Expression::make_temporary_reference(map_temp,
1cce762f 7542 loc);
0d5530d9 7543 Expression* e3 = Expression::make_temporary_reference(key_temp,
1cce762f 7544 loc);
28819633 7545
7546 // If the call to delete is deferred, and is in a loop,
7547 // then the loop will only have a single instance of the
7548 // temporary variable. Passing the address of the
7549 // temporary variable here means that the deferred call
7550 // will see the last value in the loop, not the current
7551 // value. So for this unusual case copy the value into
7552 // the heap.
7553 if (!this->is_deferred())
7554 e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
7555 else
7556 {
7557 Expression* a = Expression::make_allocation(mt->key_type(),
7558 loc);
7559 Temporary_statement* atemp =
7560 Statement::make_temporary(NULL, a, loc);
7561 inserter->insert(atemp);
7562
7563 a = Expression::make_temporary_reference(atemp, loc);
7564 a = Expression::make_dereference(a, NIL_CHECK_NOT_NEEDED, loc);
7565 Statement* s = Statement::make_assignment(a, e3, loc);
7566 inserter->insert(s);
7567
7568 e3 = Expression::make_temporary_reference(atemp, loc);
7569 }
7570
1cce762f 7571 return Runtime::make_call(Runtime::MAPDELETE, this->location(),
0d5530d9 7572 3, e1, e2, e3);
1cce762f 7573 }
7574 }
7575 break;
88b03a70 7576
7577 case BUILTIN_PRINT:
7578 case BUILTIN_PRINTLN:
7579 // Force all the arguments into temporary variables, so that we
7580 // don't try to evaluate something while holding the print lock.
7581 if (this->args() == NULL)
7582 break;
7583 for (Expression_list::iterator pa = this->args()->begin();
7584 pa != this->args()->end();
7585 ++pa)
7586 {
493ce3ee 7587 if (!(*pa)->is_variable() && !(*pa)->is_constant())
88b03a70 7588 {
7589 Temporary_statement* temp =
7590 Statement::make_temporary(NULL, *pa, loc);
7591 inserter->insert(temp);
7592 *pa = Expression::make_temporary_reference(temp, loc);
7593 }
7594 }
7595 break;
e440a328 7596 }
7597
7598 return this;
7599}
7600
35a54f17 7601// Flatten a builtin call expression. This turns the arguments of copy and
7602// append into temporary expressions.
7603
7604Expression*
321e5ad2 7605Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
35a54f17 7606 Statement_inserter* inserter)
7607{
16cb7fec 7608 Location loc = this->location();
7609
7610 switch (this->code_)
35a54f17 7611 {
16cb7fec 7612 default:
7613 break;
7614
7615 case BUILTIN_APPEND:
d3c55148 7616 return this->flatten_append(gogo, function, inserter, NULL, NULL);
321e5ad2 7617
16cb7fec 7618 case BUILTIN_COPY:
7619 {
7620 Type* at = this->args()->front()->type();
7621 for (Expression_list::iterator pa = this->args()->begin();
7622 pa != this->args()->end();
7623 ++pa)
7624 {
7625 if ((*pa)->is_nil_expression())
7626 {
7627 Expression* nil = Expression::make_nil(loc);
7628 Expression* zero = Expression::make_integer_ul(0, NULL, loc);
7629 *pa = Expression::make_slice_value(at, nil, zero, zero, loc);
7630 }
7631 if (!(*pa)->is_variable())
7632 {
7633 Temporary_statement* temp =
7634 Statement::make_temporary(NULL, *pa, loc);
7635 inserter->insert(temp);
7636 *pa = Expression::make_temporary_reference(temp, loc);
7637 }
7638 }
7639 }
7640 break;
7641
7642 case BUILTIN_PANIC:
35a54f17 7643 for (Expression_list::iterator pa = this->args()->begin();
16cb7fec 7644 pa != this->args()->end();
7645 ++pa)
7646 {
7647 if (!(*pa)->is_variable() && (*pa)->type()->interface_type() != NULL)
55e8ba6a 7648 {
16cb7fec 7649 Temporary_statement* temp =
7650 Statement::make_temporary(NULL, *pa, loc);
7651 inserter->insert(temp);
7652 *pa = Expression::make_temporary_reference(temp, loc);
55e8ba6a 7653 }
16cb7fec 7654 }
7739537f 7655 break;
0d5530d9 7656
7657 case BUILTIN_LEN:
132ed071 7658 case BUILTIN_CAP:
321e5ad2 7659 {
7660 Expression_list::iterator pa = this->args()->begin();
7661 if (!(*pa)->is_variable()
7662 && ((*pa)->type()->map_type() != NULL
7663 || (*pa)->type()->channel_type() != NULL))
7664 {
7665 Temporary_statement* temp =
7666 Statement::make_temporary(NULL, *pa, loc);
7667 inserter->insert(temp);
7668 *pa = Expression::make_temporary_reference(temp, loc);
7669 }
7670 }
7671 break;
35a54f17 7672 }
16cb7fec 7673
35a54f17 7674 return this;
7675}
7676
a9182619 7677// Lower a make expression.
7678
7679Expression*
321e5ad2 7680Builtin_call_expression::lower_make(Statement_inserter* inserter)
a9182619 7681{
b13c66cd 7682 Location loc = this->location();
a9182619 7683
7684 const Expression_list* args = this->args();
7685 if (args == NULL || args->size() < 1)
7686 {
7687 this->report_error(_("not enough arguments"));
7688 return Expression::make_error(this->location());
7689 }
7690
7691 Expression_list::const_iterator parg = args->begin();
7692
7693 Expression* first_arg = *parg;
7694 if (!first_arg->is_type_expression())
7695 {
631d5788 7696 go_error_at(first_arg->location(), "expected type");
a9182619 7697 this->set_is_error();
7698 return Expression::make_error(this->location());
7699 }
7700 Type* type = first_arg->type();
7701
22deed0d 7702 if (!type->in_heap())
7703 go_error_at(first_arg->location(),
7704 "can't make slice of go:notinheap type");
7705
a9182619 7706 bool is_slice = false;
7707 bool is_map = false;
7708 bool is_chan = false;
411eb89e 7709 if (type->is_slice_type())
a9182619 7710 is_slice = true;
7711 else if (type->map_type() != NULL)
7712 is_map = true;
7713 else if (type->channel_type() != NULL)
7714 is_chan = true;
7715 else
7716 {
7717 this->report_error(_("invalid type for make function"));
7718 return Expression::make_error(this->location());
7719 }
7720
f6bc81e6 7721 Type_context int_context(Type::lookup_integer_type("int"), false);
7722
a9182619 7723 ++parg;
7724 Expression* len_arg;
ccea2b36 7725 bool len_small = false;
a9182619 7726 if (parg == args->end())
7727 {
7728 if (is_slice)
7729 {
7730 this->report_error(_("length required when allocating a slice"));
7731 return Expression::make_error(this->location());
7732 }
e67508fa 7733 len_arg = Expression::make_integer_ul(0, NULL, loc);
33d1d391 7734 len_small = true;
a9182619 7735 }
7736 else
7737 {
7738 len_arg = *parg;
f6bc81e6 7739 len_arg->determine_type(&int_context);
a065edc5 7740 if (len_arg->type()->integer_type() == NULL)
7741 {
7742 go_error_at(len_arg->location(), "non-integer len argument in make");
7743 return Expression::make_error(this->location());
7744 }
ccea2b36 7745 if (!this->check_int_value(len_arg, true, &len_small))
1ad00fd4 7746 return Expression::make_error(this->location());
a9182619 7747 ++parg;
7748 }
7749
7750 Expression* cap_arg = NULL;
ccea2b36 7751 bool cap_small = false;
72bf0e6e 7752 Numeric_constant nclen;
7753 Numeric_constant nccap;
7754 unsigned long vlen;
7755 unsigned long vcap;
a9182619 7756 if (is_slice && parg != args->end())
7757 {
7758 cap_arg = *parg;
f6bc81e6 7759 cap_arg->determine_type(&int_context);
a065edc5 7760 if (cap_arg->type()->integer_type() == NULL)
7761 {
7762 go_error_at(cap_arg->location(), "non-integer cap argument in make");
7763 return Expression::make_error(this->location());
7764 }
ccea2b36 7765 if (!this->check_int_value(cap_arg, false, &cap_small))
1ad00fd4 7766 return Expression::make_error(this->location());
7767
1ad00fd4 7768 if (len_arg->numeric_constant_value(&nclen)
7769 && cap_arg->numeric_constant_value(&nccap)
7770 && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
7771 && nccap.to_unsigned_long(&vcap) == Numeric_constant::NC_UL_VALID
7772 && vlen > vcap)
a9182619 7773 {
1ad00fd4 7774 this->report_error(_("len larger than cap"));
a9182619 7775 return Expression::make_error(this->location());
7776 }
1ad00fd4 7777
a9182619 7778 ++parg;
7779 }
7780
7781 if (parg != args->end())
7782 {
7783 this->report_error(_("too many arguments to make"));
7784 return Expression::make_error(this->location());
7785 }
7786
b13c66cd 7787 Location type_loc = first_arg->location();
a9182619 7788
7789 Expression* call;
7790 if (is_slice)
7791 {
d633d0fb 7792 Temporary_statement* len_temp = NULL;
7793 if (!len_arg->is_constant())
7794 {
7795 len_temp = Statement::make_temporary(NULL, len_arg, loc);
7796 inserter->insert(len_temp);
7797 len_arg = Expression::make_temporary_reference(len_temp, loc);
7798 }
7799
a9182619 7800 if (cap_arg == NULL)
321e5ad2 7801 {
72bf0e6e 7802 cap_small = len_small;
d633d0fb 7803 if (len_temp == NULL)
7804 cap_arg = len_arg->copy();
7805 else
7806 cap_arg = Expression::make_temporary_reference(len_temp, loc);
7807 }
7808 else if (!cap_arg->is_constant())
7809 {
7810 Temporary_statement* cap_temp = Statement::make_temporary(NULL,
7811 cap_arg,
7812 loc);
7813 inserter->insert(cap_temp);
7814 cap_arg = Expression::make_temporary_reference(cap_temp, loc);
321e5ad2 7815 }
ccea2b36 7816
72bf0e6e 7817 Type* et = type->array_type()->element_type();
7818 Expression* type_arg = Expression::make_type_descriptor(et, type_loc);
ccea2b36 7819 Runtime::Function code = Runtime::MAKESLICE;
7820 if (!len_small || !cap_small)
7821 code = Runtime::MAKESLICE64;
d633d0fb 7822 Expression* mem = Runtime::make_call(code, loc, 3, type_arg, len_arg,
7823 cap_arg);
7824 mem = Expression::make_unsafe_cast(Type::make_pointer_type(et), mem,
7825 loc);
f81232c1 7826 Type* int_type = Type::lookup_integer_type("int");
7827 len_arg = Expression::make_cast(int_type, len_arg->copy(), loc);
7828 cap_arg = Expression::make_cast(int_type, cap_arg->copy(), loc);
7829 call = Expression::make_slice_value(type, mem, len_arg, cap_arg, loc);
a9182619 7830 }
7831 else if (is_map)
321e5ad2 7832 {
7833 Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
33d1d391 7834 if (!len_small)
7835 call = Runtime::make_call(Runtime::MAKEMAP64, loc, 3, type_arg,
7836 len_arg,
7837 Expression::make_nil(loc));
7838 else
7839 {
7840 Numeric_constant nclen;
7841 unsigned long vlen;
7842 if (len_arg->numeric_constant_value(&nclen)
7843 && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
7844 && vlen <= Map_type::bucket_size)
7845 call = Runtime::make_call(Runtime::MAKEMAP_SMALL, loc, 0);
7846 else
7847 call = Runtime::make_call(Runtime::MAKEMAP, loc, 3, type_arg,
7848 len_arg,
7849 Expression::make_nil(loc));
7850 }
321e5ad2 7851 }
a9182619 7852 else if (is_chan)
321e5ad2 7853 {
7854 Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
1423c90a 7855 Runtime::Function code = Runtime::MAKECHAN;
7856 if (!len_small)
7857 code = Runtime::MAKECHAN64;
7858 call = Runtime::make_call(code, loc, 2, type_arg, len_arg);
321e5ad2 7859 }
a9182619 7860 else
7861 go_unreachable();
7862
7863 return Expression::make_unsafe_cast(type, call, loc);
7864}
7865
321e5ad2 7866// Flatten a call to the predeclared append function. We do this in
7867// the flatten phase, not the lowering phase, so that we run after
d3c55148 7868// type checking and after order_evaluations. If ASSIGN_LHS is not
7869// NULL, this append is the right-hand-side of an assignment and
7870// ASSIGN_LHS is the left-hand-side; in that case, set LHS directly
7871// rather than returning a slice. This lets us omit a write barrier
7872// in common cases like a = append(a, ...) when the slice does not
7873// need to grow. ENCLOSING is not NULL iff ASSIGN_LHS is not NULL.
321e5ad2 7874
7875Expression*
7876Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
d3c55148 7877 Statement_inserter* inserter,
7878 Expression* assign_lhs,
7879 Block* enclosing)
321e5ad2 7880{
7881 if (this->is_error_expression())
7882 return this;
7883
7884 Location loc = this->location();
7885
7886 const Expression_list* args = this->args();
7887 go_assert(args != NULL && !args->empty());
7888
7889 Type* slice_type = args->front()->type();
7890 go_assert(slice_type->is_slice_type());
7891 Type* element_type = slice_type->array_type()->element_type();
7892
7893 if (args->size() == 1)
7894 {
7895 // append(s) evaluates to s.
d3c55148 7896 if (assign_lhs != NULL)
7897 return NULL;
321e5ad2 7898 return args->front();
7899 }
7900
7901 Type* int_type = Type::lookup_integer_type("int");
7902 Type* uint_type = Type::lookup_integer_type("uint");
7903
7904 // Implementing
7905 // append(s1, s2...)
7906 // or
7907 // append(s1, a1, a2, a3, ...)
7908
7909 // s1tmp := s1
7910 Temporary_statement* s1tmp = Statement::make_temporary(NULL, args->front(),
7911 loc);
7912 inserter->insert(s1tmp);
7913
7914 // l1tmp := len(s1tmp)
7915 Named_object* lenfn = gogo->lookup_global("len");
7916 Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
7917 Expression_list* call_args = new Expression_list();
7918 call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
7919 Expression* len = Expression::make_call(lenref, call_args, false, loc);
7920 gogo->lower_expression(function, inserter, &len);
7921 gogo->flatten_expression(function, inserter, &len);
7922 Temporary_statement* l1tmp = Statement::make_temporary(int_type, len, loc);
7923 inserter->insert(l1tmp);
7924
7925 Temporary_statement* s2tmp = NULL;
7926 Temporary_statement* l2tmp = NULL;
7927 Expression_list* add = NULL;
7928 Expression* len2;
7929 if (this->is_varargs())
7930 {
7931 go_assert(args->size() == 2);
7932
7933 // s2tmp := s2
7934 s2tmp = Statement::make_temporary(NULL, args->back(), loc);
7935 inserter->insert(s2tmp);
7936
7937 // l2tmp := len(s2tmp)
7938 lenref = Expression::make_func_reference(lenfn, NULL, loc);
7939 call_args = new Expression_list();
7940 call_args->push_back(Expression::make_temporary_reference(s2tmp, loc));
7941 len = Expression::make_call(lenref, call_args, false, loc);
7942 gogo->lower_expression(function, inserter, &len);
7943 gogo->flatten_expression(function, inserter, &len);
7944 l2tmp = Statement::make_temporary(int_type, len, loc);
7945 inserter->insert(l2tmp);
7946
7947 // len2 = l2tmp
7948 len2 = Expression::make_temporary_reference(l2tmp, loc);
7949 }
7950 else
7951 {
7952 // We have to ensure that all the arguments are in variables
7953 // now, because otherwise if one of them is an index expression
7954 // into the current slice we could overwrite it before we fetch
7955 // it.
7956 add = new Expression_list();
7957 Expression_list::const_iterator pa = args->begin();
7958 for (++pa; pa != args->end(); ++pa)
7959 {
7960 if ((*pa)->is_variable())
7961 add->push_back(*pa);
7962 else
7963 {
7964 Temporary_statement* tmp = Statement::make_temporary(NULL, *pa,
7965 loc);
7966 inserter->insert(tmp);
7967 add->push_back(Expression::make_temporary_reference(tmp, loc));
7968 }
7969 }
7970
7971 // len2 = len(add)
7972 len2 = Expression::make_integer_ul(add->size(), int_type, loc);
7973 }
7974
7975 // ntmp := l1tmp + len2
7976 Expression* ref = Expression::make_temporary_reference(l1tmp, loc);
7977 Expression* sum = Expression::make_binary(OPERATOR_PLUS, ref, len2, loc);
7978 gogo->lower_expression(function, inserter, &sum);
7979 gogo->flatten_expression(function, inserter, &sum);
7980 Temporary_statement* ntmp = Statement::make_temporary(int_type, sum, loc);
7981 inserter->insert(ntmp);
7982
7983 // s1tmp = uint(ntmp) > uint(cap(s1tmp)) ?
7984 // growslice(type, s1tmp, ntmp) :
7985 // s1tmp[:ntmp]
7986 // Using uint here means that if the computation of ntmp overflowed,
7987 // we will call growslice which will panic.
7988
7989 Expression* left = Expression::make_temporary_reference(ntmp, loc);
7990 left = Expression::make_cast(uint_type, left, loc);
7991
7992 Named_object* capfn = gogo->lookup_global("cap");
7993 Expression* capref = Expression::make_func_reference(capfn, NULL, loc);
7994 call_args = new Expression_list();
7995 call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
7996 Expression* right = Expression::make_call(capref, call_args, false, loc);
7997 right = Expression::make_cast(uint_type, right, loc);
7998
7999 Expression* cond = Expression::make_binary(OPERATOR_GT, left, right, loc);
8000
8001 Expression* a1 = Expression::make_type_descriptor(element_type, loc);
8002 Expression* a2 = Expression::make_temporary_reference(s1tmp, loc);
8003 Expression* a3 = Expression::make_temporary_reference(ntmp, loc);
8004 Expression* call = Runtime::make_call(Runtime::GROWSLICE, loc, 3,
8005 a1, a2, a3);
8006 call = Expression::make_unsafe_cast(slice_type, call, loc);
8007
8008 ref = Expression::make_temporary_reference(s1tmp, loc);
8009 Expression* zero = Expression::make_integer_ul(0, int_type, loc);
8010 Expression* ref2 = Expression::make_temporary_reference(ntmp, loc);
3d135120 8011 ref = Expression::make_array_index(ref, zero, ref2, NULL, loc);
8012 ref->array_index_expression()->set_needs_bounds_check(false);
321e5ad2 8013
d3c55148 8014 if (assign_lhs == NULL)
8015 {
8016 Expression* rhs = Expression::make_conditional(cond, call, ref, loc);
8017
8018 gogo->lower_expression(function, inserter, &rhs);
8019 gogo->flatten_expression(function, inserter, &rhs);
8020
8021 ref = Expression::make_temporary_reference(s1tmp, loc);
8022 Statement* assign = Statement::make_assignment(ref, rhs, loc);
8023 inserter->insert(assign);
8024 }
8025 else
8026 {
8027 gogo->lower_expression(function, inserter, &cond);
8028 gogo->flatten_expression(function, inserter, &cond);
8029 gogo->lower_expression(function, inserter, &call);
8030 gogo->flatten_expression(function, inserter, &call);
8031 gogo->lower_expression(function, inserter, &ref);
8032 gogo->flatten_expression(function, inserter, &ref);
8033
8034 Block* then_block = new Block(enclosing, loc);
8035 Assignment_statement* assign =
8036 Statement::make_assignment(assign_lhs, call, loc);
8037 then_block->add_statement(assign);
321e5ad2 8038
d3c55148 8039 Block* else_block = new Block(enclosing, loc);
8040 assign = Statement::make_assignment(assign_lhs->copy(), ref, loc);
8041 // This assignment will not change the pointer value, so it does
8042 // not need a write barrier.
8043 assign->set_omit_write_barrier();
8044 else_block->add_statement(assign);
321e5ad2 8045
d3c55148 8046 Statement* s = Statement::make_if_statement(cond, then_block,
8047 else_block, loc);
8048 inserter->insert(s);
8049
8050 ref = Expression::make_temporary_reference(s1tmp, loc);
8051 assign = Statement::make_assignment(ref, assign_lhs->copy(), loc);
8052 inserter->insert(assign);
8053 }
321e5ad2 8054
8055 if (this->is_varargs())
8056 {
8057 // copy(s1tmp[l1tmp:], s2tmp)
8058 a1 = Expression::make_temporary_reference(s1tmp, loc);
8059 ref = Expression::make_temporary_reference(l1tmp, loc);
8060 Expression* nil = Expression::make_nil(loc);
3d135120 8061 a1 = Expression::make_array_index(a1, ref, nil, NULL, loc);
8062 a1->array_index_expression()->set_needs_bounds_check(false);
321e5ad2 8063
8064 a2 = Expression::make_temporary_reference(s2tmp, loc);
8065
8066 Named_object* copyfn = gogo->lookup_global("copy");
8067 Expression* copyref = Expression::make_func_reference(copyfn, NULL, loc);
8068 call_args = new Expression_list();
8069 call_args->push_back(a1);
8070 call_args->push_back(a2);
8071 call = Expression::make_call(copyref, call_args, false, loc);
8072 gogo->lower_expression(function, inserter, &call);
8073 gogo->flatten_expression(function, inserter, &call);
8074 inserter->insert(Statement::make_statement(call, false));
8075 }
8076 else
8077 {
8078 // For each argument:
8079 // s1tmp[l1tmp+i] = a
8080 unsigned long i = 0;
8081 for (Expression_list::const_iterator pa = add->begin();
8082 pa != add->end();
8083 ++pa, ++i)
8084 {
8085 ref = Expression::make_temporary_reference(s1tmp, loc);
8086 ref2 = Expression::make_temporary_reference(l1tmp, loc);
8087 Expression* off = Expression::make_integer_ul(i, int_type, loc);
8088 ref2 = Expression::make_binary(OPERATOR_PLUS, ref2, off, loc);
3d135120 8089 Expression* lhs = Expression::make_array_index(ref, ref2, NULL,
8090 NULL, loc);
8091 lhs->array_index_expression()->set_needs_bounds_check(false);
321e5ad2 8092 gogo->lower_expression(function, inserter, &lhs);
8093 gogo->flatten_expression(function, inserter, &lhs);
03118c21 8094 // The flatten pass runs after the write barrier pass, so we
8095 // need to insert a write barrier here if necessary.
d3c55148 8096 // However, if ASSIGN_LHS is not NULL, we have been called
8097 // directly before the write barrier pass.
8098 Statement* assign;
8099 if (assign_lhs != NULL
8100 || !gogo->assign_needs_write_barrier(lhs))
03118c21 8101 assign = Statement::make_assignment(lhs, *pa, loc);
8102 else
8103 {
8104 Function* f = function == NULL ? NULL : function->func_value();
8105 assign = gogo->assign_with_write_barrier(f, NULL, inserter,
8106 lhs, *pa, loc);
8107 }
321e5ad2 8108 inserter->insert(assign);
8109 }
8110 }
8111
d3c55148 8112 if (assign_lhs != NULL)
8113 return NULL;
8114
321e5ad2 8115 return Expression::make_temporary_reference(s1tmp, loc);
8116}
8117
a9182619 8118// Return whether an expression has an integer value. Report an error
8119// if not. This is used when handling calls to the predeclared make
ccea2b36 8120// function. Set *SMALL if the value is known to fit in type "int".
a9182619 8121
8122bool
ccea2b36 8123Builtin_call_expression::check_int_value(Expression* e, bool is_length,
8124 bool *small)
a9182619 8125{
ccea2b36 8126 *small = false;
8127
0c77715b 8128 Numeric_constant nc;
1ad00fd4 8129 if (e->numeric_constant_value(&nc))
a9182619 8130 {
1ad00fd4 8131 unsigned long v;
8132 switch (nc.to_unsigned_long(&v))
8133 {
8134 case Numeric_constant::NC_UL_VALID:
1b10c5e7 8135 break;
1ad00fd4 8136 case Numeric_constant::NC_UL_NOTINT:
631d5788 8137 go_error_at(e->location(), "non-integer %s argument to make",
8138 is_length ? "len" : "cap");
1ad00fd4 8139 return false;
8140 case Numeric_constant::NC_UL_NEGATIVE:
631d5788 8141 go_error_at(e->location(), "negative %s argument to make",
8142 is_length ? "len" : "cap");
1ad00fd4 8143 return false;
8144 case Numeric_constant::NC_UL_BIG:
8145 // We don't want to give a compile-time error for a 64-bit
8146 // value on a 32-bit target.
1b10c5e7 8147 break;
1ad00fd4 8148 }
1b10c5e7 8149
8150 mpz_t val;
8151 if (!nc.to_int(&val))
8152 go_unreachable();
8153 int bits = mpz_sizeinbase(val, 2);
8154 mpz_clear(val);
8155 Type* int_type = Type::lookup_integer_type("int");
8156 if (bits >= int_type->integer_type()->bits())
8157 {
631d5788 8158 go_error_at(e->location(), "%s argument too large for make",
8159 is_length ? "len" : "cap");
1b10c5e7 8160 return false;
8161 }
8162
ccea2b36 8163 *small = true;
1b10c5e7 8164 return true;
a9182619 8165 }
8166
1ad00fd4 8167 if (e->type()->integer_type() != NULL)
ccea2b36 8168 {
8169 int ebits = e->type()->integer_type()->bits();
8170 int intbits = Type::lookup_integer_type("int")->integer_type()->bits();
8171
8172 // We can treat ebits == intbits as small even for an unsigned
8173 // integer type, because we will convert the value to int and
8174 // then reject it in the runtime if it is negative.
8175 *small = ebits <= intbits;
8176
8177 return true;
8178 }
1ad00fd4 8179
631d5788 8180 go_error_at(e->location(), "non-integer %s argument to make",
8181 is_length ? "len" : "cap");
a9182619 8182 return false;
8183}
8184
e440a328 8185// Return the type of the real or imag functions, given the type of
fcbea5e4 8186// the argument. We need to map complex64 to float32 and complex128
8187// to float64, so it has to be done by name. This returns NULL if it
8188// can't figure out the type.
e440a328 8189
8190Type*
8191Builtin_call_expression::real_imag_type(Type* arg_type)
8192{
8193 if (arg_type == NULL || arg_type->is_abstract())
8194 return NULL;
8195 Named_type* nt = arg_type->named_type();
8196 if (nt == NULL)
8197 return NULL;
8198 while (nt->real_type()->named_type() != NULL)
8199 nt = nt->real_type()->named_type();
48080209 8200 if (nt->name() == "complex64")
e440a328 8201 return Type::lookup_float_type("float32");
8202 else if (nt->name() == "complex128")
8203 return Type::lookup_float_type("float64");
8204 else
8205 return NULL;
8206}
8207
48080209 8208// Return the type of the complex function, given the type of one of the
e440a328 8209// argments. Like real_imag_type, we have to map by name.
8210
8211Type*
48080209 8212Builtin_call_expression::complex_type(Type* arg_type)
e440a328 8213{
8214 if (arg_type == NULL || arg_type->is_abstract())
8215 return NULL;
8216 Named_type* nt = arg_type->named_type();
8217 if (nt == NULL)
8218 return NULL;
8219 while (nt->real_type()->named_type() != NULL)
8220 nt = nt->real_type()->named_type();
48080209 8221 if (nt->name() == "float32")
e440a328 8222 return Type::lookup_complex_type("complex64");
8223 else if (nt->name() == "float64")
8224 return Type::lookup_complex_type("complex128");
8225 else
8226 return NULL;
8227}
8228
8229// Return a single argument, or NULL if there isn't one.
8230
8231Expression*
8232Builtin_call_expression::one_arg() const
8233{
8234 const Expression_list* args = this->args();
aa615cb3 8235 if (args == NULL || args->size() != 1)
e440a328 8236 return NULL;
8237 return args->front();
8238}
8239
83921647 8240// A traversal class which looks for a call or receive expression.
8241
8242class Find_call_expression : public Traverse
8243{
8244 public:
8245 Find_call_expression()
8246 : Traverse(traverse_expressions),
8247 found_(false)
8248 { }
8249
8250 int
8251 expression(Expression**);
8252
8253 bool
8254 found()
8255 { return this->found_; }
8256
8257 private:
8258 bool found_;
8259};
8260
8261int
8262Find_call_expression::expression(Expression** pexpr)
8263{
4714afb2 8264 Expression* expr = *pexpr;
8265 if (!expr->is_constant()
8266 && (expr->call_expression() != NULL
8267 || expr->receive_expression() != NULL))
83921647 8268 {
8269 this->found_ = true;
8270 return TRAVERSE_EXIT;
8271 }
8272 return TRAVERSE_CONTINUE;
8273}
8274
4714afb2 8275// Return whether calling len or cap on EXPR, of array type, is a
8276// constant. The language spec says "the expressions len(s) and
8277// cap(s) are constants if the type of s is an array or pointer to an
8278// array and the expression s does not contain channel receives or
8279// (non-constant) function calls."
8280
8281bool
8282Builtin_call_expression::array_len_is_constant(Expression* expr)
8283{
8284 go_assert(expr->type()->deref()->array_type() != NULL
8285 && !expr->type()->deref()->is_slice_type());
8286 if (expr->is_constant())
8287 return true;
8288 Find_call_expression find_call;
8289 Expression::traverse(&expr, &find_call);
8290 return !find_call.found();
8291}
8292
83921647 8293// Return whether this is constant: len of a string constant, or len
8294// or cap of an array, or unsafe.Sizeof, unsafe.Offsetof,
8295// unsafe.Alignof.
e440a328 8296
8297bool
8298Builtin_call_expression::do_is_constant() const
8299{
12e69faa 8300 if (this->is_error_expression())
8301 return true;
e440a328 8302 switch (this->code_)
8303 {
8304 case BUILTIN_LEN:
8305 case BUILTIN_CAP:
8306 {
0f914071 8307 if (this->seen_)
8308 return false;
8309
e440a328 8310 Expression* arg = this->one_arg();
8311 if (arg == NULL)
8312 return false;
8313 Type* arg_type = arg->type();
8314
8315 if (arg_type->points_to() != NULL
8316 && arg_type->points_to()->array_type() != NULL
411eb89e 8317 && !arg_type->points_to()->is_slice_type())
e440a328 8318 arg_type = arg_type->points_to();
8319
8320 if (arg_type->array_type() != NULL
54934d77 8321 && arg_type->array_type()->length() != NULL)
8322 {
8323 this->seen_ = true;
8324 bool ret = Builtin_call_expression::array_len_is_constant(arg);
8325 this->seen_ = false;
8326 return ret;
8327 }
e440a328 8328
8329 if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
0f914071 8330 {
8331 this->seen_ = true;
8332 bool ret = arg->is_constant();
8333 this->seen_ = false;
8334 return ret;
8335 }
e440a328 8336 }
8337 break;
8338
8339 case BUILTIN_SIZEOF:
8340 case BUILTIN_ALIGNOF:
8341 return this->one_arg() != NULL;
8342
8343 case BUILTIN_OFFSETOF:
8344 {
8345 Expression* arg = this->one_arg();
8346 if (arg == NULL)
8347 return false;
8348 return arg->field_reference_expression() != NULL;
8349 }
8350
48080209 8351 case BUILTIN_COMPLEX:
e440a328 8352 {
8353 const Expression_list* args = this->args();
8354 if (args != NULL && args->size() == 2)
8355 return args->front()->is_constant() && args->back()->is_constant();
8356 }
8357 break;
8358
8359 case BUILTIN_REAL:
8360 case BUILTIN_IMAG:
8361 {
8362 Expression* arg = this->one_arg();
8363 return arg != NULL && arg->is_constant();
8364 }
8365
8366 default:
8367 break;
8368 }
8369
8370 return false;
8371}
8372
0c77715b 8373// Return a numeric constant if possible.
e440a328 8374
8375bool
0c77715b 8376Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
e440a328 8377{
8378 if (this->code_ == BUILTIN_LEN
8379 || this->code_ == BUILTIN_CAP)
8380 {
8381 Expression* arg = this->one_arg();
8382 if (arg == NULL)
8383 return false;
8384 Type* arg_type = arg->type();
8385
8386 if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
8387 {
8388 std::string sval;
8389 if (arg->string_constant_value(&sval))
8390 {
0c77715b 8391 nc->set_unsigned_long(Type::lookup_integer_type("int"),
8392 sval.length());
e440a328 8393 return true;
8394 }
8395 }
8396
8397 if (arg_type->points_to() != NULL
8398 && arg_type->points_to()->array_type() != NULL
411eb89e 8399 && !arg_type->points_to()->is_slice_type())
e440a328 8400 arg_type = arg_type->points_to();
8401
8402 if (arg_type->array_type() != NULL
8403 && arg_type->array_type()->length() != NULL)
8404 {
0f914071 8405 if (this->seen_)
8406 return false;
e440a328 8407 Expression* e = arg_type->array_type()->length();
0f914071 8408 this->seen_ = true;
0c77715b 8409 bool r = e->numeric_constant_value(nc);
0f914071 8410 this->seen_ = false;
8411 if (r)
e440a328 8412 {
0c77715b 8413 if (!nc->set_type(Type::lookup_integer_type("int"), false,
8414 this->location()))
8415 r = false;
e440a328 8416 }
0c77715b 8417 return r;
e440a328 8418 }
8419 }
8420 else if (this->code_ == BUILTIN_SIZEOF
8421 || this->code_ == BUILTIN_ALIGNOF)
8422 {
8423 Expression* arg = this->one_arg();
8424 if (arg == NULL)
8425 return false;
8426 Type* arg_type = arg->type();
5c13bd80 8427 if (arg_type->is_error())
e440a328 8428 return false;
8429 if (arg_type->is_abstract())
7200ac0e 8430 arg_type = arg_type->make_non_abstract_type();
2c809f8f 8431 if (this->seen_)
8432 return false;
927a01eb 8433
3f378015 8434 int64_t ret;
e440a328 8435 if (this->code_ == BUILTIN_SIZEOF)
8436 {
2c809f8f 8437 this->seen_ = true;
8438 bool ok = arg_type->backend_type_size(this->gogo_, &ret);
8439 this->seen_ = false;
8440 if (!ok)
e440a328 8441 return false;
8442 }
8443 else if (this->code_ == BUILTIN_ALIGNOF)
8444 {
2c809f8f 8445 bool ok;
8446 this->seen_ = true;
637bd3af 8447 if (arg->field_reference_expression() == NULL)
2c809f8f 8448 ok = arg_type->backend_type_align(this->gogo_, &ret);
637bd3af 8449 else
e440a328 8450 {
8451 // Calling unsafe.Alignof(s.f) returns the alignment of
8452 // the type of f when it is used as a field in a struct.
2c809f8f 8453 ok = arg_type->backend_type_field_align(this->gogo_, &ret);
e440a328 8454 }
2c809f8f 8455 this->seen_ = false;
8456 if (!ok)
8457 return false;
e440a328 8458 }
8459 else
c3e6f413 8460 go_unreachable();
927a01eb 8461
3f378015 8462 mpz_t zval;
8463 set_mpz_from_int64(&zval, ret);
8464 nc->set_int(Type::lookup_integer_type("uintptr"), zval);
8465 mpz_clear(zval);
e440a328 8466 return true;
8467 }
8468 else if (this->code_ == BUILTIN_OFFSETOF)
8469 {
8470 Expression* arg = this->one_arg();
8471 if (arg == NULL)
8472 return false;
8473 Field_reference_expression* farg = arg->field_reference_expression();
8474 if (farg == NULL)
8475 return false;
2c809f8f 8476 if (this->seen_)
8477 return false;
8478
3f378015 8479 int64_t total_offset = 0;
9a4bd570 8480 while (true)
8481 {
8482 Expression* struct_expr = farg->expr();
8483 Type* st = struct_expr->type();
8484 if (st->struct_type() == NULL)
8485 return false;
8486 if (st->named_type() != NULL)
8487 st->named_type()->convert(this->gogo_);
fbabafbd 8488 if (st->is_error_type())
8489 {
8490 go_assert(saw_errors());
8491 return false;
8492 }
3f378015 8493 int64_t offset;
2c809f8f 8494 this->seen_ = true;
8495 bool ok = st->struct_type()->backend_field_offset(this->gogo_,
8496 farg->field_index(),
8497 &offset);
8498 this->seen_ = false;
8499 if (!ok)
8500 return false;
9a4bd570 8501 total_offset += offset;
8502 if (farg->implicit() && struct_expr->field_reference_expression() != NULL)
8503 {
8504 // Go up until we reach the original base.
8505 farg = struct_expr->field_reference_expression();
8506 continue;
8507 }
8508 break;
8509 }
3f378015 8510 mpz_t zval;
8511 set_mpz_from_int64(&zval, total_offset);
8512 nc->set_int(Type::lookup_integer_type("uintptr"), zval);
8513 mpz_clear(zval);
e440a328 8514 return true;
8515 }
0c77715b 8516 else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG)
e440a328 8517 {
8518 Expression* arg = this->one_arg();
8519 if (arg == NULL)
8520 return false;
8521
0c77715b 8522 Numeric_constant argnc;
8523 if (!arg->numeric_constant_value(&argnc))
8524 return false;
8525
fcbea5e4 8526 mpc_t val;
8527 if (!argnc.to_complex(&val))
0c77715b 8528 return false;
e440a328 8529
0c77715b 8530 Type* type = Builtin_call_expression::real_imag_type(argnc.type());
8531 if (this->code_ == BUILTIN_REAL)
fcbea5e4 8532 nc->set_float(type, mpc_realref(val));
0c77715b 8533 else
fcbea5e4 8534 nc->set_float(type, mpc_imagref(val));
8535 mpc_clear(val);
0c77715b 8536 return true;
e440a328 8537 }
0c77715b 8538 else if (this->code_ == BUILTIN_COMPLEX)
e440a328 8539 {
8540 const Expression_list* args = this->args();
8541 if (args == NULL || args->size() != 2)
8542 return false;
8543
0c77715b 8544 Numeric_constant rnc;
8545 if (!args->front()->numeric_constant_value(&rnc))
8546 return false;
8547 Numeric_constant inc;
8548 if (!args->back()->numeric_constant_value(&inc))
8549 return false;
8550
8551 if (rnc.type() != NULL
8552 && !rnc.type()->is_abstract()
8553 && inc.type() != NULL
8554 && !inc.type()->is_abstract()
3a522dcc 8555 && !Type::are_identical(rnc.type(), inc.type(),
8556 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
8557 NULL))
0c77715b 8558 return false;
8559
e440a328 8560 mpfr_t r;
0c77715b 8561 if (!rnc.to_float(&r))
8562 return false;
8563 mpfr_t i;
8564 if (!inc.to_float(&i))
e440a328 8565 {
8566 mpfr_clear(r);
8567 return false;
8568 }
8569
0c77715b 8570 Type* arg_type = rnc.type();
8571 if (arg_type == NULL || arg_type->is_abstract())
8572 arg_type = inc.type();
e440a328 8573
fcbea5e4 8574 mpc_t val;
8575 mpc_init2(val, mpc_precision);
8576 mpc_set_fr_fr(val, r, i, MPC_RNDNN);
e440a328 8577 mpfr_clear(r);
8578 mpfr_clear(i);
8579
fcbea5e4 8580 Type* type = Builtin_call_expression::complex_type(arg_type);
8581 nc->set_complex(type, val);
8582
8583 mpc_clear(val);
8584
0c77715b 8585 return true;
e440a328 8586 }
8587
8588 return false;
8589}
8590
a7549a6a 8591// Give an error if we are discarding the value of an expression which
8592// should not normally be discarded. We don't give an error for
8593// discarding the value of an ordinary function call, but we do for
8594// builtin functions, purely for consistency with the gc compiler.
8595
4f2138d7 8596bool
a7549a6a 8597Builtin_call_expression::do_discarding_value()
8598{
8599 switch (this->code_)
8600 {
8601 case BUILTIN_INVALID:
8602 default:
8603 go_unreachable();
8604
8605 case BUILTIN_APPEND:
8606 case BUILTIN_CAP:
8607 case BUILTIN_COMPLEX:
8608 case BUILTIN_IMAG:
8609 case BUILTIN_LEN:
8610 case BUILTIN_MAKE:
8611 case BUILTIN_NEW:
8612 case BUILTIN_REAL:
8613 case BUILTIN_ALIGNOF:
8614 case BUILTIN_OFFSETOF:
8615 case BUILTIN_SIZEOF:
8616 this->unused_value_error();
4f2138d7 8617 return false;
a7549a6a 8618
8619 case BUILTIN_CLOSE:
8620 case BUILTIN_COPY:
1cce762f 8621 case BUILTIN_DELETE:
a7549a6a 8622 case BUILTIN_PANIC:
8623 case BUILTIN_PRINT:
8624 case BUILTIN_PRINTLN:
8625 case BUILTIN_RECOVER:
4f2138d7 8626 return true;
a7549a6a 8627 }
8628}
8629
e440a328 8630// Return the type.
8631
8632Type*
8633Builtin_call_expression::do_type()
8634{
79651b1f 8635 if (this->is_error_expression())
8636 return Type::make_error_type();
e440a328 8637 switch (this->code_)
8638 {
8639 case BUILTIN_INVALID:
8640 default:
79651b1f 8641 return Type::make_error_type();
e440a328 8642
8643 case BUILTIN_NEW:
e440a328 8644 {
8645 const Expression_list* args = this->args();
8646 if (args == NULL || args->empty())
8647 return Type::make_error_type();
8648 return Type::make_pointer_type(args->front()->type());
8649 }
8650
a065edc5 8651 case BUILTIN_MAKE:
8652 {
8653 const Expression_list* args = this->args();
8654 if (args == NULL || args->empty())
8655 return Type::make_error_type();
8656 return args->front()->type();
8657 }
8658
e440a328 8659 case BUILTIN_CAP:
8660 case BUILTIN_COPY:
8661 case BUILTIN_LEN:
7ba86326 8662 return Type::lookup_integer_type("int");
8663
e440a328 8664 case BUILTIN_ALIGNOF:
8665 case BUILTIN_OFFSETOF:
8666 case BUILTIN_SIZEOF:
7ba86326 8667 return Type::lookup_integer_type("uintptr");
e440a328 8668
8669 case BUILTIN_CLOSE:
1cce762f 8670 case BUILTIN_DELETE:
e440a328 8671 case BUILTIN_PANIC:
8672 case BUILTIN_PRINT:
8673 case BUILTIN_PRINTLN:
8674 return Type::make_void_type();
8675
e440a328 8676 case BUILTIN_RECOVER:
823c7e3d 8677 return Type::make_empty_interface_type(Linemap::predeclared_location());
e440a328 8678
8679 case BUILTIN_APPEND:
8680 {
8681 const Expression_list* args = this->args();
8682 if (args == NULL || args->empty())
8683 return Type::make_error_type();
3ff4863b 8684 Type *ret = args->front()->type();
8685 if (!ret->is_slice_type())
8686 return Type::make_error_type();
8687 return ret;
e440a328 8688 }
8689
8690 case BUILTIN_REAL:
8691 case BUILTIN_IMAG:
8692 {
8693 Expression* arg = this->one_arg();
8694 if (arg == NULL)
8695 return Type::make_error_type();
8696 Type* t = arg->type();
8697 if (t->is_abstract())
8698 t = t->make_non_abstract_type();
8699 t = Builtin_call_expression::real_imag_type(t);
8700 if (t == NULL)
8701 t = Type::make_error_type();
8702 return t;
8703 }
8704
48080209 8705 case BUILTIN_COMPLEX:
e440a328 8706 {
8707 const Expression_list* args = this->args();
8708 if (args == NULL || args->size() != 2)
8709 return Type::make_error_type();
8710 Type* t = args->front()->type();
8711 if (t->is_abstract())
8712 {
8713 t = args->back()->type();
8714 if (t->is_abstract())
8715 t = t->make_non_abstract_type();
8716 }
48080209 8717 t = Builtin_call_expression::complex_type(t);
e440a328 8718 if (t == NULL)
8719 t = Type::make_error_type();
8720 return t;
8721 }
8722 }
8723}
8724
8725// Determine the type.
8726
8727void
8728Builtin_call_expression::do_determine_type(const Type_context* context)
8729{
fb94b0ca 8730 if (!this->determining_types())
8731 return;
8732
e440a328 8733 this->fn()->determine_type_no_context();
8734
8735 const Expression_list* args = this->args();
8736
8737 bool is_print;
8738 Type* arg_type = NULL;
321e5ad2 8739 Type* trailing_arg_types = NULL;
e440a328 8740 switch (this->code_)
8741 {
8742 case BUILTIN_PRINT:
8743 case BUILTIN_PRINTLN:
8744 // Do not force a large integer constant to "int".
8745 is_print = true;
8746 break;
8747
8748 case BUILTIN_REAL:
8749 case BUILTIN_IMAG:
48080209 8750 arg_type = Builtin_call_expression::complex_type(context->type);
f6bc81e6 8751 if (arg_type == NULL)
8752 arg_type = Type::lookup_complex_type("complex128");
e440a328 8753 is_print = false;
8754 break;
8755
48080209 8756 case BUILTIN_COMPLEX:
e440a328 8757 {
48080209 8758 // For the complex function the type of one operand can
e440a328 8759 // determine the type of the other, as in a binary expression.
8760 arg_type = Builtin_call_expression::real_imag_type(context->type);
f6bc81e6 8761 if (arg_type == NULL)
8762 arg_type = Type::lookup_float_type("float64");
e440a328 8763 if (args != NULL && args->size() == 2)
8764 {
8765 Type* t1 = args->front()->type();
c849bb59 8766 Type* t2 = args->back()->type();
e440a328 8767 if (!t1->is_abstract())
8768 arg_type = t1;
8769 else if (!t2->is_abstract())
8770 arg_type = t2;
8771 }
8772 is_print = false;
8773 }
8774 break;
8775
321e5ad2 8776 case BUILTIN_APPEND:
8777 if (!this->is_varargs()
8778 && args != NULL
8779 && !args->empty()
8780 && args->front()->type()->is_slice_type())
8781 trailing_arg_types =
8782 args->front()->type()->array_type()->element_type();
8783 is_print = false;
8784 break;
8785
e440a328 8786 default:
8787 is_print = false;
8788 break;
8789 }
8790
8791 if (args != NULL)
8792 {
8793 for (Expression_list::const_iterator pa = args->begin();
8794 pa != args->end();
8795 ++pa)
8796 {
8797 Type_context subcontext;
8798 subcontext.type = arg_type;
8799
8800 if (is_print)
8801 {
8802 // We want to print large constants, we so can't just
8803 // use the appropriate nonabstract type. Use uint64 for
8804 // an integer if we know it is nonnegative, otherwise
8805 // use int64 for a integer, otherwise use float64 for a
8806 // float or complex128 for a complex.
8807 Type* want_type = NULL;
8808 Type* atype = (*pa)->type();
8809 if (atype->is_abstract())
8810 {
8811 if (atype->integer_type() != NULL)
8812 {
0c77715b 8813 Numeric_constant nc;
8814 if (this->numeric_constant_value(&nc))
8815 {
8816 mpz_t val;
8817 if (nc.to_int(&val))
8818 {
8819 if (mpz_sgn(val) >= 0)
8820 want_type = Type::lookup_integer_type("uint64");
8821 mpz_clear(val);
8822 }
8823 }
8824 if (want_type == NULL)
e440a328 8825 want_type = Type::lookup_integer_type("int64");
e440a328 8826 }
8827 else if (atype->float_type() != NULL)
8828 want_type = Type::lookup_float_type("float64");
8829 else if (atype->complex_type() != NULL)
8830 want_type = Type::lookup_complex_type("complex128");
8831 else if (atype->is_abstract_string_type())
8832 want_type = Type::lookup_string_type();
8833 else if (atype->is_abstract_boolean_type())
8834 want_type = Type::lookup_bool_type();
8835 else
c3e6f413 8836 go_unreachable();
e440a328 8837 subcontext.type = want_type;
8838 }
8839 }
8840
8841 (*pa)->determine_type(&subcontext);
321e5ad2 8842
8843 if (trailing_arg_types != NULL)
8844 {
8845 arg_type = trailing_arg_types;
8846 trailing_arg_types = NULL;
8847 }
e440a328 8848 }
8849 }
8850}
8851
8852// If there is exactly one argument, return true. Otherwise give an
8853// error message and return false.
8854
8855bool
8856Builtin_call_expression::check_one_arg()
8857{
8858 const Expression_list* args = this->args();
8859 if (args == NULL || args->size() < 1)
8860 {
8861 this->report_error(_("not enough arguments"));
8862 return false;
8863 }
8864 else if (args->size() > 1)
8865 {
8866 this->report_error(_("too many arguments"));
8867 return false;
8868 }
8869 if (args->front()->is_error_expression()
5c13bd80 8870 || args->front()->type()->is_error())
e440a328 8871 {
8872 this->set_is_error();
8873 return false;
8874 }
8875 return true;
8876}
8877
8878// Check argument types for a builtin function.
8879
8880void
8881Builtin_call_expression::do_check_types(Gogo*)
8882{
375646ea 8883 if (this->is_error_expression())
8884 return;
e440a328 8885 switch (this->code_)
8886 {
8887 case BUILTIN_INVALID:
8888 case BUILTIN_NEW:
8889 case BUILTIN_MAKE:
cd238b8d 8890 case BUILTIN_DELETE:
e440a328 8891 return;
8892
8893 case BUILTIN_LEN:
8894 case BUILTIN_CAP:
8895 {
8896 // The single argument may be either a string or an array or a
8897 // map or a channel, or a pointer to a closed array.
8898 if (this->check_one_arg())
8899 {
8900 Type* arg_type = this->one_arg()->type();
8901 if (arg_type->points_to() != NULL
8902 && arg_type->points_to()->array_type() != NULL
411eb89e 8903 && !arg_type->points_to()->is_slice_type())
e440a328 8904 arg_type = arg_type->points_to();
8905 if (this->code_ == BUILTIN_CAP)
8906 {
5c13bd80 8907 if (!arg_type->is_error()
e440a328 8908 && arg_type->array_type() == NULL
8909 && arg_type->channel_type() == NULL)
8910 this->report_error(_("argument must be array or slice "
8911 "or channel"));
8912 }
8913 else
8914 {
5c13bd80 8915 if (!arg_type->is_error()
e440a328 8916 && !arg_type->is_string_type()
8917 && arg_type->array_type() == NULL
8918 && arg_type->map_type() == NULL
8919 && arg_type->channel_type() == NULL)
8920 this->report_error(_("argument must be string or "
8921 "array or slice or map or channel"));
8922 }
8923 }
8924 }
8925 break;
8926
8927 case BUILTIN_PRINT:
8928 case BUILTIN_PRINTLN:
8929 {
8930 const Expression_list* args = this->args();
8931 if (args == NULL)
8932 {
8933 if (this->code_ == BUILTIN_PRINT)
631d5788 8934 go_warning_at(this->location(), 0,
e440a328 8935 "no arguments for builtin function %<%s%>",
8936 (this->code_ == BUILTIN_PRINT
8937 ? "print"
8938 : "println"));
8939 }
8940 else
8941 {
8942 for (Expression_list::const_iterator p = args->begin();
8943 p != args->end();
8944 ++p)
8945 {
8946 Type* type = (*p)->type();
5c13bd80 8947 if (type->is_error()
e440a328 8948 || type->is_string_type()
8949 || type->integer_type() != NULL
8950 || type->float_type() != NULL
8951 || type->complex_type() != NULL
8952 || type->is_boolean_type()
8953 || type->points_to() != NULL
8954 || type->interface_type() != NULL
8955 || type->channel_type() != NULL
8956 || type->map_type() != NULL
8957 || type->function_type() != NULL
411eb89e 8958 || type->is_slice_type())
e440a328 8959 ;
acf8e158 8960 else if ((*p)->is_type_expression())
8961 {
8962 // If this is a type expression it's going to give
8963 // an error anyhow, so we don't need one here.
8964 }
e440a328 8965 else
8966 this->report_error(_("unsupported argument type to "
8967 "builtin function"));
8968 }
8969 }
8970 }
8971 break;
8972
8973 case BUILTIN_CLOSE:
e440a328 8974 if (this->check_one_arg())
8975 {
8976 if (this->one_arg()->type()->channel_type() == NULL)
8977 this->report_error(_("argument must be channel"));
5202d986 8978 else if (!this->one_arg()->type()->channel_type()->may_send())
8979 this->report_error(_("cannot close receive-only channel"));
e440a328 8980 }
8981 break;
8982
8983 case BUILTIN_PANIC:
8984 case BUILTIN_SIZEOF:
8985 case BUILTIN_ALIGNOF:
8986 this->check_one_arg();
8987 break;
8988
8989 case BUILTIN_RECOVER:
6334270b 8990 if (this->args() != NULL
8991 && !this->args()->empty()
8992 && !this->recover_arg_is_set_)
e440a328 8993 this->report_error(_("too many arguments"));
8994 break;
8995
8996 case BUILTIN_OFFSETOF:
8997 if (this->check_one_arg())
8998 {
8999 Expression* arg = this->one_arg();
9000 if (arg->field_reference_expression() == NULL)
9001 this->report_error(_("argument must be a field reference"));
9002 }
9003 break;
9004
9005 case BUILTIN_COPY:
9006 {
9007 const Expression_list* args = this->args();
9008 if (args == NULL || args->size() < 2)
9009 {
9010 this->report_error(_("not enough arguments"));
9011 break;
9012 }
9013 else if (args->size() > 2)
9014 {
9015 this->report_error(_("too many arguments"));
9016 break;
9017 }
9018 Type* arg1_type = args->front()->type();
9019 Type* arg2_type = args->back()->type();
5c13bd80 9020 if (arg1_type->is_error() || arg2_type->is_error())
6bebb39d 9021 {
9022 this->set_is_error();
9023 break;
9024 }
e440a328 9025
9026 Type* e1;
411eb89e 9027 if (arg1_type->is_slice_type())
e440a328 9028 e1 = arg1_type->array_type()->element_type();
9029 else
9030 {
9031 this->report_error(_("left argument must be a slice"));
9032 break;
9033 }
9034
411eb89e 9035 if (arg2_type->is_slice_type())
60963afd 9036 {
9037 Type* e2 = arg2_type->array_type()->element_type();
3a522dcc 9038 if (!Type::are_identical(e1, e2, Type::COMPARE_TAGS, NULL))
60963afd 9039 this->report_error(_("element types must be the same"));
9040 }
e440a328 9041 else if (arg2_type->is_string_type())
e440a328 9042 {
60963afd 9043 if (e1->integer_type() == NULL || !e1->integer_type()->is_byte())
9044 this->report_error(_("first argument must be []byte"));
e440a328 9045 }
60963afd 9046 else
9047 this->report_error(_("second argument must be slice or string"));
e440a328 9048 }
9049 break;
9050
9051 case BUILTIN_APPEND:
9052 {
9053 const Expression_list* args = this->args();
321e5ad2 9054 if (args == NULL || args->empty())
e440a328 9055 {
9056 this->report_error(_("not enough arguments"));
9057 break;
9058 }
321e5ad2 9059
9060 Type* slice_type = args->front()->type();
9061 if (!slice_type->is_slice_type())
6bebb39d 9062 {
321e5ad2 9063 if (slice_type->is_error_type())
9064 break;
9065 if (slice_type->is_nil_type())
9066 go_error_at(args->front()->location(), "use of untyped nil");
9067 else
9068 go_error_at(args->front()->location(),
9069 "argument 1 must be a slice");
6bebb39d 9070 this->set_is_error();
9071 break;
9072 }
cd238b8d 9073
321e5ad2 9074 Type* element_type = slice_type->array_type()->element_type();
22deed0d 9075 if (!element_type->in_heap())
9076 go_error_at(args->front()->location(),
9077 "can't append to slice of go:notinheap type");
321e5ad2 9078 if (this->is_varargs())
4fd4fcf4 9079 {
321e5ad2 9080 if (!args->back()->type()->is_slice_type()
9081 && !args->back()->type()->is_string_type())
9082 {
9083 go_error_at(args->back()->location(),
9084 "invalid use of %<...%> with non-slice/non-string");
9085 this->set_is_error();
9086 break;
9087 }
4fd4fcf4 9088
321e5ad2 9089 if (args->size() < 2)
9090 {
9091 this->report_error(_("not enough arguments"));
9092 break;
9093 }
9094 if (args->size() > 2)
9095 {
9096 this->report_error(_("too many arguments"));
9097 break;
9098 }
9099
9100 if (args->back()->type()->is_string_type()
9101 && element_type->integer_type() != NULL
9102 && element_type->integer_type()->is_byte())
9103 {
9104 // Permit append(s1, s2...) when s1 is a slice of
9105 // bytes and s2 is a string type.
9106 }
e440a328 9107 else
9108 {
321e5ad2 9109 // We have to test for assignment compatibility to a
9110 // slice of the element type, which is not necessarily
9111 // the same as the type of the first argument: the
9112 // first argument might have a named type.
9113 Type* check_type = Type::make_array_type(element_type, NULL);
9114 std::string reason;
9115 if (!Type::are_assignable(check_type, args->back()->type(),
9116 &reason))
9117 {
9118 if (reason.empty())
9119 go_error_at(args->back()->location(),
9120 "argument 2 has invalid type");
9121 else
9122 go_error_at(args->back()->location(),
9123 "argument 2 has invalid type (%s)",
9124 reason.c_str());
9125 this->set_is_error();
9126 break;
9127 }
9128 }
9129 }
9130 else
9131 {
9132 Expression_list::const_iterator pa = args->begin();
9133 int i = 2;
9134 for (++pa; pa != args->end(); ++pa, ++i)
9135 {
9136 std::string reason;
9137 if (!Type::are_assignable(element_type, (*pa)->type(),
9138 &reason))
9139 {
9140 if (reason.empty())
9141 go_error_at((*pa)->location(),
9142 "argument %d has incompatible type", i);
9143 else
9144 go_error_at((*pa)->location(),
9145 "argument %d has incompatible type (%s)",
9146 i, reason.c_str());
9147 this->set_is_error();
9148 }
e440a328 9149 }
9150 }
e440a328 9151 }
321e5ad2 9152 break;
e440a328 9153
9154 case BUILTIN_REAL:
9155 case BUILTIN_IMAG:
9156 if (this->check_one_arg())
9157 {
9158 if (this->one_arg()->type()->complex_type() == NULL)
9159 this->report_error(_("argument must have complex type"));
9160 }
9161 break;
9162
48080209 9163 case BUILTIN_COMPLEX:
e440a328 9164 {
9165 const Expression_list* args = this->args();
9166 if (args == NULL || args->size() < 2)
9167 this->report_error(_("not enough arguments"));
9168 else if (args->size() > 2)
9169 this->report_error(_("too many arguments"));
9170 else if (args->front()->is_error_expression()
5c13bd80 9171 || args->front()->type()->is_error()
e440a328 9172 || args->back()->is_error_expression()
5c13bd80 9173 || args->back()->type()->is_error())
e440a328 9174 this->set_is_error();
9175 else if (!Type::are_identical(args->front()->type(),
3a522dcc 9176 args->back()->type(),
9177 Type::COMPARE_TAGS, NULL))
48080209 9178 this->report_error(_("complex arguments must have identical types"));
e440a328 9179 else if (args->front()->type()->float_type() == NULL)
48080209 9180 this->report_error(_("complex arguments must have "
e440a328 9181 "floating-point type"));
9182 }
9183 break;
9184
9185 default:
c3e6f413 9186 go_unreachable();
e440a328 9187 }
9188}
9189
72666aed 9190Expression*
9191Builtin_call_expression::do_copy()
9192{
9193 Call_expression* bce =
9194 new Builtin_call_expression(this->gogo_, this->fn()->copy(),
da244e59 9195 (this->args() == NULL
9196 ? NULL
9197 : this->args()->copy()),
72666aed 9198 this->is_varargs(),
9199 this->location());
9200
9201 if (this->varargs_are_lowered())
9202 bce->set_varargs_are_lowered();
28819633 9203 if (this->is_deferred())
9204 bce->set_is_deferred();
9205 if (this->is_concurrent())
9206 bce->set_is_concurrent();
72666aed 9207 return bce;
9208}
9209
ea664253 9210// Return the backend representation for a builtin function.
e440a328 9211
ea664253 9212Bexpression*
9213Builtin_call_expression::do_get_backend(Translate_context* context)
e440a328 9214{
9215 Gogo* gogo = context->gogo();
b13c66cd 9216 Location location = this->location();
a0d8874e 9217
9218 if (this->is_erroneous_call())
9219 {
9220 go_assert(saw_errors());
9221 return gogo->backend()->error_expression();
9222 }
9223
e440a328 9224 switch (this->code_)
9225 {
9226 case BUILTIN_INVALID:
9227 case BUILTIN_NEW:
9228 case BUILTIN_MAKE:
c3e6f413 9229 go_unreachable();
e440a328 9230
9231 case BUILTIN_LEN:
9232 case BUILTIN_CAP:
9233 {
9234 const Expression_list* args = this->args();
c484d925 9235 go_assert(args != NULL && args->size() == 1);
2c809f8f 9236 Expression* arg = args->front();
e440a328 9237 Type* arg_type = arg->type();
0f914071 9238
9239 if (this->seen_)
9240 {
c484d925 9241 go_assert(saw_errors());
ea664253 9242 return context->backend()->error_expression();
0f914071 9243 }
9244 this->seen_ = true;
0f914071 9245 this->seen_ = false;
e440a328 9246 if (arg_type->points_to() != NULL)
9247 {
9248 arg_type = arg_type->points_to();
c484d925 9249 go_assert(arg_type->array_type() != NULL
411eb89e 9250 && !arg_type->is_slice_type());
f614ea8b 9251 arg = Expression::make_dereference(arg, NIL_CHECK_DEFAULT,
9252 location);
e440a328 9253 }
9254
1b1f2abf 9255 Type* int_type = Type::lookup_integer_type("int");
2c809f8f 9256 Expression* val;
e440a328 9257 if (this->code_ == BUILTIN_LEN)
9258 {
9259 if (arg_type->is_string_type())
2c809f8f 9260 val = Expression::make_string_info(arg, STRING_INFO_LENGTH,
9261 location);
e440a328 9262 else if (arg_type->array_type() != NULL)
0f914071 9263 {
9264 if (this->seen_)
9265 {
c484d925 9266 go_assert(saw_errors());
ea664253 9267 return context->backend()->error_expression();
0f914071 9268 }
9269 this->seen_ = true;
2c809f8f 9270 val = arg_type->array_type()->get_length(gogo, arg);
0f914071 9271 this->seen_ = false;
9272 }
0d5530d9 9273 else if (arg_type->map_type() != NULL
9274 || arg_type->channel_type() != NULL)
9275 {
9276 // The first field is the length. If the pointer is
9277 // nil, the length is zero.
9278 Type* pint_type = Type::make_pointer_type(int_type);
9279 arg = Expression::make_unsafe_cast(pint_type, arg, location);
9280 Expression* nil = Expression::make_nil(location);
9281 nil = Expression::make_cast(pint_type, nil, location);
9282 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
9283 arg, nil, location);
9284 Expression* zero = Expression::make_integer_ul(0, int_type,
9285 location);
f614ea8b 9286 Expression* indir =
9287 Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED,
9288 location);
0d5530d9 9289 val = Expression::make_conditional(cmp, zero, indir, location);
9290 }
e440a328 9291 else
c3e6f413 9292 go_unreachable();
e440a328 9293 }
9294 else
9295 {
9296 if (arg_type->array_type() != NULL)
0f914071 9297 {
9298 if (this->seen_)
9299 {
c484d925 9300 go_assert(saw_errors());
ea664253 9301 return context->backend()->error_expression();
0f914071 9302 }
9303 this->seen_ = true;
2c809f8f 9304 val = arg_type->array_type()->get_capacity(gogo, arg);
0f914071 9305 this->seen_ = false;
9306 }
e440a328 9307 else if (arg_type->channel_type() != NULL)
132ed071 9308 {
9309 // The second field is the capacity. If the pointer
9310 // is nil, the capacity is zero.
9311 Type* uintptr_type = Type::lookup_integer_type("uintptr");
9312 Type* pint_type = Type::make_pointer_type(int_type);
9313 Expression* parg = Expression::make_unsafe_cast(uintptr_type,
9314 arg,
9315 location);
9316 int off = int_type->integer_type()->bits() / 8;
9317 Expression* eoff = Expression::make_integer_ul(off,
9318 uintptr_type,
9319 location);
9320 parg = Expression::make_binary(OPERATOR_PLUS, parg, eoff,
9321 location);
9322 parg = Expression::make_unsafe_cast(pint_type, parg, location);
9323 Expression* nil = Expression::make_nil(location);
9324 nil = Expression::make_cast(pint_type, nil, location);
9325 Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
9326 arg, nil, location);
9327 Expression* zero = Expression::make_integer_ul(0, int_type,
9328 location);
f614ea8b 9329 Expression* indir =
9330 Expression::make_dereference(parg, NIL_CHECK_NOT_NEEDED,
9331 location);
132ed071 9332 val = Expression::make_conditional(cmp, zero, indir, location);
9333 }
e440a328 9334 else
c3e6f413 9335 go_unreachable();
e440a328 9336 }
9337
2c809f8f 9338 return Expression::make_cast(int_type, val,
ea664253 9339 location)->get_backend(context);
e440a328 9340 }
9341
9342 case BUILTIN_PRINT:
9343 case BUILTIN_PRINTLN:
9344 {
9345 const bool is_ln = this->code_ == BUILTIN_PRINTLN;
88b03a70 9346
9347 Expression* print_stmts = Runtime::make_call(Runtime::PRINTLOCK,
9348 location, 0);
e440a328 9349
9350 const Expression_list* call_args = this->args();
9351 if (call_args != NULL)
9352 {
9353 for (Expression_list::const_iterator p = call_args->begin();
9354 p != call_args->end();
9355 ++p)
9356 {
9357 if (is_ln && p != call_args->begin())
9358 {
2c809f8f 9359 Expression* print_space =
88b03a70 9360 Runtime::make_call(Runtime::PRINTSP, location, 0);
e440a328 9361
2c809f8f 9362 print_stmts =
9363 Expression::make_compound(print_stmts, print_space,
9364 location);
9365 }
e440a328 9366
2c809f8f 9367 Expression* arg = *p;
9368 Type* type = arg->type();
9369 Runtime::Function code;
e440a328 9370 if (type->is_string_type())
88b03a70 9371 code = Runtime::PRINTSTRING;
e440a328 9372 else if (type->integer_type() != NULL
9373 && type->integer_type()->is_unsigned())
9374 {
e440a328 9375 Type* itype = Type::lookup_integer_type("uint64");
2c809f8f 9376 arg = Expression::make_cast(itype, arg, location);
88b03a70 9377 code = Runtime::PRINTUINT;
e440a328 9378 }
9379 else if (type->integer_type() != NULL)
9380 {
e440a328 9381 Type* itype = Type::lookup_integer_type("int64");
2c809f8f 9382 arg = Expression::make_cast(itype, arg, location);
88b03a70 9383 code = Runtime::PRINTINT;
e440a328 9384 }
9385 else if (type->float_type() != NULL)
9386 {
2c809f8f 9387 Type* dtype = Type::lookup_float_type("float64");
9388 arg = Expression::make_cast(dtype, arg, location);
88b03a70 9389 code = Runtime::PRINTFLOAT;
e440a328 9390 }
9391 else if (type->complex_type() != NULL)
9392 {
2c809f8f 9393 Type* ctype = Type::lookup_complex_type("complex128");
9394 arg = Expression::make_cast(ctype, arg, location);
88b03a70 9395 code = Runtime::PRINTCOMPLEX;
e440a328 9396 }
9397 else if (type->is_boolean_type())
88b03a70 9398 code = Runtime::PRINTBOOL;
e440a328 9399 else if (type->points_to() != NULL
9400 || type->channel_type() != NULL
9401 || type->map_type() != NULL
9402 || type->function_type() != NULL)
9403 {
2c809f8f 9404 arg = Expression::make_cast(type, arg, location);
88b03a70 9405 code = Runtime::PRINTPOINTER;
e440a328 9406 }
9407 else if (type->interface_type() != NULL)
9408 {
9409 if (type->interface_type()->is_empty())
88b03a70 9410 code = Runtime::PRINTEFACE;
e440a328 9411 else
88b03a70 9412 code = Runtime::PRINTIFACE;
e440a328 9413 }
411eb89e 9414 else if (type->is_slice_type())
88b03a70 9415 code = Runtime::PRINTSLICE;
e440a328 9416 else
cd238b8d 9417 {
9418 go_assert(saw_errors());
ea664253 9419 return context->backend()->error_expression();
cd238b8d 9420 }
e440a328 9421
2c809f8f 9422 Expression* call = Runtime::make_call(code, location, 1, arg);
88b03a70 9423 print_stmts = Expression::make_compound(print_stmts, call,
9424 location);
e440a328 9425 }
9426 }
9427
9428 if (is_ln)
9429 {
2c809f8f 9430 Expression* print_nl =
88b03a70 9431 Runtime::make_call(Runtime::PRINTNL, location, 0);
9432 print_stmts = Expression::make_compound(print_stmts, print_nl,
9433 location);
e440a328 9434 }
9435
88b03a70 9436 Expression* unlock = Runtime::make_call(Runtime::PRINTUNLOCK,
9437 location, 0);
9438 print_stmts = Expression::make_compound(print_stmts, unlock, location);
32e3ff69 9439
ea664253 9440 return print_stmts->get_backend(context);
e440a328 9441 }
9442
9443 case BUILTIN_PANIC:
9444 {
9445 const Expression_list* args = this->args();
c484d925 9446 go_assert(args != NULL && args->size() == 1);
e440a328 9447 Expression* arg = args->front();
b13c66cd 9448 Type *empty =
823c7e3d 9449 Type::make_empty_interface_type(Linemap::predeclared_location());
2c809f8f 9450 arg = Expression::convert_for_assignment(gogo, empty, arg, location);
9451
9452 Expression* panic =
03ac9de4 9453 Runtime::make_call(Runtime::GOPANIC, location, 1, arg);
ea664253 9454 return panic->get_backend(context);
e440a328 9455 }
9456
9457 case BUILTIN_RECOVER:
9458 {
9459 // The argument is set when building recover thunks. It's a
9460 // boolean value which is true if we can recover a value now.
9461 const Expression_list* args = this->args();
c484d925 9462 go_assert(args != NULL && args->size() == 1);
e440a328 9463 Expression* arg = args->front();
b13c66cd 9464 Type *empty =
823c7e3d 9465 Type::make_empty_interface_type(Linemap::predeclared_location());
e440a328 9466
e440a328 9467 Expression* nil = Expression::make_nil(location);
2c809f8f 9468 nil = Expression::convert_for_assignment(gogo, empty, nil, location);
e440a328 9469
9470 // We need to handle a deferred call to recover specially,
9471 // because it changes whether it can recover a panic or not.
9472 // See test7 in test/recover1.go.
2c809f8f 9473 Expression* recover = Runtime::make_call((this->is_deferred()
03ac9de4 9474 ? Runtime::DEFERREDRECOVER
9475 : Runtime::GORECOVER),
2c809f8f 9476 location, 0);
9477 Expression* cond =
9478 Expression::make_conditional(arg, recover, nil, location);
ea664253 9479 return cond->get_backend(context);
e440a328 9480 }
9481
9482 case BUILTIN_CLOSE:
e440a328 9483 {
9484 const Expression_list* args = this->args();
c484d925 9485 go_assert(args != NULL && args->size() == 1);
e440a328 9486 Expression* arg = args->front();
2c809f8f 9487 Expression* close = Runtime::make_call(Runtime::CLOSE, location,
9488 1, arg);
ea664253 9489 return close->get_backend(context);
e440a328 9490 }
9491
9492 case BUILTIN_SIZEOF:
9493 case BUILTIN_OFFSETOF:
9494 case BUILTIN_ALIGNOF:
9495 {
0c77715b 9496 Numeric_constant nc;
9497 unsigned long val;
9498 if (!this->numeric_constant_value(&nc)
9499 || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
7f1d9abd 9500 {
c484d925 9501 go_assert(saw_errors());
ea664253 9502 return context->backend()->error_expression();
7f1d9abd 9503 }
7ba86326 9504 Type* uintptr_type = Type::lookup_integer_type("uintptr");
2c809f8f 9505 mpz_t ival;
9506 nc.get_int(&ival);
9507 Expression* int_cst =
e67508fa 9508 Expression::make_integer_z(&ival, uintptr_type, location);
2c809f8f 9509 mpz_clear(ival);
ea664253 9510 return int_cst->get_backend(context);
e440a328 9511 }
9512
9513 case BUILTIN_COPY:
9514 {
9515 const Expression_list* args = this->args();
c484d925 9516 go_assert(args != NULL && args->size() == 2);
e440a328 9517 Expression* arg1 = args->front();
9518 Expression* arg2 = args->back();
9519
e440a328 9520 Type* arg1_type = arg1->type();
9521 Array_type* at = arg1_type->array_type();
35a54f17 9522 go_assert(arg1->is_variable());
321e5ad2 9523
9524 Expression* call;
e440a328 9525
9526 Type* arg2_type = arg2->type();
2c809f8f 9527 go_assert(arg2->is_variable());
321e5ad2 9528 if (arg2_type->is_string_type())
9529 call = Runtime::make_call(Runtime::SLICESTRINGCOPY, location,
9530 2, arg1, arg2);
e440a328 9531 else
9532 {
321e5ad2 9533 Type* et = at->element_type();
9534 if (et->has_pointer())
9535 {
9536 Expression* td = Expression::make_type_descriptor(et,
9537 location);
9538 call = Runtime::make_call(Runtime::TYPEDSLICECOPY, location,
9539 3, td, arg1, arg2);
9540 }
9541 else
9542 {
9543 Expression* sz = Expression::make_type_info(et,
9544 TYPE_INFO_SIZE);
9545 call = Runtime::make_call(Runtime::SLICECOPY, location, 3,
9546 arg1, arg2, sz);
9547 }
e440a328 9548 }
2c809f8f 9549
321e5ad2 9550 return call->get_backend(context);
e440a328 9551 }
9552
9553 case BUILTIN_APPEND:
321e5ad2 9554 // Handled in Builtin_call_expression::flatten_append.
9555 go_unreachable();
e440a328 9556
9557 case BUILTIN_REAL:
9558 case BUILTIN_IMAG:
9559 {
9560 const Expression_list* args = this->args();
c484d925 9561 go_assert(args != NULL && args->size() == 1);
2c809f8f 9562
9563 Bexpression* ret;
ea664253 9564 Bexpression* bcomplex = args->front()->get_backend(context);
2c809f8f 9565 if (this->code_ == BUILTIN_REAL)
9566 ret = gogo->backend()->real_part_expression(bcomplex, location);
9567 else
9568 ret = gogo->backend()->imag_part_expression(bcomplex, location);
ea664253 9569 return ret;
e440a328 9570 }
9571
48080209 9572 case BUILTIN_COMPLEX:
e440a328 9573 {
9574 const Expression_list* args = this->args();
c484d925 9575 go_assert(args != NULL && args->size() == 2);
ea664253 9576 Bexpression* breal = args->front()->get_backend(context);
9577 Bexpression* bimag = args->back()->get_backend(context);
9578 return gogo->backend()->complex_expression(breal, bimag, location);
e440a328 9579 }
9580
9581 default:
c3e6f413 9582 go_unreachable();
e440a328 9583 }
9584}
9585
9586// We have to support exporting a builtin call expression, because
9587// code can set a constant to the result of a builtin expression.
9588
9589void
548be246 9590Builtin_call_expression::do_export(Export_function_body* efb) const
e440a328 9591{
0c77715b 9592 Numeric_constant nc;
9593 if (!this->numeric_constant_value(&nc))
9594 {
631d5788 9595 go_error_at(this->location(), "value is not constant");
0c77715b 9596 return;
9597 }
e440a328 9598
0c77715b 9599 if (nc.is_int())
e440a328 9600 {
0c77715b 9601 mpz_t val;
9602 nc.get_int(&val);
548be246 9603 Integer_expression::export_integer(efb, val);
0c77715b 9604 mpz_clear(val);
e440a328 9605 }
0c77715b 9606 else if (nc.is_float())
e440a328 9607 {
9608 mpfr_t fval;
0c77715b 9609 nc.get_float(&fval);
548be246 9610 Float_expression::export_float(efb, fval);
e440a328 9611 mpfr_clear(fval);
9612 }
0c77715b 9613 else if (nc.is_complex())
e440a328 9614 {
fcbea5e4 9615 mpc_t cval;
9616 nc.get_complex(&cval);
548be246 9617 Complex_expression::export_complex(efb, cval);
fcbea5e4 9618 mpc_clear(cval);
e440a328 9619 }
0c77715b 9620 else
9621 go_unreachable();
e440a328 9622
9623 // A trailing space lets us reliably identify the end of the number.
548be246 9624 efb->write_c_string(" ");
e440a328 9625}
9626
9627// Class Call_expression.
9628
8381eda7 9629// A Go function can be viewed in a couple of different ways. The
9630// code of a Go function becomes a backend function with parameters
9631// whose types are simply the backend representation of the Go types.
9632// If there are multiple results, they are returned as a backend
9633// struct.
9634
9635// However, when Go code refers to a function other than simply
9636// calling it, the backend type of that function is actually a struct.
9637// The first field of the struct points to the Go function code
9638// (sometimes a wrapper as described below). The remaining fields
9639// hold addresses of closed-over variables. This struct is called a
9640// closure.
9641
9642// There are a few cases to consider.
9643
9644// A direct function call of a known function in package scope. In
9645// this case there are no closed-over variables, and we know the name
9646// of the function code. We can simply produce a backend call to the
9647// function directly, and not worry about the closure.
9648
9649// A direct function call of a known function literal. In this case
9650// we know the function code and we know the closure. We generate the
9651// function code such that it expects an additional final argument of
9652// the closure type. We pass the closure as the last argument, after
9653// the other arguments.
9654
9655// An indirect function call. In this case we have a closure. We
9656// load the pointer to the function code from the first field of the
9657// closure. We pass the address of the closure as the last argument.
9658
9659// A call to a method of an interface. Type methods are always at
9660// package scope, so we call the function directly, and don't worry
9661// about the closure.
9662
9663// This means that for a function at package scope we have two cases.
9664// One is the direct call, which has no closure. The other is the
9665// indirect call, which does have a closure. We can't simply ignore
9666// the closure, even though it is the last argument, because that will
9667// fail on targets where the function pops its arguments. So when
9668// generating a closure for a package-scope function we set the
9669// function code pointer in the closure to point to a wrapper
9670// function. This wrapper function accepts a final argument that
9671// points to the closure, ignores it, and calls the real function as a
9672// direct function call. This wrapper will normally be efficient, and
9673// can often simply be a tail call to the real function.
9674
9675// We don't use GCC's static chain pointer because 1) we don't need
9676// it; 2) GCC only permits using a static chain to call a known
9677// function, so we can't use it for an indirect call anyhow. Since we
9678// can't use it for an indirect call, we may as well not worry about
9679// using it for a direct call either.
9680
9681// We pass the closure last rather than first because it means that
9682// the function wrapper we put into a closure for a package-scope
9683// function can normally just be a tail call to the real function.
9684
9685// For method expressions we generate a wrapper that loads the
9686// receiver from the closure and then calls the method. This
9687// unfortunately forces reshuffling the arguments, since there is a
9688// new first argument, but we can't avoid reshuffling either for
9689// method expressions or for indirect calls of package-scope
9690// functions, and since the latter are more common we reshuffle for
9691// method expressions.
9692
9693// Note that the Go code retains the Go types. The extra final
9694// argument only appears when we convert to the backend
9695// representation.
9696
e440a328 9697// Traversal.
9698
9699int
9700Call_expression::do_traverse(Traverse* traverse)
9701{
0c0dacab 9702 // If we are calling a function in a different package that returns
9703 // an unnamed type, this may be the only chance we get to traverse
9704 // that type. We don't traverse this->type_ because it may be a
9705 // Call_multiple_result_type that will just lead back here.
9706 if (this->type_ != NULL && !this->type_->is_error_type())
9707 {
9708 Function_type *fntype = this->get_function_type();
9709 if (fntype != NULL && Type::traverse(fntype, traverse) == TRAVERSE_EXIT)
9710 return TRAVERSE_EXIT;
9711 }
e440a328 9712 if (Expression::traverse(&this->fn_, traverse) == TRAVERSE_EXIT)
9713 return TRAVERSE_EXIT;
9714 if (this->args_ != NULL)
9715 {
9716 if (this->args_->traverse(traverse) == TRAVERSE_EXIT)
9717 return TRAVERSE_EXIT;
9718 }
9719 return TRAVERSE_CONTINUE;
9720}
9721
9722// Lower a call statement.
9723
9724Expression*
ceeb4318 9725Call_expression::do_lower(Gogo* gogo, Named_object* function,
9726 Statement_inserter* inserter, int)
e440a328 9727{
b13c66cd 9728 Location loc = this->location();
09ea332d 9729
ceeb4318 9730 // A type cast can look like a function call.
e440a328 9731 if (this->fn_->is_type_expression()
9732 && this->args_ != NULL
9733 && this->args_->size() == 1)
9734 return Expression::make_cast(this->fn_->type(), this->args_->front(),
09ea332d 9735 loc);
e440a328 9736
88f06749 9737 // Because do_type will return an error type and thus prevent future
9738 // errors, check for that case now to ensure that the error gets
9739 // reported.
37448b10 9740 Function_type* fntype = this->get_function_type();
9741 if (fntype == NULL)
88f06749 9742 {
9743 if (!this->fn_->type()->is_error())
9744 this->report_error(_("expected function"));
5f1045b5 9745 this->set_is_error();
9746 return this;
88f06749 9747 }
9748
e440a328 9749 // Handle an argument which is a call to a function which returns
9750 // multiple results.
9751 if (this->args_ != NULL
9752 && this->args_->size() == 1
37448b10 9753 && this->args_->front()->call_expression() != NULL)
e440a328 9754 {
e440a328 9755 size_t rc = this->args_->front()->call_expression()->result_count();
9756 if (rc > 1
37448b10 9757 && ((fntype->parameters() != NULL
9758 && (fntype->parameters()->size() == rc
9759 || (fntype->is_varargs()
9760 && fntype->parameters()->size() - 1 <= rc)))
9761 || fntype->is_builtin()))
e440a328 9762 {
9763 Call_expression* call = this->args_->front()->call_expression();
e90ecd2d 9764 call->set_is_multi_value_arg();
c33af8e4 9765 if (this->is_varargs_)
9766 {
9767 // It is not clear which result of a multiple result call
9768 // the ellipsis operator should be applied to. If we unpack the
9769 // the call into its individual results here, the ellipsis will be
9770 // applied to the last result.
631d5788 9771 go_error_at(call->location(),
9772 _("multiple-value argument in single-value context"));
c33af8e4 9773 return Expression::make_error(call->location());
9774 }
9775
e440a328 9776 Expression_list* args = new Expression_list;
9777 for (size_t i = 0; i < rc; ++i)
9778 args->push_back(Expression::make_call_result(call, i));
9779 // We can't return a new call expression here, because this
42535814 9780 // one may be referenced by Call_result expressions. We
9781 // also can't delete the old arguments, because we may still
9782 // traverse them somewhere up the call stack. FIXME.
e440a328 9783 this->args_ = args;
9784 }
9785 }
9786
37448b10 9787 // Recognize a call to a builtin function.
9788 if (fntype->is_builtin())
28819633 9789 {
9790 Builtin_call_expression* bce =
9791 new Builtin_call_expression(gogo, this->fn_, this->args_,
9792 this->is_varargs_, loc);
9793 if (this->is_deferred_)
9794 bce->set_is_deferred();
9795 if (this->is_concurrent_)
9796 bce->set_is_concurrent();
9797 return bce;
9798 }
37448b10 9799
ceeb4318 9800 // If this call returns multiple results, create a temporary
5731103c 9801 // variable to hold them.
9802 if (this->result_count() > 1 && this->call_temp_ == NULL)
ceeb4318 9803 {
5731103c 9804 Struct_field_list* sfl = new Struct_field_list();
9805 Function_type* fntype = this->get_function_type();
37448b10 9806 const Typed_identifier_list* results = fntype->results();
5731103c 9807 Location loc = this->location();
9808
9809 int i = 0;
9810 char buf[20];
ceeb4318 9811 for (Typed_identifier_list::const_iterator p = results->begin();
5731103c 9812 p != results->end();
9813 ++p, ++i)
9814 {
9815 snprintf(buf, sizeof buf, "res%d", i);
9816 sfl->push_back(Struct_field(Typed_identifier(buf, p->type(), loc)));
9817 }
9818
9819 Struct_type* st = Type::make_struct_type(sfl, loc);
9820 st->set_is_struct_incomparable();
9821 this->call_temp_ = Statement::make_temporary(st, NULL, loc);
9822 inserter->insert(this->call_temp_);
ceeb4318 9823 }
9824
e440a328 9825 // Handle a call to a varargs function by packaging up the extra
9826 // parameters.
37448b10 9827 if (fntype->is_varargs())
e440a328 9828 {
e440a328 9829 const Typed_identifier_list* parameters = fntype->parameters();
c484d925 9830 go_assert(parameters != NULL && !parameters->empty());
e440a328 9831 Type* varargs_type = parameters->back().type();
09ea332d 9832 this->lower_varargs(gogo, function, inserter, varargs_type,
0e9a2e72 9833 parameters->size(), SLICE_STORAGE_MAY_ESCAPE);
09ea332d 9834 }
9835
9836 // If this is call to a method, call the method directly passing the
9837 // object as the first parameter.
9838 Bound_method_expression* bme = this->fn_->bound_method_expression();
9839 if (bme != NULL)
9840 {
0afbb937 9841 Named_object* methodfn = bme->function();
09ea332d 9842 Expression* first_arg = bme->first_argument();
9843
9844 // We always pass a pointer when calling a method.
9845 if (first_arg->type()->points_to() == NULL
9846 && !first_arg->type()->is_error())
9847 {
9848 first_arg = Expression::make_unary(OPERATOR_AND, first_arg, loc);
9849 // We may need to create a temporary variable so that we can
9850 // take the address. We can't do that here because it will
9851 // mess up the order of evaluation.
9852 Unary_expression* ue = static_cast<Unary_expression*>(first_arg);
9853 ue->set_create_temp();
9854 }
9855
9856 // If we are calling a method which was inherited from an
9857 // embedded struct, and the method did not get a stub, then the
9858 // first type may be wrong.
9859 Type* fatype = bme->first_argument_type();
9860 if (fatype != NULL)
9861 {
9862 if (fatype->points_to() == NULL)
9863 fatype = Type::make_pointer_type(fatype);
9864 first_arg = Expression::make_unsafe_cast(fatype, first_arg, loc);
9865 }
9866
9867 Expression_list* new_args = new Expression_list();
9868 new_args->push_back(first_arg);
9869 if (this->args_ != NULL)
9870 {
9871 for (Expression_list::const_iterator p = this->args_->begin();
9872 p != this->args_->end();
9873 ++p)
9874 new_args->push_back(*p);
9875 }
9876
9877 // We have to change in place because this structure may be
9878 // referenced by Call_result_expressions. We can't delete the
9879 // old arguments, because we may be traversing them up in some
9880 // caller. FIXME.
9881 this->args_ = new_args;
0afbb937 9882 this->fn_ = Expression::make_func_reference(methodfn, NULL,
09ea332d 9883 bme->location());
e440a328 9884 }
9885
105f9a24 9886 // Handle a couple of special runtime functions. In the runtime
9887 // package, getcallerpc returns the PC of the caller, and
9888 // getcallersp returns the frame pointer of the caller. Implement
9889 // these by turning them into calls to GCC builtin functions. We
9890 // could implement them in normal code, but then we would have to
9891 // explicitly unwind the stack. These functions are intended to be
9892 // efficient. Note that this technique obviously only works for
33d1d391 9893 // direct calls, but that is the only way they are used.
9894 if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
105f9a24 9895 {
9896 Func_expression* fe = this->fn_->func_expression();
9897 if (fe != NULL
9898 && fe->named_object()->is_function_declaration()
9899 && fe->named_object()->package() == NULL)
9900 {
9901 std::string n = Gogo::unpack_hidden_name(fe->named_object()->name());
33d1d391 9902 if ((this->args_ == NULL || this->args_->size() == 0)
9903 && n == "getcallerpc")
105f9a24 9904 {
9905 static Named_object* builtin_return_address;
9a8c5dc0 9906 int arg = 0;
105f9a24 9907 return this->lower_to_builtin(&builtin_return_address,
9908 "__builtin_return_address",
9a8c5dc0 9909 &arg);
105f9a24 9910 }
b5665f52 9911 else if ((this->args_ == NULL || this->args_->size() == 0)
33d1d391 9912 && n == "getcallersp")
105f9a24 9913 {
9a8c5dc0 9914 static Named_object* builtin_dwarf_cfa;
9915 return this->lower_to_builtin(&builtin_dwarf_cfa,
9916 "__builtin_dwarf_cfa",
9917 NULL);
105f9a24 9918 }
9919 }
9920 }
9921
81affb1d 9922 // If this is a call to an imported function for which we have an
9923 // inlinable function body, add it to the list of functions to give
9924 // to the backend as inlining opportunities.
9925 Func_expression* fe = this->fn_->func_expression();
9926 if (fe != NULL
9927 && fe->named_object()->is_function_declaration()
9928 && fe->named_object()->func_declaration_value()->has_imported_body())
9929 gogo->add_imported_inlinable_function(fe->named_object());
9930
e440a328 9931 return this;
9932}
9933
9934// Lower a call to a varargs function. FUNCTION is the function in
9935// which the call occurs--it's not the function we are calling.
9936// VARARGS_TYPE is the type of the varargs parameter, a slice type.
9937// PARAM_COUNT is the number of parameters of the function we are
9938// calling; the last of these parameters will be the varargs
9939// parameter.
9940
09ea332d 9941void
e440a328 9942Call_expression::lower_varargs(Gogo* gogo, Named_object* function,
ceeb4318 9943 Statement_inserter* inserter,
0e9a2e72 9944 Type* varargs_type, size_t param_count,
9945 Slice_storage_escape_disp escape_disp)
e440a328 9946{
9947 if (this->varargs_are_lowered_)
09ea332d 9948 return;
e440a328 9949
b13c66cd 9950 Location loc = this->location();
e440a328 9951
c484d925 9952 go_assert(param_count > 0);
411eb89e 9953 go_assert(varargs_type->is_slice_type());
e440a328 9954
9955 size_t arg_count = this->args_ == NULL ? 0 : this->args_->size();
9956 if (arg_count < param_count - 1)
9957 {
9958 // Not enough arguments; will be caught in check_types.
09ea332d 9959 return;
e440a328 9960 }
9961
9962 Expression_list* old_args = this->args_;
9963 Expression_list* new_args = new Expression_list();
9964 bool push_empty_arg = false;
9965 if (old_args == NULL || old_args->empty())
9966 {
c484d925 9967 go_assert(param_count == 1);
e440a328 9968 push_empty_arg = true;
9969 }
9970 else
9971 {
9972 Expression_list::const_iterator pa;
9973 int i = 1;
9974 for (pa = old_args->begin(); pa != old_args->end(); ++pa, ++i)
9975 {
9976 if (static_cast<size_t>(i) == param_count)
9977 break;
9978 new_args->push_back(*pa);
9979 }
9980
9981 // We have reached the varargs parameter.
9982
9983 bool issued_error = false;
9984 if (pa == old_args->end())
9985 push_empty_arg = true;
9986 else if (pa + 1 == old_args->end() && this->is_varargs_)
9987 new_args->push_back(*pa);
9988 else if (this->is_varargs_)
9989 {
a6645f74 9990 if ((*pa)->type()->is_slice_type())
9991 this->report_error(_("too many arguments"));
9992 else
9993 {
631d5788 9994 go_error_at(this->location(),
9995 _("invalid use of %<...%> with non-slice"));
a6645f74 9996 this->set_is_error();
9997 }
09ea332d 9998 return;
e440a328 9999 }
e440a328 10000 else
10001 {
10002 Type* element_type = varargs_type->array_type()->element_type();
10003 Expression_list* vals = new Expression_list;
10004 for (; pa != old_args->end(); ++pa, ++i)
10005 {
10006 // Check types here so that we get a better message.
10007 Type* patype = (*pa)->type();
b13c66cd 10008 Location paloc = (*pa)->location();
e440a328 10009 if (!this->check_argument_type(i, element_type, patype,
10010 paloc, issued_error))
10011 continue;
10012 vals->push_back(*pa);
10013 }
0e9a2e72 10014 Slice_construction_expression* sce =
e440a328 10015 Expression::make_slice_composite_literal(varargs_type, vals, loc);
0e9a2e72 10016 if (escape_disp == SLICE_STORAGE_DOES_NOT_ESCAPE)
10017 sce->set_storage_does_not_escape();
10018 Expression* val = sce;
09ea332d 10019 gogo->lower_expression(function, inserter, &val);
e440a328 10020 new_args->push_back(val);
10021 }
10022 }
10023
10024 if (push_empty_arg)
10025 new_args->push_back(Expression::make_nil(loc));
10026
10027 // We can't return a new call expression here, because this one may
6d4c2432 10028 // be referenced by Call_result expressions. FIXME. We can't
10029 // delete OLD_ARGS because we may have both a Call_expression and a
10030 // Builtin_call_expression which refer to them. FIXME.
e440a328 10031 this->args_ = new_args;
10032 this->varargs_are_lowered_ = true;
e440a328 10033}
10034
9a8c5dc0 10035// Return a call to __builtin_return_address or __builtin_dwarf_cfa.
105f9a24 10036
10037Expression*
10038Call_expression::lower_to_builtin(Named_object** pno, const char* name,
9a8c5dc0 10039 int* arg)
105f9a24 10040{
10041 if (*pno == NULL)
9a8c5dc0 10042 *pno = Gogo::declare_builtin_rf_address(name, arg != NULL);
105f9a24 10043
10044 Location loc = this->location();
10045
10046 Expression* fn = Expression::make_func_reference(*pno, NULL, loc);
105f9a24 10047 Expression_list *args = new Expression_list();
9a8c5dc0 10048 if (arg != NULL)
10049 {
10050 Expression* a = Expression::make_integer_ul(*arg, NULL, loc);
10051 args->push_back(a);
10052 }
105f9a24 10053 Expression* call = Expression::make_call(fn, args, false, loc);
10054
10055 // The builtin functions return void*, but the Go functions return uintptr.
10056 Type* uintptr_type = Type::lookup_integer_type("uintptr");
10057 return Expression::make_cast(uintptr_type, call, loc);
10058}
10059
2c809f8f 10060// Flatten a call with multiple results into a temporary.
10061
10062Expression*
b8e86a51 10063Call_expression::do_flatten(Gogo* gogo, Named_object*,
10064 Statement_inserter* inserter)
2c809f8f 10065{
5bf8be8b 10066 if (this->is_erroneous_call())
10067 {
10068 go_assert(saw_errors());
10069 return Expression::make_error(this->location());
10070 }
b8e86a51 10071
91c0fd76 10072 if (this->is_flattened_)
10073 return this;
10074 this->is_flattened_ = true;
10075
b8e86a51 10076 // Add temporary variables for all arguments that require type
10077 // conversion.
10078 Function_type* fntype = this->get_function_type();
9782d556 10079 if (fntype == NULL)
10080 {
10081 go_assert(saw_errors());
10082 return this;
10083 }
b8e86a51 10084 if (this->args_ != NULL && !this->args_->empty()
10085 && fntype->parameters() != NULL && !fntype->parameters()->empty())
10086 {
10087 bool is_interface_method =
10088 this->fn_->interface_field_reference_expression() != NULL;
10089
10090 Expression_list *args = new Expression_list();
10091 Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
10092 Expression_list::const_iterator pa = this->args_->begin();
10093 if (!is_interface_method && fntype->is_method())
10094 {
10095 // The receiver argument.
10096 args->push_back(*pa);
10097 ++pa;
10098 }
10099 for (; pa != this->args_->end(); ++pa, ++pp)
10100 {
10101 go_assert(pp != fntype->parameters()->end());
3a522dcc 10102 if (Type::are_identical(pp->type(), (*pa)->type(),
10103 Type::COMPARE_TAGS, NULL))
b8e86a51 10104 args->push_back(*pa);
10105 else
10106 {
10107 Location loc = (*pa)->location();
8ba8cc87 10108 Expression* arg = *pa;
10109 if (!arg->is_variable())
10110 {
10111 Temporary_statement *temp =
10112 Statement::make_temporary(NULL, arg, loc);
10113 inserter->insert(temp);
10114 arg = Expression::make_temporary_reference(temp, loc);
10115 }
10116 arg = Expression::convert_for_assignment(gogo, pp->type(), arg,
10117 loc);
10118 args->push_back(arg);
b8e86a51 10119 }
10120 }
10121 delete this->args_;
10122 this->args_ = args;
10123 }
10124
2c809f8f 10125 return this;
10126}
10127
ceeb4318 10128// Get the function type. This can return NULL in error cases.
e440a328 10129
10130Function_type*
10131Call_expression::get_function_type() const
10132{
10133 return this->fn_->type()->function_type();
10134}
10135
10136// Return the number of values which this call will return.
10137
10138size_t
10139Call_expression::result_count() const
10140{
10141 const Function_type* fntype = this->get_function_type();
10142 if (fntype == NULL)
10143 return 0;
10144 if (fntype->results() == NULL)
10145 return 0;
10146 return fntype->results()->size();
10147}
10148
5731103c 10149// Return the temporary that holds the result for a call with multiple
10150// results.
ceeb4318 10151
10152Temporary_statement*
5731103c 10153Call_expression::results() const
ceeb4318 10154{
5731103c 10155 if (this->call_temp_ == NULL)
cd238b8d 10156 {
10157 go_assert(saw_errors());
10158 return NULL;
10159 }
5731103c 10160 return this->call_temp_;
ceeb4318 10161}
10162
1373401e 10163// Set the number of results expected from a call expression.
10164
10165void
10166Call_expression::set_expected_result_count(size_t count)
10167{
10168 go_assert(this->expected_result_count_ == 0);
10169 this->expected_result_count_ = count;
10170}
10171
e440a328 10172// Return whether this is a call to the predeclared function recover.
10173
10174bool
10175Call_expression::is_recover_call() const
10176{
10177 return this->do_is_recover_call();
10178}
10179
10180// Set the argument to the recover function.
10181
10182void
10183Call_expression::set_recover_arg(Expression* arg)
10184{
10185 this->do_set_recover_arg(arg);
10186}
10187
10188// Virtual functions also implemented by Builtin_call_expression.
10189
10190bool
10191Call_expression::do_is_recover_call() const
10192{
10193 return false;
10194}
10195
10196void
10197Call_expression::do_set_recover_arg(Expression*)
10198{
c3e6f413 10199 go_unreachable();
e440a328 10200}
10201
ceeb4318 10202// We have found an error with this call expression; return true if
10203// we should report it.
10204
10205bool
10206Call_expression::issue_error()
10207{
10208 if (this->issued_error_)
10209 return false;
10210 else
10211 {
10212 this->issued_error_ = true;
10213 return true;
10214 }
10215}
10216
5bf8be8b 10217// Whether or not this call contains errors, either in the call or the
10218// arguments to the call.
10219
10220bool
10221Call_expression::is_erroneous_call()
10222{
10223 if (this->is_error_expression() || this->fn()->is_error_expression())
10224 return true;
10225
10226 if (this->args() == NULL)
10227 return false;
10228 for (Expression_list::iterator pa = this->args()->begin();
10229 pa != this->args()->end();
10230 ++pa)
10231 {
10232 if ((*pa)->type()->is_error_type() || (*pa)->is_error_expression())
10233 return true;
10234 }
10235 return false;
10236}
10237
e440a328 10238// Get the type.
10239
10240Type*
10241Call_expression::do_type()
10242{
10243 if (this->type_ != NULL)
10244 return this->type_;
10245
10246 Type* ret;
10247 Function_type* fntype = this->get_function_type();
10248 if (fntype == NULL)
10249 return Type::make_error_type();
10250
10251 const Typed_identifier_list* results = fntype->results();
10252 if (results == NULL)
10253 ret = Type::make_void_type();
10254 else if (results->size() == 1)
10255 ret = results->begin()->type();
10256 else
2801343b 10257 ret = Type::make_call_multiple_result_type(this);
e440a328 10258
10259 this->type_ = ret;
10260
10261 return this->type_;
10262}
10263
10264// Determine types for a call expression. We can use the function
10265// parameter types to set the types of the arguments.
10266
10267void
10268Call_expression::do_determine_type(const Type_context*)
10269{
fb94b0ca 10270 if (!this->determining_types())
10271 return;
10272
e440a328 10273 this->fn_->determine_type_no_context();
10274 Function_type* fntype = this->get_function_type();
10275 const Typed_identifier_list* parameters = NULL;
10276 if (fntype != NULL)
10277 parameters = fntype->parameters();
10278 if (this->args_ != NULL)
10279 {
10280 Typed_identifier_list::const_iterator pt;
10281 if (parameters != NULL)
10282 pt = parameters->begin();
09ea332d 10283 bool first = true;
e440a328 10284 for (Expression_list::const_iterator pa = this->args_->begin();
10285 pa != this->args_->end();
10286 ++pa)
10287 {
09ea332d 10288 if (first)
10289 {
10290 first = false;
10291 // If this is a method, the first argument is the
10292 // receiver.
10293 if (fntype != NULL && fntype->is_method())
10294 {
10295 Type* rtype = fntype->receiver()->type();
10296 // The receiver is always passed as a pointer.
10297 if (rtype->points_to() == NULL)
10298 rtype = Type::make_pointer_type(rtype);
10299 Type_context subcontext(rtype, false);
10300 (*pa)->determine_type(&subcontext);
10301 continue;
10302 }
10303 }
10304
e440a328 10305 if (parameters != NULL && pt != parameters->end())
10306 {
10307 Type_context subcontext(pt->type(), false);
10308 (*pa)->determine_type(&subcontext);
10309 ++pt;
10310 }
10311 else
10312 (*pa)->determine_type_no_context();
10313 }
10314 }
10315}
10316
fb94b0ca 10317// Called when determining types for a Call_expression. Return true
10318// if we should go ahead, false if they have already been determined.
10319
10320bool
10321Call_expression::determining_types()
10322{
10323 if (this->types_are_determined_)
10324 return false;
10325 else
10326 {
10327 this->types_are_determined_ = true;
10328 return true;
10329 }
10330}
10331
e440a328 10332// Check types for parameter I.
10333
10334bool
10335Call_expression::check_argument_type(int i, const Type* parameter_type,
10336 const Type* argument_type,
b13c66cd 10337 Location argument_location,
e440a328 10338 bool issued_error)
10339{
10340 std::string reason;
1eae365b 10341 if (!Type::are_assignable(parameter_type, argument_type, &reason))
e440a328 10342 {
10343 if (!issued_error)
10344 {
10345 if (reason.empty())
631d5788 10346 go_error_at(argument_location, "argument %d has incompatible type", i);
e440a328 10347 else
631d5788 10348 go_error_at(argument_location,
10349 "argument %d has incompatible type (%s)",
10350 i, reason.c_str());
e440a328 10351 }
10352 this->set_is_error();
10353 return false;
10354 }
10355 return true;
10356}
10357
10358// Check types.
10359
10360void
10361Call_expression::do_check_types(Gogo*)
10362{
a6645f74 10363 if (this->classification() == EXPRESSION_ERROR)
10364 return;
10365
e440a328 10366 Function_type* fntype = this->get_function_type();
10367 if (fntype == NULL)
10368 {
5c13bd80 10369 if (!this->fn_->type()->is_error())
e440a328 10370 this->report_error(_("expected function"));
10371 return;
10372 }
10373
1373401e 10374 if (this->expected_result_count_ != 0
10375 && this->expected_result_count_ != this->result_count())
10376 {
10377 if (this->issue_error())
10378 this->report_error(_("function result count mismatch"));
10379 this->set_is_error();
10380 return;
10381 }
10382
09ea332d 10383 bool is_method = fntype->is_method();
10384 if (is_method)
e440a328 10385 {
09ea332d 10386 go_assert(this->args_ != NULL && !this->args_->empty());
10387 Type* rtype = fntype->receiver()->type();
10388 Expression* first_arg = this->args_->front();
1eae365b 10389 // We dereference the values since receivers are always passed
10390 // as pointers.
09ea332d 10391 std::string reason;
1eae365b 10392 if (!Type::are_assignable(rtype->deref(), first_arg->type()->deref(),
10393 &reason))
e440a328 10394 {
09ea332d 10395 if (reason.empty())
10396 this->report_error(_("incompatible type for receiver"));
10397 else
e440a328 10398 {
631d5788 10399 go_error_at(this->location(),
10400 "incompatible type for receiver (%s)",
10401 reason.c_str());
09ea332d 10402 this->set_is_error();
e440a328 10403 }
10404 }
10405 }
10406
10407 // Note that varargs was handled by the lower_varargs() method, so
a6645f74 10408 // we don't have to worry about it here unless something is wrong.
10409 if (this->is_varargs_ && !this->varargs_are_lowered_)
10410 {
10411 if (!fntype->is_varargs())
10412 {
631d5788 10413 go_error_at(this->location(),
10414 _("invalid use of %<...%> calling non-variadic function"));
a6645f74 10415 this->set_is_error();
10416 return;
10417 }
10418 }
e440a328 10419
10420 const Typed_identifier_list* parameters = fntype->parameters();
33d1d391 10421 if (this->args_ == NULL || this->args_->size() == 0)
e440a328 10422 {
10423 if (parameters != NULL && !parameters->empty())
10424 this->report_error(_("not enough arguments"));
10425 }
10426 else if (parameters == NULL)
09ea332d 10427 {
10428 if (!is_method || this->args_->size() > 1)
10429 this->report_error(_("too many arguments"));
10430 }
1373401e 10431 else if (this->args_->size() == 1
10432 && this->args_->front()->call_expression() != NULL
10433 && this->args_->front()->call_expression()->result_count() > 1)
10434 {
10435 // This is F(G()) when G returns more than one result. If the
10436 // results can be matched to parameters, it would have been
10437 // lowered in do_lower. If we get here we know there is a
10438 // mismatch.
10439 if (this->args_->front()->call_expression()->result_count()
10440 < parameters->size())
10441 this->report_error(_("not enough arguments"));
10442 else
10443 this->report_error(_("too many arguments"));
10444 }
e440a328 10445 else
10446 {
10447 int i = 0;
09ea332d 10448 Expression_list::const_iterator pa = this->args_->begin();
10449 if (is_method)
10450 ++pa;
10451 for (Typed_identifier_list::const_iterator pt = parameters->begin();
10452 pt != parameters->end();
10453 ++pt, ++pa, ++i)
e440a328 10454 {
09ea332d 10455 if (pa == this->args_->end())
e440a328 10456 {
09ea332d 10457 this->report_error(_("not enough arguments"));
e440a328 10458 return;
10459 }
10460 this->check_argument_type(i + 1, pt->type(), (*pa)->type(),
10461 (*pa)->location(), false);
10462 }
09ea332d 10463 if (pa != this->args_->end())
10464 this->report_error(_("too many arguments"));
e440a328 10465 }
10466}
10467
72666aed 10468Expression*
10469Call_expression::do_copy()
10470{
10471 Call_expression* call =
10472 Expression::make_call(this->fn_->copy(),
10473 (this->args_ == NULL
10474 ? NULL
10475 : this->args_->copy()),
10476 this->is_varargs_, this->location());
10477
10478 if (this->varargs_are_lowered_)
10479 call->set_varargs_are_lowered();
28819633 10480 if (this->is_deferred_)
10481 call->set_is_deferred();
10482 if (this->is_concurrent_)
10483 call->set_is_concurrent();
72666aed 10484 return call;
10485}
10486
e440a328 10487// Return whether we have to use a temporary variable to ensure that
10488// we evaluate this call expression in order. If the call returns no
ceeb4318 10489// results then it will inevitably be executed last.
e440a328 10490
10491bool
10492Call_expression::do_must_eval_in_order() const
10493{
ceeb4318 10494 return this->result_count() > 0;
e440a328 10495}
10496
e440a328 10497// Get the function and the first argument to use when calling an
10498// interface method.
10499
2387f644 10500Expression*
e440a328 10501Call_expression::interface_method_function(
e440a328 10502 Interface_field_reference_expression* interface_method,
db122cb9 10503 Expression** first_arg_ptr,
10504 Location location)
e440a328 10505{
db122cb9 10506 Expression* object = interface_method->get_underlying_object();
10507 Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
10508 *first_arg_ptr =
10509 Expression::make_unsafe_cast(unsafe_ptr_type, object, location);
2387f644 10510 return interface_method->get_function();
e440a328 10511}
10512
10513// Build the call expression.
10514
ea664253 10515Bexpression*
10516Call_expression::do_get_backend(Translate_context* context)
e440a328 10517{
5731103c 10518 Location location = this->location();
10519
2c809f8f 10520 if (this->call_ != NULL)
5731103c 10521 {
10522 // If the call returns multiple results, make a new reference to
10523 // the temporary.
10524 if (this->call_temp_ != NULL)
10525 {
10526 Expression* ref =
10527 Expression::make_temporary_reference(this->call_temp_, location);
10528 return ref->get_backend(context);
10529 }
10530
10531 return this->call_;
10532 }
e440a328 10533
10534 Function_type* fntype = this->get_function_type();
10535 if (fntype == NULL)
ea664253 10536 return context->backend()->error_expression();
e440a328 10537
10538 if (this->fn_->is_error_expression())
ea664253 10539 return context->backend()->error_expression();
e440a328 10540
10541 Gogo* gogo = context->gogo();
e440a328 10542
10543 Func_expression* func = this->fn_->func_expression();
e440a328 10544 Interface_field_reference_expression* interface_method =
10545 this->fn_->interface_field_reference_expression();
10546 const bool has_closure = func != NULL && func->closure() != NULL;
09ea332d 10547 const bool is_interface_method = interface_method != NULL;
e440a328 10548
f8bdf81a 10549 bool has_closure_arg;
8381eda7 10550 if (has_closure)
f8bdf81a 10551 has_closure_arg = true;
8381eda7 10552 else if (func != NULL)
f8bdf81a 10553 has_closure_arg = false;
8381eda7 10554 else if (is_interface_method)
f8bdf81a 10555 has_closure_arg = false;
8381eda7 10556 else
f8bdf81a 10557 has_closure_arg = true;
8381eda7 10558
e440a328 10559 int nargs;
2c809f8f 10560 std::vector<Bexpression*> fn_args;
e440a328 10561 if (this->args_ == NULL || this->args_->empty())
10562 {
f8bdf81a 10563 nargs = is_interface_method ? 1 : 0;
2c809f8f 10564 if (nargs > 0)
10565 fn_args.resize(1);
e440a328 10566 }
09ea332d 10567 else if (fntype->parameters() == NULL || fntype->parameters()->empty())
10568 {
10569 // Passing a receiver parameter.
10570 go_assert(!is_interface_method
10571 && fntype->is_method()
10572 && this->args_->size() == 1);
f8bdf81a 10573 nargs = 1;
2c809f8f 10574 fn_args.resize(1);
ea664253 10575 fn_args[0] = this->args_->front()->get_backend(context);
09ea332d 10576 }
e440a328 10577 else
10578 {
10579 const Typed_identifier_list* params = fntype->parameters();
e440a328 10580
10581 nargs = this->args_->size();
09ea332d 10582 int i = is_interface_method ? 1 : 0;
e440a328 10583 nargs += i;
2c809f8f 10584 fn_args.resize(nargs);
e440a328 10585
10586 Typed_identifier_list::const_iterator pp = params->begin();
09ea332d 10587 Expression_list::const_iterator pe = this->args_->begin();
10588 if (!is_interface_method && fntype->is_method())
10589 {
ea664253 10590 fn_args[i] = (*pe)->get_backend(context);
09ea332d 10591 ++pe;
10592 ++i;
10593 }
10594 for (; pe != this->args_->end(); ++pe, ++pp, ++i)
e440a328 10595 {
c484d925 10596 go_assert(pp != params->end());
2c809f8f 10597 Expression* arg =
10598 Expression::convert_for_assignment(gogo, pp->type(), *pe,
10599 location);
ea664253 10600 fn_args[i] = arg->get_backend(context);
e440a328 10601 }
c484d925 10602 go_assert(pp == params->end());
f8bdf81a 10603 go_assert(i == nargs);
e440a328 10604 }
10605
2c809f8f 10606 Expression* fn;
10607 Expression* closure = NULL;
8381eda7 10608 if (func != NULL)
10609 {
10610 Named_object* no = func->named_object();
2c809f8f 10611 fn = Expression::make_func_code_reference(no, location);
10612 if (has_closure)
10613 closure = func->closure();
8381eda7 10614 }
09ea332d 10615 else if (!is_interface_method)
8381eda7 10616 {
2c809f8f 10617 closure = this->fn_;
10618
10619 // The backend representation of this function type is a pointer
10620 // to a struct whose first field is the actual function to call.
10621 Type* pfntype =
10622 Type::make_pointer_type(
10623 Type::make_pointer_type(Type::make_void_type()));
10624 fn = Expression::make_unsafe_cast(pfntype, this->fn_, location);
f614ea8b 10625 fn = Expression::make_dereference(fn, NIL_CHECK_NOT_NEEDED, location);
2c809f8f 10626 }
e440a328 10627 else
cf609de4 10628 {
2387f644 10629 Expression* first_arg;
db122cb9 10630 fn = this->interface_method_function(interface_method, &first_arg,
10631 location);
ea664253 10632 fn_args[0] = first_arg->get_backend(context);
e440a328 10633 }
10634
1ecc6157 10635 Bexpression* bclosure = NULL;
10636 if (has_closure_arg)
10637 bclosure = closure->get_backend(context);
f8bdf81a 10638 else
1ecc6157 10639 go_assert(closure == NULL);
f8bdf81a 10640
ea664253 10641 Bexpression* bfn = fn->get_backend(context);
80d1e1a8 10642
10643 // When not calling a named function directly, use a type conversion
10644 // in case the type of the function is a recursive type which refers
10645 // to itself. We don't do this for an interface method because 1)
10646 // an interface method never refers to itself, so we always have a
10647 // function type here; 2) we pass an extra first argument to an
10648 // interface method, so fntype is not correct.
10649 if (func == NULL && !is_interface_method)
10650 {
10651 Btype* bft = fntype->get_backend_fntype(gogo);
10652 bfn = gogo->backend()->convert_expression(bft, bfn, location);
10653 }
10654
4ced7af9 10655 Bfunction* bfunction = NULL;
10656 if (context->function())
10657 bfunction = context->function()->func_value()->get_decl();
10658 Bexpression* call = gogo->backend()->call_expression(bfunction, bfn,
10659 fn_args, bclosure,
10660 location);
e440a328 10661
5731103c 10662 if (this->call_temp_ != NULL)
e440a328 10663 {
5731103c 10664 // This case occurs when the call returns multiple results.
e440a328 10665
5731103c 10666 Expression* ref = Expression::make_temporary_reference(this->call_temp_,
10667 location);
10668 Bexpression* bref = ref->get_backend(context);
10669 Bstatement* bassn = gogo->backend()->assignment_statement(bfunction,
10670 bref, call,
10671 location);
e440a328 10672
5731103c 10673 ref = Expression::make_temporary_reference(this->call_temp_, location);
10674 this->call_ = ref->get_backend(context);
10675
10676 return gogo->backend()->compound_expression(bassn, this->call_,
10677 location);
2c809f8f 10678 }
e440a328 10679
2c809f8f 10680 this->call_ = call;
ea664253 10681 return this->call_;
e440a328 10682}
10683
d751bb78 10684// Dump ast representation for a call expressin.
10685
10686void
10687Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
10688{
10689 this->fn_->dump_expression(ast_dump_context);
10690 ast_dump_context->ostream() << "(";
10691 if (args_ != NULL)
10692 ast_dump_context->dump_expression_list(this->args_);
10693
10694 ast_dump_context->ostream() << ") ";
10695}
10696
e440a328 10697// Make a call expression.
10698
10699Call_expression*
10700Expression::make_call(Expression* fn, Expression_list* args, bool is_varargs,
b13c66cd 10701 Location location)
e440a328 10702{
10703 return new Call_expression(fn, args, is_varargs, location);
10704}
10705
da244e59 10706// Class Call_result_expression.
e440a328 10707
10708// Traverse a call result.
10709
10710int
10711Call_result_expression::do_traverse(Traverse* traverse)
10712{
10713 if (traverse->remember_expression(this->call_))
10714 {
10715 // We have already traversed the call expression.
10716 return TRAVERSE_CONTINUE;
10717 }
10718 return Expression::traverse(&this->call_, traverse);
10719}
10720
10721// Get the type.
10722
10723Type*
10724Call_result_expression::do_type()
10725{
425dd051 10726 if (this->classification() == EXPRESSION_ERROR)
10727 return Type::make_error_type();
10728
e440a328 10729 // THIS->CALL_ can be replaced with a temporary reference due to
10730 // Call_expression::do_must_eval_in_order when there is an error.
10731 Call_expression* ce = this->call_->call_expression();
10732 if (ce == NULL)
5e85f268 10733 {
10734 this->set_is_error();
10735 return Type::make_error_type();
10736 }
e440a328 10737 Function_type* fntype = ce->get_function_type();
10738 if (fntype == NULL)
5e85f268 10739 {
e37658e2 10740 if (ce->issue_error())
99b3f06f 10741 {
10742 if (!ce->fn()->type()->is_error())
10743 this->report_error(_("expected function"));
10744 }
5e85f268 10745 this->set_is_error();
10746 return Type::make_error_type();
10747 }
e440a328 10748 const Typed_identifier_list* results = fntype->results();
ceeb4318 10749 if (results == NULL || results->size() < 2)
7b8d861f 10750 {
ceeb4318 10751 if (ce->issue_error())
10752 this->report_error(_("number of results does not match "
10753 "number of values"));
7b8d861f 10754 return Type::make_error_type();
10755 }
e440a328 10756 Typed_identifier_list::const_iterator pr = results->begin();
10757 for (unsigned int i = 0; i < this->index_; ++i)
10758 {
10759 if (pr == results->end())
425dd051 10760 break;
e440a328 10761 ++pr;
10762 }
10763 if (pr == results->end())
425dd051 10764 {
ceeb4318 10765 if (ce->issue_error())
10766 this->report_error(_("number of results does not match "
10767 "number of values"));
425dd051 10768 return Type::make_error_type();
10769 }
e440a328 10770 return pr->type();
10771}
10772
425dd051 10773// Check the type. Just make sure that we trigger the warning in
10774// do_type.
e440a328 10775
10776void
10777Call_result_expression::do_check_types(Gogo*)
10778{
425dd051 10779 this->type();
e440a328 10780}
10781
10782// Determine the type. We have nothing to do here, but the 0 result
10783// needs to pass down to the caller.
10784
10785void
10786Call_result_expression::do_determine_type(const Type_context*)
10787{
fb94b0ca 10788 this->call_->determine_type_no_context();
e440a328 10789}
10790
ea664253 10791// Return the backend representation. We just refer to the temporary set by the
10792// call expression. We don't do this at lowering time because it makes it
ceeb4318 10793// hard to evaluate the call at the right time.
e440a328 10794
ea664253 10795Bexpression*
10796Call_result_expression::do_get_backend(Translate_context* context)
e440a328 10797{
ceeb4318 10798 Call_expression* ce = this->call_->call_expression();
cd238b8d 10799 if (ce == NULL)
10800 {
10801 go_assert(this->call_->is_error_expression());
ea664253 10802 return context->backend()->error_expression();
cd238b8d 10803 }
5731103c 10804 Temporary_statement* ts = ce->results();
cd238b8d 10805 if (ts == NULL)
10806 {
10807 go_assert(saw_errors());
ea664253 10808 return context->backend()->error_expression();
cd238b8d 10809 }
ceeb4318 10810 Expression* ref = Expression::make_temporary_reference(ts, this->location());
5731103c 10811 ref = Expression::make_field_reference(ref, this->index_, this->location());
ea664253 10812 return ref->get_backend(context);
e440a328 10813}
10814
d751bb78 10815// Dump ast representation for a call result expression.
10816
10817void
10818Call_result_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
10819 const
10820{
f03a9fbf 10821 // FIXME: Wouldn't it be better if the call is assigned to a temporary
d751bb78 10822 // (struct) and the fields are referenced instead.
10823 ast_dump_context->ostream() << this->index_ << "@(";
10824 ast_dump_context->dump_expression(this->call_);
10825 ast_dump_context->ostream() << ")";
10826}
10827
e440a328 10828// Make a reference to a single result of a call which returns
10829// multiple results.
10830
10831Expression*
10832Expression::make_call_result(Call_expression* call, unsigned int index)
10833{
10834 return new Call_result_expression(call, index);
10835}
10836
10837// Class Index_expression.
10838
10839// Traversal.
10840
10841int
10842Index_expression::do_traverse(Traverse* traverse)
10843{
10844 if (Expression::traverse(&this->left_, traverse) == TRAVERSE_EXIT
10845 || Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT
10846 || (this->end_ != NULL
acf2b673 10847 && Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
10848 || (this->cap_ != NULL
10849 && Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT))
e440a328 10850 return TRAVERSE_EXIT;
10851 return TRAVERSE_CONTINUE;
10852}
10853
10854// Lower an index expression. This converts the generic index
10855// expression into an array index, a string index, or a map index.
10856
10857Expression*
ceeb4318 10858Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
e440a328 10859{
b13c66cd 10860 Location location = this->location();
e440a328 10861 Expression* left = this->left_;
10862 Expression* start = this->start_;
10863 Expression* end = this->end_;
acf2b673 10864 Expression* cap = this->cap_;
e440a328 10865
10866 Type* type = left->type();
5c13bd80 10867 if (type->is_error())
d9f3743a 10868 {
10869 go_assert(saw_errors());
10870 return Expression::make_error(location);
10871 }
b0cf7ddd 10872 else if (left->is_type_expression())
10873 {
631d5788 10874 go_error_at(location, "attempt to index type expression");
b0cf7ddd 10875 return Expression::make_error(location);
10876 }
e440a328 10877 else if (type->array_type() != NULL)
acf2b673 10878 return Expression::make_array_index(left, start, end, cap, location);
e440a328 10879 else if (type->points_to() != NULL
10880 && type->points_to()->array_type() != NULL
411eb89e 10881 && !type->points_to()->is_slice_type())
e440a328 10882 {
f614ea8b 10883 Expression* deref =
10884 Expression::make_dereference(left, NIL_CHECK_DEFAULT, location);
38092374 10885
10886 // For an ordinary index into the array, the pointer will be
10887 // dereferenced. For a slice it will not--the resulting slice
10888 // will simply reuse the pointer, which is incorrect if that
10889 // pointer is nil.
10890 if (end != NULL || cap != NULL)
10891 deref->issue_nil_check();
10892
acf2b673 10893 return Expression::make_array_index(deref, start, end, cap, location);
e440a328 10894 }
10895 else if (type->is_string_type())
acf2b673 10896 {
10897 if (cap != NULL)
10898 {
631d5788 10899 go_error_at(location, "invalid 3-index slice of string");
acf2b673 10900 return Expression::make_error(location);
10901 }
10902 return Expression::make_string_index(left, start, end, location);
10903 }
e440a328 10904 else if (type->map_type() != NULL)
10905 {
acf2b673 10906 if (end != NULL || cap != NULL)
e440a328 10907 {
631d5788 10908 go_error_at(location, "invalid slice of map");
e440a328 10909 return Expression::make_error(location);
10910 }
0d5530d9 10911 return Expression::make_map_index(left, start, location);
e440a328 10912 }
b1aba207 10913 else if (cap != NULL)
10914 {
10915 go_error_at(location,
10916 "invalid 3-index slice of object that is not a slice");
10917 return Expression::make_error(location);
10918 }
10919 else if (end != NULL)
10920 {
10921 go_error_at(location,
10922 ("attempt to slice object that is not "
10923 "array, slice, or string"));
10924 return Expression::make_error(location);
10925 }
e440a328 10926 else
10927 {
631d5788 10928 go_error_at(location,
b1aba207 10929 ("attempt to index object that is not "
10930 "array, slice, string, or map"));
e440a328 10931 return Expression::make_error(location);
10932 }
10933}
10934
acf2b673 10935// Write an indexed expression
10936// (expr[expr:expr:expr], expr[expr:expr] or expr[expr]) to a dump context.
d751bb78 10937
10938void
f03a9fbf 10939Index_expression::dump_index_expression(Ast_dump_context* ast_dump_context,
10940 const Expression* expr,
d751bb78 10941 const Expression* start,
acf2b673 10942 const Expression* end,
10943 const Expression* cap)
d751bb78 10944{
10945 expr->dump_expression(ast_dump_context);
10946 ast_dump_context->ostream() << "[";
10947 start->dump_expression(ast_dump_context);
10948 if (end != NULL)
10949 {
10950 ast_dump_context->ostream() << ":";
10951 end->dump_expression(ast_dump_context);
10952 }
acf2b673 10953 if (cap != NULL)
10954 {
10955 ast_dump_context->ostream() << ":";
10956 cap->dump_expression(ast_dump_context);
10957 }
d751bb78 10958 ast_dump_context->ostream() << "]";
10959}
10960
10961// Dump ast representation for an index expression.
10962
10963void
f03a9fbf 10964Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 10965 const
10966{
f03a9fbf 10967 Index_expression::dump_index_expression(ast_dump_context, this->left_,
acf2b673 10968 this->start_, this->end_, this->cap_);
d751bb78 10969}
10970
e440a328 10971// Make an index expression.
10972
10973Expression*
10974Expression::make_index(Expression* left, Expression* start, Expression* end,
acf2b673 10975 Expression* cap, Location location)
e440a328 10976{
acf2b673 10977 return new Index_expression(left, start, end, cap, location);
e440a328 10978}
10979
da244e59 10980// Class Array_index_expression.
e440a328 10981
10982// Array index traversal.
10983
10984int
10985Array_index_expression::do_traverse(Traverse* traverse)
10986{
10987 if (Expression::traverse(&this->array_, traverse) == TRAVERSE_EXIT)
10988 return TRAVERSE_EXIT;
10989 if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
10990 return TRAVERSE_EXIT;
10991 if (this->end_ != NULL)
10992 {
10993 if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
10994 return TRAVERSE_EXIT;
10995 }
acf2b673 10996 if (this->cap_ != NULL)
10997 {
10998 if (Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
10999 return TRAVERSE_EXIT;
11000 }
e440a328 11001 return TRAVERSE_CONTINUE;
11002}
11003
11004// Return the type of an array index.
11005
11006Type*
11007Array_index_expression::do_type()
11008{
11009 if (this->type_ == NULL)
11010 {
11011 Array_type* type = this->array_->type()->array_type();
11012 if (type == NULL)
11013 this->type_ = Type::make_error_type();
11014 else if (this->end_ == NULL)
11015 this->type_ = type->element_type();
411eb89e 11016 else if (type->is_slice_type())
e440a328 11017 {
11018 // A slice of a slice has the same type as the original
11019 // slice.
11020 this->type_ = this->array_->type()->deref();
11021 }
11022 else
11023 {
11024 // A slice of an array is a slice.
11025 this->type_ = Type::make_array_type(type->element_type(), NULL);
11026 }
11027 }
11028 return this->type_;
11029}
11030
11031// Set the type of an array index.
11032
11033void
11034Array_index_expression::do_determine_type(const Type_context*)
11035{
11036 this->array_->determine_type_no_context();
f77aa642 11037
11038 Type_context index_context(Type::lookup_integer_type("int"), false);
11039 if (this->start_->is_constant())
11040 this->start_->determine_type(&index_context);
11041 else
11042 this->start_->determine_type_no_context();
e440a328 11043 if (this->end_ != NULL)
f77aa642 11044 {
11045 if (this->end_->is_constant())
11046 this->end_->determine_type(&index_context);
11047 else
11048 this->end_->determine_type_no_context();
11049 }
acf2b673 11050 if (this->cap_ != NULL)
f77aa642 11051 {
11052 if (this->cap_->is_constant())
11053 this->cap_->determine_type(&index_context);
11054 else
11055 this->cap_->determine_type_no_context();
11056 }
e440a328 11057}
11058
11059// Check types of an array index.
11060
11061void
b7327dbf 11062Array_index_expression::do_check_types(Gogo*)
e440a328 11063{
f6bc81e6 11064 Numeric_constant nc;
11065 unsigned long v;
11066 if (this->start_->type()->integer_type() == NULL
11067 && !this->start_->type()->is_error()
11068 && (!this->start_->numeric_constant_value(&nc)
11069 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 11070 this->report_error(_("index must be integer"));
11071 if (this->end_ != NULL
11072 && this->end_->type()->integer_type() == NULL
99b3f06f 11073 && !this->end_->type()->is_error()
11074 && !this->end_->is_nil_expression()
f6bc81e6 11075 && !this->end_->is_error_expression()
11076 && (!this->end_->numeric_constant_value(&nc)
11077 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 11078 this->report_error(_("slice end must be integer"));
acf2b673 11079 if (this->cap_ != NULL
11080 && this->cap_->type()->integer_type() == NULL
11081 && !this->cap_->type()->is_error()
11082 && !this->cap_->is_nil_expression()
11083 && !this->cap_->is_error_expression()
11084 && (!this->cap_->numeric_constant_value(&nc)
11085 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
11086 this->report_error(_("slice capacity must be integer"));
e440a328 11087
11088 Array_type* array_type = this->array_->type()->array_type();
f9c68f17 11089 if (array_type == NULL)
11090 {
c484d925 11091 go_assert(this->array_->type()->is_error());
f9c68f17 11092 return;
11093 }
e440a328 11094
11095 unsigned int int_bits =
11096 Type::lookup_integer_type("int")->integer_type()->bits();
11097
0c77715b 11098 Numeric_constant lvalnc;
e440a328 11099 mpz_t lval;
e440a328 11100 bool lval_valid = (array_type->length() != NULL
0c77715b 11101 && array_type->length()->numeric_constant_value(&lvalnc)
11102 && lvalnc.to_int(&lval));
11103 Numeric_constant inc;
e440a328 11104 mpz_t ival;
0bd5d859 11105 bool ival_valid = false;
0c77715b 11106 if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
e440a328 11107 {
0bd5d859 11108 ival_valid = true;
e440a328 11109 if (mpz_sgn(ival) < 0
11110 || mpz_sizeinbase(ival, 2) >= int_bits
11111 || (lval_valid
11112 && (this->end_ == NULL
11113 ? mpz_cmp(ival, lval) >= 0
11114 : mpz_cmp(ival, lval) > 0)))
11115 {
631d5788 11116 go_error_at(this->start_->location(), "array index out of bounds");
e440a328 11117 this->set_is_error();
11118 }
11119 }
11120 if (this->end_ != NULL && !this->end_->is_nil_expression())
11121 {
0c77715b 11122 Numeric_constant enc;
11123 mpz_t eval;
acf2b673 11124 bool eval_valid = false;
0c77715b 11125 if (this->end_->numeric_constant_value(&enc) && enc.to_int(&eval))
e440a328 11126 {
acf2b673 11127 eval_valid = true;
0c77715b 11128 if (mpz_sgn(eval) < 0
11129 || mpz_sizeinbase(eval, 2) >= int_bits
11130 || (lval_valid && mpz_cmp(eval, lval) > 0))
e440a328 11131 {
631d5788 11132 go_error_at(this->end_->location(), "array index out of bounds");
e440a328 11133 this->set_is_error();
11134 }
0bd5d859 11135 else if (ival_valid && mpz_cmp(ival, eval) > 0)
11136 this->report_error(_("inverted slice range"));
e440a328 11137 }
acf2b673 11138
11139 Numeric_constant cnc;
11140 mpz_t cval;
11141 if (this->cap_ != NULL
11142 && this->cap_->numeric_constant_value(&cnc) && cnc.to_int(&cval))
11143 {
11144 if (mpz_sgn(cval) < 0
11145 || mpz_sizeinbase(cval, 2) >= int_bits
11146 || (lval_valid && mpz_cmp(cval, lval) > 0))
11147 {
631d5788 11148 go_error_at(this->cap_->location(), "array index out of bounds");
acf2b673 11149 this->set_is_error();
11150 }
11151 else if (ival_valid && mpz_cmp(ival, cval) > 0)
11152 {
631d5788 11153 go_error_at(this->cap_->location(),
11154 "invalid slice index: capacity less than start");
acf2b673 11155 this->set_is_error();
11156 }
11157 else if (eval_valid && mpz_cmp(eval, cval) > 0)
11158 {
631d5788 11159 go_error_at(this->cap_->location(),
11160 "invalid slice index: capacity less than length");
acf2b673 11161 this->set_is_error();
11162 }
11163 mpz_clear(cval);
11164 }
11165
11166 if (eval_valid)
11167 mpz_clear(eval);
e440a328 11168 }
0bd5d859 11169 if (ival_valid)
11170 mpz_clear(ival);
0c77715b 11171 if (lval_valid)
11172 mpz_clear(lval);
e440a328 11173
11174 // A slice of an array requires an addressable array. A slice of a
11175 // slice is always possible.
411eb89e 11176 if (this->end_ != NULL && !array_type->is_slice_type())
88ec30c8 11177 {
11178 if (!this->array_->is_addressable())
8da39c3b 11179 this->report_error(_("slice of unaddressable value"));
88ec30c8 11180 else
b7327dbf 11181 // Set the array address taken but not escape. The escape
11182 // analysis will make it escape to heap when needed.
11183 this->array_->address_taken(false);
88ec30c8 11184 }
e440a328 11185}
11186
71a38860 11187// The subexpressions of an array index must be evaluated in order.
11188// If this is indexing into an array, rather than a slice, then only
11189// the index should be evaluated. Since this is called for values on
11190// the left hand side of an assigment, evaluating the array, meaning
11191// copying the array, will cause a different array to be modified.
11192
11193bool
11194Array_index_expression::do_must_eval_subexpressions_in_order(
11195 int* skip) const
11196{
11197 *skip = this->array_->type()->is_slice_type() ? 0 : 1;
11198 return true;
11199}
11200
2c809f8f 11201// Flatten array indexing by using temporary variables for slices and indexes.
35a54f17 11202
11203Expression*
11204Array_index_expression::do_flatten(Gogo*, Named_object*,
11205 Statement_inserter* inserter)
11206{
11207 Location loc = this->location();
5bf8be8b 11208 Expression* array = this->array_;
11209 Expression* start = this->start_;
11210 Expression* end = this->end_;
11211 Expression* cap = this->cap_;
11212 if (array->is_error_expression()
11213 || array->type()->is_error_type()
11214 || start->is_error_expression()
11215 || start->type()->is_error_type()
11216 || (end != NULL
11217 && (end->is_error_expression() || end->type()->is_error_type()))
11218 || (cap != NULL
11219 && (cap->is_error_expression() || cap->type()->is_error_type())))
11220 {
11221 go_assert(saw_errors());
11222 return Expression::make_error(loc);
11223 }
11224
2c809f8f 11225 Temporary_statement* temp;
5bf8be8b 11226 if (array->type()->is_slice_type() && !array->is_variable())
35a54f17 11227 {
5bf8be8b 11228 temp = Statement::make_temporary(NULL, array, loc);
35a54f17 11229 inserter->insert(temp);
11230 this->array_ = Expression::make_temporary_reference(temp, loc);
11231 }
5bf8be8b 11232 if (!start->is_variable())
2c809f8f 11233 {
5bf8be8b 11234 temp = Statement::make_temporary(NULL, start, loc);
2c809f8f 11235 inserter->insert(temp);
11236 this->start_ = Expression::make_temporary_reference(temp, loc);
11237 }
5bf8be8b 11238 if (end != NULL
11239 && !end->is_nil_expression()
11240 && !end->is_variable())
2c809f8f 11241 {
5bf8be8b 11242 temp = Statement::make_temporary(NULL, end, loc);
2c809f8f 11243 inserter->insert(temp);
11244 this->end_ = Expression::make_temporary_reference(temp, loc);
11245 }
03118c21 11246 if (cap != NULL && !cap->is_variable())
2c809f8f 11247 {
5bf8be8b 11248 temp = Statement::make_temporary(NULL, cap, loc);
2c809f8f 11249 inserter->insert(temp);
11250 this->cap_ = Expression::make_temporary_reference(temp, loc);
11251 }
11252
35a54f17 11253 return this;
11254}
11255
e440a328 11256// Return whether this expression is addressable.
11257
11258bool
11259Array_index_expression::do_is_addressable() const
11260{
11261 // A slice expression is not addressable.
11262 if (this->end_ != NULL)
11263 return false;
11264
11265 // An index into a slice is addressable.
411eb89e 11266 if (this->array_->type()->is_slice_type())
e440a328 11267 return true;
11268
11269 // An index into an array is addressable if the array is
11270 // addressable.
11271 return this->array_->is_addressable();
11272}
11273
bf1323be 11274void
11275Array_index_expression::do_address_taken(bool escapes)
11276{
11277 // In &x[0], if x is a slice, then x's address is not taken.
11278 if (!this->array_->type()->is_slice_type())
11279 this->array_->address_taken(escapes);
11280}
11281
ea664253 11282// Get the backend representation for an array index.
e440a328 11283
ea664253 11284Bexpression*
11285Array_index_expression::do_get_backend(Translate_context* context)
e440a328 11286{
e440a328 11287 Array_type* array_type = this->array_->type()->array_type();
d8cd8e2d 11288 if (array_type == NULL)
11289 {
c484d925 11290 go_assert(this->array_->type()->is_error());
ea664253 11291 return context->backend()->error_expression();
d8cd8e2d 11292 }
35a54f17 11293 go_assert(!array_type->is_slice_type() || this->array_->is_variable());
e440a328 11294
2c809f8f 11295 Location loc = this->location();
11296 Gogo* gogo = context->gogo();
11297
6dfedc16 11298 Type* int_type = Type::lookup_integer_type("int");
11299 Btype* int_btype = int_type->get_backend(gogo);
e440a328 11300
2c809f8f 11301 // We need to convert the length and capacity to the Go "int" type here
11302 // because the length of a fixed-length array could be of type "uintptr"
11303 // and gimple disallows binary operations between "uintptr" and other
11304 // integer types. FIXME.
11305 Bexpression* length = NULL;
a04bfdfc 11306 if (this->end_ == NULL || this->end_->is_nil_expression())
11307 {
35a54f17 11308 Expression* len = array_type->get_length(gogo, this->array_);
ea664253 11309 length = len->get_backend(context);
2c809f8f 11310 length = gogo->backend()->convert_expression(int_btype, length, loc);
a04bfdfc 11311 }
11312
2c809f8f 11313 Bexpression* capacity = NULL;
a04bfdfc 11314 if (this->end_ != NULL)
11315 {
35a54f17 11316 Expression* cap = array_type->get_capacity(gogo, this->array_);
ea664253 11317 capacity = cap->get_backend(context);
2c809f8f 11318 capacity = gogo->backend()->convert_expression(int_btype, capacity, loc);
a04bfdfc 11319 }
11320
2c809f8f 11321 Bexpression* cap_arg = capacity;
acf2b673 11322 if (this->cap_ != NULL)
11323 {
ea664253 11324 cap_arg = this->cap_->get_backend(context);
2c809f8f 11325 cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
acf2b673 11326 }
11327
2c809f8f 11328 if (length == NULL)
11329 length = cap_arg;
e440a328 11330
6dfedc16 11331 if (this->start_->type()->integer_type() == NULL
11332 && !Type::are_convertible(int_type, this->start_->type(), NULL))
11333 {
11334 go_assert(saw_errors());
11335 return context->backend()->error_expression();
11336 }
d9f3743a 11337
ea664253 11338 Bexpression* start = this->start_->get_backend(context);
2c809f8f 11339 start = gogo->backend()->convert_expression(int_btype, start, loc);
3d135120 11340
11341 Bexpression* crash = NULL;
11342 Bexpression* bad_index = NULL;
11343 if (this->needs_bounds_check_)
11344 {
11345 int code = (array_type->length() != NULL
11346 ? (this->end_ == NULL
11347 ? RUNTIME_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS
11348 : RUNTIME_ERROR_ARRAY_SLICE_OUT_OF_BOUNDS)
11349 : (this->end_ == NULL
11350 ? RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS
11351 : RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS));
11352 crash = gogo->runtime_error(code, loc)->get_backend(context);
11353 bad_index = Expression::check_bounds(this->start_, loc)->get_backend(context);
11354 Bexpression* start_too_large =
11355 gogo->backend()->binary_expression((this->end_ == NULL
11356 ? OPERATOR_GE
11357 : OPERATOR_GT),
11358 start,
11359 (this->end_ == NULL
11360 ? length
11361 : capacity),
11362 loc);
11363 bad_index = gogo->backend()->binary_expression(OPERATOR_OROR,
11364 start_too_large,
11365 bad_index, loc);
11366 }
11367
e440a328 11368
93715b75 11369 Bfunction* bfn = context->function()->func_value()->get_decl();
e440a328 11370 if (this->end_ == NULL)
11371 {
11372 // Simple array indexing. This has to return an l-value, so
2c809f8f 11373 // wrap the index check into START.
3d135120 11374 if (this->needs_bounds_check_)
11375 start =
11376 gogo->backend()->conditional_expression(bfn, int_btype, bad_index,
11377 crash, start, loc);
e440a328 11378
2c809f8f 11379 Bexpression* ret;
e440a328 11380 if (array_type->length() != NULL)
11381 {
ea664253 11382 Bexpression* array = this->array_->get_backend(context);
2c809f8f 11383 ret = gogo->backend()->array_index_expression(array, start, loc);
e440a328 11384 }
11385 else
11386 {
2c809f8f 11387 // Slice.
11388 Expression* valptr =
44dbe1d7 11389 array_type->get_value_pointer(gogo, this->array_,
11390 this->is_lvalue_);
ea664253 11391 Bexpression* ptr = valptr->get_backend(context);
2c809f8f 11392 ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc);
9b27b43c 11393
11394 Type* ele_type = this->array_->type()->array_type()->element_type();
11395 Btype* ele_btype = ele_type->get_backend(gogo);
11396 ret = gogo->backend()->indirect_expression(ele_btype, ptr, true, loc);
e440a328 11397 }
ea664253 11398 return ret;
e440a328 11399 }
11400
11401 // Array slice.
11402
acf2b673 11403 if (this->cap_ != NULL)
11404 {
2c809f8f 11405 cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
11406
3d135120 11407 if (this->needs_bounds_check_)
11408 {
11409 Bexpression* bounds_bcheck =
11410 Expression::check_bounds(this->cap_, loc)->get_backend(context);
11411 bad_index =
11412 gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck,
11413 bad_index, loc);
11414
11415 Bexpression* cap_too_small =
11416 gogo->backend()->binary_expression(OPERATOR_LT, cap_arg, start, loc);
11417 Bexpression* cap_too_large =
11418 gogo->backend()->binary_expression(OPERATOR_GT, cap_arg, capacity, loc);
11419 Bexpression* bad_cap =
11420 gogo->backend()->binary_expression(OPERATOR_OROR, cap_too_small,
11421 cap_too_large, loc);
11422 bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_cap,
11423 bad_index, loc);
11424 }
2c809f8f 11425 }
11426
11427 Bexpression* end;
e440a328 11428 if (this->end_->is_nil_expression())
2c809f8f 11429 end = length;
e440a328 11430 else
11431 {
ea664253 11432 end = this->end_->get_backend(context);
2c809f8f 11433 end = gogo->backend()->convert_expression(int_btype, end, loc);
3d135120 11434 if (this->needs_bounds_check_)
11435 {
11436 Bexpression* bounds_bcheck =
11437 Expression::check_bounds(this->end_, loc)->get_backend(context);
11438 bad_index =
11439 gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck,
11440 bad_index, loc);
11441
11442 Bexpression* end_too_small =
11443 gogo->backend()->binary_expression(OPERATOR_LT, end, start, loc);
11444 Bexpression* end_too_large =
11445 gogo->backend()->binary_expression(OPERATOR_GT, end, cap_arg, loc);
11446 Bexpression* bad_end =
11447 gogo->backend()->binary_expression(OPERATOR_OROR, end_too_small,
11448 end_too_large, loc);
11449 bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_end,
11450 bad_index, loc);
11451 }
e440a328 11452 }
11453
2c809f8f 11454 Bexpression* result_length =
11455 gogo->backend()->binary_expression(OPERATOR_MINUS, end, start, loc);
e440a328 11456
2c809f8f 11457 Bexpression* result_capacity =
11458 gogo->backend()->binary_expression(OPERATOR_MINUS, cap_arg, start, loc);
e440a328 11459
03118c21 11460 // If the new capacity is zero, don't change val. Otherwise we can
11461 // get a pointer to the next object in memory, keeping it live
11462 // unnecessarily. When the capacity is zero, the actual pointer
11463 // value doesn't matter.
11464 Bexpression* zero =
11465 Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
11466 Bexpression* cond =
11467 gogo->backend()->binary_expression(OPERATOR_EQEQ, result_capacity, zero,
11468 loc);
11469 Bexpression* offset = gogo->backend()->conditional_expression(bfn, int_btype,
11470 cond, zero,
11471 start, loc);
44dbe1d7 11472 Expression* valptr = array_type->get_value_pointer(gogo, this->array_,
11473 this->is_lvalue_);
03118c21 11474 Bexpression* val = valptr->get_backend(context);
11475 val = gogo->backend()->pointer_offset_expression(val, offset, loc);
11476
2c809f8f 11477 Btype* struct_btype = this->type()->get_backend(gogo);
11478 std::vector<Bexpression*> init;
11479 init.push_back(val);
11480 init.push_back(result_length);
11481 init.push_back(result_capacity);
e440a328 11482
3d135120 11483 Bexpression* ret =
2c809f8f 11484 gogo->backend()->constructor_expression(struct_btype, init, loc);
3d135120 11485 if (this->needs_bounds_check_)
11486 ret = gogo->backend()->conditional_expression(bfn, struct_btype, bad_index,
11487 crash, ret, loc);
11488 return ret;
e440a328 11489}
11490
d751bb78 11491// Dump ast representation for an array index expression.
11492
11493void
f03a9fbf 11494Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 11495 const
11496{
f03a9fbf 11497 Index_expression::dump_index_expression(ast_dump_context, this->array_,
acf2b673 11498 this->start_, this->end_, this->cap_);
d751bb78 11499}
11500
acf2b673 11501// Make an array index expression. END and CAP may be NULL.
e440a328 11502
11503Expression*
11504Expression::make_array_index(Expression* array, Expression* start,
acf2b673 11505 Expression* end, Expression* cap,
11506 Location location)
e440a328 11507{
acf2b673 11508 return new Array_index_expression(array, start, end, cap, location);
e440a328 11509}
11510
50075d74 11511// Class String_index_expression.
e440a328 11512
11513// String index traversal.
11514
11515int
11516String_index_expression::do_traverse(Traverse* traverse)
11517{
11518 if (Expression::traverse(&this->string_, traverse) == TRAVERSE_EXIT)
11519 return TRAVERSE_EXIT;
11520 if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
11521 return TRAVERSE_EXIT;
11522 if (this->end_ != NULL)
11523 {
11524 if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
11525 return TRAVERSE_EXIT;
11526 }
11527 return TRAVERSE_CONTINUE;
11528}
11529
2c809f8f 11530Expression*
11531String_index_expression::do_flatten(Gogo*, Named_object*,
11532 Statement_inserter* inserter)
e440a328 11533{
2c809f8f 11534 Location loc = this->location();
5bf8be8b 11535 Expression* string = this->string_;
11536 Expression* start = this->start_;
11537 Expression* end = this->end_;
11538 if (string->is_error_expression()
11539 || string->type()->is_error_type()
11540 || start->is_error_expression()
11541 || start->type()->is_error_type()
11542 || (end != NULL
11543 && (end->is_error_expression() || end->type()->is_error_type())))
11544 {
11545 go_assert(saw_errors());
11546 return Expression::make_error(loc);
11547 }
11548
11549 Temporary_statement* temp;
2c809f8f 11550 if (!this->string_->is_variable())
11551 {
11552 temp = Statement::make_temporary(NULL, this->string_, loc);
11553 inserter->insert(temp);
11554 this->string_ = Expression::make_temporary_reference(temp, loc);
11555 }
11556 if (!this->start_->is_variable())
11557 {
11558 temp = Statement::make_temporary(NULL, this->start_, loc);
11559 inserter->insert(temp);
11560 this->start_ = Expression::make_temporary_reference(temp, loc);
11561 }
11562 if (this->end_ != NULL
11563 && !this->end_->is_nil_expression()
11564 && !this->end_->is_variable())
11565 {
11566 temp = Statement::make_temporary(NULL, this->end_, loc);
11567 inserter->insert(temp);
11568 this->end_ = Expression::make_temporary_reference(temp, loc);
11569 }
11570
11571 return this;
11572}
11573
11574// Return the type of a string index.
11575
11576Type*
11577String_index_expression::do_type()
11578{
11579 if (this->end_ == NULL)
11580 return Type::lookup_integer_type("uint8");
11581 else
11582 return this->string_->type();
11583}
11584
11585// Determine the type of a string index.
11586
11587void
11588String_index_expression::do_determine_type(const Type_context*)
11589{
11590 this->string_->determine_type_no_context();
f77aa642 11591
11592 Type_context index_context(Type::lookup_integer_type("int"), false);
11593 if (this->start_->is_constant())
11594 this->start_->determine_type(&index_context);
11595 else
11596 this->start_->determine_type_no_context();
e440a328 11597 if (this->end_ != NULL)
f77aa642 11598 {
11599 if (this->end_->is_constant())
11600 this->end_->determine_type(&index_context);
11601 else
11602 this->end_->determine_type_no_context();
11603 }
e440a328 11604}
11605
11606// Check types of a string index.
11607
11608void
11609String_index_expression::do_check_types(Gogo*)
11610{
acdc230d 11611 Numeric_constant nc;
11612 unsigned long v;
11613 if (this->start_->type()->integer_type() == NULL
11614 && !this->start_->type()->is_error()
11615 && (!this->start_->numeric_constant_value(&nc)
11616 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 11617 this->report_error(_("index must be integer"));
11618 if (this->end_ != NULL
11619 && this->end_->type()->integer_type() == NULL
acdc230d 11620 && !this->end_->type()->is_error()
11621 && !this->end_->is_nil_expression()
11622 && !this->end_->is_error_expression()
11623 && (!this->end_->numeric_constant_value(&nc)
11624 || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
e440a328 11625 this->report_error(_("slice end must be integer"));
11626
11627 std::string sval;
11628 bool sval_valid = this->string_->string_constant_value(&sval);
11629
0c77715b 11630 Numeric_constant inc;
e440a328 11631 mpz_t ival;
0bd5d859 11632 bool ival_valid = false;
0c77715b 11633 if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
e440a328 11634 {
0bd5d859 11635 ival_valid = true;
e440a328 11636 if (mpz_sgn(ival) < 0
b10f32fb 11637 || (sval_valid
11638 && (this->end_ == NULL
11639 ? mpz_cmp_ui(ival, sval.length()) >= 0
11640 : mpz_cmp_ui(ival, sval.length()) > 0)))
e440a328 11641 {
631d5788 11642 go_error_at(this->start_->location(), "string index out of bounds");
e440a328 11643 this->set_is_error();
11644 }
11645 }
11646 if (this->end_ != NULL && !this->end_->is_nil_expression())
11647 {
0c77715b 11648 Numeric_constant enc;
11649 mpz_t eval;
11650 if (this->end_->numeric_constant_value(&enc) && enc.to_int(&eval))
e440a328 11651 {
0c77715b 11652 if (mpz_sgn(eval) < 0
11653 || (sval_valid && mpz_cmp_ui(eval, sval.length()) > 0))
e440a328 11654 {
631d5788 11655 go_error_at(this->end_->location(), "string index out of bounds");
e440a328 11656 this->set_is_error();
11657 }
0bd5d859 11658 else if (ival_valid && mpz_cmp(ival, eval) > 0)
11659 this->report_error(_("inverted slice range"));
0c77715b 11660 mpz_clear(eval);
e440a328 11661 }
11662 }
0bd5d859 11663 if (ival_valid)
11664 mpz_clear(ival);
e440a328 11665}
11666
ea664253 11667// Get the backend representation for a string index.
e440a328 11668
ea664253 11669Bexpression*
11670String_index_expression::do_get_backend(Translate_context* context)
e440a328 11671{
b13c66cd 11672 Location loc = this->location();
2c809f8f 11673 Expression* string_arg = this->string_;
11674 if (this->string_->type()->points_to() != NULL)
f614ea8b 11675 string_arg = Expression::make_dereference(this->string_,
11676 NIL_CHECK_NOT_NEEDED, loc);
e440a328 11677
2c809f8f 11678 Expression* bad_index = Expression::check_bounds(this->start_, loc);
e440a328 11679
2c809f8f 11680 int code = (this->end_ == NULL
11681 ? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS
11682 : RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS);
e440a328 11683
2c809f8f 11684 Gogo* gogo = context->gogo();
ea664253 11685 Bexpression* crash = gogo->runtime_error(code, loc)->get_backend(context);
1b1f2abf 11686
11687 Type* int_type = Type::lookup_integer_type("int");
e440a328 11688
2c809f8f 11689 // It is possible that an error occurred earlier because the start index
11690 // cannot be represented as an integer type. In this case, we shouldn't
11691 // try casting the starting index into an integer since
11692 // Type_conversion_expression will fail to get the backend representation.
11693 // FIXME.
11694 if (this->start_->type()->integer_type() == NULL
11695 && !Type::are_convertible(int_type, this->start_->type(), NULL))
11696 {
11697 go_assert(saw_errors());
ea664253 11698 return context->backend()->error_expression();
2c809f8f 11699 }
e440a328 11700
2c809f8f 11701 Expression* start = Expression::make_cast(int_type, this->start_, loc);
93715b75 11702 Bfunction* bfn = context->function()->func_value()->get_decl();
e440a328 11703
2c809f8f 11704 if (this->end_ == NULL)
11705 {
11706 Expression* length =
11707 Expression::make_string_info(this->string_, STRING_INFO_LENGTH, loc);
e440a328 11708
2c809f8f 11709 Expression* start_too_large =
11710 Expression::make_binary(OPERATOR_GE, start, length, loc);
11711 bad_index = Expression::make_binary(OPERATOR_OROR, start_too_large,
11712 bad_index, loc);
11713 Expression* bytes =
11714 Expression::make_string_info(this->string_, STRING_INFO_DATA, loc);
e440a328 11715
ea664253 11716 Bexpression* bstart = start->get_backend(context);
11717 Bexpression* ptr = bytes->get_backend(context);
2c809f8f 11718 ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc);
9b27b43c 11719 Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
f03a9fbf 11720 Bexpression* index =
9b27b43c 11721 gogo->backend()->indirect_expression(ubtype, ptr, true, loc);
e440a328 11722
2c809f8f 11723 Btype* byte_btype = bytes->type()->points_to()->get_backend(gogo);
ea664253 11724 Bexpression* index_error = bad_index->get_backend(context);
93715b75 11725 return gogo->backend()->conditional_expression(bfn, byte_btype,
11726 index_error, crash,
11727 index, loc);
2c809f8f 11728 }
11729
11730 Expression* end = NULL;
11731 if (this->end_->is_nil_expression())
e67508fa 11732 end = Expression::make_integer_sl(-1, int_type, loc);
e440a328 11733 else
11734 {
2c809f8f 11735 Expression* bounds_check = Expression::check_bounds(this->end_, loc);
11736 bad_index =
11737 Expression::make_binary(OPERATOR_OROR, bounds_check, bad_index, loc);
11738 end = Expression::make_cast(int_type, this->end_, loc);
e440a328 11739 }
2c809f8f 11740
11741 Expression* strslice = Runtime::make_call(Runtime::STRING_SLICE, loc, 3,
11742 string_arg, start, end);
ea664253 11743 Bexpression* bstrslice = strslice->get_backend(context);
2c809f8f 11744
11745 Btype* str_btype = strslice->type()->get_backend(gogo);
ea664253 11746 Bexpression* index_error = bad_index->get_backend(context);
93715b75 11747 return gogo->backend()->conditional_expression(bfn, str_btype, index_error,
ea664253 11748 crash, bstrslice, loc);
e440a328 11749}
11750
d751bb78 11751// Dump ast representation for a string index expression.
11752
11753void
11754String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
11755 const
11756{
acf2b673 11757 Index_expression::dump_index_expression(ast_dump_context, this->string_,
11758 this->start_, this->end_, NULL);
d751bb78 11759}
11760
e440a328 11761// Make a string index expression. END may be NULL.
11762
11763Expression*
11764Expression::make_string_index(Expression* string, Expression* start,
b13c66cd 11765 Expression* end, Location location)
e440a328 11766{
11767 return new String_index_expression(string, start, end, location);
11768}
11769
11770// Class Map_index.
11771
11772// Get the type of the map.
11773
11774Map_type*
11775Map_index_expression::get_map_type() const
11776{
0d5530d9 11777 Map_type* mt = this->map_->type()->map_type();
c7524fae 11778 if (mt == NULL)
c484d925 11779 go_assert(saw_errors());
e440a328 11780 return mt;
11781}
11782
11783// Map index traversal.
11784
11785int
11786Map_index_expression::do_traverse(Traverse* traverse)
11787{
11788 if (Expression::traverse(&this->map_, traverse) == TRAVERSE_EXIT)
11789 return TRAVERSE_EXIT;
11790 return Expression::traverse(&this->index_, traverse);
11791}
11792
2c809f8f 11793// We need to pass in a pointer to the key, so flatten the index into a
11794// temporary variable if it isn't already. The value pointer will be
11795// dereferenced and checked for nil, so flatten into a temporary to avoid
11796// recomputation.
11797
11798Expression*
91c0fd76 11799Map_index_expression::do_flatten(Gogo* gogo, Named_object*,
2c809f8f 11800 Statement_inserter* inserter)
11801{
91c0fd76 11802 Location loc = this->location();
2c809f8f 11803 Map_type* mt = this->get_map_type();
5bf8be8b 11804 if (this->index()->is_error_expression()
11805 || this->index()->type()->is_error_type()
11806 || mt->is_error_type())
11807 {
11808 go_assert(saw_errors());
11809 return Expression::make_error(loc);
11810 }
11811
3a522dcc 11812 if (!Type::are_identical(mt->key_type(), this->index_->type(),
11813 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
11814 NULL))
91c0fd76 11815 {
11816 if (this->index_->type()->interface_type() != NULL
11817 && !this->index_->is_variable())
11818 {
11819 Temporary_statement* temp =
11820 Statement::make_temporary(NULL, this->index_, loc);
11821 inserter->insert(temp);
11822 this->index_ = Expression::make_temporary_reference(temp, loc);
11823 }
11824 this->index_ = Expression::convert_for_assignment(gogo, mt->key_type(),
11825 this->index_, loc);
11826 }
2c809f8f 11827
11828 if (!this->index_->is_variable())
11829 {
11830 Temporary_statement* temp = Statement::make_temporary(NULL, this->index_,
91c0fd76 11831 loc);
2c809f8f 11832 inserter->insert(temp);
91c0fd76 11833 this->index_ = Expression::make_temporary_reference(temp, loc);
2c809f8f 11834 }
11835
11836 if (this->value_pointer_ == NULL)
0d5530d9 11837 this->get_value_pointer(gogo);
5bf8be8b 11838 if (this->value_pointer_->is_error_expression()
11839 || this->value_pointer_->type()->is_error_type())
11840 return Expression::make_error(loc);
2c809f8f 11841 if (!this->value_pointer_->is_variable())
11842 {
11843 Temporary_statement* temp =
91c0fd76 11844 Statement::make_temporary(NULL, this->value_pointer_, loc);
2c809f8f 11845 inserter->insert(temp);
91c0fd76 11846 this->value_pointer_ = Expression::make_temporary_reference(temp, loc);
2c809f8f 11847 }
11848
11849 return this;
11850}
11851
e440a328 11852// Return the type of a map index.
11853
11854Type*
11855Map_index_expression::do_type()
11856{
c7524fae 11857 Map_type* mt = this->get_map_type();
11858 if (mt == NULL)
11859 return Type::make_error_type();
0d5530d9 11860 return mt->val_type();
e440a328 11861}
11862
11863// Fix the type of a map index.
11864
11865void
11866Map_index_expression::do_determine_type(const Type_context*)
11867{
11868 this->map_->determine_type_no_context();
c7524fae 11869 Map_type* mt = this->get_map_type();
11870 Type* key_type = mt == NULL ? NULL : mt->key_type();
11871 Type_context subcontext(key_type, false);
e440a328 11872 this->index_->determine_type(&subcontext);
11873}
11874
11875// Check types of a map index.
11876
11877void
11878Map_index_expression::do_check_types(Gogo*)
11879{
11880 std::string reason;
c7524fae 11881 Map_type* mt = this->get_map_type();
11882 if (mt == NULL)
11883 return;
11884 if (!Type::are_assignable(mt->key_type(), this->index_->type(), &reason))
e440a328 11885 {
11886 if (reason.empty())
11887 this->report_error(_("incompatible type for map index"));
11888 else
11889 {
631d5788 11890 go_error_at(this->location(), "incompatible type for map index (%s)",
11891 reason.c_str());
e440a328 11892 this->set_is_error();
11893 }
11894 }
11895}
11896
ea664253 11897// Get the backend representation for a map index.
e440a328 11898
ea664253 11899Bexpression*
11900Map_index_expression::do_get_backend(Translate_context* context)
e440a328 11901{
11902 Map_type* type = this->get_map_type();
c7524fae 11903 if (type == NULL)
2c809f8f 11904 {
11905 go_assert(saw_errors());
ea664253 11906 return context->backend()->error_expression();
2c809f8f 11907 }
e440a328 11908
2c809f8f 11909 go_assert(this->value_pointer_ != NULL
11910 && this->value_pointer_->is_variable());
e440a328 11911
f614ea8b 11912 Expression* val = Expression::make_dereference(this->value_pointer_,
11913 NIL_CHECK_NOT_NEEDED,
11914 this->location());
0d5530d9 11915 return val->get_backend(context);
e440a328 11916}
11917
0d5530d9 11918// Get an expression for the map index. This returns an expression
11919// that evaluates to a pointer to a value. If the key is not in the
11920// map, the pointer will point to a zero value.
e440a328 11921
2c809f8f 11922Expression*
0d5530d9 11923Map_index_expression::get_value_pointer(Gogo* gogo)
e440a328 11924{
2c809f8f 11925 if (this->value_pointer_ == NULL)
746d2e73 11926 {
2c809f8f 11927 Map_type* type = this->get_map_type();
11928 if (type == NULL)
746d2e73 11929 {
2c809f8f 11930 go_assert(saw_errors());
11931 return Expression::make_error(this->location());
746d2e73 11932 }
e440a328 11933
2c809f8f 11934 Location loc = this->location();
11935 Expression* map_ref = this->map_;
e440a328 11936
0d5530d9 11937 Expression* index_ptr = Expression::make_unary(OPERATOR_AND,
11938 this->index_,
2c809f8f 11939 loc);
0d5530d9 11940
11941 Expression* zero = type->fat_zero_value(gogo);
11942
11943 Expression* map_index;
11944
11945 if (zero == NULL)
11946 map_index =
11947 Runtime::make_call(Runtime::MAPACCESS1, loc, 3,
11948 Expression::make_type_descriptor(type, loc),
11949 map_ref, index_ptr);
11950 else
11951 map_index =
11952 Runtime::make_call(Runtime::MAPACCESS1_FAT, loc, 4,
11953 Expression::make_type_descriptor(type, loc),
11954 map_ref, index_ptr, zero);
2c809f8f 11955
11956 Type* val_type = type->val_type();
11957 this->value_pointer_ =
11958 Expression::make_unsafe_cast(Type::make_pointer_type(val_type),
11959 map_index, this->location());
11960 }
0d5530d9 11961
2c809f8f 11962 return this->value_pointer_;
e440a328 11963}
11964
d751bb78 11965// Dump ast representation for a map index expression
11966
11967void
f03a9fbf 11968Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 11969 const
11970{
acf2b673 11971 Index_expression::dump_index_expression(ast_dump_context, this->map_,
11972 this->index_, NULL, NULL);
d751bb78 11973}
11974
e440a328 11975// Make a map index expression.
11976
11977Map_index_expression*
11978Expression::make_map_index(Expression* map, Expression* index,
b13c66cd 11979 Location location)
e440a328 11980{
11981 return new Map_index_expression(map, index, location);
11982}
11983
11984// Class Field_reference_expression.
11985
149eabc5 11986// Lower a field reference expression. There is nothing to lower, but
11987// this is where we generate the tracking information for fields with
11988// the magic go:"track" tag.
11989
11990Expression*
11991Field_reference_expression::do_lower(Gogo* gogo, Named_object* function,
11992 Statement_inserter* inserter, int)
11993{
11994 Struct_type* struct_type = this->expr_->type()->struct_type();
11995 if (struct_type == NULL)
11996 {
11997 // Error will be reported elsewhere.
11998 return this;
11999 }
12000 const Struct_field* field = struct_type->field(this->field_index_);
12001 if (field == NULL)
12002 return this;
12003 if (!field->has_tag())
12004 return this;
12005 if (field->tag().find("go:\"track\"") == std::string::npos)
12006 return this;
12007
604e278d 12008 // References from functions generated by the compiler don't count.
c6292d1d 12009 if (function != NULL && function->func_value()->is_type_specific_function())
604e278d 12010 return this;
12011
149eabc5 12012 // We have found a reference to a tracked field. Build a call to
12013 // the runtime function __go_fieldtrack with a string that describes
12014 // the field. FIXME: We should only call this once per referenced
12015 // field per function, not once for each reference to the field.
12016
12017 if (this->called_fieldtrack_)
12018 return this;
12019 this->called_fieldtrack_ = true;
12020
12021 Location loc = this->location();
12022
12023 std::string s = "fieldtrack \"";
e65055a5 12024 Named_type* nt = this->expr_->type()->unalias()->named_type();
149eabc5 12025 if (nt == NULL || nt->named_object()->package() == NULL)
12026 s.append(gogo->pkgpath());
12027 else
12028 s.append(nt->named_object()->package()->pkgpath());
12029 s.push_back('.');
12030 if (nt != NULL)
5c29ad36 12031 s.append(Gogo::unpack_hidden_name(nt->name()));
149eabc5 12032 s.push_back('.');
12033 s.append(field->field_name());
12034 s.push_back('"');
12035
12036 // We can't use a string here, because internally a string holds a
12037 // pointer to the actual bytes; when the linker garbage collects the
12038 // string, it won't garbage collect the bytes. So we use a
12039 // [...]byte.
12040
e67508fa 12041 Expression* length_expr = Expression::make_integer_ul(s.length(), NULL, loc);
149eabc5 12042
12043 Type* byte_type = gogo->lookup_global("byte")->type_value();
6bf4793c 12044 Array_type* array_type = Type::make_array_type(byte_type, length_expr);
12045 array_type->set_is_array_incomparable();
149eabc5 12046
12047 Expression_list* bytes = new Expression_list();
12048 for (std::string::const_iterator p = s.begin(); p != s.end(); p++)
12049 {
e67508fa 12050 unsigned char c = static_cast<unsigned char>(*p);
12051 bytes->push_back(Expression::make_integer_ul(c, NULL, loc));
149eabc5 12052 }
12053
12054 Expression* e = Expression::make_composite_literal(array_type, 0, false,
62750cd5 12055 bytes, false, loc);
149eabc5 12056
12057 Variable* var = new Variable(array_type, e, true, false, false, loc);
12058
12059 static int count;
12060 char buf[50];
12061 snprintf(buf, sizeof buf, "fieldtrack.%d", count);
12062 ++count;
12063
12064 Named_object* no = gogo->add_variable(buf, var);
12065 e = Expression::make_var_reference(no, loc);
12066 e = Expression::make_unary(OPERATOR_AND, e, loc);
12067
12068 Expression* call = Runtime::make_call(Runtime::FIELDTRACK, loc, 1, e);
604e278d 12069 gogo->lower_expression(function, inserter, &call);
149eabc5 12070 inserter->insert(Statement::make_statement(call, false));
12071
12072 // Put this function, and the global variable we just created, into
12073 // unique sections. This will permit the linker to garbage collect
12074 // them if they are not referenced. The effect is that the only
12075 // strings, indicating field references, that will wind up in the
12076 // executable will be those for functions that are actually needed.
66a6be58 12077 if (function != NULL)
12078 function->func_value()->set_in_unique_section();
149eabc5 12079 var->set_in_unique_section();
12080
12081 return this;
12082}
12083
e440a328 12084// Return the type of a field reference.
12085
12086Type*
12087Field_reference_expression::do_type()
12088{
b0e628fb 12089 Type* type = this->expr_->type();
5c13bd80 12090 if (type->is_error())
b0e628fb 12091 return type;
12092 Struct_type* struct_type = type->struct_type();
c484d925 12093 go_assert(struct_type != NULL);
e440a328 12094 return struct_type->field(this->field_index_)->type();
12095}
12096
12097// Check the types for a field reference.
12098
12099void
12100Field_reference_expression::do_check_types(Gogo*)
12101{
b0e628fb 12102 Type* type = this->expr_->type();
5c13bd80 12103 if (type->is_error())
b0e628fb 12104 return;
12105 Struct_type* struct_type = type->struct_type();
c484d925 12106 go_assert(struct_type != NULL);
12107 go_assert(struct_type->field(this->field_index_) != NULL);
e440a328 12108}
12109
ea664253 12110// Get the backend representation for a field reference.
e440a328 12111
ea664253 12112Bexpression*
12113Field_reference_expression::do_get_backend(Translate_context* context)
e440a328 12114{
ea664253 12115 Bexpression* bstruct = this->expr_->get_backend(context);
12116 return context->gogo()->backend()->struct_field_expression(bstruct,
12117 this->field_index_,
12118 this->location());
e440a328 12119}
12120
d751bb78 12121// Dump ast representation for a field reference expression.
12122
12123void
12124Field_reference_expression::do_dump_expression(
12125 Ast_dump_context* ast_dump_context) const
12126{
12127 this->expr_->dump_expression(ast_dump_context);
12128 ast_dump_context->ostream() << "." << this->field_index_;
12129}
12130
e440a328 12131// Make a reference to a qualified identifier in an expression.
12132
12133Field_reference_expression*
12134Expression::make_field_reference(Expression* expr, unsigned int field_index,
b13c66cd 12135 Location location)
e440a328 12136{
12137 return new Field_reference_expression(expr, field_index, location);
12138}
12139
12140// Class Interface_field_reference_expression.
12141
2387f644 12142// Return an expression for the pointer to the function to call.
e440a328 12143
2387f644 12144Expression*
12145Interface_field_reference_expression::get_function()
e440a328 12146{
2387f644 12147 Expression* ref = this->expr_;
12148 Location loc = this->location();
12149 if (ref->type()->points_to() != NULL)
f614ea8b 12150 ref = Expression::make_dereference(ref, NIL_CHECK_DEFAULT, loc);
e440a328 12151
2387f644 12152 Expression* mtable =
12153 Expression::make_interface_info(ref, INTERFACE_INFO_METHODS, loc);
12154 Struct_type* mtable_type = mtable->type()->points_to()->struct_type();
e440a328 12155
12156 std::string name = Gogo::unpack_hidden_name(this->name_);
2387f644 12157 unsigned int index;
12158 const Struct_field* field = mtable_type->find_local_field(name, &index);
12159 go_assert(field != NULL);
f614ea8b 12160
12161 mtable = Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, loc);
2387f644 12162 return Expression::make_field_reference(mtable, index, loc);
e440a328 12163}
12164
2387f644 12165// Return an expression for the first argument to pass to the interface
e440a328 12166// function.
12167
2387f644 12168Expression*
12169Interface_field_reference_expression::get_underlying_object()
e440a328 12170{
2387f644 12171 Expression* expr = this->expr_;
12172 if (expr->type()->points_to() != NULL)
f614ea8b 12173 expr = Expression::make_dereference(expr, NIL_CHECK_DEFAULT,
12174 this->location());
2387f644 12175 return Expression::make_interface_info(expr, INTERFACE_INFO_OBJECT,
12176 this->location());
e440a328 12177}
12178
12179// Traversal.
12180
12181int
12182Interface_field_reference_expression::do_traverse(Traverse* traverse)
12183{
12184 return Expression::traverse(&this->expr_, traverse);
12185}
12186
0afbb937 12187// Lower the expression. If this expression is not called, we need to
12188// evaluate the expression twice when converting to the backend
12189// interface. So introduce a temporary variable if necessary.
12190
12191Expression*
9782d556 12192Interface_field_reference_expression::do_flatten(Gogo*, Named_object*,
12193 Statement_inserter* inserter)
0afbb937 12194{
5bf8be8b 12195 if (this->expr_->is_error_expression()
12196 || this->expr_->type()->is_error_type())
12197 {
12198 go_assert(saw_errors());
12199 return Expression::make_error(this->location());
12200 }
12201
2387f644 12202 if (!this->expr_->is_variable())
0afbb937 12203 {
12204 Temporary_statement* temp =
9189e53b 12205 Statement::make_temporary(NULL, this->expr_, this->location());
0afbb937 12206 inserter->insert(temp);
9189e53b 12207 this->expr_ = Expression::make_temporary_reference(temp, this->location());
0afbb937 12208 }
12209 return this;
12210}
12211
e440a328 12212// Return the type of an interface field reference.
12213
12214Type*
12215Interface_field_reference_expression::do_type()
12216{
12217 Type* expr_type = this->expr_->type();
12218
12219 Type* points_to = expr_type->points_to();
12220 if (points_to != NULL)
12221 expr_type = points_to;
12222
12223 Interface_type* interface_type = expr_type->interface_type();
12224 if (interface_type == NULL)
12225 return Type::make_error_type();
12226
12227 const Typed_identifier* method = interface_type->find_method(this->name_);
12228 if (method == NULL)
12229 return Type::make_error_type();
12230
12231 return method->type();
12232}
12233
12234// Determine types.
12235
12236void
12237Interface_field_reference_expression::do_determine_type(const Type_context*)
12238{
12239 this->expr_->determine_type_no_context();
12240}
12241
12242// Check the types for an interface field reference.
12243
12244void
12245Interface_field_reference_expression::do_check_types(Gogo*)
12246{
12247 Type* type = this->expr_->type();
12248
12249 Type* points_to = type->points_to();
12250 if (points_to != NULL)
12251 type = points_to;
12252
12253 Interface_type* interface_type = type->interface_type();
12254 if (interface_type == NULL)
5c491127 12255 {
12256 if (!type->is_error_type())
12257 this->report_error(_("expected interface or pointer to interface"));
12258 }
e440a328 12259 else
12260 {
12261 const Typed_identifier* method =
12262 interface_type->find_method(this->name_);
12263 if (method == NULL)
12264 {
631d5788 12265 go_error_at(this->location(), "method %qs not in interface",
12266 Gogo::message_name(this->name_).c_str());
e440a328 12267 this->set_is_error();
12268 }
12269 }
12270}
12271
0afbb937 12272// If an interface field reference is not simply called, then it is
12273// represented as a closure. The closure will hold a single variable,
12274// the value of the interface on which the method should be called.
12275// The function will be a simple thunk that pulls the value from the
12276// closure and calls the method with the remaining arguments.
12277
12278// Because method values are not common, we don't build all thunks for
12279// all possible interface methods, but instead only build them as we
12280// need them. In particular, we even build them on demand for
12281// interface methods defined in other packages.
12282
12283Interface_field_reference_expression::Interface_method_thunks
12284 Interface_field_reference_expression::interface_method_thunks;
12285
12286// Find or create the thunk to call method NAME on TYPE.
12287
12288Named_object*
12289Interface_field_reference_expression::create_thunk(Gogo* gogo,
12290 Interface_type* type,
12291 const std::string& name)
12292{
12293 std::pair<Interface_type*, Method_thunks*> val(type, NULL);
12294 std::pair<Interface_method_thunks::iterator, bool> ins =
12295 Interface_field_reference_expression::interface_method_thunks.insert(val);
12296 if (ins.second)
12297 {
12298 // This is the first time we have seen this interface.
12299 ins.first->second = new Method_thunks();
12300 }
12301
12302 for (Method_thunks::const_iterator p = ins.first->second->begin();
12303 p != ins.first->second->end();
12304 p++)
12305 if (p->first == name)
12306 return p->second;
12307
12308 Location loc = type->location();
12309
12310 const Typed_identifier* method_id = type->find_method(name);
12311 if (method_id == NULL)
13f2fdb8 12312 return Named_object::make_erroneous_name(gogo->thunk_name());
0afbb937 12313
12314 Function_type* orig_fntype = method_id->type()->function_type();
12315 if (orig_fntype == NULL)
13f2fdb8 12316 return Named_object::make_erroneous_name(gogo->thunk_name());
0afbb937 12317
12318 Struct_field_list* sfl = new Struct_field_list();
f8bdf81a 12319 // The type here is wrong--it should be the C function type. But it
12320 // doesn't really matter.
0afbb937 12321 Type* vt = Type::make_pointer_type(Type::make_void_type());
13f2fdb8 12322 sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
12323 sfl->push_back(Struct_field(Typed_identifier("val", type, loc)));
6bf4793c 12324 Struct_type* st = Type::make_struct_type(sfl, loc);
12325 st->set_is_struct_incomparable();
12326 Type* closure_type = Type::make_pointer_type(st);
0afbb937 12327
f8bdf81a 12328 Function_type* new_fntype = orig_fntype->copy_with_names();
0afbb937 12329
13f2fdb8 12330 std::string thunk_name = gogo->thunk_name();
da244e59 12331 Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
0afbb937 12332 false, loc);
12333
f8bdf81a 12334 Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
12335 cvar->set_is_used();
1ecc6157 12336 cvar->set_is_closure();
da244e59 12337 Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
12338 NULL, cvar);
f8bdf81a 12339 new_no->func_value()->set_closure_var(cp);
0afbb937 12340
f8bdf81a 12341 gogo->start_block(loc);
0afbb937 12342
12343 // Field 0 of the closure is the function code pointer, field 1 is
12344 // the value on which to invoke the method.
12345 Expression* arg = Expression::make_var_reference(cp, loc);
f614ea8b 12346 arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
0afbb937 12347 arg = Expression::make_field_reference(arg, 1, loc);
12348
12349 Expression *ifre = Expression::make_interface_field_reference(arg, name,
12350 loc);
12351
12352 const Typed_identifier_list* orig_params = orig_fntype->parameters();
12353 Expression_list* args;
12354 if (orig_params == NULL || orig_params->empty())
12355 args = NULL;
12356 else
12357 {
12358 const Typed_identifier_list* new_params = new_fntype->parameters();
12359 args = new Expression_list();
12360 for (Typed_identifier_list::const_iterator p = new_params->begin();
f8bdf81a 12361 p != new_params->end();
0afbb937 12362 ++p)
12363 {
12364 Named_object* p_no = gogo->lookup(p->name(), NULL);
12365 go_assert(p_no != NULL
12366 && p_no->is_variable()
12367 && p_no->var_value()->is_parameter());
12368 args->push_back(Expression::make_var_reference(p_no, loc));
12369 }
12370 }
12371
12372 Call_expression* call = Expression::make_call(ifre, args,
12373 orig_fntype->is_varargs(),
12374 loc);
12375 call->set_varargs_are_lowered();
12376
12377 Statement* s = Statement::make_return_from_call(call, loc);
12378 gogo->add_statement(s);
12379 Block* b = gogo->finish_block(loc);
12380 gogo->add_block(b, loc);
12381 gogo->lower_block(new_no, b);
a32698ee 12382 gogo->flatten_block(new_no, b);
0afbb937 12383 gogo->finish_function(loc);
12384
12385 ins.first->second->push_back(std::make_pair(name, new_no));
12386 return new_no;
12387}
12388
ea664253 12389// Get the backend representation for a method value.
e440a328 12390
ea664253 12391Bexpression*
12392Interface_field_reference_expression::do_get_backend(Translate_context* context)
e440a328 12393{
0afbb937 12394 Interface_type* type = this->expr_->type()->interface_type();
12395 if (type == NULL)
12396 {
12397 go_assert(saw_errors());
ea664253 12398 return context->backend()->error_expression();
0afbb937 12399 }
12400
12401 Named_object* thunk =
12402 Interface_field_reference_expression::create_thunk(context->gogo(),
12403 type, this->name_);
12404 if (thunk->is_erroneous())
12405 {
12406 go_assert(saw_errors());
ea664253 12407 return context->backend()->error_expression();
0afbb937 12408 }
12409
12410 // FIXME: We should lower this earlier, but we can't it lower it in
12411 // the lowering pass because at that point we don't know whether we
12412 // need to create the thunk or not. If the expression is called, we
12413 // don't need the thunk.
12414
12415 Location loc = this->location();
12416
12417 Struct_field_list* fields = new Struct_field_list();
13f2fdb8 12418 fields->push_back(Struct_field(Typed_identifier("fn",
0afbb937 12419 thunk->func_value()->type(),
12420 loc)));
13f2fdb8 12421 fields->push_back(Struct_field(Typed_identifier("val",
0afbb937 12422 this->expr_->type(),
12423 loc)));
12424 Struct_type* st = Type::make_struct_type(fields, loc);
6bf4793c 12425 st->set_is_struct_incomparable();
0afbb937 12426
12427 Expression_list* vals = new Expression_list();
12428 vals->push_back(Expression::make_func_code_reference(thunk, loc));
12429 vals->push_back(this->expr_);
12430
12431 Expression* expr = Expression::make_struct_composite_literal(st, vals, loc);
ea664253 12432 Bexpression* bclosure =
12433 Expression::make_heap_expression(expr, loc)->get_backend(context);
0afbb937 12434
4df0c2d4 12435 Gogo* gogo = context->gogo();
12436 Btype* btype = this->type()->get_backend(gogo);
12437 bclosure = gogo->backend()->convert_expression(btype, bclosure, loc);
12438
2387f644 12439 Expression* nil_check =
12440 Expression::make_binary(OPERATOR_EQEQ, this->expr_,
12441 Expression::make_nil(loc), loc);
ea664253 12442 Bexpression* bnil_check = nil_check->get_backend(context);
0afbb937 12443
ea664253 12444 Bexpression* bcrash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
12445 loc)->get_backend(context);
2387f644 12446
93715b75 12447 Bfunction* bfn = context->function()->func_value()->get_decl();
2387f644 12448 Bexpression* bcond =
93715b75 12449 gogo->backend()->conditional_expression(bfn, NULL,
12450 bnil_check, bcrash, NULL, loc);
0ab48656 12451 Bfunction* bfunction = context->function()->func_value()->get_decl();
12452 Bstatement* cond_statement =
12453 gogo->backend()->expression_statement(bfunction, bcond);
ea664253 12454 return gogo->backend()->compound_expression(cond_statement, bclosure, loc);
e440a328 12455}
12456
d751bb78 12457// Dump ast representation for an interface field reference.
12458
12459void
12460Interface_field_reference_expression::do_dump_expression(
12461 Ast_dump_context* ast_dump_context) const
12462{
12463 this->expr_->dump_expression(ast_dump_context);
12464 ast_dump_context->ostream() << "." << this->name_;
12465}
12466
e440a328 12467// Make a reference to a field in an interface.
12468
12469Expression*
12470Expression::make_interface_field_reference(Expression* expr,
12471 const std::string& field,
b13c66cd 12472 Location location)
e440a328 12473{
12474 return new Interface_field_reference_expression(expr, field, location);
12475}
12476
12477// A general selector. This is a Parser_expression for LEFT.NAME. It
12478// is lowered after we know the type of the left hand side.
12479
12480class Selector_expression : public Parser_expression
12481{
12482 public:
12483 Selector_expression(Expression* left, const std::string& name,
b13c66cd 12484 Location location)
e440a328 12485 : Parser_expression(EXPRESSION_SELECTOR, location),
12486 left_(left), name_(name)
12487 { }
12488
12489 protected:
12490 int
12491 do_traverse(Traverse* traverse)
12492 { return Expression::traverse(&this->left_, traverse); }
12493
12494 Expression*
ceeb4318 12495 do_lower(Gogo*, Named_object*, Statement_inserter*, int);
e440a328 12496
12497 Expression*
12498 do_copy()
12499 {
12500 return new Selector_expression(this->left_->copy(), this->name_,
12501 this->location());
12502 }
12503
d751bb78 12504 void
12505 do_dump_expression(Ast_dump_context* ast_dump_context) const;
12506
e440a328 12507 private:
12508 Expression*
12509 lower_method_expression(Gogo*);
12510
12511 // The expression on the left hand side.
12512 Expression* left_;
12513 // The name on the right hand side.
12514 std::string name_;
12515};
12516
12517// Lower a selector expression once we know the real type of the left
12518// hand side.
12519
12520Expression*
ceeb4318 12521Selector_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*,
12522 int)
e440a328 12523{
12524 Expression* left = this->left_;
12525 if (left->is_type_expression())
12526 return this->lower_method_expression(gogo);
12527 return Type::bind_field_or_method(gogo, left->type(), left, this->name_,
12528 this->location());
12529}
12530
12531// Lower a method expression T.M or (*T).M. We turn this into a
12532// function literal.
12533
12534Expression*
12535Selector_expression::lower_method_expression(Gogo* gogo)
12536{
b13c66cd 12537 Location location = this->location();
868b439e 12538 Type* left_type = this->left_->type();
12539 Type* type = left_type;
e440a328 12540 const std::string& name(this->name_);
12541
12542 bool is_pointer;
12543 if (type->points_to() == NULL)
12544 is_pointer = false;
12545 else
12546 {
12547 is_pointer = true;
12548 type = type->points_to();
12549 }
12550 Named_type* nt = type->named_type();
12551 if (nt == NULL)
12552 {
631d5788 12553 go_error_at(location,
12554 ("method expression requires named type or "
12555 "pointer to named type"));
e440a328 12556 return Expression::make_error(location);
12557 }
12558
12559 bool is_ambiguous;
12560 Method* method = nt->method_function(name, &is_ambiguous);
ab1468c3 12561 const Typed_identifier* imethod = NULL;
dcc8506b 12562 if (method == NULL && !is_pointer)
ab1468c3 12563 {
12564 Interface_type* it = nt->interface_type();
12565 if (it != NULL)
12566 imethod = it->find_method(name);
12567 }
12568
f03a9fbf 12569 if ((method == NULL && imethod == NULL)
868b439e 12570 || (left_type->named_type() != NULL && left_type->points_to() != NULL))
e440a328 12571 {
12572 if (!is_ambiguous)
631d5788 12573 go_error_at(location, "type %<%s%s%> has no method %<%s%>",
12574 is_pointer ? "*" : "",
12575 nt->message_name().c_str(),
12576 Gogo::message_name(name).c_str());
e440a328 12577 else
631d5788 12578 go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
12579 Gogo::message_name(name).c_str(),
12580 is_pointer ? "*" : "",
12581 nt->message_name().c_str());
e440a328 12582 return Expression::make_error(location);
12583 }
12584
ab1468c3 12585 if (method != NULL && !is_pointer && !method->is_value_method())
e440a328 12586 {
631d5788 12587 go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
12588 nt->message_name().c_str(),
12589 Gogo::message_name(name).c_str());
e440a328 12590 return Expression::make_error(location);
12591 }
12592
12593 // Build a new function type in which the receiver becomes the first
12594 // argument.
ab1468c3 12595 Function_type* method_type;
12596 if (method != NULL)
12597 {
12598 method_type = method->type();
c484d925 12599 go_assert(method_type->is_method());
ab1468c3 12600 }
12601 else
12602 {
12603 method_type = imethod->type()->function_type();
c484d925 12604 go_assert(method_type != NULL && !method_type->is_method());
ab1468c3 12605 }
e440a328 12606
12607 const char* const receiver_name = "$this";
12608 Typed_identifier_list* parameters = new Typed_identifier_list();
12609 parameters->push_back(Typed_identifier(receiver_name, this->left_->type(),
12610 location));
12611
12612 const Typed_identifier_list* method_parameters = method_type->parameters();
12613 if (method_parameters != NULL)
12614 {
f470da59 12615 int i = 0;
e440a328 12616 for (Typed_identifier_list::const_iterator p = method_parameters->begin();
12617 p != method_parameters->end();
f470da59 12618 ++p, ++i)
12619 {
68883531 12620 if (!p->name().empty())
f470da59 12621 parameters->push_back(*p);
12622 else
12623 {
12624 char buf[20];
12625 snprintf(buf, sizeof buf, "$param%d", i);
12626 parameters->push_back(Typed_identifier(buf, p->type(),
12627 p->location()));
12628 }
12629 }
e440a328 12630 }
12631
12632 const Typed_identifier_list* method_results = method_type->results();
12633 Typed_identifier_list* results;
12634 if (method_results == NULL)
12635 results = NULL;
12636 else
12637 {
12638 results = new Typed_identifier_list();
12639 for (Typed_identifier_list::const_iterator p = method_results->begin();
12640 p != method_results->end();
12641 ++p)
12642 results->push_back(*p);
12643 }
f03a9fbf 12644
e440a328 12645 Function_type* fntype = Type::make_function_type(NULL, parameters, results,
12646 location);
12647 if (method_type->is_varargs())
12648 fntype->set_is_varargs();
12649
12650 // We generate methods which always takes a pointer to the receiver
12651 // as their first argument. If this is for a pointer type, we can
12652 // simply reuse the existing function. We use an internal hack to
12653 // get the right type.
8381eda7 12654 // FIXME: This optimization is disabled because it doesn't yet work
12655 // with function descriptors when the method expression is not
12656 // directly called.
12657 if (method != NULL && is_pointer && false)
e440a328 12658 {
12659 Named_object* mno = (method->needs_stub_method()
12660 ? method->stub_object()
12661 : method->named_object());
12662 Expression* f = Expression::make_func_reference(mno, NULL, location);
12663 f = Expression::make_cast(fntype, f, location);
12664 Type_conversion_expression* tce =
12665 static_cast<Type_conversion_expression*>(f);
12666 tce->set_may_convert_function_types();
12667 return f;
12668 }
12669
13f2fdb8 12670 Named_object* no = gogo->start_function(gogo->thunk_name(), fntype, false,
e440a328 12671 location);
12672
12673 Named_object* vno = gogo->lookup(receiver_name, NULL);
c484d925 12674 go_assert(vno != NULL);
e440a328 12675 Expression* ve = Expression::make_var_reference(vno, location);
ab1468c3 12676 Expression* bm;
12677 if (method != NULL)
12678 bm = Type::bind_field_or_method(gogo, nt, ve, name, location);
12679 else
12680 bm = Expression::make_interface_field_reference(ve, name, location);
f690b0bb 12681
12682 // Even though we found the method above, if it has an error type we
12683 // may see an error here.
12684 if (bm->is_error_expression())
463fe805 12685 {
12686 gogo->finish_function(location);
12687 return bm;
12688 }
e440a328 12689
12690 Expression_list* args;
f470da59 12691 if (parameters->size() <= 1)
e440a328 12692 args = NULL;
12693 else
12694 {
12695 args = new Expression_list();
f470da59 12696 Typed_identifier_list::const_iterator p = parameters->begin();
12697 ++p;
12698 for (; p != parameters->end(); ++p)
e440a328 12699 {
12700 vno = gogo->lookup(p->name(), NULL);
c484d925 12701 go_assert(vno != NULL);
e440a328 12702 args->push_back(Expression::make_var_reference(vno, location));
12703 }
12704 }
12705
ceeb4318 12706 gogo->start_block(location);
12707
e440a328 12708 Call_expression* call = Expression::make_call(bm, args,
12709 method_type->is_varargs(),
12710 location);
12711
0afbb937 12712 Statement* s = Statement::make_return_from_call(call, location);
e440a328 12713 gogo->add_statement(s);
12714
ceeb4318 12715 Block* b = gogo->finish_block(location);
12716
12717 gogo->add_block(b, location);
12718
12719 // Lower the call in case there are multiple results.
12720 gogo->lower_block(no, b);
a32698ee 12721 gogo->flatten_block(no, b);
ceeb4318 12722
e440a328 12723 gogo->finish_function(location);
12724
12725 return Expression::make_func_reference(no, NULL, location);
12726}
12727
d751bb78 12728// Dump the ast for a selector expression.
12729
12730void
f03a9fbf 12731Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 12732 const
12733{
12734 ast_dump_context->dump_expression(this->left_);
12735 ast_dump_context->ostream() << ".";
12736 ast_dump_context->ostream() << this->name_;
12737}
f03a9fbf 12738
e440a328 12739// Make a selector expression.
12740
12741Expression*
12742Expression::make_selector(Expression* left, const std::string& name,
b13c66cd 12743 Location location)
e440a328 12744{
12745 return new Selector_expression(left, name, location);
12746}
12747
da244e59 12748// Class Allocation_expression.
e440a328 12749
da244e59 12750int
12751Allocation_expression::do_traverse(Traverse* traverse)
e440a328 12752{
da244e59 12753 return Type::traverse(this->type_, traverse);
12754}
e440a328 12755
da244e59 12756Type*
12757Allocation_expression::do_type()
12758{
12759 return Type::make_pointer_type(this->type_);
12760}
e440a328 12761
22deed0d 12762void
12763Allocation_expression::do_check_types(Gogo*)
12764{
12765 if (!this->type_->in_heap())
12766 go_error_at(this->location(), "can't heap allocate go:notinheap type");
12767}
12768
da244e59 12769// Make a copy of an allocation expression.
e440a328 12770
da244e59 12771Expression*
12772Allocation_expression::do_copy()
12773{
12774 Allocation_expression* alloc =
de590a61 12775 new Allocation_expression(this->type_->copy_expressions(),
12776 this->location());
da244e59 12777 if (this->allocate_on_stack_)
12778 alloc->set_allocate_on_stack();
12779 return alloc;
12780}
e440a328 12781
ea664253 12782// Return the backend representation for an allocation expression.
e440a328 12783
ea664253 12784Bexpression*
12785Allocation_expression::do_get_backend(Translate_context* context)
e440a328 12786{
2c809f8f 12787 Gogo* gogo = context->gogo();
12788 Location loc = this->location();
06e83d10 12789 Btype* btype = this->type_->get_backend(gogo);
da244e59 12790
5973ede0 12791 if (this->allocate_on_stack_)
da244e59 12792 {
2a305b85 12793 int64_t size;
12794 bool ok = this->type_->backend_type_size(gogo, &size);
12795 if (!ok)
12796 {
12797 go_assert(saw_errors());
12798 return gogo->backend()->error_expression();
12799 }
06e83d10 12800 Bstatement* decl;
12801 Named_object* fn = context->function();
12802 go_assert(fn != NULL);
12803 Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
12804 Bexpression* zero = gogo->backend()->zero_expression(btype);
12805 Bvariable* temp =
12806 gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
12807 zero, true, loc, &decl);
12808 Bexpression* ret = gogo->backend()->var_expression(temp, loc);
12809 ret = gogo->backend()->address_expression(ret, loc);
12810 ret = gogo->backend()->compound_expression(decl, ret, loc);
12811 return ret;
da244e59 12812 }
12813
2a305b85 12814 Bexpression* space =
ea664253 12815 gogo->allocate_memory(this->type_, loc)->get_backend(context);
d5d1c295 12816 Btype* pbtype = gogo->backend()->pointer_type(btype);
ea664253 12817 return gogo->backend()->convert_expression(pbtype, space, loc);
e440a328 12818}
12819
d751bb78 12820// Dump ast representation for an allocation expression.
12821
12822void
f03a9fbf 12823Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 12824 const
12825{
12826 ast_dump_context->ostream() << "new(";
12827 ast_dump_context->dump_type(this->type_);
12828 ast_dump_context->ostream() << ")";
12829}
12830
e440a328 12831// Make an allocation expression.
12832
12833Expression*
b13c66cd 12834Expression::make_allocation(Type* type, Location location)
e440a328 12835{
12836 return new Allocation_expression(type, location);
12837}
12838
e32de7ba 12839// Class Ordered_value_list.
e440a328 12840
12841int
e32de7ba 12842Ordered_value_list::traverse_vals(Traverse* traverse)
e440a328 12843{
0c4f5a19 12844 if (this->vals_ != NULL)
12845 {
12846 if (this->traverse_order_ == NULL)
12847 {
12848 if (this->vals_->traverse(traverse) == TRAVERSE_EXIT)
12849 return TRAVERSE_EXIT;
12850 }
12851 else
12852 {
e32de7ba 12853 for (std::vector<unsigned long>::const_iterator p =
12854 this->traverse_order_->begin();
0c4f5a19 12855 p != this->traverse_order_->end();
12856 ++p)
12857 {
12858 if (Expression::traverse(&this->vals_->at(*p), traverse)
12859 == TRAVERSE_EXIT)
12860 return TRAVERSE_EXIT;
12861 }
12862 }
12863 }
e32de7ba 12864 return TRAVERSE_CONTINUE;
12865}
12866
12867// Class Struct_construction_expression.
12868
12869// Traversal.
12870
12871int
12872Struct_construction_expression::do_traverse(Traverse* traverse)
12873{
12874 if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
12875 return TRAVERSE_EXIT;
e440a328 12876 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
12877 return TRAVERSE_EXIT;
12878 return TRAVERSE_CONTINUE;
12879}
12880
12881// Return whether this is a constant initializer.
12882
12883bool
12884Struct_construction_expression::is_constant_struct() const
12885{
e32de7ba 12886 if (this->vals() == NULL)
e440a328 12887 return true;
e32de7ba 12888 for (Expression_list::const_iterator pv = this->vals()->begin();
12889 pv != this->vals()->end();
e440a328 12890 ++pv)
12891 {
12892 if (*pv != NULL
12893 && !(*pv)->is_constant()
12894 && (!(*pv)->is_composite_literal()
12895 || (*pv)->is_nonconstant_composite_literal()))
12896 return false;
12897 }
12898
12899 const Struct_field_list* fields = this->type_->struct_type()->fields();
12900 for (Struct_field_list::const_iterator pf = fields->begin();
12901 pf != fields->end();
12902 ++pf)
12903 {
12904 // There are no constant constructors for interfaces.
12905 if (pf->type()->interface_type() != NULL)
12906 return false;
12907 }
12908
12909 return true;
12910}
12911
3ae06f68 12912// Return whether this struct can be used as a constant initializer.
f9ca30f9 12913
12914bool
3ae06f68 12915Struct_construction_expression::do_is_static_initializer() const
f9ca30f9 12916{
e32de7ba 12917 if (this->vals() == NULL)
f9ca30f9 12918 return true;
e32de7ba 12919 for (Expression_list::const_iterator pv = this->vals()->begin();
12920 pv != this->vals()->end();
f9ca30f9 12921 ++pv)
12922 {
3ae06f68 12923 if (*pv != NULL && !(*pv)->is_static_initializer())
f9ca30f9 12924 return false;
12925 }
de048538 12926
12927 const Struct_field_list* fields = this->type_->struct_type()->fields();
12928 for (Struct_field_list::const_iterator pf = fields->begin();
12929 pf != fields->end();
12930 ++pf)
12931 {
12932 // There are no constant constructors for interfaces.
12933 if (pf->type()->interface_type() != NULL)
12934 return false;
12935 }
12936
f9ca30f9 12937 return true;
12938}
12939
e440a328 12940// Final type determination.
12941
12942void
12943Struct_construction_expression::do_determine_type(const Type_context*)
12944{
e32de7ba 12945 if (this->vals() == NULL)
e440a328 12946 return;
12947 const Struct_field_list* fields = this->type_->struct_type()->fields();
e32de7ba 12948 Expression_list::const_iterator pv = this->vals()->begin();
e440a328 12949 for (Struct_field_list::const_iterator pf = fields->begin();
12950 pf != fields->end();
12951 ++pf, ++pv)
12952 {
e32de7ba 12953 if (pv == this->vals()->end())
e440a328 12954 return;
12955 if (*pv != NULL)
12956 {
12957 Type_context subcontext(pf->type(), false);
12958 (*pv)->determine_type(&subcontext);
12959 }
12960 }
a6cb4c0e 12961 // Extra values are an error we will report elsewhere; we still want
12962 // to determine the type to avoid knockon errors.
e32de7ba 12963 for (; pv != this->vals()->end(); ++pv)
a6cb4c0e 12964 (*pv)->determine_type_no_context();
e440a328 12965}
12966
12967// Check types.
12968
12969void
12970Struct_construction_expression::do_check_types(Gogo*)
12971{
e32de7ba 12972 if (this->vals() == NULL)
e440a328 12973 return;
12974
12975 Struct_type* st = this->type_->struct_type();
e32de7ba 12976 if (this->vals()->size() > st->field_count())
e440a328 12977 {
12978 this->report_error(_("too many expressions for struct"));
12979 return;
12980 }
12981
12982 const Struct_field_list* fields = st->fields();
e32de7ba 12983 Expression_list::const_iterator pv = this->vals()->begin();
e440a328 12984 int i = 0;
12985 for (Struct_field_list::const_iterator pf = fields->begin();
12986 pf != fields->end();
12987 ++pf, ++pv, ++i)
12988 {
e32de7ba 12989 if (pv == this->vals()->end())
e440a328 12990 {
12991 this->report_error(_("too few expressions for struct"));
12992 break;
12993 }
12994
12995 if (*pv == NULL)
12996 continue;
12997
12998 std::string reason;
12999 if (!Type::are_assignable(pf->type(), (*pv)->type(), &reason))
13000 {
13001 if (reason.empty())
631d5788 13002 go_error_at((*pv)->location(),
13003 "incompatible type for field %d in struct construction",
13004 i + 1);
e440a328 13005 else
631d5788 13006 go_error_at((*pv)->location(),
13007 ("incompatible type for field %d in "
13008 "struct construction (%s)"),
13009 i + 1, reason.c_str());
e440a328 13010 this->set_is_error();
13011 }
13012 }
e32de7ba 13013 go_assert(pv == this->vals()->end());
e440a328 13014}
13015
de590a61 13016// Copy.
13017
13018Expression*
13019Struct_construction_expression::do_copy()
13020{
13021 Struct_construction_expression* ret =
13022 new Struct_construction_expression(this->type_->copy_expressions(),
13023 (this->vals() == NULL
13024 ? NULL
13025 : this->vals()->copy()),
13026 this->location());
13027 if (this->traverse_order() != NULL)
13028 ret->set_traverse_order(this->traverse_order());
13029 return ret;
13030}
13031
8ba8cc87 13032// Flatten a struct construction expression. Store the values into
13033// temporaries in case they need interface conversion.
13034
13035Expression*
13036Struct_construction_expression::do_flatten(Gogo*, Named_object*,
13037 Statement_inserter* inserter)
13038{
e32de7ba 13039 if (this->vals() == NULL)
8ba8cc87 13040 return this;
13041
13042 // If this is a constant struct, we don't need temporaries.
de048538 13043 if (this->is_constant_struct() || this->is_static_initializer())
8ba8cc87 13044 return this;
13045
13046 Location loc = this->location();
e32de7ba 13047 for (Expression_list::iterator pv = this->vals()->begin();
13048 pv != this->vals()->end();
8ba8cc87 13049 ++pv)
13050 {
13051 if (*pv != NULL)
13052 {
5bf8be8b 13053 if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type())
13054 {
13055 go_assert(saw_errors());
13056 return Expression::make_error(loc);
13057 }
8ba8cc87 13058 if (!(*pv)->is_variable())
13059 {
13060 Temporary_statement* temp =
13061 Statement::make_temporary(NULL, *pv, loc);
13062 inserter->insert(temp);
13063 *pv = Expression::make_temporary_reference(temp, loc);
13064 }
13065 }
13066 }
13067 return this;
13068}
13069
ea664253 13070// Return the backend representation for constructing a struct.
e440a328 13071
ea664253 13072Bexpression*
13073Struct_construction_expression::do_get_backend(Translate_context* context)
e440a328 13074{
13075 Gogo* gogo = context->gogo();
13076
2c809f8f 13077 Btype* btype = this->type_->get_backend(gogo);
e32de7ba 13078 if (this->vals() == NULL)
ea664253 13079 return gogo->backend()->zero_expression(btype);
e440a328 13080
e440a328 13081 const Struct_field_list* fields = this->type_->struct_type()->fields();
e32de7ba 13082 Expression_list::const_iterator pv = this->vals()->begin();
2c809f8f 13083 std::vector<Bexpression*> init;
13084 for (Struct_field_list::const_iterator pf = fields->begin();
13085 pf != fields->end();
13086 ++pf)
e440a328 13087 {
63697958 13088 Btype* fbtype = pf->type()->get_backend(gogo);
e32de7ba 13089 if (pv == this->vals()->end())
2c809f8f 13090 init.push_back(gogo->backend()->zero_expression(fbtype));
e440a328 13091 else if (*pv == NULL)
13092 {
2c809f8f 13093 init.push_back(gogo->backend()->zero_expression(fbtype));
e440a328 13094 ++pv;
13095 }
13096 else
13097 {
2c809f8f 13098 Expression* val =
13099 Expression::convert_for_assignment(gogo, pf->type(),
13100 *pv, this->location());
ea664253 13101 init.push_back(val->get_backend(context));
e440a328 13102 ++pv;
13103 }
e440a328 13104 }
0fdf8340 13105 if (this->type_->struct_type()->has_padding())
13106 {
13107 // Feed an extra value if there is a padding field.
13108 Btype *fbtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
13109 init.push_back(gogo->backend()->zero_expression(fbtype));
13110 }
ea664253 13111 return gogo->backend()->constructor_expression(btype, init, this->location());
e440a328 13112}
13113
13114// Export a struct construction.
13115
13116void
548be246 13117Struct_construction_expression::do_export(Export_function_body* efb) const
e440a328 13118{
204d4af4 13119 efb->write_c_string("$convert(");
548be246 13120 efb->write_type(this->type_);
e32de7ba 13121 for (Expression_list::const_iterator pv = this->vals()->begin();
13122 pv != this->vals()->end();
e440a328 13123 ++pv)
13124 {
548be246 13125 efb->write_c_string(", ");
e440a328 13126 if (*pv != NULL)
548be246 13127 (*pv)->export_expression(efb);
e440a328 13128 }
548be246 13129 efb->write_c_string(")");
e440a328 13130}
13131
d751bb78 13132// Dump ast representation of a struct construction expression.
13133
13134void
13135Struct_construction_expression::do_dump_expression(
13136 Ast_dump_context* ast_dump_context) const
13137{
d751bb78 13138 ast_dump_context->dump_type(this->type_);
13139 ast_dump_context->ostream() << "{";
e32de7ba 13140 ast_dump_context->dump_expression_list(this->vals());
d751bb78 13141 ast_dump_context->ostream() << "}";
13142}
13143
e440a328 13144// Make a struct composite literal. This used by the thunk code.
13145
13146Expression*
13147Expression::make_struct_composite_literal(Type* type, Expression_list* vals,
b13c66cd 13148 Location location)
e440a328 13149{
c484d925 13150 go_assert(type->struct_type() != NULL);
e440a328 13151 return new Struct_construction_expression(type, vals, location);
13152}
13153
da244e59 13154// Class Array_construction_expression.
e440a328 13155
13156// Traversal.
13157
13158int
13159Array_construction_expression::do_traverse(Traverse* traverse)
13160{
e32de7ba 13161 if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
e440a328 13162 return TRAVERSE_EXIT;
13163 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
13164 return TRAVERSE_EXIT;
13165 return TRAVERSE_CONTINUE;
13166}
13167
13168// Return whether this is a constant initializer.
13169
13170bool
13171Array_construction_expression::is_constant_array() const
13172{
e32de7ba 13173 if (this->vals() == NULL)
e440a328 13174 return true;
13175
13176 // There are no constant constructors for interfaces.
13177 if (this->type_->array_type()->element_type()->interface_type() != NULL)
13178 return false;
13179
e32de7ba 13180 for (Expression_list::const_iterator pv = this->vals()->begin();
13181 pv != this->vals()->end();
e440a328 13182 ++pv)
13183 {
13184 if (*pv != NULL
13185 && !(*pv)->is_constant()
13186 && (!(*pv)->is_composite_literal()
13187 || (*pv)->is_nonconstant_composite_literal()))
13188 return false;
13189 }
13190 return true;
13191}
13192
3ae06f68 13193// Return whether this can be used a constant initializer.
f9ca30f9 13194
13195bool
3ae06f68 13196Array_construction_expression::do_is_static_initializer() const
f9ca30f9 13197{
e32de7ba 13198 if (this->vals() == NULL)
f9ca30f9 13199 return true;
de048538 13200
13201 // There are no constant constructors for interfaces.
13202 if (this->type_->array_type()->element_type()->interface_type() != NULL)
13203 return false;
13204
e32de7ba 13205 for (Expression_list::const_iterator pv = this->vals()->begin();
13206 pv != this->vals()->end();
f9ca30f9 13207 ++pv)
13208 {
3ae06f68 13209 if (*pv != NULL && !(*pv)->is_static_initializer())
f9ca30f9 13210 return false;
13211 }
13212 return true;
13213}
13214
e440a328 13215// Final type determination.
13216
13217void
13218Array_construction_expression::do_determine_type(const Type_context*)
13219{
e32de7ba 13220 if (this->vals() == NULL)
e440a328 13221 return;
13222 Type_context subcontext(this->type_->array_type()->element_type(), false);
e32de7ba 13223 for (Expression_list::const_iterator pv = this->vals()->begin();
13224 pv != this->vals()->end();
e440a328 13225 ++pv)
13226 {
13227 if (*pv != NULL)
13228 (*pv)->determine_type(&subcontext);
13229 }
13230}
13231
13232// Check types.
13233
13234void
13235Array_construction_expression::do_check_types(Gogo*)
13236{
e32de7ba 13237 if (this->vals() == NULL)
e440a328 13238 return;
13239
13240 Array_type* at = this->type_->array_type();
13241 int i = 0;
13242 Type* element_type = at->element_type();
e32de7ba 13243 for (Expression_list::const_iterator pv = this->vals()->begin();
13244 pv != this->vals()->end();
e440a328 13245 ++pv, ++i)
13246 {
13247 if (*pv != NULL
13248 && !Type::are_assignable(element_type, (*pv)->type(), NULL))
13249 {
631d5788 13250 go_error_at((*pv)->location(),
13251 "incompatible type for element %d in composite literal",
13252 i + 1);
e440a328 13253 this->set_is_error();
13254 }
13255 }
e440a328 13256}
13257
8ba8cc87 13258// Flatten an array construction expression. Store the values into
13259// temporaries in case they need interface conversion.
13260
13261Expression*
13262Array_construction_expression::do_flatten(Gogo*, Named_object*,
13263 Statement_inserter* inserter)
13264{
e32de7ba 13265 if (this->vals() == NULL)
8ba8cc87 13266 return this;
13267
13268 // If this is a constant array, we don't need temporaries.
de048538 13269 if (this->is_constant_array() || this->is_static_initializer())
8ba8cc87 13270 return this;
13271
13272 Location loc = this->location();
e32de7ba 13273 for (Expression_list::iterator pv = this->vals()->begin();
13274 pv != this->vals()->end();
8ba8cc87 13275 ++pv)
13276 {
13277 if (*pv != NULL)
13278 {
5bf8be8b 13279 if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type())
13280 {
13281 go_assert(saw_errors());
13282 return Expression::make_error(loc);
13283 }
8ba8cc87 13284 if (!(*pv)->is_variable())
13285 {
13286 Temporary_statement* temp =
13287 Statement::make_temporary(NULL, *pv, loc);
13288 inserter->insert(temp);
13289 *pv = Expression::make_temporary_reference(temp, loc);
13290 }
13291 }
13292 }
13293 return this;
13294}
13295
2c809f8f 13296// Get a constructor expression for the array values.
e440a328 13297
2c809f8f 13298Bexpression*
13299Array_construction_expression::get_constructor(Translate_context* context,
13300 Btype* array_btype)
e440a328 13301{
e440a328 13302 Type* element_type = this->type_->array_type()->element_type();
2c809f8f 13303
13304 std::vector<unsigned long> indexes;
13305 std::vector<Bexpression*> vals;
13306 Gogo* gogo = context->gogo();
e32de7ba 13307 if (this->vals() != NULL)
e440a328 13308 {
13309 size_t i = 0;
ffe743ca 13310 std::vector<unsigned long>::const_iterator pi;
13311 if (this->indexes_ != NULL)
13312 pi = this->indexes_->begin();
e32de7ba 13313 for (Expression_list::const_iterator pv = this->vals()->begin();
13314 pv != this->vals()->end();
e440a328 13315 ++pv, ++i)
13316 {
ffe743ca 13317 if (this->indexes_ != NULL)
13318 go_assert(pi != this->indexes_->end());
ffe743ca 13319
13320 if (this->indexes_ == NULL)
2c809f8f 13321 indexes.push_back(i);
ffe743ca 13322 else
2c809f8f 13323 indexes.push_back(*pi);
e440a328 13324 if (*pv == NULL)
63697958 13325 {
63697958 13326 Btype* ebtype = element_type->get_backend(gogo);
13327 Bexpression *zv = gogo->backend()->zero_expression(ebtype);
2c809f8f 13328 vals.push_back(zv);
63697958 13329 }
e440a328 13330 else
13331 {
2c809f8f 13332 Expression* val_expr =
13333 Expression::convert_for_assignment(gogo, element_type, *pv,
13334 this->location());
ea664253 13335 vals.push_back(val_expr->get_backend(context));
e440a328 13336 }
ffe743ca 13337 if (this->indexes_ != NULL)
13338 ++pi;
e440a328 13339 }
ffe743ca 13340 if (this->indexes_ != NULL)
13341 go_assert(pi == this->indexes_->end());
e440a328 13342 }
2c809f8f 13343 return gogo->backend()->array_constructor_expression(array_btype, indexes,
13344 vals, this->location());
e440a328 13345}
13346
13347// Export an array construction.
13348
13349void
548be246 13350Array_construction_expression::do_export(Export_function_body* efb) const
e440a328 13351{
204d4af4 13352 efb->write_c_string("$convert(");
548be246 13353 efb->write_type(this->type_);
e32de7ba 13354 if (this->vals() != NULL)
e440a328 13355 {
ffe743ca 13356 std::vector<unsigned long>::const_iterator pi;
13357 if (this->indexes_ != NULL)
13358 pi = this->indexes_->begin();
e32de7ba 13359 for (Expression_list::const_iterator pv = this->vals()->begin();
13360 pv != this->vals()->end();
e440a328 13361 ++pv)
13362 {
548be246 13363 efb->write_c_string(", ");
ffe743ca 13364
13365 if (this->indexes_ != NULL)
13366 {
13367 char buf[100];
13368 snprintf(buf, sizeof buf, "%lu", *pi);
548be246 13369 efb->write_c_string(buf);
13370 efb->write_c_string(":");
ffe743ca 13371 }
13372
e440a328 13373 if (*pv != NULL)
548be246 13374 (*pv)->export_expression(efb);
ffe743ca 13375
13376 if (this->indexes_ != NULL)
13377 ++pi;
e440a328 13378 }
13379 }
548be246 13380 efb->write_c_string(")");
e440a328 13381}
13382
0e9a2e72 13383// Dump ast representation of an array construction expression.
d751bb78 13384
13385void
13386Array_construction_expression::do_dump_expression(
13387 Ast_dump_context* ast_dump_context) const
13388{
ffe743ca 13389 Expression* length = this->type_->array_type()->length();
8b1c301d 13390
13391 ast_dump_context->ostream() << "[" ;
13392 if (length != NULL)
13393 {
13394 ast_dump_context->dump_expression(length);
13395 }
13396 ast_dump_context->ostream() << "]" ;
d751bb78 13397 ast_dump_context->dump_type(this->type_);
0e9a2e72 13398 this->dump_slice_storage_expression(ast_dump_context);
d751bb78 13399 ast_dump_context->ostream() << "{" ;
ffe743ca 13400 if (this->indexes_ == NULL)
e32de7ba 13401 ast_dump_context->dump_expression_list(this->vals());
ffe743ca 13402 else
13403 {
e32de7ba 13404 Expression_list::const_iterator pv = this->vals()->begin();
ffe743ca 13405 for (std::vector<unsigned long>::const_iterator pi =
13406 this->indexes_->begin();
13407 pi != this->indexes_->end();
13408 ++pi, ++pv)
13409 {
13410 if (pi != this->indexes_->begin())
13411 ast_dump_context->ostream() << ", ";
13412 ast_dump_context->ostream() << *pi << ':';
13413 ast_dump_context->dump_expression(*pv);
13414 }
13415 }
d751bb78 13416 ast_dump_context->ostream() << "}" ;
13417
13418}
13419
da244e59 13420// Class Fixed_array_construction_expression.
e440a328 13421
da244e59 13422Fixed_array_construction_expression::Fixed_array_construction_expression(
13423 Type* type, const std::vector<unsigned long>* indexes,
13424 Expression_list* vals, Location location)
13425 : Array_construction_expression(EXPRESSION_FIXED_ARRAY_CONSTRUCTION,
13426 type, indexes, vals, location)
13427{ go_assert(type->array_type() != NULL && !type->is_slice_type()); }
e440a328 13428
de590a61 13429
13430// Copy.
13431
13432Expression*
13433Fixed_array_construction_expression::do_copy()
13434{
13435 Type* t = this->type()->copy_expressions();
13436 return new Fixed_array_construction_expression(t, this->indexes(),
13437 (this->vals() == NULL
13438 ? NULL
13439 : this->vals()->copy()),
13440 this->location());
13441}
13442
ea664253 13443// Return the backend representation for constructing a fixed array.
e440a328 13444
ea664253 13445Bexpression*
13446Fixed_array_construction_expression::do_get_backend(Translate_context* context)
e440a328 13447{
9f0e0513 13448 Type* type = this->type();
13449 Btype* btype = type->get_backend(context->gogo());
ea664253 13450 return this->get_constructor(context, btype);
e440a328 13451}
13452
76f85fd6 13453Expression*
13454Expression::make_array_composite_literal(Type* type, Expression_list* vals,
13455 Location location)
13456{
13457 go_assert(type->array_type() != NULL && !type->is_slice_type());
13458 return new Fixed_array_construction_expression(type, NULL, vals, location);
13459}
13460
da244e59 13461// Class Slice_construction_expression.
e440a328 13462
da244e59 13463Slice_construction_expression::Slice_construction_expression(
13464 Type* type, const std::vector<unsigned long>* indexes,
13465 Expression_list* vals, Location location)
13466 : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
13467 type, indexes, vals, location),
0e9a2e72 13468 valtype_(NULL), array_val_(NULL), slice_storage_(NULL),
13469 storage_escapes_(true)
e440a328 13470{
da244e59 13471 go_assert(type->is_slice_type());
23d77f91 13472
da244e59 13473 unsigned long lenval;
13474 Expression* length;
13475 if (vals == NULL || vals->empty())
13476 lenval = 0;
13477 else
13478 {
13479 if (this->indexes() == NULL)
13480 lenval = vals->size();
13481 else
13482 lenval = indexes->back() + 1;
13483 }
13484 Type* int_type = Type::lookup_integer_type("int");
13485 length = Expression::make_integer_ul(lenval, int_type, location);
13486 Type* element_type = type->array_type()->element_type();
6bf4793c 13487 Array_type* array_type = Type::make_array_type(element_type, length);
13488 array_type->set_is_array_incomparable();
13489 this->valtype_ = array_type;
da244e59 13490}
e440a328 13491
23d77f91 13492// Traversal.
13493
13494int
13495Slice_construction_expression::do_traverse(Traverse* traverse)
13496{
13497 if (this->Array_construction_expression::do_traverse(traverse)
13498 == TRAVERSE_EXIT)
13499 return TRAVERSE_EXIT;
13500 if (Type::traverse(this->valtype_, traverse) == TRAVERSE_EXIT)
13501 return TRAVERSE_EXIT;
0e9a2e72 13502 if (this->array_val_ != NULL
13503 && Expression::traverse(&this->array_val_, traverse) == TRAVERSE_EXIT)
13504 return TRAVERSE_EXIT;
13505 if (this->slice_storage_ != NULL
13506 && Expression::traverse(&this->slice_storage_, traverse) == TRAVERSE_EXIT)
13507 return TRAVERSE_EXIT;
23d77f91 13508 return TRAVERSE_CONTINUE;
13509}
13510
0e9a2e72 13511// Helper routine to create fixed array value underlying the slice literal.
13512// May be called during flattening, or later during do_get_backend().
e440a328 13513
0e9a2e72 13514Expression*
13515Slice_construction_expression::create_array_val()
e440a328 13516{
f9c68f17 13517 Array_type* array_type = this->type()->array_type();
13518 if (array_type == NULL)
13519 {
c484d925 13520 go_assert(this->type()->is_error());
0e9a2e72 13521 return NULL;
f9c68f17 13522 }
13523
f23d7786 13524 Location loc = this->location();
23d77f91 13525 go_assert(this->valtype_ != NULL);
3d60812e 13526
f23d7786 13527 Expression_list* vals = this->vals();
0e9a2e72 13528 return new Fixed_array_construction_expression(
13529 this->valtype_, this->indexes(), vals, loc);
13530}
13531
13532// If we're previous established that the slice storage does not
13533// escape, then create a separate array temp val here for it. We
13534// need to do this as part of flattening so as to be able to insert
13535// the new temp statement.
13536
13537Expression*
13538Slice_construction_expression::do_flatten(Gogo* gogo, Named_object* no,
13539 Statement_inserter* inserter)
13540{
13541 if (this->type()->array_type() == NULL)
13542 return NULL;
13543
13544 // Base class flattening first
13545 this->Array_construction_expression::do_flatten(gogo, no, inserter);
13546
a1bbc2c3 13547 // Create a stack-allocated storage temp if storage won't escape
03118c21 13548 if (!this->storage_escapes_
13549 && this->slice_storage_ == NULL
13550 && this->element_count() > 0)
0e9a2e72 13551 {
13552 Location loc = this->location();
03118c21 13553 this->array_val_ = this->create_array_val();
0e9a2e72 13554 go_assert(this->array_val_);
13555 Temporary_statement* temp =
13556 Statement::make_temporary(this->valtype_, this->array_val_, loc);
13557 inserter->insert(temp);
13558 this->slice_storage_ = Expression::make_temporary_reference(temp, loc);
13559 }
13560 return this;
13561}
13562
13563// When dumping a slice construction expression that has an explicit
13564// storeage temp, emit the temp here (if we don't do this the storage
13565// temp appears unused in the AST dump).
13566
13567void
13568Slice_construction_expression::
13569dump_slice_storage_expression(Ast_dump_context* ast_dump_context) const
13570{
13571 if (this->slice_storage_ == NULL)
13572 return;
13573 ast_dump_context->ostream() << "storage=" ;
13574 ast_dump_context->dump_expression(this->slice_storage_);
13575}
13576
de590a61 13577// Copy.
13578
13579Expression*
13580Slice_construction_expression::do_copy()
13581{
13582 return new Slice_construction_expression(this->type()->copy_expressions(),
13583 this->indexes(),
13584 (this->vals() == NULL
13585 ? NULL
13586 : this->vals()->copy()),
13587 this->location());
13588}
13589
0e9a2e72 13590// Return the backend representation for constructing a slice.
13591
13592Bexpression*
13593Slice_construction_expression::do_get_backend(Translate_context* context)
13594{
13595 if (this->array_val_ == NULL)
03118c21 13596 this->array_val_ = this->create_array_val();
0e9a2e72 13597 if (this->array_val_ == NULL)
13598 {
13599 go_assert(this->type()->is_error());
13600 return context->backend()->error_expression();
13601 }
13602
13603 Location loc = this->location();
e440a328 13604
3ae06f68 13605 bool is_static_initializer = this->array_val_->is_static_initializer();
d8829beb 13606
13607 // We have to copy the initial values into heap memory if we are in
3ae06f68 13608 // a function or if the values are not constants.
13609 bool copy_to_heap = context->function() != NULL || !is_static_initializer;
e440a328 13610
f23d7786 13611 Expression* space;
0e9a2e72 13612
13613 if (this->slice_storage_ != NULL)
13614 {
13615 go_assert(!this->storage_escapes_);
13616 space = Expression::make_unary(OPERATOR_AND, this->slice_storage_, loc);
13617 }
13618 else if (!copy_to_heap)
e440a328 13619 {
f23d7786 13620 // The initializer will only run once.
0e9a2e72 13621 space = Expression::make_unary(OPERATOR_AND, this->array_val_, loc);
f23d7786 13622 space->unary_expression()->set_is_slice_init();
e440a328 13623 }
13624 else
45ff893b 13625 {
5973ede0 13626 go_assert(this->storage_escapes_ || this->element_count() == 0);
0e9a2e72 13627 space = Expression::make_heap_expression(this->array_val_, loc);
45ff893b 13628 }
d633d0fb 13629 Array_type* at = this->valtype_->array_type();
13630 Type* et = at->element_type();
13631 space = Expression::make_unsafe_cast(Type::make_pointer_type(et),
13632 space, loc);
e440a328 13633
2c809f8f 13634 // Build a constructor for the slice.
d633d0fb 13635 Expression* len = at->length();
f23d7786 13636 Expression* slice_val =
13637 Expression::make_slice_value(this->type(), space, len, len, loc);
ea664253 13638 return slice_val->get_backend(context);
e440a328 13639}
13640
13641// Make a slice composite literal. This is used by the type
13642// descriptor code.
13643
0e9a2e72 13644Slice_construction_expression*
e440a328 13645Expression::make_slice_composite_literal(Type* type, Expression_list* vals,
b13c66cd 13646 Location location)
e440a328 13647{
411eb89e 13648 go_assert(type->is_slice_type());
2c809f8f 13649 return new Slice_construction_expression(type, NULL, vals, location);
e440a328 13650}
13651
da244e59 13652// Class Map_construction_expression.
e440a328 13653
13654// Traversal.
13655
13656int
13657Map_construction_expression::do_traverse(Traverse* traverse)
13658{
13659 if (this->vals_ != NULL
13660 && this->vals_->traverse(traverse) == TRAVERSE_EXIT)
13661 return TRAVERSE_EXIT;
13662 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
13663 return TRAVERSE_EXIT;
13664 return TRAVERSE_CONTINUE;
13665}
13666
2c809f8f 13667// Flatten constructor initializer into a temporary variable since
13668// we need to take its address for __go_construct_map.
13669
13670Expression*
13671Map_construction_expression::do_flatten(Gogo* gogo, Named_object*,
13672 Statement_inserter* inserter)
13673{
13674 if (!this->is_error_expression()
13675 && this->vals_ != NULL
13676 && !this->vals_->empty()
13677 && this->constructor_temp_ == NULL)
13678 {
13679 Map_type* mt = this->type_->map_type();
13680 Type* key_type = mt->key_type();
13681 Type* val_type = mt->val_type();
13682 this->element_type_ = Type::make_builtin_struct_type(2,
13683 "__key", key_type,
13684 "__val", val_type);
13685
13686 Expression_list* value_pairs = new Expression_list();
13687 Location loc = this->location();
13688
13689 size_t i = 0;
13690 for (Expression_list::const_iterator pv = this->vals_->begin();
13691 pv != this->vals_->end();
13692 ++pv, ++i)
13693 {
13694 Expression_list* key_value_pair = new Expression_list();
91c0fd76 13695 Expression* key = *pv;
5bf8be8b 13696 if (key->is_error_expression() || key->type()->is_error_type())
13697 {
13698 go_assert(saw_errors());
13699 return Expression::make_error(loc);
13700 }
91c0fd76 13701 if (key->type()->interface_type() != NULL && !key->is_variable())
13702 {
13703 Temporary_statement* temp =
13704 Statement::make_temporary(NULL, key, loc);
13705 inserter->insert(temp);
13706 key = Expression::make_temporary_reference(temp, loc);
13707 }
13708 key = Expression::convert_for_assignment(gogo, key_type, key, loc);
2c809f8f 13709
13710 ++pv;
91c0fd76 13711 Expression* val = *pv;
5bf8be8b 13712 if (val->is_error_expression() || val->type()->is_error_type())
13713 {
13714 go_assert(saw_errors());
13715 return Expression::make_error(loc);
13716 }
91c0fd76 13717 if (val->type()->interface_type() != NULL && !val->is_variable())
13718 {
13719 Temporary_statement* temp =
13720 Statement::make_temporary(NULL, val, loc);
13721 inserter->insert(temp);
13722 val = Expression::make_temporary_reference(temp, loc);
13723 }
13724 val = Expression::convert_for_assignment(gogo, val_type, val, loc);
2c809f8f 13725
13726 key_value_pair->push_back(key);
13727 key_value_pair->push_back(val);
13728 value_pairs->push_back(
13729 Expression::make_struct_composite_literal(this->element_type_,
13730 key_value_pair, loc));
13731 }
13732
e67508fa 13733 Expression* element_count = Expression::make_integer_ul(i, NULL, loc);
6bf4793c 13734 Array_type* ctor_type =
2c809f8f 13735 Type::make_array_type(this->element_type_, element_count);
6bf4793c 13736 ctor_type->set_is_array_incomparable();
2c809f8f 13737 Expression* constructor =
13738 new Fixed_array_construction_expression(ctor_type, NULL,
13739 value_pairs, loc);
13740
13741 this->constructor_temp_ =
13742 Statement::make_temporary(NULL, constructor, loc);
13743 constructor->issue_nil_check();
13744 this->constructor_temp_->set_is_address_taken();
13745 inserter->insert(this->constructor_temp_);
13746 }
13747
13748 return this;
13749}
13750
e440a328 13751// Final type determination.
13752
13753void
13754Map_construction_expression::do_determine_type(const Type_context*)
13755{
13756 if (this->vals_ == NULL)
13757 return;
13758
13759 Map_type* mt = this->type_->map_type();
13760 Type_context key_context(mt->key_type(), false);
13761 Type_context val_context(mt->val_type(), false);
13762 for (Expression_list::const_iterator pv = this->vals_->begin();
13763 pv != this->vals_->end();
13764 ++pv)
13765 {
13766 (*pv)->determine_type(&key_context);
13767 ++pv;
13768 (*pv)->determine_type(&val_context);
13769 }
13770}
13771
13772// Check types.
13773
13774void
13775Map_construction_expression::do_check_types(Gogo*)
13776{
13777 if (this->vals_ == NULL)
13778 return;
13779
13780 Map_type* mt = this->type_->map_type();
13781 int i = 0;
13782 Type* key_type = mt->key_type();
13783 Type* val_type = mt->val_type();
13784 for (Expression_list::const_iterator pv = this->vals_->begin();
13785 pv != this->vals_->end();
13786 ++pv, ++i)
13787 {
13788 if (!Type::are_assignable(key_type, (*pv)->type(), NULL))
13789 {
631d5788 13790 go_error_at((*pv)->location(),
13791 "incompatible type for element %d key in map construction",
13792 i + 1);
e440a328 13793 this->set_is_error();
13794 }
13795 ++pv;
13796 if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
13797 {
631d5788 13798 go_error_at((*pv)->location(),
13799 ("incompatible type for element %d value "
13800 "in map construction"),
e440a328 13801 i + 1);
13802 this->set_is_error();
13803 }
13804 }
13805}
13806
de590a61 13807// Copy.
13808
13809Expression*
13810Map_construction_expression::do_copy()
13811{
13812 return new Map_construction_expression(this->type_->copy_expressions(),
13813 (this->vals_ == NULL
13814 ? NULL
13815 : this->vals_->copy()),
13816 this->location());
13817}
13818
ea664253 13819// Return the backend representation for constructing a map.
e440a328 13820
ea664253 13821Bexpression*
13822Map_construction_expression::do_get_backend(Translate_context* context)
e440a328 13823{
2c809f8f 13824 if (this->is_error_expression())
ea664253 13825 return context->backend()->error_expression();
2c809f8f 13826 Location loc = this->location();
e440a328 13827
e440a328 13828 size_t i = 0;
2c809f8f 13829 Expression* ventries;
e440a328 13830 if (this->vals_ == NULL || this->vals_->empty())
2c809f8f 13831 ventries = Expression::make_nil(loc);
e440a328 13832 else
13833 {
2c809f8f 13834 go_assert(this->constructor_temp_ != NULL);
13835 i = this->vals_->size() / 2;
e440a328 13836
2c809f8f 13837 Expression* ctor_ref =
13838 Expression::make_temporary_reference(this->constructor_temp_, loc);
13839 ventries = Expression::make_unary(OPERATOR_AND, ctor_ref, loc);
13840 }
e440a328 13841
2c809f8f 13842 Map_type* mt = this->type_->map_type();
13843 if (this->element_type_ == NULL)
13844 this->element_type_ =
13845 Type::make_builtin_struct_type(2,
13846 "__key", mt->key_type(),
13847 "__val", mt->val_type());
0d5530d9 13848 Expression* descriptor = Expression::make_type_descriptor(mt, loc);
2c809f8f 13849
13850 Type* uintptr_t = Type::lookup_integer_type("uintptr");
e67508fa 13851 Expression* count = Expression::make_integer_ul(i, uintptr_t, loc);
2c809f8f 13852
13853 Expression* entry_size =
13854 Expression::make_type_info(this->element_type_, TYPE_INFO_SIZE);
13855
13856 unsigned int field_index;
13857 const Struct_field* valfield =
13858 this->element_type_->find_local_field("__val", &field_index);
13859 Expression* val_offset =
13860 Expression::make_struct_field_offset(this->element_type_, valfield);
2c809f8f 13861
13862 Expression* map_ctor =
0d5530d9 13863 Runtime::make_call(Runtime::CONSTRUCT_MAP, loc, 5, descriptor, count,
13864 entry_size, val_offset, ventries);
ea664253 13865 return map_ctor->get_backend(context);
2c809f8f 13866}
e440a328 13867
2c809f8f 13868// Export an array construction.
e440a328 13869
2c809f8f 13870void
548be246 13871Map_construction_expression::do_export(Export_function_body* efb) const
2c809f8f 13872{
204d4af4 13873 efb->write_c_string("$convert(");
548be246 13874 efb->write_type(this->type_);
2c809f8f 13875 for (Expression_list::const_iterator pv = this->vals_->begin();
13876 pv != this->vals_->end();
13877 ++pv)
13878 {
548be246 13879 efb->write_c_string(", ");
13880 (*pv)->export_expression(efb);
2c809f8f 13881 }
548be246 13882 efb->write_c_string(")");
2c809f8f 13883}
e440a328 13884
2c809f8f 13885// Dump ast representation for a map construction expression.
d751bb78 13886
13887void
13888Map_construction_expression::do_dump_expression(
13889 Ast_dump_context* ast_dump_context) const
13890{
d751bb78 13891 ast_dump_context->ostream() << "{" ;
8b1c301d 13892 ast_dump_context->dump_expression_list(this->vals_, true);
d751bb78 13893 ast_dump_context->ostream() << "}";
13894}
13895
7795ac51 13896// Class Composite_literal_expression.
e440a328 13897
13898// Traversal.
13899
13900int
13901Composite_literal_expression::do_traverse(Traverse* traverse)
13902{
dbffccfc 13903 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
e440a328 13904 return TRAVERSE_EXIT;
dbffccfc 13905
13906 // If this is a struct composite literal with keys, then the keys
13907 // are field names, not expressions. We don't want to traverse them
13908 // in that case. If we do, we can give an erroneous error "variable
13909 // initializer refers to itself." See bug482.go in the testsuite.
13910 if (this->has_keys_ && this->vals_ != NULL)
13911 {
13912 // The type may not be resolvable at this point.
13913 Type* type = this->type_;
a01f2481 13914
7795ac51 13915 for (int depth = 0; depth < this->depth_; ++depth)
a01f2481 13916 {
13917 if (type->array_type() != NULL)
13918 type = type->array_type()->element_type();
13919 else if (type->map_type() != NULL)
7795ac51 13920 {
13921 if (this->key_path_[depth])
13922 type = type->map_type()->key_type();
13923 else
13924 type = type->map_type()->val_type();
13925 }
a01f2481 13926 else
13927 {
13928 // This error will be reported during lowering.
13929 return TRAVERSE_CONTINUE;
13930 }
13931 }
13932
dbffccfc 13933 while (true)
13934 {
13935 if (type->classification() == Type::TYPE_NAMED)
13936 type = type->named_type()->real_type();
13937 else if (type->classification() == Type::TYPE_FORWARD)
13938 {
13939 Type* t = type->forwarded();
13940 if (t == type)
13941 break;
13942 type = t;
13943 }
13944 else
13945 break;
13946 }
13947
13948 if (type->classification() == Type::TYPE_STRUCT)
13949 {
13950 Expression_list::iterator p = this->vals_->begin();
13951 while (p != this->vals_->end())
13952 {
13953 // Skip key.
13954 ++p;
13955 go_assert(p != this->vals_->end());
13956 if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
13957 return TRAVERSE_EXIT;
13958 ++p;
13959 }
13960 return TRAVERSE_CONTINUE;
13961 }
13962 }
13963
13964 if (this->vals_ != NULL)
13965 return this->vals_->traverse(traverse);
13966
13967 return TRAVERSE_CONTINUE;
e440a328 13968}
13969
13970// Lower a generic composite literal into a specific version based on
13971// the type.
13972
13973Expression*
ceeb4318 13974Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
13975 Statement_inserter* inserter, int)
e440a328 13976{
13977 Type* type = this->type_;
13978
7795ac51 13979 for (int depth = 0; depth < this->depth_; ++depth)
e440a328 13980 {
67a2ed75 13981 type = type->deref();
e440a328 13982 if (type->array_type() != NULL)
13983 type = type->array_type()->element_type();
13984 else if (type->map_type() != NULL)
7795ac51 13985 {
13986 if (this->key_path_[depth])
13987 type = type->map_type()->key_type();
13988 else
13989 type = type->map_type()->val_type();
13990 }
e440a328 13991 else
13992 {
5c13bd80 13993 if (!type->is_error())
631d5788 13994 go_error_at(this->location(),
13995 ("may only omit types within composite literals "
13996 "of slice, array, or map type"));
e440a328 13997 return Expression::make_error(this->location());
13998 }
13999 }
14000
e00772b3 14001 Type *pt = type->points_to();
14002 bool is_pointer = false;
14003 if (pt != NULL)
14004 {
14005 is_pointer = true;
14006 type = pt;
14007 }
14008
14009 Expression* ret;
5c13bd80 14010 if (type->is_error())
e440a328 14011 return Expression::make_error(this->location());
14012 else if (type->struct_type() != NULL)
e00772b3 14013 ret = this->lower_struct(gogo, type);
e440a328 14014 else if (type->array_type() != NULL)
113ef6a5 14015 ret = this->lower_array(type);
e440a328 14016 else if (type->map_type() != NULL)
e00772b3 14017 ret = this->lower_map(gogo, function, inserter, type);
e440a328 14018 else
14019 {
631d5788 14020 go_error_at(this->location(),
14021 ("expected struct, slice, array, or map type "
14022 "for composite literal"));
e440a328 14023 return Expression::make_error(this->location());
14024 }
e00772b3 14025
14026 if (is_pointer)
2c809f8f 14027 ret = Expression::make_heap_expression(ret, this->location());
e00772b3 14028
14029 return ret;
e440a328 14030}
14031
14032// Lower a struct composite literal.
14033
14034Expression*
81c4b26b 14035Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
e440a328 14036{
b13c66cd 14037 Location location = this->location();
e440a328 14038 Struct_type* st = type->struct_type();
14039 if (this->vals_ == NULL || !this->has_keys_)
07daa4e7 14040 {
e6013c28 14041 if (this->vals_ != NULL
14042 && !this->vals_->empty()
14043 && type->named_type() != NULL
14044 && type->named_type()->named_object()->package() != NULL)
14045 {
14046 for (Struct_field_list::const_iterator pf = st->fields()->begin();
14047 pf != st->fields()->end();
14048 ++pf)
07daa4e7 14049 {
07ba7f26 14050 if (Gogo::is_hidden_name(pf->field_name())
14051 || pf->is_embedded_builtin(gogo))
631d5788 14052 go_error_at(this->location(),
14053 "assignment of unexported field %qs in %qs literal",
14054 Gogo::message_name(pf->field_name()).c_str(),
14055 type->named_type()->message_name().c_str());
07daa4e7 14056 }
14057 }
14058
14059 return new Struct_construction_expression(type, this->vals_, location);
14060 }
e440a328 14061
14062 size_t field_count = st->field_count();
14063 std::vector<Expression*> vals(field_count);
e32de7ba 14064 std::vector<unsigned long>* traverse_order = new(std::vector<unsigned long>);
e440a328 14065 Expression_list::const_iterator p = this->vals_->begin();
62750cd5 14066 Expression* external_expr = NULL;
14067 const Named_object* external_no = NULL;
e440a328 14068 while (p != this->vals_->end())
14069 {
14070 Expression* name_expr = *p;
14071
14072 ++p;
c484d925 14073 go_assert(p != this->vals_->end());
e440a328 14074 Expression* val = *p;
14075
14076 ++p;
14077
14078 if (name_expr == NULL)
14079 {
631d5788 14080 go_error_at(val->location(),
14081 "mixture of field and value initializers");
e440a328 14082 return Expression::make_error(location);
14083 }
14084
14085 bool bad_key = false;
14086 std::string name;
81c4b26b 14087 const Named_object* no = NULL;
e440a328 14088 switch (name_expr->classification())
14089 {
14090 case EXPRESSION_UNKNOWN_REFERENCE:
14091 name = name_expr->unknown_expression()->name();
7f7ce694 14092 if (type->named_type() != NULL)
14093 {
14094 // If the named object found for this field name comes from a
14095 // different package than the struct it is a part of, do not count
14096 // this incorrect lookup as a usage of the object's package.
14097 no = name_expr->unknown_expression()->named_object();
14098 if (no->package() != NULL
14099 && no->package() != type->named_type()->named_object()->package())
14100 no->package()->forget_usage(name_expr);
14101 }
e440a328 14102 break;
14103
14104 case EXPRESSION_CONST_REFERENCE:
81c4b26b 14105 no = static_cast<Const_expression*>(name_expr)->named_object();
e440a328 14106 break;
14107
14108 case EXPRESSION_TYPE:
14109 {
14110 Type* t = name_expr->type();
14111 Named_type* nt = t->named_type();
14112 if (nt == NULL)
14113 bad_key = true;
14114 else
81c4b26b 14115 no = nt->named_object();
e440a328 14116 }
14117 break;
14118
14119 case EXPRESSION_VAR_REFERENCE:
81c4b26b 14120 no = name_expr->var_expression()->named_object();
e440a328 14121 break;
14122
b0c09712 14123 case EXPRESSION_ENCLOSED_VAR_REFERENCE:
14124 no = name_expr->enclosed_var_expression()->variable();
e440a328 14125 break;
14126
b0c09712 14127 case EXPRESSION_FUNC_REFERENCE:
14128 no = name_expr->func_expression()->named_object();
e440a328 14129 break;
14130
14131 default:
14132 bad_key = true;
14133 break;
14134 }
14135 if (bad_key)
14136 {
631d5788 14137 go_error_at(name_expr->location(), "expected struct field name");
e440a328 14138 return Expression::make_error(location);
14139 }
14140
81c4b26b 14141 if (no != NULL)
14142 {
62750cd5 14143 if (no->package() != NULL && external_expr == NULL)
14144 {
14145 external_expr = name_expr;
14146 external_no = no;
14147 }
14148
81c4b26b 14149 name = no->name();
14150
14151 // A predefined name won't be packed. If it starts with a
14152 // lower case letter we need to check for that case, because
2d29d278 14153 // the field name will be packed. FIXME.
81c4b26b 14154 if (!Gogo::is_hidden_name(name)
14155 && name[0] >= 'a'
14156 && name[0] <= 'z')
14157 {
14158 Named_object* gno = gogo->lookup_global(name.c_str());
14159 if (gno == no)
14160 name = gogo->pack_hidden_name(name, false);
14161 }
14162 }
14163
e440a328 14164 unsigned int index;
14165 const Struct_field* sf = st->find_local_field(name, &index);
14166 if (sf == NULL)
14167 {
631d5788 14168 go_error_at(name_expr->location(), "unknown field %qs in %qs",
14169 Gogo::message_name(name).c_str(),
14170 (type->named_type() != NULL
14171 ? type->named_type()->message_name().c_str()
14172 : "unnamed struct"));
e440a328 14173 return Expression::make_error(location);
14174 }
14175 if (vals[index] != NULL)
14176 {
631d5788 14177 go_error_at(name_expr->location(),
14178 "duplicate value for field %qs in %qs",
14179 Gogo::message_name(name).c_str(),
14180 (type->named_type() != NULL
14181 ? type->named_type()->message_name().c_str()
14182 : "unnamed struct"));
e440a328 14183 return Expression::make_error(location);
14184 }
14185
07daa4e7 14186 if (type->named_type() != NULL
14187 && type->named_type()->named_object()->package() != NULL
07ba7f26 14188 && (Gogo::is_hidden_name(sf->field_name())
14189 || sf->is_embedded_builtin(gogo)))
631d5788 14190 go_error_at(name_expr->location(),
14191 "assignment of unexported field %qs in %qs literal",
14192 Gogo::message_name(sf->field_name()).c_str(),
14193 type->named_type()->message_name().c_str());
07daa4e7 14194
e440a328 14195 vals[index] = val;
e32de7ba 14196 traverse_order->push_back(static_cast<unsigned long>(index));
e440a328 14197 }
14198
62750cd5 14199 if (!this->all_are_names_)
14200 {
14201 // This is a weird case like bug462 in the testsuite.
14202 if (external_expr == NULL)
631d5788 14203 go_error_at(this->location(), "unknown field in %qs literal",
14204 (type->named_type() != NULL
14205 ? type->named_type()->message_name().c_str()
14206 : "unnamed struct"));
62750cd5 14207 else
631d5788 14208 go_error_at(external_expr->location(), "unknown field %qs in %qs",
14209 external_no->message_name().c_str(),
14210 (type->named_type() != NULL
14211 ? type->named_type()->message_name().c_str()
14212 : "unnamed struct"));
62750cd5 14213 return Expression::make_error(location);
14214 }
14215
e440a328 14216 Expression_list* list = new Expression_list;
14217 list->reserve(field_count);
14218 for (size_t i = 0; i < field_count; ++i)
14219 list->push_back(vals[i]);
14220
0c4f5a19 14221 Struct_construction_expression* ret =
14222 new Struct_construction_expression(type, list, location);
14223 ret->set_traverse_order(traverse_order);
14224 return ret;
e440a328 14225}
14226
e32de7ba 14227// Index/value/traversal-order triple.
00773463 14228
e32de7ba 14229struct IVT_triple {
14230 unsigned long index;
14231 unsigned long traversal_order;
14232 Expression* expr;
14233 IVT_triple(unsigned long i, unsigned long to, Expression *e)
14234 : index(i), traversal_order(to), expr(e) { }
14235 bool operator<(const IVT_triple& other) const
14236 { return this->index < other.index; }
00773463 14237};
14238
e440a328 14239// Lower an array composite literal.
14240
14241Expression*
113ef6a5 14242Composite_literal_expression::lower_array(Type* type)
e440a328 14243{
b13c66cd 14244 Location location = this->location();
e440a328 14245 if (this->vals_ == NULL || !this->has_keys_)
ffe743ca 14246 return this->make_array(type, NULL, this->vals_);
e440a328 14247
ffe743ca 14248 std::vector<unsigned long>* indexes = new std::vector<unsigned long>;
14249 indexes->reserve(this->vals_->size());
00773463 14250 bool indexes_out_of_order = false;
ffe743ca 14251 Expression_list* vals = new Expression_list();
14252 vals->reserve(this->vals_->size());
e440a328 14253 unsigned long index = 0;
14254 Expression_list::const_iterator p = this->vals_->begin();
14255 while (p != this->vals_->end())
14256 {
14257 Expression* index_expr = *p;
14258
14259 ++p;
c484d925 14260 go_assert(p != this->vals_->end());
e440a328 14261 Expression* val = *p;
14262
14263 ++p;
14264
ffe743ca 14265 if (index_expr == NULL)
14266 {
8f2ebee5 14267 if (std::find(indexes->begin(), indexes->end(), index)
14268 != indexes->end())
14269 {
14270 go_error_at(val->location(),
14271 "duplicate value for index %lu", index);
14272 return Expression::make_error(location);
14273 }
ffe743ca 14274 if (!indexes->empty())
14275 indexes->push_back(index);
14276 }
14277 else
e440a328 14278 {
ffe743ca 14279 if (indexes->empty() && !vals->empty())
14280 {
14281 for (size_t i = 0; i < vals->size(); ++i)
14282 indexes->push_back(i);
14283 }
14284
0c77715b 14285 Numeric_constant nc;
14286 if (!index_expr->numeric_constant_value(&nc))
e440a328 14287 {
631d5788 14288 go_error_at(index_expr->location(),
14289 "index expression is not integer constant");
e440a328 14290 return Expression::make_error(location);
14291 }
6f6d9955 14292
0c77715b 14293 switch (nc.to_unsigned_long(&index))
e440a328 14294 {
0c77715b 14295 case Numeric_constant::NC_UL_VALID:
14296 break;
14297 case Numeric_constant::NC_UL_NOTINT:
631d5788 14298 go_error_at(index_expr->location(),
14299 "index expression is not integer constant");
0c77715b 14300 return Expression::make_error(location);
14301 case Numeric_constant::NC_UL_NEGATIVE:
631d5788 14302 go_error_at(index_expr->location(),
14303 "index expression is negative");
e440a328 14304 return Expression::make_error(location);
0c77715b 14305 case Numeric_constant::NC_UL_BIG:
631d5788 14306 go_error_at(index_expr->location(), "index value overflow");
e440a328 14307 return Expression::make_error(location);
0c77715b 14308 default:
14309 go_unreachable();
e440a328 14310 }
6f6d9955 14311
14312 Named_type* ntype = Type::lookup_integer_type("int");
14313 Integer_type* inttype = ntype->integer_type();
0c77715b 14314 if (sizeof(index) <= static_cast<size_t>(inttype->bits() * 8)
14315 && index >> (inttype->bits() - 1) != 0)
6f6d9955 14316 {
631d5788 14317 go_error_at(index_expr->location(), "index value overflow");
6f6d9955 14318 return Expression::make_error(location);
14319 }
14320
ffe743ca 14321 if (std::find(indexes->begin(), indexes->end(), index)
14322 != indexes->end())
e440a328 14323 {
631d5788 14324 go_error_at(index_expr->location(),
14325 "duplicate value for index %lu",
14326 index);
e440a328 14327 return Expression::make_error(location);
14328 }
ffe743ca 14329
00773463 14330 if (!indexes->empty() && index < indexes->back())
14331 indexes_out_of_order = true;
14332
ffe743ca 14333 indexes->push_back(index);
e440a328 14334 }
14335
ffe743ca 14336 vals->push_back(val);
14337
e440a328 14338 ++index;
14339 }
14340
ffe743ca 14341 if (indexes->empty())
14342 {
14343 delete indexes;
14344 indexes = NULL;
14345 }
e440a328 14346
e32de7ba 14347 std::vector<unsigned long>* traverse_order = NULL;
00773463 14348 if (indexes_out_of_order)
14349 {
e32de7ba 14350 typedef std::vector<IVT_triple> V;
00773463 14351
14352 V v;
14353 v.reserve(indexes->size());
14354 std::vector<unsigned long>::const_iterator pi = indexes->begin();
e32de7ba 14355 unsigned long torder = 0;
00773463 14356 for (Expression_list::const_iterator pe = vals->begin();
14357 pe != vals->end();
e32de7ba 14358 ++pe, ++pi, ++torder)
14359 v.push_back(IVT_triple(*pi, torder, *pe));
00773463 14360
e32de7ba 14361 std::sort(v.begin(), v.end());
00773463 14362
14363 delete indexes;
14364 delete vals;
e32de7ba 14365
00773463 14366 indexes = new std::vector<unsigned long>();
14367 indexes->reserve(v.size());
14368 vals = new Expression_list();
14369 vals->reserve(v.size());
e32de7ba 14370 traverse_order = new std::vector<unsigned long>();
14371 traverse_order->reserve(v.size());
00773463 14372
14373 for (V::const_iterator p = v.begin(); p != v.end(); ++p)
14374 {
e32de7ba 14375 indexes->push_back(p->index);
14376 vals->push_back(p->expr);
14377 traverse_order->push_back(p->traversal_order);
00773463 14378 }
14379 }
14380
e32de7ba 14381 Expression* ret = this->make_array(type, indexes, vals);
14382 Array_construction_expression* ace = ret->array_literal();
14383 if (ace != NULL && traverse_order != NULL)
14384 ace->set_traverse_order(traverse_order);
14385 return ret;
e440a328 14386}
14387
14388// Actually build the array composite literal. This handles
14389// [...]{...}.
14390
14391Expression*
ffe743ca 14392Composite_literal_expression::make_array(
14393 Type* type,
14394 const std::vector<unsigned long>* indexes,
14395 Expression_list* vals)
e440a328 14396{
b13c66cd 14397 Location location = this->location();
e440a328 14398 Array_type* at = type->array_type();
ffe743ca 14399
e440a328 14400 if (at->length() != NULL && at->length()->is_nil_expression())
14401 {
ffe743ca 14402 size_t size;
14403 if (vals == NULL)
14404 size = 0;
00773463 14405 else if (indexes != NULL)
14406 size = indexes->back() + 1;
14407 else
ffe743ca 14408 {
14409 size = vals->size();
14410 Integer_type* it = Type::lookup_integer_type("int")->integer_type();
14411 if (sizeof(size) <= static_cast<size_t>(it->bits() * 8)
14412 && size >> (it->bits() - 1) != 0)
14413 {
631d5788 14414 go_error_at(location, "too many elements in composite literal");
ffe743ca 14415 return Expression::make_error(location);
14416 }
14417 }
ffe743ca 14418
e67508fa 14419 Expression* elen = Expression::make_integer_ul(size, NULL, location);
e440a328 14420 at = Type::make_array_type(at->element_type(), elen);
14421 type = at;
14422 }
ffe743ca 14423 else if (at->length() != NULL
14424 && !at->length()->is_error_expression()
14425 && this->vals_ != NULL)
14426 {
14427 Numeric_constant nc;
14428 unsigned long val;
14429 if (at->length()->numeric_constant_value(&nc)
14430 && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID)
14431 {
14432 if (indexes == NULL)
14433 {
14434 if (this->vals_->size() > val)
14435 {
631d5788 14436 go_error_at(location,
14437 "too many elements in composite literal");
ffe743ca 14438 return Expression::make_error(location);
14439 }
14440 }
14441 else
14442 {
00773463 14443 unsigned long max = indexes->back();
ffe743ca 14444 if (max >= val)
14445 {
631d5788 14446 go_error_at(location,
14447 ("some element keys in composite literal "
14448 "are out of range"));
ffe743ca 14449 return Expression::make_error(location);
14450 }
14451 }
14452 }
14453 }
14454
e440a328 14455 if (at->length() != NULL)
ffe743ca 14456 return new Fixed_array_construction_expression(type, indexes, vals,
14457 location);
e440a328 14458 else
2c809f8f 14459 return new Slice_construction_expression(type, indexes, vals, location);
e440a328 14460}
14461
14462// Lower a map composite literal.
14463
14464Expression*
a287720d 14465Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
ceeb4318 14466 Statement_inserter* inserter,
a287720d 14467 Type* type)
e440a328 14468{
b13c66cd 14469 Location location = this->location();
f03a9fbf 14470 Unordered_map(unsigned int, std::vector<Expression*>) st;
0ab32342 14471 Unordered_map(unsigned int, std::vector<Expression*>) nt;
e440a328 14472 if (this->vals_ != NULL)
14473 {
14474 if (!this->has_keys_)
14475 {
631d5788 14476 go_error_at(location, "map composite literal must have keys");
e440a328 14477 return Expression::make_error(location);
14478 }
14479
a287720d 14480 for (Expression_list::iterator p = this->vals_->begin();
e440a328 14481 p != this->vals_->end();
14482 p += 2)
14483 {
14484 if (*p == NULL)
14485 {
14486 ++p;
631d5788 14487 go_error_at((*p)->location(),
14488 ("map composite literal must "
14489 "have keys for every value"));
e440a328 14490 return Expression::make_error(location);
14491 }
a287720d 14492 // Make sure we have lowered the key; it may not have been
14493 // lowered in order to handle keys for struct composite
14494 // literals. Lower it now to get the right error message.
14495 if ((*p)->unknown_expression() != NULL)
14496 {
14497 (*p)->unknown_expression()->clear_is_composite_literal_key();
ceeb4318 14498 gogo->lower_expression(function, inserter, &*p);
c484d925 14499 go_assert((*p)->is_error_expression());
a287720d 14500 return Expression::make_error(location);
14501 }
f03a9fbf 14502 // Check if there are duplicate constant keys.
14503 if (!(*p)->is_constant())
14504 continue;
14505 std::string sval;
0ab32342 14506 Numeric_constant nval;
14507 if ((*p)->string_constant_value(&sval)) // Check string keys.
f03a9fbf 14508 {
14509 unsigned int h = Gogo::hash_string(sval, 0);
14510 // Search the index h in the hash map.
14511 Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
14512 mit = st.find(h);
14513 if (mit == st.end())
14514 {
14515 // No duplicate since h is a new index.
14516 // Create a new vector indexed by h and add it to the hash map.
14517 std::vector<Expression*> l;
14518 l.push_back(*p);
14519 std::pair<unsigned int, std::vector<Expression*> > val(h, l);
14520 st.insert(val);
14521 }
14522 else
14523 {
14524 // Do further check since index h already exists.
14525 for (std::vector<Expression*>::iterator lit =
14526 mit->second.begin();
14527 lit != mit->second.end();
14528 lit++)
14529 {
14530 std::string s;
14531 bool ok = (*lit)->string_constant_value(&s);
14532 go_assert(ok);
14533 if (s == sval)
14534 {
14535 go_error_at((*p)->location(), ("duplicate key "
14536 "in map literal"));
14537 return Expression::make_error(location);
14538 }
14539 }
14540 // Add this new string key to the vector indexed by h.
14541 mit->second.push_back(*p);
14542 }
14543 }
0ab32342 14544 else if ((*p)->numeric_constant_value(&nval)) // Check numeric keys.
14545 {
14546 unsigned int h = nval.hash(0);
14547 Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
14548 mit = nt.find(h);
14549 if (mit == nt.end())
14550 {
14551 // No duplicate since h is a new code.
14552 // Create a new vector indexed by h and add it to the hash map.
14553 std::vector<Expression*> l;
14554 l.push_back(*p);
14555 std::pair<unsigned int, std::vector<Expression*> > val(h, l);
14556 nt.insert(val);
14557 }
14558 else
14559 {
14560 // Do further check since h already exists.
14561 for (std::vector<Expression*>::iterator lit =
14562 mit->second.begin();
14563 lit != mit->second.end();
14564 lit++)
14565 {
14566 Numeric_constant rval;
14567 bool ok = (*lit)->numeric_constant_value(&rval);
14568 go_assert(ok);
14569 if (nval.equals(rval))
14570 {
14571 go_error_at((*p)->location(),
14572 "duplicate key in map literal");
14573 return Expression::make_error(location);
14574 }
14575 }
14576 // Add this new numeric key to the vector indexed by h.
14577 mit->second.push_back(*p);
14578 }
14579 }
e440a328 14580 }
14581 }
14582
14583 return new Map_construction_expression(type, this->vals_, location);
14584}
14585
de590a61 14586// Copy.
14587
14588Expression*
14589Composite_literal_expression::do_copy()
14590{
14591 Composite_literal_expression* ret =
14592 new Composite_literal_expression(this->type_->copy_expressions(),
14593 this->depth_, this->has_keys_,
14594 (this->vals_ == NULL
14595 ? NULL
14596 : this->vals_->copy()),
14597 this->all_are_names_,
14598 this->location());
14599 ret->key_path_ = this->key_path_;
14600 return ret;
14601}
14602
d751bb78 14603// Dump ast representation for a composite literal expression.
14604
14605void
14606Composite_literal_expression::do_dump_expression(
14607 Ast_dump_context* ast_dump_context) const
14608{
8b1c301d 14609 ast_dump_context->ostream() << "composite(";
d751bb78 14610 ast_dump_context->dump_type(this->type_);
14611 ast_dump_context->ostream() << ", {";
8b1c301d 14612 ast_dump_context->dump_expression_list(this->vals_, this->has_keys_);
d751bb78 14613 ast_dump_context->ostream() << "})";
14614}
14615
e440a328 14616// Make a composite literal expression.
14617
14618Expression*
14619Expression::make_composite_literal(Type* type, int depth, bool has_keys,
62750cd5 14620 Expression_list* vals, bool all_are_names,
b13c66cd 14621 Location location)
e440a328 14622{
14623 return new Composite_literal_expression(type, depth, has_keys, vals,
62750cd5 14624 all_are_names, location);
e440a328 14625}
14626
14627// Return whether this expression is a composite literal.
14628
14629bool
14630Expression::is_composite_literal() const
14631{
14632 switch (this->classification_)
14633 {
14634 case EXPRESSION_COMPOSITE_LITERAL:
14635 case EXPRESSION_STRUCT_CONSTRUCTION:
14636 case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
2c809f8f 14637 case EXPRESSION_SLICE_CONSTRUCTION:
e440a328 14638 case EXPRESSION_MAP_CONSTRUCTION:
14639 return true;
14640 default:
14641 return false;
14642 }
14643}
14644
14645// Return whether this expression is a composite literal which is not
14646// constant.
14647
14648bool
14649Expression::is_nonconstant_composite_literal() const
14650{
14651 switch (this->classification_)
14652 {
14653 case EXPRESSION_STRUCT_CONSTRUCTION:
14654 {
14655 const Struct_construction_expression *psce =
14656 static_cast<const Struct_construction_expression*>(this);
14657 return !psce->is_constant_struct();
14658 }
14659 case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
14660 {
14661 const Fixed_array_construction_expression *pace =
14662 static_cast<const Fixed_array_construction_expression*>(this);
14663 return !pace->is_constant_array();
14664 }
2c809f8f 14665 case EXPRESSION_SLICE_CONSTRUCTION:
e440a328 14666 {
2c809f8f 14667 const Slice_construction_expression *pace =
14668 static_cast<const Slice_construction_expression*>(this);
e440a328 14669 return !pace->is_constant_array();
14670 }
14671 case EXPRESSION_MAP_CONSTRUCTION:
14672 return true;
14673 default:
14674 return false;
14675 }
14676}
14677
35a54f17 14678// Return true if this is a variable or temporary_variable.
14679
14680bool
14681Expression::is_variable() const
14682{
14683 switch (this->classification_)
14684 {
14685 case EXPRESSION_VAR_REFERENCE:
14686 case EXPRESSION_TEMPORARY_REFERENCE:
14687 case EXPRESSION_SET_AND_USE_TEMPORARY:
b0c09712 14688 case EXPRESSION_ENCLOSED_VAR_REFERENCE:
35a54f17 14689 return true;
14690 default:
14691 return false;
14692 }
14693}
14694
e440a328 14695// Return true if this is a reference to a local variable.
14696
14697bool
14698Expression::is_local_variable() const
14699{
14700 const Var_expression* ve = this->var_expression();
14701 if (ve == NULL)
14702 return false;
14703 const Named_object* no = ve->named_object();
14704 return (no->is_result_variable()
14705 || (no->is_variable() && !no->var_value()->is_global()));
14706}
14707
14708// Class Type_guard_expression.
14709
14710// Traversal.
14711
14712int
14713Type_guard_expression::do_traverse(Traverse* traverse)
14714{
14715 if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
14716 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
14717 return TRAVERSE_EXIT;
14718 return TRAVERSE_CONTINUE;
14719}
14720
2c809f8f 14721Expression*
14722Type_guard_expression::do_flatten(Gogo*, Named_object*,
14723 Statement_inserter* inserter)
14724{
5bf8be8b 14725 if (this->expr_->is_error_expression()
14726 || this->expr_->type()->is_error_type())
14727 {
14728 go_assert(saw_errors());
14729 return Expression::make_error(this->location());
14730 }
14731
2c809f8f 14732 if (!this->expr_->is_variable())
14733 {
14734 Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_,
14735 this->location());
14736 inserter->insert(temp);
14737 this->expr_ =
14738 Expression::make_temporary_reference(temp, this->location());
14739 }
14740 return this;
14741}
14742
e440a328 14743// Check types of a type guard expression. The expression must have
14744// an interface type, but the actual type conversion is checked at run
14745// time.
14746
14747void
14748Type_guard_expression::do_check_types(Gogo*)
14749{
e440a328 14750 Type* expr_type = this->expr_->type();
7e9da23f 14751 if (expr_type->interface_type() == NULL)
f725ade8 14752 {
5c13bd80 14753 if (!expr_type->is_error() && !this->type_->is_error())
f725ade8 14754 this->report_error(_("type assertion only valid for interface types"));
14755 this->set_is_error();
14756 }
e440a328 14757 else if (this->type_->interface_type() == NULL)
14758 {
14759 std::string reason;
14760 if (!expr_type->interface_type()->implements_interface(this->type_,
14761 &reason))
14762 {
5c13bd80 14763 if (!this->type_->is_error())
e440a328 14764 {
f725ade8 14765 if (reason.empty())
14766 this->report_error(_("impossible type assertion: "
14767 "type does not implement interface"));
14768 else
631d5788 14769 go_error_at(this->location(),
14770 ("impossible type assertion: "
14771 "type does not implement interface (%s)"),
14772 reason.c_str());
e440a328 14773 }
f725ade8 14774 this->set_is_error();
e440a328 14775 }
14776 }
14777}
14778
de590a61 14779// Copy.
14780
14781Expression*
14782Type_guard_expression::do_copy()
14783{
14784 return new Type_guard_expression(this->expr_->copy(),
14785 this->type_->copy_expressions(),
14786 this->location());
14787}
14788
ea664253 14789// Return the backend representation for a type guard expression.
e440a328 14790
ea664253 14791Bexpression*
14792Type_guard_expression::do_get_backend(Translate_context* context)
e440a328 14793{
2c809f8f 14794 Expression* conversion;
7e9da23f 14795 if (this->type_->interface_type() != NULL)
2c809f8f 14796 conversion =
14797 Expression::convert_interface_to_interface(this->type_, this->expr_,
14798 true, this->location());
e440a328 14799 else
2c809f8f 14800 conversion =
14801 Expression::convert_for_assignment(context->gogo(), this->type_,
14802 this->expr_, this->location());
14803
21b70e8f 14804 Gogo* gogo = context->gogo();
14805 Btype* bt = this->type_->get_backend(gogo);
14806 Bexpression* bexpr = conversion->get_backend(context);
14807 return gogo->backend()->convert_expression(bt, bexpr, this->location());
e440a328 14808}
14809
d751bb78 14810// Dump ast representation for a type guard expression.
14811
14812void
2c809f8f 14813Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
d751bb78 14814 const
14815{
14816 this->expr_->dump_expression(ast_dump_context);
14817 ast_dump_context->ostream() << ".";
14818 ast_dump_context->dump_type(this->type_);
14819}
14820
e440a328 14821// Make a type guard expression.
14822
14823Expression*
14824Expression::make_type_guard(Expression* expr, Type* type,
b13c66cd 14825 Location location)
e440a328 14826{
14827 return new Type_guard_expression(expr, type, location);
14828}
14829
2c809f8f 14830// Class Heap_expression.
e440a328 14831
da244e59 14832// Return the type of the expression stored on the heap.
e440a328 14833
da244e59 14834Type*
14835Heap_expression::do_type()
14836{ return Type::make_pointer_type(this->expr_->type()); }
e440a328 14837
ea664253 14838// Return the backend representation for allocating an expression on the heap.
e440a328 14839
ea664253 14840Bexpression*
14841Heap_expression::do_get_backend(Translate_context* context)
e440a328 14842{
03118c21 14843 Type* etype = this->expr_->type();
14844 if (this->expr_->is_error_expression() || etype->is_error())
ea664253 14845 return context->backend()->error_expression();
2c809f8f 14846
02c19a1a 14847 Location loc = this->location();
2c809f8f 14848 Gogo* gogo = context->gogo();
02c19a1a 14849 Btype* btype = this->type()->get_backend(gogo);
45ff893b 14850
03118c21 14851 Expression* alloc = Expression::make_allocation(etype, loc);
5973ede0 14852 if (this->allocate_on_stack_)
45ff893b 14853 alloc->allocation_expression()->set_allocate_on_stack();
14854 Bexpression* space = alloc->get_backend(context);
02c19a1a 14855
14856 Bstatement* decl;
14857 Named_object* fn = context->function();
14858 go_assert(fn != NULL);
14859 Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
14860 Bvariable* space_temp =
14861 gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
14862 space, true, loc, &decl);
03118c21 14863 Btype* expr_btype = etype->get_backend(gogo);
02c19a1a 14864
ea664253 14865 Bexpression* bexpr = this->expr_->get_backend(context);
03118c21 14866
14867 // If this assignment needs a write barrier, call typedmemmove. We
14868 // don't do this in the write barrier pass because in some cases
14869 // backend conversion can introduce new Heap_expression values.
14870 Bstatement* assn;
06e83d10 14871 if (!etype->has_pointer() || this->allocate_on_stack_)
03118c21 14872 {
7af8e400 14873 space = gogo->backend()->var_expression(space_temp, loc);
03118c21 14874 Bexpression* ref =
14875 gogo->backend()->indirect_expression(expr_btype, space, true, loc);
14876 assn = gogo->backend()->assignment_statement(fndecl, ref, bexpr, loc);
14877 }
14878 else
14879 {
14880 Bstatement* edecl;
14881 Bvariable* btemp =
14882 gogo->backend()->temporary_variable(fndecl, context->bblock(),
14883 expr_btype, bexpr, true, loc,
14884 &edecl);
14885 Bexpression* btempref = gogo->backend()->var_expression(btemp,
7af8e400 14886 loc);
03118c21 14887 Bexpression* addr = gogo->backend()->address_expression(btempref, loc);
14888
14889 Expression* td = Expression::make_type_descriptor(etype, loc);
14890 Type* etype_ptr = Type::make_pointer_type(etype);
7af8e400 14891 space = gogo->backend()->var_expression(space_temp, loc);
03118c21 14892 Expression* elhs = Expression::make_backend(space, etype_ptr, loc);
14893 Expression* erhs = Expression::make_backend(addr, etype_ptr, loc);
14894 Expression* call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
14895 td, elhs, erhs);
14896 Bexpression* bcall = call->get_backend(context);
14897 Bstatement* s = gogo->backend()->expression_statement(fndecl, bcall);
14898 assn = gogo->backend()->compound_statement(edecl, s);
14899 }
02c19a1a 14900 decl = gogo->backend()->compound_statement(decl, assn);
7af8e400 14901 space = gogo->backend()->var_expression(space_temp, loc);
ea664253 14902 return gogo->backend()->compound_expression(decl, space, loc);
e440a328 14903}
14904
2c809f8f 14905// Dump ast representation for a heap expression.
d751bb78 14906
14907void
2c809f8f 14908Heap_expression::do_dump_expression(
d751bb78 14909 Ast_dump_context* ast_dump_context) const
14910{
14911 ast_dump_context->ostream() << "&(";
14912 ast_dump_context->dump_expression(this->expr_);
14913 ast_dump_context->ostream() << ")";
14914}
14915
2c809f8f 14916// Allocate an expression on the heap.
e440a328 14917
14918Expression*
2c809f8f 14919Expression::make_heap_expression(Expression* expr, Location location)
e440a328 14920{
2c809f8f 14921 return new Heap_expression(expr, location);
e440a328 14922}
14923
14924// Class Receive_expression.
14925
14926// Return the type of a receive expression.
14927
14928Type*
14929Receive_expression::do_type()
14930{
e429e3bd 14931 if (this->is_error_expression())
14932 return Type::make_error_type();
e440a328 14933 Channel_type* channel_type = this->channel_->type()->channel_type();
14934 if (channel_type == NULL)
e429e3bd 14935 {
14936 this->report_error(_("expected channel"));
14937 return Type::make_error_type();
14938 }
e440a328 14939 return channel_type->element_type();
14940}
14941
14942// Check types for a receive expression.
14943
14944void
14945Receive_expression::do_check_types(Gogo*)
14946{
14947 Type* type = this->channel_->type();
5c13bd80 14948 if (type->is_error())
e440a328 14949 {
e429e3bd 14950 go_assert(saw_errors());
e440a328 14951 this->set_is_error();
14952 return;
14953 }
14954 if (type->channel_type() == NULL)
14955 {
14956 this->report_error(_("expected channel"));
14957 return;
14958 }
14959 if (!type->channel_type()->may_receive())
14960 {
14961 this->report_error(_("invalid receive on send-only channel"));
14962 return;
14963 }
14964}
14965
2c809f8f 14966// Flattening for receive expressions creates a temporary variable to store
14967// received data in for receives.
14968
14969Expression*
14970Receive_expression::do_flatten(Gogo*, Named_object*,
14971 Statement_inserter* inserter)
14972{
14973 Channel_type* channel_type = this->channel_->type()->channel_type();
14974 if (channel_type == NULL)
14975 {
14976 go_assert(saw_errors());
14977 return this;
14978 }
5bf8be8b 14979 else if (this->channel_->is_error_expression())
14980 {
14981 go_assert(saw_errors());
14982 return Expression::make_error(this->location());
14983 }
2c809f8f 14984
14985 Type* element_type = channel_type->element_type();
14986 if (this->temp_receiver_ == NULL)
14987 {
14988 this->temp_receiver_ = Statement::make_temporary(element_type, NULL,
14989 this->location());
14990 this->temp_receiver_->set_is_address_taken();
14991 inserter->insert(this->temp_receiver_);
14992 }
14993
14994 return this;
14995}
14996
ea664253 14997// Get the backend representation for a receive expression.
e440a328 14998
ea664253 14999Bexpression*
15000Receive_expression::do_get_backend(Translate_context* context)
e440a328 15001{
f24f10bb 15002 Location loc = this->location();
15003
e440a328 15004 Channel_type* channel_type = this->channel_->type()->channel_type();
5b8368f4 15005 if (channel_type == NULL)
15006 {
c484d925 15007 go_assert(this->channel_->type()->is_error());
ea664253 15008 return context->backend()->error_expression();
5b8368f4 15009 }
e440a328 15010
2c809f8f 15011 Expression* recv_ref =
15012 Expression::make_temporary_reference(this->temp_receiver_, loc);
15013 Expression* recv_addr =
15014 Expression::make_temporary_reference(this->temp_receiver_, loc);
15015 recv_addr = Expression::make_unary(OPERATOR_AND, recv_addr, loc);
e36a5ff5 15016 Expression* recv = Runtime::make_call(Runtime::CHANRECV1, loc, 2,
15017 this->channel_, recv_addr);
ea664253 15018 return Expression::make_compound(recv, recv_ref, loc)->get_backend(context);
e440a328 15019}
15020
d751bb78 15021// Dump ast representation for a receive expression.
15022
15023void
15024Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
15025{
15026 ast_dump_context->ostream() << " <- " ;
15027 ast_dump_context->dump_expression(channel_);
15028}
15029
e440a328 15030// Make a receive expression.
15031
15032Receive_expression*
b13c66cd 15033Expression::make_receive(Expression* channel, Location location)
e440a328 15034{
15035 return new Receive_expression(channel, location);
15036}
15037
e440a328 15038// An expression which evaluates to a pointer to the type descriptor
15039// of a type.
15040
15041class Type_descriptor_expression : public Expression
15042{
15043 public:
b13c66cd 15044 Type_descriptor_expression(Type* type, Location location)
e440a328 15045 : Expression(EXPRESSION_TYPE_DESCRIPTOR, location),
15046 type_(type)
15047 { }
15048
15049 protected:
4b686186 15050 int
15051 do_traverse(Traverse*);
15052
e440a328 15053 Type*
15054 do_type()
15055 { return Type::make_type_descriptor_ptr_type(); }
15056
f9ca30f9 15057 bool
3ae06f68 15058 do_is_static_initializer() const
f9ca30f9 15059 { return true; }
15060
e440a328 15061 void
15062 do_determine_type(const Type_context*)
15063 { }
15064
15065 Expression*
15066 do_copy()
15067 { return this; }
15068
ea664253 15069 Bexpression*
15070 do_get_backend(Translate_context* context)
a1d23b41 15071 {
ea664253 15072 return this->type_->type_descriptor_pointer(context->gogo(),
15073 this->location());
a1d23b41 15074 }
e440a328 15075
d751bb78 15076 void
15077 do_dump_expression(Ast_dump_context*) const;
15078
e440a328 15079 private:
15080 // The type for which this is the descriptor.
15081 Type* type_;
15082};
15083
4b686186 15084int
15085Type_descriptor_expression::do_traverse(Traverse* traverse)
15086{
15087 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
15088 return TRAVERSE_EXIT;
15089 return TRAVERSE_CONTINUE;
15090}
15091
d751bb78 15092// Dump ast representation for a type descriptor expression.
15093
15094void
15095Type_descriptor_expression::do_dump_expression(
15096 Ast_dump_context* ast_dump_context) const
15097{
15098 ast_dump_context->dump_type(this->type_);
15099}
15100
e440a328 15101// Make a type descriptor expression.
15102
15103Expression*
b13c66cd 15104Expression::make_type_descriptor(Type* type, Location location)
e440a328 15105{
15106 return new Type_descriptor_expression(type, location);
15107}
15108
aa5ae575 15109// An expression which evaluates to a pointer to the Garbage Collection symbol
15110// of a type.
15111
15112class GC_symbol_expression : public Expression
15113{
15114 public:
15115 GC_symbol_expression(Type* type)
15116 : Expression(EXPRESSION_GC_SYMBOL, Linemap::predeclared_location()),
15117 type_(type)
15118 {}
15119
15120 protected:
15121 Type*
15122 do_type()
03118c21 15123 { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
aa5ae575 15124
15125 bool
3ae06f68 15126 do_is_static_initializer() const
aa5ae575 15127 { return true; }
15128
15129 void
15130 do_determine_type(const Type_context*)
15131 { }
15132
15133 Expression*
15134 do_copy()
15135 { return this; }
15136
15137 Bexpression*
15138 do_get_backend(Translate_context* context)
15139 { return this->type_->gc_symbol_pointer(context->gogo()); }
15140
15141 void
15142 do_dump_expression(Ast_dump_context*) const;
15143
15144 private:
15145 // The type which this gc symbol describes.
15146 Type* type_;
15147};
15148
15149// Dump ast representation for a gc symbol expression.
15150
15151void
15152GC_symbol_expression::do_dump_expression(
15153 Ast_dump_context* ast_dump_context) const
15154{
15155 ast_dump_context->ostream() << "gcdata(";
15156 ast_dump_context->dump_type(this->type_);
15157 ast_dump_context->ostream() << ")";
15158}
15159
15160// Make a gc symbol expression.
15161
15162Expression*
15163Expression::make_gc_symbol(Type* type)
15164{
15165 return new GC_symbol_expression(type);
15166}
15167
03118c21 15168// An expression that evaluates to a pointer to a symbol holding the
15169// ptrmask data of a type.
15170
15171class Ptrmask_symbol_expression : public Expression
15172{
15173 public:
15174 Ptrmask_symbol_expression(Type* type)
15175 : Expression(EXPRESSION_PTRMASK_SYMBOL, Linemap::predeclared_location()),
15176 type_(type)
15177 {}
15178
15179 protected:
15180 Type*
15181 do_type()
15182 { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
15183
15184 bool
15185 do_is_static_initializer() const
15186 { return true; }
15187
15188 void
15189 do_determine_type(const Type_context*)
15190 { }
15191
15192 Expression*
15193 do_copy()
15194 { return this; }
15195
15196 Bexpression*
15197 do_get_backend(Translate_context*);
15198
15199 void
15200 do_dump_expression(Ast_dump_context*) const;
15201
15202 private:
15203 // The type that this ptrmask symbol describes.
15204 Type* type_;
15205};
15206
15207// Return the ptrmask variable.
15208
15209Bexpression*
15210Ptrmask_symbol_expression::do_get_backend(Translate_context* context)
15211{
15212 Gogo* gogo = context->gogo();
15213
15214 // If this type does not need a gcprog, then we can use the standard
15215 // GC symbol.
15216 int64_t ptrsize, ptrdata;
15217 if (!this->type_->needs_gcprog(gogo, &ptrsize, &ptrdata))
15218 return this->type_->gc_symbol_pointer(gogo);
15219
15220 // Otherwise we have to build a ptrmask variable, and return a
15221 // pointer to it.
15222
15223 Bvariable* bvar = this->type_->gc_ptrmask_var(gogo, ptrsize, ptrdata);
15224 Location bloc = Linemap::predeclared_location();
7af8e400 15225 Bexpression* bref = gogo->backend()->var_expression(bvar, bloc);
03118c21 15226 Bexpression* baddr = gogo->backend()->address_expression(bref, bloc);
15227
15228 Type* uint8_type = Type::lookup_integer_type("uint8");
15229 Type* pointer_uint8_type = Type::make_pointer_type(uint8_type);
15230 Btype* ubtype = pointer_uint8_type->get_backend(gogo);
15231 return gogo->backend()->convert_expression(ubtype, baddr, bloc);
15232}
15233
15234// Dump AST for a ptrmask symbol expression.
15235
15236void
15237Ptrmask_symbol_expression::do_dump_expression(
15238 Ast_dump_context* ast_dump_context) const
15239{
15240 ast_dump_context->ostream() << "ptrmask(";
15241 ast_dump_context->dump_type(this->type_);
15242 ast_dump_context->ostream() << ")";
15243}
15244
15245// Make a ptrmask symbol expression.
15246
15247Expression*
15248Expression::make_ptrmask_symbol(Type* type)
15249{
15250 return new Ptrmask_symbol_expression(type);
15251}
15252
e440a328 15253// An expression which evaluates to some characteristic of a type.
15254// This is only used to initialize fields of a type descriptor. Using
15255// a new expression class is slightly inefficient but gives us a good
15256// separation between the frontend and the middle-end with regard to
15257// how types are laid out.
15258
15259class Type_info_expression : public Expression
15260{
15261 public:
15262 Type_info_expression(Type* type, Type_info type_info)
b13c66cd 15263 : Expression(EXPRESSION_TYPE_INFO, Linemap::predeclared_location()),
e440a328 15264 type_(type), type_info_(type_info)
15265 { }
15266
15267 protected:
0e168074 15268 bool
3ae06f68 15269 do_is_static_initializer() const
0e168074 15270 { return true; }
15271
e440a328 15272 Type*
15273 do_type();
15274
15275 void
15276 do_determine_type(const Type_context*)
15277 { }
15278
15279 Expression*
15280 do_copy()
15281 { return this; }
15282
ea664253 15283 Bexpression*
15284 do_get_backend(Translate_context* context);
e440a328 15285
d751bb78 15286 void
15287 do_dump_expression(Ast_dump_context*) const;
15288
e440a328 15289 private:
15290 // The type for which we are getting information.
15291 Type* type_;
15292 // What information we want.
15293 Type_info type_info_;
15294};
15295
15296// The type is chosen to match what the type descriptor struct
15297// expects.
15298
15299Type*
15300Type_info_expression::do_type()
15301{
15302 switch (this->type_info_)
15303 {
15304 case TYPE_INFO_SIZE:
03118c21 15305 case TYPE_INFO_BACKEND_PTRDATA:
15306 case TYPE_INFO_DESCRIPTOR_PTRDATA:
e440a328 15307 return Type::lookup_integer_type("uintptr");
15308 case TYPE_INFO_ALIGNMENT:
15309 case TYPE_INFO_FIELD_ALIGNMENT:
15310 return Type::lookup_integer_type("uint8");
15311 default:
c3e6f413 15312 go_unreachable();
e440a328 15313 }
15314}
15315
ea664253 15316// Return the backend representation for type information.
e440a328 15317
ea664253 15318Bexpression*
15319Type_info_expression::do_get_backend(Translate_context* context)
e440a328 15320{
927a01eb 15321 Gogo* gogo = context->gogo();
2a305b85 15322 bool ok = true;
3f378015 15323 int64_t val;
927a01eb 15324 switch (this->type_info_)
e440a328 15325 {
927a01eb 15326 case TYPE_INFO_SIZE:
2a305b85 15327 ok = this->type_->backend_type_size(gogo, &val);
927a01eb 15328 break;
15329 case TYPE_INFO_ALIGNMENT:
2a305b85 15330 ok = this->type_->backend_type_align(gogo, &val);
927a01eb 15331 break;
15332 case TYPE_INFO_FIELD_ALIGNMENT:
2a305b85 15333 ok = this->type_->backend_type_field_align(gogo, &val);
927a01eb 15334 break;
03118c21 15335 case TYPE_INFO_BACKEND_PTRDATA:
15336 ok = this->type_->backend_type_ptrdata(gogo, &val);
15337 break;
15338 case TYPE_INFO_DESCRIPTOR_PTRDATA:
15339 ok = this->type_->descriptor_ptrdata(gogo, &val);
15340 break;
927a01eb 15341 default:
15342 go_unreachable();
e440a328 15343 }
2a305b85 15344 if (!ok)
15345 {
15346 go_assert(saw_errors());
15347 return gogo->backend()->error_expression();
15348 }
3f378015 15349 Expression* e = Expression::make_integer_int64(val, this->type(),
15350 this->location());
15351 return e->get_backend(context);
e440a328 15352}
15353
d751bb78 15354// Dump ast representation for a type info expression.
15355
15356void
15357Type_info_expression::do_dump_expression(
15358 Ast_dump_context* ast_dump_context) const
15359{
15360 ast_dump_context->ostream() << "typeinfo(";
15361 ast_dump_context->dump_type(this->type_);
15362 ast_dump_context->ostream() << ",";
f03a9fbf 15363 ast_dump_context->ostream() <<
15364 (this->type_info_ == TYPE_INFO_ALIGNMENT ? "alignment"
d751bb78 15365 : this->type_info_ == TYPE_INFO_FIELD_ALIGNMENT ? "field alignment"
03118c21 15366 : this->type_info_ == TYPE_INFO_SIZE ? "size"
15367 : this->type_info_ == TYPE_INFO_BACKEND_PTRDATA ? "backend_ptrdata"
15368 : this->type_info_ == TYPE_INFO_DESCRIPTOR_PTRDATA ? "descriptor_ptrdata"
d751bb78 15369 : "unknown");
15370 ast_dump_context->ostream() << ")";
15371}
15372
e440a328 15373// Make a type info expression.
15374
15375Expression*
15376Expression::make_type_info(Type* type, Type_info type_info)
15377{
15378 return new Type_info_expression(type, type_info);
15379}
15380
35a54f17 15381// An expression that evaluates to some characteristic of a slice.
15382// This is used when indexing, bound-checking, or nil checking a slice.
15383
15384class Slice_info_expression : public Expression
15385{
15386 public:
15387 Slice_info_expression(Expression* slice, Slice_info slice_info,
15388 Location location)
15389 : Expression(EXPRESSION_SLICE_INFO, location),
15390 slice_(slice), slice_info_(slice_info)
15391 { }
15392
15393 protected:
15394 Type*
15395 do_type();
15396
15397 void
15398 do_determine_type(const Type_context*)
15399 { }
15400
15401 Expression*
15402 do_copy()
15403 {
15404 return new Slice_info_expression(this->slice_->copy(), this->slice_info_,
15405 this->location());
15406 }
15407
ea664253 15408 Bexpression*
15409 do_get_backend(Translate_context* context);
35a54f17 15410
15411 void
15412 do_dump_expression(Ast_dump_context*) const;
15413
15414 void
15415 do_issue_nil_check()
15416 { this->slice_->issue_nil_check(); }
15417
15418 private:
15419 // The slice for which we are getting information.
15420 Expression* slice_;
15421 // What information we want.
15422 Slice_info slice_info_;
15423};
15424
15425// Return the type of the slice info.
15426
15427Type*
15428Slice_info_expression::do_type()
15429{
15430 switch (this->slice_info_)
15431 {
15432 case SLICE_INFO_VALUE_POINTER:
15433 return Type::make_pointer_type(
15434 this->slice_->type()->array_type()->element_type());
15435 case SLICE_INFO_LENGTH:
15436 case SLICE_INFO_CAPACITY:
15437 return Type::lookup_integer_type("int");
15438 default:
15439 go_unreachable();
15440 }
15441}
15442
ea664253 15443// Return the backend information for slice information.
35a54f17 15444
ea664253 15445Bexpression*
15446Slice_info_expression::do_get_backend(Translate_context* context)
35a54f17 15447{
15448 Gogo* gogo = context->gogo();
ea664253 15449 Bexpression* bslice = this->slice_->get_backend(context);
35a54f17 15450 switch (this->slice_info_)
15451 {
15452 case SLICE_INFO_VALUE_POINTER:
15453 case SLICE_INFO_LENGTH:
15454 case SLICE_INFO_CAPACITY:
ea664253 15455 return gogo->backend()->struct_field_expression(bslice, this->slice_info_,
15456 this->location());
35a54f17 15457 break;
15458 default:
15459 go_unreachable();
15460 }
35a54f17 15461}
15462
15463// Dump ast representation for a type info expression.
15464
15465void
15466Slice_info_expression::do_dump_expression(
15467 Ast_dump_context* ast_dump_context) const
15468{
15469 ast_dump_context->ostream() << "sliceinfo(";
15470 this->slice_->dump_expression(ast_dump_context);
15471 ast_dump_context->ostream() << ",";
f03a9fbf 15472 ast_dump_context->ostream() <<
15473 (this->slice_info_ == SLICE_INFO_VALUE_POINTER ? "values"
35a54f17 15474 : this->slice_info_ == SLICE_INFO_LENGTH ? "length"
15475 : this->slice_info_ == SLICE_INFO_CAPACITY ? "capacity "
15476 : "unknown");
15477 ast_dump_context->ostream() << ")";
15478}
15479
15480// Make a slice info expression.
15481
15482Expression*
15483Expression::make_slice_info(Expression* slice, Slice_info slice_info,
15484 Location location)
15485{
15486 return new Slice_info_expression(slice, slice_info, location);
15487}
15488
d633d0fb 15489// Class Slice_value_expression.
2c809f8f 15490
15491int
15492Slice_value_expression::do_traverse(Traverse* traverse)
15493{
55e8ba6a 15494 if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT
d633d0fb 15495 || Expression::traverse(&this->valmem_, traverse) == TRAVERSE_EXIT
2c809f8f 15496 || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT
15497 || Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
15498 return TRAVERSE_EXIT;
15499 return TRAVERSE_CONTINUE;
15500}
15501
d633d0fb 15502Expression*
15503Slice_value_expression::do_copy()
15504{
15505 return new Slice_value_expression(this->type_->copy_expressions(),
15506 this->valmem_->copy(),
15507 this->len_->copy(), this->cap_->copy(),
15508 this->location());
15509}
15510
ea664253 15511Bexpression*
15512Slice_value_expression::do_get_backend(Translate_context* context)
2c809f8f 15513{
15514 std::vector<Bexpression*> vals(3);
d633d0fb 15515 vals[0] = this->valmem_->get_backend(context);
ea664253 15516 vals[1] = this->len_->get_backend(context);
15517 vals[2] = this->cap_->get_backend(context);
2c809f8f 15518
15519 Gogo* gogo = context->gogo();
15520 Btype* btype = this->type_->get_backend(gogo);
ea664253 15521 return gogo->backend()->constructor_expression(btype, vals, this->location());
2c809f8f 15522}
15523
15524void
15525Slice_value_expression::do_dump_expression(
15526 Ast_dump_context* ast_dump_context) const
15527{
15528 ast_dump_context->ostream() << "slicevalue(";
15529 ast_dump_context->ostream() << "values: ";
d633d0fb 15530 this->valmem_->dump_expression(ast_dump_context);
2c809f8f 15531 ast_dump_context->ostream() << ", length: ";
15532 this->len_->dump_expression(ast_dump_context);
15533 ast_dump_context->ostream() << ", capacity: ";
15534 this->cap_->dump_expression(ast_dump_context);
15535 ast_dump_context->ostream() << ")";
15536}
15537
15538Expression*
d633d0fb 15539Expression::make_slice_value(Type* at, Expression* valmem, Expression* len,
2c809f8f 15540 Expression* cap, Location location)
15541{
15542 go_assert(at->is_slice_type());
d633d0fb 15543 go_assert(valmem->is_nil_expression()
15544 || (at->array_type()->element_type()
15545 == valmem->type()->points_to()));
15546 return new Slice_value_expression(at, valmem, len, cap, location);
2c809f8f 15547}
2387f644 15548
15549// An expression that evaluates to some characteristic of a non-empty interface.
15550// This is used to access the method table or underlying object of an interface.
15551
15552class Interface_info_expression : public Expression
15553{
15554 public:
15555 Interface_info_expression(Expression* iface, Interface_info iface_info,
2c809f8f 15556 Location location)
2387f644 15557 : Expression(EXPRESSION_INTERFACE_INFO, location),
15558 iface_(iface), iface_info_(iface_info)
15559 { }
15560
15561 protected:
15562 Type*
15563 do_type();
15564
15565 void
15566 do_determine_type(const Type_context*)
15567 { }
15568
15569 Expression*
15570 do_copy()
15571 {
15572 return new Interface_info_expression(this->iface_->copy(),
15573 this->iface_info_, this->location());
15574 }
15575
ea664253 15576 Bexpression*
15577 do_get_backend(Translate_context* context);
2387f644 15578
15579 void
15580 do_dump_expression(Ast_dump_context*) const;
15581
15582 void
15583 do_issue_nil_check()
15584 { this->iface_->issue_nil_check(); }
15585
15586 private:
15587 // The interface for which we are getting information.
15588 Expression* iface_;
15589 // What information we want.
15590 Interface_info iface_info_;
15591};
15592
15593// Return the type of the interface info.
15594
15595Type*
15596Interface_info_expression::do_type()
15597{
15598 switch (this->iface_info_)
15599 {
15600 case INTERFACE_INFO_METHODS:
15601 {
625d3118 15602 typedef Unordered_map(Interface_type*, Type*) Hashtable;
15603 static Hashtable result_types;
15604
15605 Interface_type* itype = this->iface_->type()->interface_type();
15606
15607 Hashtable::const_iterator p = result_types.find(itype);
15608 if (p != result_types.end())
15609 return p->second;
15610
2c809f8f 15611 Type* pdt = Type::make_type_descriptor_ptr_type();
625d3118 15612 if (itype->is_empty())
15613 {
15614 result_types[itype] = pdt;
15615 return pdt;
15616 }
2c809f8f 15617
2387f644 15618 Location loc = this->location();
15619 Struct_field_list* sfl = new Struct_field_list();
2387f644 15620 sfl->push_back(
15621 Struct_field(Typed_identifier("__type_descriptor", pdt, loc)));
15622
2387f644 15623 for (Typed_identifier_list::const_iterator p = itype->methods()->begin();
15624 p != itype->methods()->end();
15625 ++p)
15626 {
15627 Function_type* ft = p->type()->function_type();
15628 go_assert(ft->receiver() == NULL);
15629
15630 const Typed_identifier_list* params = ft->parameters();
15631 Typed_identifier_list* mparams = new Typed_identifier_list();
15632 if (params != NULL)
15633 mparams->reserve(params->size() + 1);
15634 Type* vt = Type::make_pointer_type(Type::make_void_type());
15635 mparams->push_back(Typed_identifier("", vt, ft->location()));
15636 if (params != NULL)
15637 {
15638 for (Typed_identifier_list::const_iterator pp = params->begin();
15639 pp != params->end();
15640 ++pp)
15641 mparams->push_back(*pp);
15642 }
15643
15644 Typed_identifier_list* mresults = (ft->results() == NULL
15645 ? NULL
15646 : ft->results()->copy());
15647 Backend_function_type* mft =
15648 Type::make_backend_function_type(NULL, mparams, mresults,
15649 ft->location());
15650
15651 std::string fname = Gogo::unpack_hidden_name(p->name());
15652 sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc)));
15653 }
15654
6bf4793c 15655 Struct_type* st = Type::make_struct_type(sfl, loc);
15656 st->set_is_struct_incomparable();
15657 Pointer_type *pt = Type::make_pointer_type(st);
625d3118 15658 result_types[itype] = pt;
15659 return pt;
2387f644 15660 }
15661 case INTERFACE_INFO_OBJECT:
15662 return Type::make_pointer_type(Type::make_void_type());
15663 default:
15664 go_unreachable();
15665 }
15666}
15667
ea664253 15668// Return the backend representation for interface information.
2387f644 15669
ea664253 15670Bexpression*
15671Interface_info_expression::do_get_backend(Translate_context* context)
2387f644 15672{
15673 Gogo* gogo = context->gogo();
ea664253 15674 Bexpression* biface = this->iface_->get_backend(context);
2387f644 15675 switch (this->iface_info_)
15676 {
15677 case INTERFACE_INFO_METHODS:
15678 case INTERFACE_INFO_OBJECT:
ea664253 15679 return gogo->backend()->struct_field_expression(biface, this->iface_info_,
15680 this->location());
2387f644 15681 break;
15682 default:
15683 go_unreachable();
15684 }
2387f644 15685}
15686
15687// Dump ast representation for an interface info expression.
15688
15689void
15690Interface_info_expression::do_dump_expression(
15691 Ast_dump_context* ast_dump_context) const
15692{
2c809f8f 15693 bool is_empty = this->iface_->type()->interface_type()->is_empty();
2387f644 15694 ast_dump_context->ostream() << "interfaceinfo(";
15695 this->iface_->dump_expression(ast_dump_context);
15696 ast_dump_context->ostream() << ",";
15697 ast_dump_context->ostream() <<
2c809f8f 15698 (this->iface_info_ == INTERFACE_INFO_METHODS && !is_empty ? "methods"
15699 : this->iface_info_ == INTERFACE_INFO_TYPE_DESCRIPTOR ? "type_descriptor"
2387f644 15700 : this->iface_info_ == INTERFACE_INFO_OBJECT ? "object"
15701 : "unknown");
15702 ast_dump_context->ostream() << ")";
15703}
15704
15705// Make an interface info expression.
15706
15707Expression*
15708Expression::make_interface_info(Expression* iface, Interface_info iface_info,
15709 Location location)
15710{
15711 return new Interface_info_expression(iface, iface_info, location);
15712}
15713
2c809f8f 15714// An expression that represents an interface value. The first field is either
15715// a type descriptor for an empty interface or a pointer to the interface method
15716// table for a non-empty interface. The second field is always the object.
15717
15718class Interface_value_expression : public Expression
15719{
15720 public:
15721 Interface_value_expression(Type* type, Expression* first_field,
15722 Expression* obj, Location location)
15723 : Expression(EXPRESSION_INTERFACE_VALUE, location),
15724 type_(type), first_field_(first_field), obj_(obj)
15725 { }
15726
15727 protected:
15728 int
15729 do_traverse(Traverse*);
15730
15731 Type*
15732 do_type()
15733 { return this->type_; }
15734
15735 void
15736 do_determine_type(const Type_context*)
15737 { go_unreachable(); }
15738
15739 Expression*
15740 do_copy()
15741 {
de590a61 15742 return new Interface_value_expression(this->type_->copy_expressions(),
2c809f8f 15743 this->first_field_->copy(),
15744 this->obj_->copy(), this->location());
15745 }
15746
ea664253 15747 Bexpression*
15748 do_get_backend(Translate_context* context);
2c809f8f 15749
15750 void
15751 do_dump_expression(Ast_dump_context*) const;
15752
15753 private:
15754 // The type of the interface value.
15755 Type* type_;
15756 // The first field of the interface (either a type descriptor or a pointer
15757 // to the method table.
15758 Expression* first_field_;
15759 // The underlying object of the interface.
15760 Expression* obj_;
15761};
15762
15763int
15764Interface_value_expression::do_traverse(Traverse* traverse)
15765{
15766 if (Expression::traverse(&this->first_field_, traverse) == TRAVERSE_EXIT
15767 || Expression::traverse(&this->obj_, traverse) == TRAVERSE_EXIT)
15768 return TRAVERSE_EXIT;
15769 return TRAVERSE_CONTINUE;
15770}
15771
ea664253 15772Bexpression*
15773Interface_value_expression::do_get_backend(Translate_context* context)
2c809f8f 15774{
15775 std::vector<Bexpression*> vals(2);
ea664253 15776 vals[0] = this->first_field_->get_backend(context);
15777 vals[1] = this->obj_->get_backend(context);
2c809f8f 15778
15779 Gogo* gogo = context->gogo();
15780 Btype* btype = this->type_->get_backend(gogo);
ea664253 15781 return gogo->backend()->constructor_expression(btype, vals, this->location());
2c809f8f 15782}
15783
15784void
15785Interface_value_expression::do_dump_expression(
15786 Ast_dump_context* ast_dump_context) const
15787{
15788 ast_dump_context->ostream() << "interfacevalue(";
15789 ast_dump_context->ostream() <<
15790 (this->type_->interface_type()->is_empty()
15791 ? "type_descriptor: "
15792 : "methods: ");
15793 this->first_field_->dump_expression(ast_dump_context);
15794 ast_dump_context->ostream() << ", object: ";
15795 this->obj_->dump_expression(ast_dump_context);
15796 ast_dump_context->ostream() << ")";
15797}
15798
15799Expression*
15800Expression::make_interface_value(Type* type, Expression* first_value,
15801 Expression* object, Location location)
15802{
15803 return new Interface_value_expression(type, first_value, object, location);
15804}
15805
15806// An interface method table for a pair of types: an interface type and a type
15807// that implements that interface.
15808
15809class Interface_mtable_expression : public Expression
15810{
15811 public:
15812 Interface_mtable_expression(Interface_type* itype, Type* type,
15813 bool is_pointer, Location location)
15814 : Expression(EXPRESSION_INTERFACE_MTABLE, location),
15815 itype_(itype), type_(type), is_pointer_(is_pointer),
15816 method_table_type_(NULL), bvar_(NULL)
15817 { }
15818
15819 protected:
15820 int
15821 do_traverse(Traverse*);
15822
15823 Type*
15824 do_type();
15825
15826 bool
3ae06f68 15827 do_is_static_initializer() const
2c809f8f 15828 { return true; }
15829
15830 void
15831 do_determine_type(const Type_context*)
15832 { go_unreachable(); }
15833
15834 Expression*
15835 do_copy()
15836 {
de590a61 15837 Interface_type* itype = this->itype_->copy_expressions()->interface_type();
15838 return new Interface_mtable_expression(itype,
15839 this->type_->copy_expressions(),
2c809f8f 15840 this->is_pointer_, this->location());
15841 }
15842
15843 bool
15844 do_is_addressable() const
15845 { return true; }
15846
ea664253 15847 Bexpression*
15848 do_get_backend(Translate_context* context);
2c809f8f 15849
15850 void
15851 do_dump_expression(Ast_dump_context*) const;
15852
15853 private:
15854 // The interface type for which the methods are defined.
15855 Interface_type* itype_;
15856 // The type to construct the interface method table for.
15857 Type* type_;
15858 // Whether this table contains the method set for the receiver type or the
15859 // pointer receiver type.
15860 bool is_pointer_;
15861 // The type of the method table.
15862 Type* method_table_type_;
15863 // The backend variable that refers to the interface method table.
15864 Bvariable* bvar_;
15865};
15866
15867int
15868Interface_mtable_expression::do_traverse(Traverse* traverse)
15869{
15870 if (Type::traverse(this->itype_, traverse) == TRAVERSE_EXIT
15871 || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
15872 return TRAVERSE_EXIT;
15873 return TRAVERSE_CONTINUE;
15874}
15875
15876Type*
15877Interface_mtable_expression::do_type()
15878{
15879 if (this->method_table_type_ != NULL)
15880 return this->method_table_type_;
15881
15882 const Typed_identifier_list* interface_methods = this->itype_->methods();
15883 go_assert(!interface_methods->empty());
15884
15885 Struct_field_list* sfl = new Struct_field_list;
15886 Typed_identifier tid("__type_descriptor", Type::make_type_descriptor_ptr_type(),
15887 this->location());
15888 sfl->push_back(Struct_field(tid));
db122cb9 15889 Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
2c809f8f 15890 for (Typed_identifier_list::const_iterator p = interface_methods->begin();
15891 p != interface_methods->end();
15892 ++p)
db122cb9 15893 {
15894 // We want C function pointers here, not func descriptors; model
15895 // using void* pointers.
15896 Typed_identifier method(p->name(), unsafe_ptr_type, p->location());
15897 sfl->push_back(Struct_field(method));
15898 }
6bf4793c 15899 Struct_type* st = Type::make_struct_type(sfl, this->location());
15900 st->set_is_struct_incomparable();
15901 this->method_table_type_ = st;
2c809f8f 15902 return this->method_table_type_;
15903}
15904
ea664253 15905Bexpression*
15906Interface_mtable_expression::do_get_backend(Translate_context* context)
2c809f8f 15907{
15908 Gogo* gogo = context->gogo();
2c809f8f 15909 Location loc = Linemap::predeclared_location();
15910 if (this->bvar_ != NULL)
7af8e400 15911 return gogo->backend()->var_expression(this->bvar_, this->location());
2c809f8f 15912
15913 const Typed_identifier_list* interface_methods = this->itype_->methods();
15914 go_assert(!interface_methods->empty());
15915
19272321 15916 std::string mangled_name =
15917 gogo->interface_method_table_name(this->itype_, this->type_,
15918 this->is_pointer_);
2c809f8f 15919
1530c754 15920 // Set is_public if we are converting a named type to an interface
15921 // type that is defined in the same package as the named type, and
15922 // the interface has hidden methods. In that case the interface
15923 // method table will be defined by the package that defines the
15924 // types.
15925 bool is_public = false;
15926 if (this->type_->named_type() != NULL
15927 && (this->type_->named_type()->named_object()->package()
15928 == this->itype_->package()))
15929 {
15930 for (Typed_identifier_list::const_iterator p = interface_methods->begin();
15931 p != interface_methods->end();
15932 ++p)
2c809f8f 15933 {
1530c754 15934 if (Gogo::is_hidden_name(p->name()))
15935 {
15936 is_public = true;
15937 break;
15938 }
2c809f8f 15939 }
15940 }
15941
1530c754 15942 if (is_public
2c809f8f 15943 && this->type_->named_type()->named_object()->package() != NULL)
15944 {
1530c754 15945 // The interface conversion table is defined elsewhere.
2c809f8f 15946 Btype* btype = this->type()->get_backend(gogo);
438b4bec 15947 std::string asm_name(go_selectively_encode_id(mangled_name));
2c809f8f 15948 this->bvar_ =
438b4bec 15949 gogo->backend()->immutable_struct_reference(mangled_name, asm_name,
15950 btype, loc);
7af8e400 15951 return gogo->backend()->var_expression(this->bvar_, this->location());
2c809f8f 15952 }
15953
15954 // The first element is the type descriptor.
15955 Type* td_type;
15956 if (!this->is_pointer_)
15957 td_type = this->type_;
15958 else
15959 td_type = Type::make_pointer_type(this->type_);
15960
db122cb9 15961 std::vector<Backend::Btyped_identifier> bstructfields;
15962
2c809f8f 15963 // Build an interface method table for a type: a type descriptor followed by a
15964 // list of function pointers, one for each interface method. This is used for
15965 // interfaces.
15966 Expression_list* svals = new Expression_list();
db122cb9 15967 Expression* tdescriptor = Expression::make_type_descriptor(td_type, loc);
15968 svals->push_back(tdescriptor);
15969
15970 Btype* tdesc_btype = tdescriptor->type()->get_backend(gogo);
15971 Backend::Btyped_identifier btd("_type", tdesc_btype, loc);
15972 bstructfields.push_back(btd);
2c809f8f 15973
15974 Named_type* nt = this->type_->named_type();
15975 Struct_type* st = this->type_->struct_type();
15976 go_assert(nt != NULL || st != NULL);
15977
15978 for (Typed_identifier_list::const_iterator p = interface_methods->begin();
15979 p != interface_methods->end();
15980 ++p)
15981 {
15982 bool is_ambiguous;
15983 Method* m;
15984 if (nt != NULL)
15985 m = nt->method_function(p->name(), &is_ambiguous);
15986 else
15987 m = st->method_function(p->name(), &is_ambiguous);
15988 go_assert(m != NULL);
15989 Named_object* no = m->named_object();
15990
15991 go_assert(no->is_function() || no->is_function_declaration());
db122cb9 15992
15993 Btype* fcn_btype = m->type()->get_backend_fntype(gogo);
15994 Backend::Btyped_identifier bmtype(p->name(), fcn_btype, loc);
15995 bstructfields.push_back(bmtype);
15996
2c809f8f 15997 svals->push_back(Expression::make_func_code_reference(no, loc));
15998 }
15999
db122cb9 16000 Btype *btype = gogo->backend()->struct_type(bstructfields);
16001 std::vector<Bexpression*> ctor_bexprs;
16002 for (Expression_list::const_iterator pe = svals->begin();
16003 pe != svals->end();
16004 ++pe)
16005 {
16006 ctor_bexprs.push_back((*pe)->get_backend(context));
16007 }
16008 Bexpression* ctor =
16009 gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
2c809f8f 16010
438b4bec 16011 std::string asm_name(go_selectively_encode_id(mangled_name));
16012 this->bvar_ = gogo->backend()->immutable_struct(mangled_name, asm_name, false,
2c809f8f 16013 !is_public, btype, loc);
16014 gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false,
16015 !is_public, btype, loc, ctor);
7af8e400 16016 return gogo->backend()->var_expression(this->bvar_, loc);
2c809f8f 16017}
16018
16019void
16020Interface_mtable_expression::do_dump_expression(
16021 Ast_dump_context* ast_dump_context) const
16022{
16023 ast_dump_context->ostream() << "__go_"
16024 << (this->is_pointer_ ? "pimt__" : "imt_");
16025 ast_dump_context->dump_type(this->itype_);
16026 ast_dump_context->ostream() << "__";
16027 ast_dump_context->dump_type(this->type_);
16028}
16029
16030Expression*
16031Expression::make_interface_mtable_ref(Interface_type* itype, Type* type,
16032 bool is_pointer, Location location)
16033{
16034 return new Interface_mtable_expression(itype, type, is_pointer, location);
16035}
16036
e440a328 16037// An expression which evaluates to the offset of a field within a
16038// struct. This, like Type_info_expression, q.v., is only used to
16039// initialize fields of a type descriptor.
16040
16041class Struct_field_offset_expression : public Expression
16042{
16043 public:
16044 Struct_field_offset_expression(Struct_type* type, const Struct_field* field)
b13c66cd 16045 : Expression(EXPRESSION_STRUCT_FIELD_OFFSET,
16046 Linemap::predeclared_location()),
e440a328 16047 type_(type), field_(field)
16048 { }
16049
16050 protected:
f23d7786 16051 bool
3ae06f68 16052 do_is_static_initializer() const
f23d7786 16053 { return true; }
16054
e440a328 16055 Type*
16056 do_type()
16057 { return Type::lookup_integer_type("uintptr"); }
16058
16059 void
16060 do_determine_type(const Type_context*)
16061 { }
16062
16063 Expression*
16064 do_copy()
16065 { return this; }
16066
ea664253 16067 Bexpression*
16068 do_get_backend(Translate_context* context);
e440a328 16069
d751bb78 16070 void
16071 do_dump_expression(Ast_dump_context*) const;
f03a9fbf 16072
e440a328 16073 private:
16074 // The type of the struct.
16075 Struct_type* type_;
16076 // The field.
16077 const Struct_field* field_;
16078};
16079
ea664253 16080// Return the backend representation for a struct field offset.
e440a328 16081
ea664253 16082Bexpression*
16083Struct_field_offset_expression::do_get_backend(Translate_context* context)
e440a328 16084{
e440a328 16085 const Struct_field_list* fields = this->type_->fields();
e440a328 16086 Struct_field_list::const_iterator p;
2c8bda43 16087 unsigned i = 0;
e440a328 16088 for (p = fields->begin();
16089 p != fields->end();
2c8bda43 16090 ++p, ++i)
16091 if (&*p == this->field_)
16092 break;
c484d925 16093 go_assert(&*p == this->field_);
e440a328 16094
2c8bda43 16095 Gogo* gogo = context->gogo();
16096 Btype* btype = this->type_->get_backend(gogo);
16097
3f378015 16098 int64_t offset = gogo->backend()->type_field_offset(btype, i);
2c8bda43 16099 Type* uptr_type = Type::lookup_integer_type("uintptr");
e67508fa 16100 Expression* ret =
3f378015 16101 Expression::make_integer_int64(offset, uptr_type,
16102 Linemap::predeclared_location());
ea664253 16103 return ret->get_backend(context);
e440a328 16104}
16105
d751bb78 16106// Dump ast representation for a struct field offset expression.
16107
16108void
16109Struct_field_offset_expression::do_dump_expression(
16110 Ast_dump_context* ast_dump_context) const
16111{
16112 ast_dump_context->ostream() << "unsafe.Offsetof(";
2d29d278 16113 ast_dump_context->dump_type(this->type_);
16114 ast_dump_context->ostream() << '.';
16115 ast_dump_context->ostream() <<
16116 Gogo::message_name(this->field_->field_name());
d751bb78 16117 ast_dump_context->ostream() << ")";
16118}
16119
e440a328 16120// Make an expression for a struct field offset.
16121
16122Expression*
16123Expression::make_struct_field_offset(Struct_type* type,
16124 const Struct_field* field)
16125{
16126 return new Struct_field_offset_expression(type, field);
16127}
16128
16129// An expression which evaluates to the address of an unnamed label.
16130
16131class Label_addr_expression : public Expression
16132{
16133 public:
b13c66cd 16134 Label_addr_expression(Label* label, Location location)
e440a328 16135 : Expression(EXPRESSION_LABEL_ADDR, location),
16136 label_(label)
16137 { }
16138
16139 protected:
16140 Type*
16141 do_type()
16142 { return Type::make_pointer_type(Type::make_void_type()); }
16143
16144 void
16145 do_determine_type(const Type_context*)
16146 { }
16147
16148 Expression*
16149 do_copy()
16150 { return new Label_addr_expression(this->label_, this->location()); }
16151
ea664253 16152 Bexpression*
16153 do_get_backend(Translate_context* context)
16154 { return this->label_->get_addr(context, this->location()); }
e440a328 16155
d751bb78 16156 void
16157 do_dump_expression(Ast_dump_context* ast_dump_context) const
16158 { ast_dump_context->ostream() << this->label_->name(); }
f03a9fbf 16159
e440a328 16160 private:
16161 // The label whose address we are taking.
16162 Label* label_;
16163};
16164
16165// Make an expression for the address of an unnamed label.
16166
16167Expression*
b13c66cd 16168Expression::make_label_addr(Label* label, Location location)
e440a328 16169{
16170 return new Label_addr_expression(label, location);
16171}
16172
da244e59 16173// Class Conditional_expression.
283a177b 16174
2c809f8f 16175// Traversal.
16176
16177int
16178Conditional_expression::do_traverse(Traverse* traverse)
16179{
16180 if (Expression::traverse(&this->cond_, traverse) == TRAVERSE_EXIT
16181 || Expression::traverse(&this->then_, traverse) == TRAVERSE_EXIT
16182 || Expression::traverse(&this->else_, traverse) == TRAVERSE_EXIT)
16183 return TRAVERSE_EXIT;
16184 return TRAVERSE_CONTINUE;
16185}
16186
283a177b 16187// Return the type of the conditional expression.
16188
16189Type*
16190Conditional_expression::do_type()
16191{
16192 Type* result_type = Type::make_void_type();
3a522dcc 16193 if (Type::are_identical(this->then_->type(), this->else_->type(),
16194 Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
2c809f8f 16195 NULL))
283a177b 16196 result_type = this->then_->type();
16197 else if (this->then_->is_nil_expression()
16198 || this->else_->is_nil_expression())
16199 result_type = (!this->then_->is_nil_expression()
16200 ? this->then_->type()
16201 : this->else_->type());
16202 return result_type;
16203}
16204
2c809f8f 16205// Determine type for a conditional expression.
16206
16207void
16208Conditional_expression::do_determine_type(const Type_context* context)
16209{
16210 this->cond_->determine_type_no_context();
16211 this->then_->determine_type(context);
16212 this->else_->determine_type(context);
16213}
16214
283a177b 16215// Get the backend representation of a conditional expression.
16216
ea664253 16217Bexpression*
16218Conditional_expression::do_get_backend(Translate_context* context)
283a177b 16219{
16220 Gogo* gogo = context->gogo();
16221 Btype* result_btype = this->type()->get_backend(gogo);
ea664253 16222 Bexpression* cond = this->cond_->get_backend(context);
16223 Bexpression* then = this->then_->get_backend(context);
16224 Bexpression* belse = this->else_->get_backend(context);
93715b75 16225 Bfunction* bfn = context->function()->func_value()->get_decl();
16226 return gogo->backend()->conditional_expression(bfn, result_btype, cond, then,
ea664253 16227 belse, this->location());
283a177b 16228}
16229
16230// Dump ast representation of a conditional expression.
16231
16232void
16233Conditional_expression::do_dump_expression(
16234 Ast_dump_context* ast_dump_context) const
16235{
16236 ast_dump_context->ostream() << "(";
16237 ast_dump_context->dump_expression(this->cond_);
16238 ast_dump_context->ostream() << " ? ";
16239 ast_dump_context->dump_expression(this->then_);
16240 ast_dump_context->ostream() << " : ";
16241 ast_dump_context->dump_expression(this->else_);
16242 ast_dump_context->ostream() << ") ";
16243}
16244
16245// Make a conditional expression.
16246
16247Expression*
16248Expression::make_conditional(Expression* cond, Expression* then,
16249 Expression* else_expr, Location location)
16250{
16251 return new Conditional_expression(cond, then, else_expr, location);
16252}
16253
da244e59 16254// Class Compound_expression.
2c809f8f 16255
16256// Traversal.
16257
16258int
16259Compound_expression::do_traverse(Traverse* traverse)
16260{
16261 if (Expression::traverse(&this->init_, traverse) == TRAVERSE_EXIT
16262 || Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT)
16263 return TRAVERSE_EXIT;
16264 return TRAVERSE_CONTINUE;
16265}
16266
16267// Return the type of the compound expression.
16268
16269Type*
16270Compound_expression::do_type()
16271{
16272 return this->expr_->type();
16273}
16274
16275// Determine type for a compound expression.
16276
16277void
16278Compound_expression::do_determine_type(const Type_context* context)
16279{
16280 this->init_->determine_type_no_context();
16281 this->expr_->determine_type(context);
16282}
16283
16284// Get the backend representation of a compound expression.
16285
ea664253 16286Bexpression*
16287Compound_expression::do_get_backend(Translate_context* context)
2c809f8f 16288{
16289 Gogo* gogo = context->gogo();
ea664253 16290 Bexpression* binit = this->init_->get_backend(context);
0ab48656 16291 Bfunction* bfunction = context->function()->func_value()->get_decl();
16292 Bstatement* init_stmt = gogo->backend()->expression_statement(bfunction,
16293 binit);
ea664253 16294 Bexpression* bexpr = this->expr_->get_backend(context);
16295 return gogo->backend()->compound_expression(init_stmt, bexpr,
16296 this->location());
2c809f8f 16297}
16298
16299// Dump ast representation of a conditional expression.
16300
16301void
16302Compound_expression::do_dump_expression(
16303 Ast_dump_context* ast_dump_context) const
16304{
16305 ast_dump_context->ostream() << "(";
16306 ast_dump_context->dump_expression(this->init_);
16307 ast_dump_context->ostream() << ",";
16308 ast_dump_context->dump_expression(this->expr_);
16309 ast_dump_context->ostream() << ") ";
16310}
16311
16312// Make a compound expression.
16313
16314Expression*
16315Expression::make_compound(Expression* init, Expression* expr, Location location)
16316{
16317 return new Compound_expression(init, expr, location);
16318}
16319
1b4fb1e0 16320// Class Backend_expression.
16321
16322int
16323Backend_expression::do_traverse(Traverse*)
16324{
16325 return TRAVERSE_CONTINUE;
16326}
16327
de590a61 16328Expression*
16329Backend_expression::do_copy()
16330{
16331 return new Backend_expression(this->bexpr_, this->type_->copy_expressions(),
16332 this->location());
16333}
16334
1b4fb1e0 16335void
16336Backend_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
16337{
16338 ast_dump_context->ostream() << "backend_expression<";
16339 ast_dump_context->dump_type(this->type_);
16340 ast_dump_context->ostream() << ">";
16341}
16342
16343Expression*
16344Expression::make_backend(Bexpression* bexpr, Type* type, Location location)
16345{
16346 return new Backend_expression(bexpr, type, location);
16347}
16348
e440a328 16349// Import an expression. This comes at the end in order to see the
16350// various class definitions.
16351
16352Expression*
bc8e2ef4 16353Expression::import_expression(Import_expression* imp, Location loc)
e440a328 16354{
16355 int c = imp->peek_char();
5f6f5357 16356 if (c == '+' || c == '-' || c == '!' || c == '^' || c == '&' || c == '*')
9b92780c 16357 return Unary_expression::do_import(imp, loc);
e440a328 16358 else if (c == '(')
9b92780c 16359 return Binary_expression::do_import(imp, loc);
204d4af4 16360 else if (imp->match_c_string("$true")
16361 || imp->match_c_string("$false")
16362 || (imp->version() < EXPORT_FORMAT_V3
16363 && (imp->match_c_string("true")
16364 || imp->match_c_string("false"))))
9b92780c 16365 return Boolean_expression::do_import(imp, loc);
e440a328 16366 else if (c == '"')
9b92780c 16367 return String_expression::do_import(imp, loc);
e440a328 16368 else if (c == '-' || (c >= '0' && c <= '9'))
16369 {
16370 // This handles integers, floats and complex constants.
9b92780c 16371 return Integer_expression::do_import(imp, loc);
e440a328 16372 }
204d4af4 16373 else if (imp->match_c_string("$nil")
16374 || (imp->version() < EXPORT_FORMAT_V3
16375 && imp->match_c_string("nil")))
9b92780c 16376 return Nil_expression::do_import(imp, loc);
204d4af4 16377 else if (imp->match_c_string("$convert")
16378 || (imp->version() < EXPORT_FORMAT_V3
16379 && imp->match_c_string("convert")))
9b92780c 16380 return Type_conversion_expression::do_import(imp, loc);
5f6f5357 16381
16382 Import_function_body* ifb = imp->ifb();
16383 if (ifb == NULL)
e440a328 16384 {
631d5788 16385 go_error_at(imp->location(), "import error: expected expression");
9b92780c 16386 return Expression::make_error(loc);
e440a328 16387 }
5f6f5357 16388 if (ifb->saw_error())
16389 return Expression::make_error(loc);
16390 std::string id = ifb->read_identifier();
16391 if (id.empty())
16392 {
16393 if (!ifb->saw_error())
16394 go_error_at(imp->location(),
16395 "import error: expected identifier at %lu",
16396 static_cast<unsigned long>(ifb->off()));
16397 ifb->set_saw_error();
16398 return Expression::make_error(loc);
16399 }
16400 Named_object* var = ifb->block()->bindings()->lookup(id);
16401 if (var == NULL)
16402 {
16403 if (!ifb->saw_error())
16404 go_error_at(imp->location(), "import error: lookup of %qs failed",
16405 id.c_str());
16406 ifb->set_saw_error();
16407 return Expression::make_error(loc);
16408 }
16409 return Expression::make_var_reference(var, loc);
e440a328 16410}
16411
16412// Class Expression_list.
16413
16414// Traverse the list.
16415
16416int
16417Expression_list::traverse(Traverse* traverse)
16418{
16419 for (Expression_list::iterator p = this->begin();
16420 p != this->end();
16421 ++p)
16422 {
16423 if (*p != NULL)
16424 {
16425 if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
16426 return TRAVERSE_EXIT;
16427 }
16428 }
16429 return TRAVERSE_CONTINUE;
16430}
16431
16432// Copy the list.
16433
16434Expression_list*
16435Expression_list::copy()
16436{
16437 Expression_list* ret = new Expression_list();
16438 for (Expression_list::iterator p = this->begin();
16439 p != this->end();
16440 ++p)
16441 {
16442 if (*p == NULL)
16443 ret->push_back(NULL);
16444 else
16445 ret->push_back((*p)->copy());
16446 }
16447 return ret;
16448}
16449
16450// Return whether an expression list has an error expression.
16451
16452bool
16453Expression_list::contains_error() const
16454{
16455 for (Expression_list::const_iterator p = this->begin();
16456 p != this->end();
16457 ++p)
16458 if (*p != NULL && (*p)->is_error_expression())
16459 return true;
16460 return false;
16461}
0c77715b 16462
16463// Class Numeric_constant.
16464
16465// Destructor.
16466
16467Numeric_constant::~Numeric_constant()
16468{
16469 this->clear();
16470}
16471
16472// Copy constructor.
16473
16474Numeric_constant::Numeric_constant(const Numeric_constant& a)
16475 : classification_(a.classification_), type_(a.type_)
16476{
16477 switch (a.classification_)
16478 {
16479 case NC_INVALID:
16480 break;
16481 case NC_INT:
16482 case NC_RUNE:
16483 mpz_init_set(this->u_.int_val, a.u_.int_val);
16484 break;
16485 case NC_FLOAT:
16486 mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
16487 break;
16488 case NC_COMPLEX:
fcbea5e4 16489 mpc_init2(this->u_.complex_val, mpc_precision);
16490 mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
0c77715b 16491 break;
16492 default:
16493 go_unreachable();
16494 }
16495}
16496
16497// Assignment operator.
16498
16499Numeric_constant&
16500Numeric_constant::operator=(const Numeric_constant& a)
16501{
16502 this->clear();
16503 this->classification_ = a.classification_;
16504 this->type_ = a.type_;
16505 switch (a.classification_)
16506 {
16507 case NC_INVALID:
16508 break;
16509 case NC_INT:
16510 case NC_RUNE:
16511 mpz_init_set(this->u_.int_val, a.u_.int_val);
16512 break;
16513 case NC_FLOAT:
16514 mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
16515 break;
16516 case NC_COMPLEX:
fcbea5e4 16517 mpc_init2(this->u_.complex_val, mpc_precision);
16518 mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
0c77715b 16519 break;
16520 default:
16521 go_unreachable();
16522 }
16523 return *this;
16524}
16525
0ab32342 16526// Check equality with another numeric constant.
16527
16528bool
16529Numeric_constant::equals(const Numeric_constant& a) const
16530{
16531 if (this->classification_ != a.classification_)
16532 return false;
16533
16534 if (this->type_ != NULL && a.type_ != NULL
16535 && !Type::are_identical(this->type_, a.type_,
16536 Type::COMPARE_ALIASES, NULL))
16537 return false;
16538
16539 switch (a.classification_)
16540 {
16541 case NC_INVALID:
16542 break;
16543 case NC_INT:
16544 case NC_RUNE:
16545 return mpz_cmp(this->u_.int_val, a.u_.int_val) == 0;
16546 case NC_FLOAT:
16547 return mpfr_cmp(this->u_.float_val, a.u_.float_val) == 0;
16548 case NC_COMPLEX:
16549 return mpc_cmp(this->u_.complex_val, a.u_.complex_val) == 0;
16550 default:
16551 go_unreachable();
16552 }
16553 return false;
16554}
16555
0c77715b 16556// Clear the contents.
16557
16558void
16559Numeric_constant::clear()
16560{
16561 switch (this->classification_)
16562 {
16563 case NC_INVALID:
16564 break;
16565 case NC_INT:
16566 case NC_RUNE:
16567 mpz_clear(this->u_.int_val);
16568 break;
16569 case NC_FLOAT:
16570 mpfr_clear(this->u_.float_val);
16571 break;
16572 case NC_COMPLEX:
fcbea5e4 16573 mpc_clear(this->u_.complex_val);
0c77715b 16574 break;
16575 default:
16576 go_unreachable();
16577 }
16578 this->classification_ = NC_INVALID;
16579}
16580
16581// Set to an unsigned long value.
16582
16583void
16584Numeric_constant::set_unsigned_long(Type* type, unsigned long val)
16585{
16586 this->clear();
16587 this->classification_ = NC_INT;
16588 this->type_ = type;
16589 mpz_init_set_ui(this->u_.int_val, val);
16590}
16591
16592// Set to an integer value.
16593
16594void
16595Numeric_constant::set_int(Type* type, const mpz_t val)
16596{
16597 this->clear();
16598 this->classification_ = NC_INT;
16599 this->type_ = type;
16600 mpz_init_set(this->u_.int_val, val);
16601}
16602
16603// Set to a rune value.
16604
16605void
16606Numeric_constant::set_rune(Type* type, const mpz_t val)
16607{
16608 this->clear();
16609 this->classification_ = NC_RUNE;
16610 this->type_ = type;
16611 mpz_init_set(this->u_.int_val, val);
16612}
16613
16614// Set to a floating point value.
16615
16616void
16617Numeric_constant::set_float(Type* type, const mpfr_t val)
16618{
16619 this->clear();
16620 this->classification_ = NC_FLOAT;
16621 this->type_ = type;
d1d4ace3 16622
833b523c 16623 // Numeric constants do not have negative zero values, so remove
16624 // them here. They also don't have infinity or NaN values, but we
16625 // should never see them here.
d1d4ace3 16626 int bits = 0;
16627 if (type != NULL
16628 && type->float_type() != NULL
16629 && !type->float_type()->is_abstract())
16630 bits = type->float_type()->bits();
16631 if (Numeric_constant::is_float_neg_zero(val, bits))
833b523c 16632 mpfr_init_set_ui(this->u_.float_val, 0, GMP_RNDN);
16633 else
16634 mpfr_init_set(this->u_.float_val, val, GMP_RNDN);
0c77715b 16635}
16636
16637// Set to a complex value.
16638
16639void
fcbea5e4 16640Numeric_constant::set_complex(Type* type, const mpc_t val)
0c77715b 16641{
16642 this->clear();
16643 this->classification_ = NC_COMPLEX;
16644 this->type_ = type;
d1d4ace3 16645
16646 // Avoid negative zero as in set_float.
16647 int bits = 0;
16648 if (type != NULL
16649 && type->complex_type() != NULL
16650 && !type->complex_type()->is_abstract())
16651 bits = type->complex_type()->bits() / 2;
16652
16653 mpfr_t real;
16654 mpfr_init_set(real, mpc_realref(val), GMP_RNDN);
16655 if (Numeric_constant::is_float_neg_zero(real, bits))
16656 mpfr_set_ui(real, 0, GMP_RNDN);
16657
16658 mpfr_t imag;
16659 mpfr_init_set(imag, mpc_imagref(val), GMP_RNDN);
16660 if (Numeric_constant::is_float_neg_zero(imag, bits))
16661 mpfr_set_ui(imag, 0, GMP_RNDN);
16662
fcbea5e4 16663 mpc_init2(this->u_.complex_val, mpc_precision);
d1d4ace3 16664 mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN);
16665
16666 mpfr_clear(real);
16667 mpfr_clear(imag);
16668}
16669
16670// Return whether VAL, at a precision of BITS, is a negative zero.
16671// BITS may be zero in which case it is ignored.
16672
16673bool
16674Numeric_constant::is_float_neg_zero(const mpfr_t val, int bits)
16675{
16676 if (!mpfr_signbit(val))
16677 return false;
16678 if (mpfr_zero_p(val))
16679 return true;
16680 mp_exp_t min_exp;
16681 switch (bits)
16682 {
16683 case 0:
16684 return false;
16685 case 32:
16686 // In a denormalized float32 the exponent is -126, and there are
16687 // 24 bits of which at least the last must be 1, so the smallest
16688 // representable non-zero exponent is -126 - (24 - 1) == -149.
16689 min_exp = -149;
16690 break;
16691 case 64:
16692 // Minimum exponent is -1022, there are 53 bits.
16693 min_exp = -1074;
16694 break;
16695 default:
16696 go_unreachable();
16697 }
16698 return mpfr_get_exp(val) < min_exp;
0c77715b 16699}
16700
16701// Get an int value.
16702
16703void
16704Numeric_constant::get_int(mpz_t* val) const
16705{
16706 go_assert(this->is_int());
16707 mpz_init_set(*val, this->u_.int_val);
16708}
16709
16710// Get a rune value.
16711
16712void
16713Numeric_constant::get_rune(mpz_t* val) const
16714{
16715 go_assert(this->is_rune());
16716 mpz_init_set(*val, this->u_.int_val);
16717}
16718
16719// Get a floating point value.
16720
16721void
16722Numeric_constant::get_float(mpfr_t* val) const
16723{
16724 go_assert(this->is_float());
16725 mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
16726}
16727
16728// Get a complex value.
16729
16730void
fcbea5e4 16731Numeric_constant::get_complex(mpc_t* val) const
0c77715b 16732{
16733 go_assert(this->is_complex());
fcbea5e4 16734 mpc_init2(*val, mpc_precision);
16735 mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
0c77715b 16736}
16737
16738// Express value as unsigned long if possible.
16739
16740Numeric_constant::To_unsigned_long
16741Numeric_constant::to_unsigned_long(unsigned long* val) const
16742{
16743 switch (this->classification_)
16744 {
16745 case NC_INT:
16746 case NC_RUNE:
16747 return this->mpz_to_unsigned_long(this->u_.int_val, val);
16748 case NC_FLOAT:
16749 return this->mpfr_to_unsigned_long(this->u_.float_val, val);
16750 case NC_COMPLEX:
fcbea5e4 16751 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 16752 return NC_UL_NOTINT;
fcbea5e4 16753 return this->mpfr_to_unsigned_long(mpc_realref(this->u_.complex_val),
16754 val);
0c77715b 16755 default:
16756 go_unreachable();
16757 }
16758}
16759
16760// Express integer value as unsigned long if possible.
16761
16762Numeric_constant::To_unsigned_long
16763Numeric_constant::mpz_to_unsigned_long(const mpz_t ival,
16764 unsigned long *val) const
16765{
16766 if (mpz_sgn(ival) < 0)
16767 return NC_UL_NEGATIVE;
16768 unsigned long ui = mpz_get_ui(ival);
16769 if (mpz_cmp_ui(ival, ui) != 0)
16770 return NC_UL_BIG;
16771 *val = ui;
16772 return NC_UL_VALID;
16773}
16774
16775// Express floating point value as unsigned long if possible.
16776
16777Numeric_constant::To_unsigned_long
16778Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval,
16779 unsigned long *val) const
16780{
16781 if (!mpfr_integer_p(fval))
16782 return NC_UL_NOTINT;
16783 mpz_t ival;
16784 mpz_init(ival);
16785 mpfr_get_z(ival, fval, GMP_RNDN);
16786 To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val);
16787 mpz_clear(ival);
16788 return ret;
16789}
16790
03118c21 16791// Express value as memory size if possible.
16792
16793bool
16794Numeric_constant::to_memory_size(int64_t* val) const
16795{
16796 switch (this->classification_)
16797 {
16798 case NC_INT:
16799 case NC_RUNE:
16800 return this->mpz_to_memory_size(this->u_.int_val, val);
16801 case NC_FLOAT:
16802 return this->mpfr_to_memory_size(this->u_.float_val, val);
16803 case NC_COMPLEX:
16804 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
16805 return false;
16806 return this->mpfr_to_memory_size(mpc_realref(this->u_.complex_val), val);
16807 default:
16808 go_unreachable();
16809 }
16810}
16811
16812// Express integer as memory size if possible.
16813
16814bool
16815Numeric_constant::mpz_to_memory_size(const mpz_t ival, int64_t* val) const
16816{
16817 if (mpz_sgn(ival) < 0)
16818 return false;
16819 if (mpz_fits_slong_p(ival))
16820 {
16821 *val = static_cast<int64_t>(mpz_get_si(ival));
16822 return true;
16823 }
16824
16825 // Test >= 64, not > 64, because an int64_t can hold 63 bits of a
16826 // positive value.
16827 if (mpz_sizeinbase(ival, 2) >= 64)
16828 return false;
16829
16830 mpz_t q, r;
16831 mpz_init(q);
16832 mpz_init(r);
16833 mpz_tdiv_q_2exp(q, ival, 32);
16834 mpz_tdiv_r_2exp(r, ival, 32);
16835 go_assert(mpz_fits_ulong_p(q) && mpz_fits_ulong_p(r));
16836 *val = ((static_cast<int64_t>(mpz_get_ui(q)) << 32)
16837 + static_cast<int64_t>(mpz_get_ui(r)));
16838 mpz_clear(r);
16839 mpz_clear(q);
16840 return true;
16841}
16842
16843// Express floating point value as memory size if possible.
16844
16845bool
16846Numeric_constant::mpfr_to_memory_size(const mpfr_t fval, int64_t* val) const
16847{
16848 if (!mpfr_integer_p(fval))
16849 return false;
16850 mpz_t ival;
16851 mpz_init(ival);
16852 mpfr_get_z(ival, fval, GMP_RNDN);
16853 bool ret = this->mpz_to_memory_size(ival, val);
16854 mpz_clear(ival);
16855 return ret;
16856}
16857
0c77715b 16858// Convert value to integer if possible.
16859
16860bool
16861Numeric_constant::to_int(mpz_t* val) const
16862{
16863 switch (this->classification_)
16864 {
16865 case NC_INT:
16866 case NC_RUNE:
16867 mpz_init_set(*val, this->u_.int_val);
16868 return true;
16869 case NC_FLOAT:
16870 if (!mpfr_integer_p(this->u_.float_val))
16871 return false;
16872 mpz_init(*val);
16873 mpfr_get_z(*val, this->u_.float_val, GMP_RNDN);
16874 return true;
16875 case NC_COMPLEX:
fcbea5e4 16876 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val))
16877 || !mpfr_integer_p(mpc_realref(this->u_.complex_val)))
0c77715b 16878 return false;
16879 mpz_init(*val);
fcbea5e4 16880 mpfr_get_z(*val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 16881 return true;
16882 default:
16883 go_unreachable();
16884 }
16885}
16886
16887// Convert value to floating point if possible.
16888
16889bool
16890Numeric_constant::to_float(mpfr_t* val) const
16891{
16892 switch (this->classification_)
16893 {
16894 case NC_INT:
16895 case NC_RUNE:
16896 mpfr_init_set_z(*val, this->u_.int_val, GMP_RNDN);
16897 return true;
16898 case NC_FLOAT:
16899 mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
16900 return true;
16901 case NC_COMPLEX:
fcbea5e4 16902 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 16903 return false;
fcbea5e4 16904 mpfr_init_set(*val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 16905 return true;
16906 default:
16907 go_unreachable();
16908 }
16909}
16910
16911// Convert value to complex.
16912
16913bool
fcbea5e4 16914Numeric_constant::to_complex(mpc_t* val) const
0c77715b 16915{
fcbea5e4 16916 mpc_init2(*val, mpc_precision);
0c77715b 16917 switch (this->classification_)
16918 {
16919 case NC_INT:
16920 case NC_RUNE:
fcbea5e4 16921 mpc_set_z(*val, this->u_.int_val, MPC_RNDNN);
0c77715b 16922 return true;
16923 case NC_FLOAT:
fcbea5e4 16924 mpc_set_fr(*val, this->u_.float_val, MPC_RNDNN);
0c77715b 16925 return true;
16926 case NC_COMPLEX:
fcbea5e4 16927 mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
0c77715b 16928 return true;
16929 default:
16930 go_unreachable();
16931 }
16932}
16933
16934// Get the type.
16935
16936Type*
16937Numeric_constant::type() const
16938{
16939 if (this->type_ != NULL)
16940 return this->type_;
16941 switch (this->classification_)
16942 {
16943 case NC_INT:
16944 return Type::make_abstract_integer_type();
16945 case NC_RUNE:
16946 return Type::make_abstract_character_type();
16947 case NC_FLOAT:
16948 return Type::make_abstract_float_type();
16949 case NC_COMPLEX:
16950 return Type::make_abstract_complex_type();
16951 default:
16952 go_unreachable();
16953 }
16954}
16955
16956// If the constant can be expressed in TYPE, then set the type of the
16957// constant to TYPE and return true. Otherwise return false, and, if
16958// ISSUE_ERROR is true, report an appropriate error message.
16959
16960bool
16961Numeric_constant::set_type(Type* type, bool issue_error, Location loc)
16962{
16963 bool ret;
f11c2155 16964 if (type == NULL || type->is_error())
0c77715b 16965 ret = true;
16966 else if (type->integer_type() != NULL)
16967 ret = this->check_int_type(type->integer_type(), issue_error, loc);
16968 else if (type->float_type() != NULL)
16969 ret = this->check_float_type(type->float_type(), issue_error, loc);
16970 else if (type->complex_type() != NULL)
16971 ret = this->check_complex_type(type->complex_type(), issue_error, loc);
16972 else
5706ab68 16973 {
16974 ret = false;
16975 if (issue_error)
16976 go_assert(saw_errors());
16977 }
0c77715b 16978 if (ret)
16979 this->type_ = type;
16980 return ret;
16981}
16982
16983// Check whether the constant can be expressed in an integer type.
16984
16985bool
16986Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
71a45216 16987 Location location)
0c77715b 16988{
16989 mpz_t val;
16990 switch (this->classification_)
16991 {
16992 case NC_INT:
16993 case NC_RUNE:
16994 mpz_init_set(val, this->u_.int_val);
16995 break;
16996
16997 case NC_FLOAT:
16998 if (!mpfr_integer_p(this->u_.float_val))
16999 {
17000 if (issue_error)
71a45216 17001 {
631d5788 17002 go_error_at(location,
17003 "floating point constant truncated to integer");
71a45216 17004 this->set_invalid();
17005 }
0c77715b 17006 return false;
17007 }
17008 mpz_init(val);
17009 mpfr_get_z(val, this->u_.float_val, GMP_RNDN);
17010 break;
17011
17012 case NC_COMPLEX:
fcbea5e4 17013 if (!mpfr_integer_p(mpc_realref(this->u_.complex_val))
17014 || !mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 17015 {
17016 if (issue_error)
71a45216 17017 {
631d5788 17018 go_error_at(location, "complex constant truncated to integer");
71a45216 17019 this->set_invalid();
17020 }
0c77715b 17021 return false;
17022 }
17023 mpz_init(val);
fcbea5e4 17024 mpfr_get_z(val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 17025 break;
17026
17027 default:
17028 go_unreachable();
17029 }
17030
17031 bool ret;
17032 if (type->is_abstract())
17033 ret = true;
17034 else
17035 {
17036 int bits = mpz_sizeinbase(val, 2);
17037 if (type->is_unsigned())
17038 {
17039 // For an unsigned type we can only accept a nonnegative
17040 // number, and we must be able to represents at least BITS.
17041 ret = mpz_sgn(val) >= 0 && bits <= type->bits();
17042 }
17043 else
17044 {
17045 // For a signed type we need an extra bit to indicate the
17046 // sign. We have to handle the most negative integer
17047 // specially.
17048 ret = (bits + 1 <= type->bits()
17049 || (bits <= type->bits()
17050 && mpz_sgn(val) < 0
17051 && (mpz_scan1(val, 0)
17052 == static_cast<unsigned long>(type->bits() - 1))
17053 && mpz_scan0(val, type->bits()) == ULONG_MAX));
17054 }
17055 }
17056
17057 if (!ret && issue_error)
71a45216 17058 {
631d5788 17059 go_error_at(location, "integer constant overflow");
71a45216 17060 this->set_invalid();
17061 }
0c77715b 17062
17063 return ret;
17064}
17065
17066// Check whether the constant can be expressed in a floating point
17067// type.
17068
17069bool
17070Numeric_constant::check_float_type(Float_type* type, bool issue_error,
d0bcce51 17071 Location location)
0c77715b 17072{
17073 mpfr_t val;
17074 switch (this->classification_)
17075 {
17076 case NC_INT:
17077 case NC_RUNE:
17078 mpfr_init_set_z(val, this->u_.int_val, GMP_RNDN);
17079 break;
17080
17081 case NC_FLOAT:
17082 mpfr_init_set(val, this->u_.float_val, GMP_RNDN);
17083 break;
17084
17085 case NC_COMPLEX:
fcbea5e4 17086 if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
0c77715b 17087 {
17088 if (issue_error)
71a45216 17089 {
17090 this->set_invalid();
631d5788 17091 go_error_at(location, "complex constant truncated to float");
71a45216 17092 }
0c77715b 17093 return false;
17094 }
fcbea5e4 17095 mpfr_init_set(val, mpc_realref(this->u_.complex_val), GMP_RNDN);
0c77715b 17096 break;
17097
17098 default:
17099 go_unreachable();
17100 }
17101
17102 bool ret;
17103 if (type->is_abstract())
17104 ret = true;
17105 else if (mpfr_nan_p(val) || mpfr_inf_p(val) || mpfr_zero_p(val))
17106 {
17107 // A NaN or Infinity always fits in the range of the type.
17108 ret = true;
17109 }
17110 else
17111 {
17112 mp_exp_t exp = mpfr_get_exp(val);
17113 mp_exp_t max_exp;
17114 switch (type->bits())
17115 {
17116 case 32:
17117 max_exp = 128;
17118 break;
17119 case 64:
17120 max_exp = 1024;
17121 break;
17122 default:
17123 go_unreachable();
17124 }
17125
17126 ret = exp <= max_exp;
d0bcce51 17127
17128 if (ret)
17129 {
17130 // Round the constant to the desired type.
17131 mpfr_t t;
17132 mpfr_init(t);
17133 switch (type->bits())
17134 {
17135 case 32:
17136 mpfr_set_prec(t, 24);
17137 break;
17138 case 64:
17139 mpfr_set_prec(t, 53);
17140 break;
17141 default:
17142 go_unreachable();
17143 }
17144 mpfr_set(t, val, GMP_RNDN);
17145 mpfr_set(val, t, GMP_RNDN);
17146 mpfr_clear(t);
17147
17148 this->set_float(type, val);
17149 }
0c77715b 17150 }
17151
17152 mpfr_clear(val);
17153
17154 if (!ret && issue_error)
71a45216 17155 {
631d5788 17156 go_error_at(location, "floating point constant overflow");
71a45216 17157 this->set_invalid();
17158 }
0c77715b 17159
17160 return ret;
f03a9fbf 17161}
0c77715b 17162
17163// Check whether the constant can be expressed in a complex type.
17164
17165bool
17166Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
d0bcce51 17167 Location location)
0c77715b 17168{
17169 if (type->is_abstract())
17170 return true;
17171
17172 mp_exp_t max_exp;
17173 switch (type->bits())
17174 {
17175 case 64:
17176 max_exp = 128;
17177 break;
17178 case 128:
17179 max_exp = 1024;
17180 break;
17181 default:
17182 go_unreachable();
17183 }
17184
fcbea5e4 17185 mpc_t val;
17186 mpc_init2(val, mpc_precision);
0c77715b 17187 switch (this->classification_)
17188 {
17189 case NC_INT:
17190 case NC_RUNE:
fcbea5e4 17191 mpc_set_z(val, this->u_.int_val, MPC_RNDNN);
0c77715b 17192 break;
17193
17194 case NC_FLOAT:
fcbea5e4 17195 mpc_set_fr(val, this->u_.float_val, MPC_RNDNN);
0c77715b 17196 break;
17197
17198 case NC_COMPLEX:
fcbea5e4 17199 mpc_set(val, this->u_.complex_val, MPC_RNDNN);
0c77715b 17200 break;
17201
17202 default:
17203 go_unreachable();
17204 }
17205
d0bcce51 17206 bool ret = true;
fcbea5e4 17207 if (!mpfr_nan_p(mpc_realref(val))
17208 && !mpfr_inf_p(mpc_realref(val))
17209 && !mpfr_zero_p(mpc_realref(val))
17210 && mpfr_get_exp(mpc_realref(val)) > max_exp)
d0bcce51 17211 {
17212 if (issue_error)
71a45216 17213 {
631d5788 17214 go_error_at(location, "complex real part overflow");
71a45216 17215 this->set_invalid();
17216 }
d0bcce51 17217 ret = false;
17218 }
0c77715b 17219
fcbea5e4 17220 if (!mpfr_nan_p(mpc_imagref(val))
17221 && !mpfr_inf_p(mpc_imagref(val))
17222 && !mpfr_zero_p(mpc_imagref(val))
17223 && mpfr_get_exp(mpc_imagref(val)) > max_exp)
d0bcce51 17224 {
17225 if (issue_error)
71a45216 17226 {
631d5788 17227 go_error_at(location, "complex imaginary part overflow");
71a45216 17228 this->set_invalid();
17229 }
d0bcce51 17230 ret = false;
17231 }
0c77715b 17232
d0bcce51 17233 if (ret)
17234 {
17235 // Round the constant to the desired type.
fcbea5e4 17236 mpc_t t;
d0bcce51 17237 switch (type->bits())
17238 {
17239 case 64:
fcbea5e4 17240 mpc_init2(t, 24);
d0bcce51 17241 break;
17242 case 128:
fcbea5e4 17243 mpc_init2(t, 53);
d0bcce51 17244 break;
17245 default:
17246 go_unreachable();
17247 }
fcbea5e4 17248 mpc_set(t, val, MPC_RNDNN);
17249 mpc_set(val, t, MPC_RNDNN);
17250 mpc_clear(t);
d0bcce51 17251
fcbea5e4 17252 this->set_complex(type, val);
d0bcce51 17253 }
17254
fcbea5e4 17255 mpc_clear(val);
0c77715b 17256
17257 return ret;
17258}
17259
17260// Return an Expression for this value.
17261
17262Expression*
17263Numeric_constant::expression(Location loc) const
17264{
17265 switch (this->classification_)
17266 {
17267 case NC_INT:
e67508fa 17268 return Expression::make_integer_z(&this->u_.int_val, this->type_, loc);
0c77715b 17269 case NC_RUNE:
17270 return Expression::make_character(&this->u_.int_val, this->type_, loc);
17271 case NC_FLOAT:
17272 return Expression::make_float(&this->u_.float_val, this->type_, loc);
17273 case NC_COMPLEX:
fcbea5e4 17274 return Expression::make_complex(&this->u_.complex_val, this->type_, loc);
71a45216 17275 case NC_INVALID:
17276 go_assert(saw_errors());
17277 return Expression::make_error(loc);
0c77715b 17278 default:
17279 go_unreachable();
17280 }
17281}
0ab32342 17282
17283// Calculate a hash code with a given seed.
17284
17285unsigned int
17286Numeric_constant::hash(unsigned int seed) const
17287{
17288 unsigned long val;
17289 const unsigned int PRIME = 97;
17290 long e = 0;
17291 double f = 1.0;
17292 mpfr_t m;
17293
17294 switch (this->classification_)
17295 {
17296 case NC_INVALID:
17297 return PRIME;
17298 case NC_INT:
17299 case NC_RUNE:
17300 val = mpz_get_ui(this->u_.int_val);
17301 break;
17302 case NC_COMPLEX:
17303 mpfr_init(m);
0570cb84 17304 mpc_abs(m, this->u_.complex_val, GMP_RNDN);
17305 val = mpfr_get_ui(m, GMP_RNDN);
0ab32342 17306 mpfr_clear(m);
17307 break;
17308 case NC_FLOAT:
29d43984 17309 f = mpfr_get_d_2exp(&e, this->u_.float_val, GMP_RNDN) * 4294967295.0;
0ab32342 17310 val = static_cast<unsigned long>(e + static_cast<long>(f));
17311 break;
17312 default:
17313 go_unreachable();
17314 }
17315
17316 return (static_cast<unsigned int>(val) + seed) * PRIME;
17317}
17318