Line data Source code
1 : // expressions.cc -- Go frontend expression handling.
2 :
3 : // Copyright 2009 The Go Authors. All rights reserved.
4 : // Use of this source code is governed by a BSD-style
5 : // license that can be found in the LICENSE file.
6 :
7 : #include "go-system.h"
8 :
9 : #include <algorithm>
10 :
11 : #include "go-c.h"
12 : #include "gogo.h"
13 : #include "go-diagnostics.h"
14 : #include "go-encode-id.h"
15 : #include "types.h"
16 : #include "export.h"
17 : #include "import.h"
18 : #include "statements.h"
19 : #include "lex.h"
20 : #include "runtime.h"
21 : #include "backend.h"
22 : #include "expressions.h"
23 : #include "ast-dump.h"
24 :
25 : // Class Expression.
26 :
27 51552131 : Expression::Expression(Expression_classification classification,
28 51552131 : Location location)
29 51552131 : : classification_(classification), location_(location)
30 : {
31 51552131 : }
32 :
33 200723 : Expression::~Expression()
34 : {
35 200723 : }
36 :
37 : // Traverse the expressions.
38 :
39 : int
40 237123108 : Expression::traverse(Expression** pexpr, Traverse* traverse)
41 : {
42 237123108 : Expression* expr = *pexpr;
43 237123108 : if ((traverse->traverse_mask() & Traverse::traverse_expressions) != 0)
44 : {
45 178416906 : int t = traverse->expression(pexpr);
46 178416906 : if (t == TRAVERSE_EXIT)
47 : return TRAVERSE_EXIT;
48 176684517 : else if (t == TRAVERSE_SKIP_COMPONENTS)
49 : return TRAVERSE_CONTINUE;
50 : }
51 165731039 : return expr->do_traverse(traverse);
52 : }
53 :
54 : // Traverse subexpressions of this expression.
55 :
56 : int
57 71958171 : Expression::traverse_subexpressions(Traverse* traverse)
58 : {
59 71958171 : return this->do_traverse(traverse);
60 : }
61 :
62 : // A traversal used to set the location of subexpressions.
63 :
64 18170 : class Set_location : public Traverse
65 : {
66 : public:
67 9085 : Set_location(Location loc)
68 9085 : : Traverse(traverse_expressions),
69 9085 : loc_(loc)
70 : { }
71 :
72 : int
73 : expression(Expression** pexpr);
74 :
75 : private:
76 : Location loc_;
77 : };
78 :
79 : // Set the location of an expression.
80 :
81 : int
82 5614 : Set_location::expression(Expression** pexpr)
83 : {
84 : // Some expressions are shared or don't have an independent
85 : // location, so we shouldn't change their location. This is the set
86 : // of expressions for which do_copy is just "return this" or
87 : // otherwise does not pass down the location.
88 5614 : switch ((*pexpr)->classification())
89 : {
90 : case Expression::EXPRESSION_ERROR:
91 : case Expression::EXPRESSION_VAR_REFERENCE:
92 : case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
93 : case Expression::EXPRESSION_STRING:
94 : case Expression::EXPRESSION_FUNC_DESCRIPTOR:
95 : case Expression::EXPRESSION_TYPE:
96 : case Expression::EXPRESSION_BOOLEAN:
97 : case Expression::EXPRESSION_CONST_REFERENCE:
98 : case Expression::EXPRESSION_NIL:
99 : case Expression::EXPRESSION_TYPE_DESCRIPTOR:
100 : case Expression::EXPRESSION_GC_SYMBOL:
101 : case Expression::EXPRESSION_PTRMASK_SYMBOL:
102 : case Expression::EXPRESSION_TYPE_INFO:
103 : case Expression::EXPRESSION_STRUCT_FIELD_OFFSET:
104 : return TRAVERSE_CONTINUE;
105 5607 : default:
106 5607 : break;
107 : }
108 :
109 5607 : (*pexpr)->location_ = this->loc_;
110 5607 : return TRAVERSE_CONTINUE;
111 : }
112 :
113 : // Set the location of an expression and its subexpressions.
114 :
115 : void
116 9085 : Expression::set_location(Location loc)
117 : {
118 9085 : this->location_ = loc;
119 9085 : Set_location sl(loc);
120 9085 : this->traverse_subexpressions(&sl);
121 9085 : }
122 :
123 : // Default implementation for do_traverse for child classes.
124 :
125 : int
126 69456858 : Expression::do_traverse(Traverse*)
127 : {
128 69456858 : return TRAVERSE_CONTINUE;
129 : }
130 :
131 : // This virtual function is called by the parser if the value of this
132 : // expression is being discarded. By default, we give an error.
133 : // Expressions with side effects override.
134 :
135 : bool
136 18 : Expression::do_discarding_value()
137 : {
138 18 : this->unused_value_error();
139 18 : return false;
140 : }
141 :
142 : // This virtual function is called to export expressions. This will
143 : // only be used by expressions which may be constant.
144 :
145 : void
146 0 : Expression::do_export(Export_function_body*) const
147 : {
148 0 : go_unreachable();
149 : }
150 :
151 : // Write a name to the export data.
152 :
153 : void
154 13427 : Expression::export_name(Export_function_body* efb, const Named_object* no)
155 : {
156 13427 : if (no->package() != NULL)
157 : {
158 4700 : char buf[50];
159 4700 : snprintf(buf, sizeof buf, "<p%d>", efb->package_index(no->package()));
160 4700 : efb->write_c_string(buf);
161 : }
162 :
163 13427 : if (!Gogo::is_hidden_name(no->name()))
164 5679 : efb->write_string(no->name());
165 : else
166 : {
167 7748 : efb->write_c_string(".");
168 7748 : efb->write_string(Gogo::unpack_hidden_name(no->name()));
169 : }
170 13427 : }
171 :
172 : // Give an error saying that the value of the expression is not used.
173 :
174 : void
175 95 : Expression::unused_value_error()
176 : {
177 95 : if (this->type()->is_error())
178 : {
179 13 : go_assert(saw_errors());
180 13 : this->set_is_error();
181 : }
182 : else
183 82 : this->report_error(_("value computed is not used"));
184 95 : }
185 :
186 : // Note that this expression is an error. This is called by children
187 : // when they discover an error.
188 :
189 : void
190 5305 : Expression::set_is_error()
191 : {
192 5305 : this->classification_ = EXPRESSION_ERROR;
193 5305 : }
194 :
195 : // For children to call to report an error conveniently.
196 :
197 : void
198 1291 : Expression::report_error(const char* msg)
199 : {
200 1291 : go_error_at(this->location_, "%s", msg);
201 1291 : this->set_is_error();
202 1291 : }
203 :
204 : // A convenience function for handling a type in do_is_untyped. If
205 : // TYPE is not abstract, return false. Otherwise set *PTYPE to TYPE
206 : // and return true.
207 :
208 : bool
209 1390308 : Expression::is_untyped_type(Type* type, Type** ptype)
210 : {
211 1390308 : if (!type->is_abstract())
212 : return false;
213 53489 : *ptype = type;
214 53489 : return true;
215 : }
216 :
217 : // Report whether this is a type expression.
218 :
219 : bool
220 26640545 : Expression::is_type_expression() const
221 : {
222 26640545 : if (this->classification_ == EXPRESSION_TYPE)
223 : return true;
224 26450893 : if (this->unknown_expression() != NULL)
225 : {
226 833639 : Named_object* no = this->unknown_expression()->named_object();
227 833639 : if (no->is_unknown())
228 : {
229 634300 : no = no->unknown_value()->real_named_object();
230 634300 : if (no == NULL)
231 : return false;
232 : }
233 250035 : return no->is_type();
234 : }
235 25617254 : if (this->unary_expression() != NULL
236 149942 : && this->unary_expression()->op() == OPERATOR_MULT
237 35160 : && this->unary_expression()->operand()->is_type_expression())
238 : return true;
239 : return false;
240 : }
241 :
242 : // Set types of variables and constants. This is implemented by the
243 : // child class.
244 :
245 : void
246 38447493 : Expression::determine_type(Gogo* gogo, const Type_context* context)
247 : {
248 38447493 : this->do_determine_type(gogo, context);
249 38447493 : }
250 :
251 : // Set types when there is no context.
252 :
253 : void
254 14367869 : Expression::determine_type_no_context(Gogo* gogo)
255 : {
256 14367869 : Type_context context;
257 14367869 : this->do_determine_type(gogo, &context);
258 14367869 : }
259 :
260 : // Return true if two expressions refer to the same variable or struct
261 : // field. This can only be true when there are no side effects.
262 :
263 : bool
264 47768 : Expression::is_same_variable(Expression* a, Expression* b)
265 : {
266 47768 : if (a->classification() != b->classification())
267 : return false;
268 :
269 43769 : Var_expression* av = a->var_expression();
270 43769 : if (av != NULL)
271 30528 : return av->named_object() == b->var_expression()->named_object();
272 :
273 13241 : Field_reference_expression* af = a->field_reference_expression();
274 13241 : if (af != NULL)
275 : {
276 6441 : Field_reference_expression* bf = b->field_reference_expression();
277 6441 : return (af->field_index() == bf->field_index()
278 6441 : && Expression::is_same_variable(af->expr(), bf->expr()));
279 : }
280 :
281 6800 : Unary_expression* au = a->unary_expression();
282 6800 : if (au != NULL)
283 : {
284 6083 : Unary_expression* bu = b->unary_expression();
285 6083 : return (au->op() == OPERATOR_MULT
286 6083 : && bu->op() == OPERATOR_MULT
287 12166 : && Expression::is_same_variable(au->operand(),
288 : bu->operand()));
289 : }
290 :
291 717 : Array_index_expression* aie = a->array_index_expression();
292 717 : if (aie != NULL)
293 : {
294 86 : Array_index_expression* bie = b->array_index_expression();
295 86 : return (aie->end() == NULL
296 86 : && bie->end() == NULL
297 86 : && Expression::is_same_variable(aie->array(), bie->array())
298 172 : && Expression::is_same_variable(aie->start(), bie->start()));
299 : }
300 :
301 631 : Numeric_constant aval;
302 631 : if (a->numeric_constant_value(&aval))
303 : {
304 28 : Numeric_constant bval;
305 28 : if (b->numeric_constant_value(&bval))
306 28 : return aval.equals(bval);
307 28 : }
308 :
309 : return false;
310 631 : }
311 :
312 : // Return an expression handling any conversions which must be done during
313 : // assignment.
314 :
315 : Expression*
316 12781511 : Expression::convert_for_assignment(Gogo* gogo, Type* lhs_type,
317 : Expression* rhs, Location location)
318 : {
319 12781511 : Type* rhs_type = rhs->type();
320 12781511 : if (lhs_type->is_error()
321 12781506 : || rhs_type->is_error()
322 25563010 : || rhs->is_error_expression())
323 13 : return Expression::make_error(location);
324 :
325 12781498 : bool are_identical = Type::are_identical(lhs_type, rhs_type,
326 : (Type::COMPARE_ERRORS
327 : | Type::COMPARE_TAGS),
328 : NULL);
329 12781498 : Expression* ret;
330 12781498 : if (!are_identical && lhs_type->interface_type() != NULL)
331 : {
332 : // Type to interface conversions have been made explicit early.
333 26024 : go_assert(rhs_type->interface_type() != NULL);
334 26024 : ret = Expression::convert_interface_to_interface(gogo, lhs_type, rhs,
335 : false, location);
336 : }
337 12755474 : else if (!are_identical && rhs_type->interface_type() != NULL)
338 12525 : ret = Expression::convert_interface_to_type(gogo, lhs_type, rhs, location);
339 12742949 : else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
340 : {
341 : // Assigning nil to a slice.
342 19166 : Expression* nil = Expression::make_nil(location);
343 19166 : Expression* zero = Expression::make_integer_ul(0, NULL, location);
344 19166 : ret = Expression::make_slice_value(lhs_type, nil, zero, zero, location);
345 : }
346 12723783 : else if (rhs_type->is_nil_type())
347 852297 : ret = Expression::make_nil(location);
348 11871486 : else if (are_identical)
349 : {
350 11668909 : if (lhs_type->forwarded() != rhs_type->forwarded())
351 : {
352 : // Different but identical types require an explicit
353 : // conversion. This happens with type aliases.
354 474035 : return Expression::make_cast(lhs_type, rhs, location);
355 : }
356 :
357 : // No conversion is needed.
358 : return rhs;
359 : }
360 202577 : else if (lhs_type->points_to() != NULL)
361 13359 : ret = Expression::make_unsafe_cast(lhs_type, rhs, location);
362 189218 : else if (lhs_type->is_numeric_type())
363 144058 : ret = Expression::make_cast(lhs_type, rhs, location);
364 45196 : else if ((lhs_type->struct_type() != NULL
365 45124 : && rhs_type->struct_type() != NULL)
366 3434 : || (lhs_type->array_type() != NULL
367 3470 : && rhs_type->array_type() != NULL))
368 : {
369 : // This conversion must be permitted by Go, or we wouldn't have
370 : // gotten here.
371 3470 : ret = Expression::make_unsafe_cast(lhs_type, rhs, location);
372 : }
373 : else
374 41690 : return rhs;
375 :
376 1070899 : Type_context context(lhs_type, false);
377 1070899 : ret->determine_type(gogo, &context);
378 1070899 : return ret;
379 : }
380 :
381 : // Return an expression for a conversion from a non-interface type to an
382 : // interface type. If ON_STACK is true, it can allocate the storage on
383 : // stack.
384 :
385 : Expression*
386 201200 : Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
387 : bool on_stack, Location location)
388 : {
389 201200 : Interface_type* lhs_interface_type = lhs_type->interface_type();
390 201200 : bool lhs_is_empty = lhs_interface_type->is_empty();
391 :
392 : // Since RHS_TYPE is a static type, we can create the interface
393 : // method table at compile time.
394 :
395 : // When setting an interface to nil, we just set both fields to
396 : // NULL.
397 201200 : Type* rhs_type = rhs->type();
398 201200 : if (rhs_type->is_nil_type())
399 : {
400 28459 : Expression* nil = Expression::make_nil(location);
401 28459 : return Expression::make_interface_value(lhs_type, nil, nil, location);
402 : }
403 :
404 : // This should have been checked already.
405 172741 : if (!lhs_interface_type->implements_interface(rhs_type, NULL))
406 : {
407 0 : go_assert(saw_errors());
408 0 : return Expression::make_error(location);
409 : }
410 :
411 : // An interface is a tuple. If LHS_TYPE is an empty interface type,
412 : // then the first field is the type descriptor for RHS_TYPE.
413 : // Otherwise it is the interface method table for RHS_TYPE.
414 172741 : Expression* first_field;
415 172741 : if (lhs_is_empty)
416 129332 : first_field = Expression::make_type_descriptor(rhs_type, location);
417 : else
418 : {
419 : // Build the interface method table for this interface and this
420 : // object type: a list of function pointers for each interface
421 : // method.
422 43409 : Named_type* rhs_named_type = rhs_type->named_type();
423 43409 : Struct_type* rhs_struct_type = rhs_type->struct_type();
424 43409 : bool is_pointer = false;
425 43409 : if (rhs_named_type == NULL && rhs_struct_type == NULL)
426 : {
427 59638 : rhs_named_type = rhs_type->deref()->named_type();
428 59638 : rhs_struct_type = rhs_type->deref()->struct_type();
429 : is_pointer = true;
430 : }
431 43409 : if (rhs_named_type != NULL)
432 43285 : first_field =
433 43285 : rhs_named_type->interface_method_table(lhs_interface_type,
434 : is_pointer);
435 124 : else if (rhs_struct_type != NULL)
436 124 : first_field =
437 124 : rhs_struct_type->interface_method_table(lhs_interface_type,
438 : is_pointer);
439 : else
440 0 : first_field = Expression::make_nil(location);
441 : }
442 :
443 172741 : Expression* obj;
444 172741 : if (rhs_type->is_direct_iface_type())
445 : {
446 : // We are assigning a pointer to the interface; the interface
447 : // holds the pointer itself.
448 47262 : obj = unpack_direct_iface(rhs, location);
449 : }
450 : else
451 : {
452 : // We are assigning a non-pointer value to the interface; the
453 : // interface gets a copy of the value in the heap if it escapes.
454 :
455 : // An exception is &global if global is notinheap, which is a
456 : // pointer value but not a direct-iface type and we can't simply
457 : // take its address.
458 125479 : bool is_address = (rhs->unary_expression() != NULL
459 735 : && rhs->unary_expression()->op() == OPERATOR_AND);
460 :
461 125479 : if (rhs->is_constant() && !is_address)
462 31942 : obj = Expression::make_unary(OPERATOR_AND, rhs, location);
463 : else
464 : {
465 93537 : obj = Expression::make_heap_expression(rhs, location);
466 93537 : if (on_stack)
467 597 : obj->heap_expression()->set_allocate_on_stack();
468 : }
469 : }
470 :
471 172741 : return Expression::make_interface_value(lhs_type, first_field, obj, location);
472 : }
473 :
474 : // Return an expression for the pointer-typed value of a direct interface
475 : // type. Specifically, for single field struct or array, get the single
476 : // field, and do this recursively. The reason for this is that we don't
477 : // want to assign a struct or an array to a pointer-typed field. The
478 : // backend may not like that.
479 :
480 : Expression*
481 57906 : Expression::unpack_direct_iface(Expression* rhs, Location loc)
482 : {
483 62190 : Struct_type* st = rhs->type()->struct_type();
484 62190 : if (st != NULL)
485 : {
486 4284 : go_assert(st->field_count() == 1);
487 4284 : Expression* field = Expression::make_field_reference(rhs, 0, loc);
488 4284 : return unpack_direct_iface(field, loc);
489 : }
490 57906 : Array_type* at = rhs->type()->array_type();
491 814 : if (at != NULL)
492 : {
493 814 : int64_t len;
494 814 : bool ok = at->int_length(&len);
495 814 : go_assert(ok && len == 1);
496 814 : Type* int_type = Type::lookup_integer_type("int");
497 814 : Expression* index = Expression::make_integer_ul(0, int_type, loc);
498 814 : Expression* elem = Expression::make_array_index(rhs, index, NULL, NULL, loc);
499 814 : return unpack_direct_iface(elem, loc);
500 : }
501 : return rhs;
502 : }
503 :
504 : // The opposite of unpack_direct_iface.
505 :
506 : Expression*
507 13513 : Expression::pack_direct_iface(Type* t, Expression* rhs, Location loc)
508 : {
509 13513 : if (rhs->type() == t)
510 : return rhs;
511 13513 : Struct_type* st = t->struct_type();
512 13513 : if (st != NULL)
513 : {
514 1665 : Expression_list* vals = new Expression_list();
515 1665 : vals->push_back(pack_direct_iface(st->field(0)->type(), rhs, loc));
516 1665 : return Expression::make_struct_composite_literal(t, vals, loc);
517 : }
518 11848 : Array_type* at = t->array_type();
519 11848 : if (at != NULL)
520 : {
521 4 : Expression_list* vals = new Expression_list();
522 4 : vals->push_back(pack_direct_iface(at->element_type(), rhs, loc));
523 4 : return Expression::make_array_composite_literal(t, vals, loc);
524 : }
525 11844 : return Expression::make_unsafe_cast(t, rhs, loc);
526 : }
527 :
528 : // Return an expression for the type descriptor of RHS.
529 :
530 : Expression*
531 54471 : Expression::get_interface_type_descriptor(Expression* rhs)
532 : {
533 54471 : go_assert(rhs->type()->interface_type() != NULL);
534 54471 : Location location = rhs->location();
535 :
536 : // The type descriptor is the first field of an empty interface.
537 108942 : if (rhs->type()->interface_type()->is_empty())
538 8989 : return Expression::make_interface_info(rhs, INTERFACE_INFO_TYPE_DESCRIPTOR,
539 8989 : location);
540 :
541 45482 : Expression* mtable =
542 45482 : Expression::make_interface_info(rhs, INTERFACE_INFO_METHODS, location);
543 :
544 45482 : Expression* descriptor =
545 45482 : Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, location);
546 45482 : descriptor = Expression::make_field_reference(descriptor, 0, location);
547 45482 : Expression* nil = Expression::make_nil(location);
548 :
549 45482 : Expression* eq =
550 45482 : Expression::make_binary(OPERATOR_EQEQ, mtable, nil, location);
551 45482 : return Expression::make_conditional(eq, nil, descriptor, location);
552 : }
553 :
554 : // Return an expression for the conversion of an interface type to an
555 : // interface type.
556 :
557 : Expression*
558 27040 : Expression::convert_interface_to_interface(Gogo* gogo, Type *lhs_type,
559 : Expression* rhs,
560 : bool for_type_guard,
561 : Location location)
562 : {
563 27040 : if (Type::are_identical(lhs_type, rhs->type(),
564 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
565 : NULL))
566 : return rhs;
567 :
568 27035 : Interface_type* lhs_interface_type = lhs_type->interface_type();
569 27035 : bool lhs_is_empty = lhs_interface_type->is_empty();
570 :
571 : // In the general case this requires runtime examination of the type
572 : // method table to match it up with the interface methods.
573 :
574 : // FIXME: If all of the methods in the right hand side interface
575 : // also appear in the left hand side interface, then we don't need
576 : // to do a runtime check, although we still need to build a new
577 : // method table.
578 :
579 : // We are going to evaluate RHS multiple times.
580 27035 : go_assert(rhs->is_multi_eval_safe());
581 :
582 : // Get the type descriptor for the right hand side. This will be
583 : // NULL for a nil interface.
584 27035 : Expression* rhs_type_expr = Expression::get_interface_type_descriptor(rhs);
585 27035 : Expression* lhs_type_expr =
586 27035 : Expression::make_type_descriptor(lhs_type, location);
587 :
588 27035 : Expression* first_field;
589 27035 : if (for_type_guard)
590 : {
591 : // A type assertion fails when converting a nil interface.
592 1011 : first_field = Runtime::make_call(gogo, Runtime::ASSERTITAB, location, 2,
593 : lhs_type_expr, rhs_type_expr);
594 : }
595 26024 : else if (lhs_is_empty)
596 : {
597 : // A conversion to an empty interface always succeeds, and the
598 : // first field is just the type descriptor of the object.
599 : first_field = rhs_type_expr;
600 : }
601 : else
602 : {
603 : // A conversion to a non-empty interface may fail, but unlike a
604 : // type assertion converting nil will always succeed.
605 4304 : first_field = Runtime::make_call(gogo, Runtime::REQUIREITAB, location, 2,
606 : lhs_type_expr, rhs_type_expr);
607 : }
608 :
609 : // The second field is simply the object pointer.
610 27035 : Expression* obj =
611 27035 : Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT, location);
612 27035 : Expression* ret = Expression::make_interface_value(lhs_type, first_field,
613 : obj, location);
614 27035 : Type_context context(lhs_type, false);
615 27035 : ret->determine_type(gogo, &context);
616 27035 : return ret;
617 : }
618 :
619 : // Return an expression for the conversion of an interface type to a
620 : // non-interface type.
621 :
622 : Expression*
623 12525 : Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rhs,
624 : Location location)
625 : {
626 : // We are going to evaluate RHS multiple times.
627 12525 : go_assert(rhs->is_multi_eval_safe());
628 :
629 : // Build an expression to check that the type is valid. It will
630 : // panic with an appropriate runtime type error if the type is not
631 : // valid.
632 : // (lhs_type == rhs_type ? nil /*dummy*/ :
633 : // panicdottype(lhs_type, rhs_type, inter_type))
634 : // For some Oses, we need to call runtime.eqtype instead of
635 : // lhs_type == rhs_type, as we may have unmerged type descriptors
636 : // from shared libraries.
637 12525 : Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type,
638 : location);
639 12525 : Expression* rhs_descriptor =
640 12525 : Expression::get_interface_type_descriptor(rhs);
641 :
642 12525 : Type* rhs_type = rhs->type();
643 12525 : Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
644 : location);
645 :
646 12525 : Expression* cond;
647 12525 : if (gogo->need_eqtype()) {
648 0 : cond = Runtime::make_call(gogo, Runtime::EQTYPE, location,
649 : 2, lhs_type_expr,
650 : rhs_descriptor);
651 : } else {
652 12525 : cond = Expression::make_binary(OPERATOR_EQEQ, lhs_type_expr,
653 : rhs_descriptor, location);
654 : }
655 :
656 12525 : rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
657 12525 : Expression* panic = Runtime::make_call(gogo, Runtime::PANICDOTTYPE, location,
658 : 3, lhs_type_expr->copy(),
659 : rhs_descriptor,
660 : rhs_inter_expr);
661 12525 : Expression* nil = Expression::make_nil(location);
662 12525 : Expression* check = Expression::make_conditional(cond, nil, panic,
663 : location);
664 :
665 : // If the conversion succeeds, pull out the value.
666 12525 : Expression* obj = Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT,
667 : location);
668 :
669 : // If the value is a direct interface, then it is the value we want.
670 : // Otherwise it points to the value.
671 12525 : if (lhs_type->is_direct_iface_type())
672 9828 : obj = Expression::pack_direct_iface(lhs_type, obj, location);
673 : else
674 : {
675 2697 : obj = Expression::make_unsafe_cast(Type::make_pointer_type(lhs_type), obj,
676 : location);
677 2697 : obj = Expression::make_dereference(obj, NIL_CHECK_NOT_NEEDED,
678 : location);
679 : }
680 12525 : return Expression::make_compound(check, obj, location);
681 : }
682 :
683 : // Convert an expression to its backend representation. This is implemented by
684 : // the child class. Not that it is not in general safe to call this multiple
685 : // times for a single expression, but that we don't catch such errors.
686 :
687 : Bexpression*
688 40338841 : Expression::get_backend(Translate_context* context)
689 : {
690 : // The child may have marked this expression as having an error.
691 40338841 : if (this->classification_ == EXPRESSION_ERROR)
692 : {
693 3629 : go_assert(saw_errors());
694 3629 : return context->backend()->error_expression();
695 : }
696 :
697 40335212 : return this->do_get_backend(context);
698 : }
699 :
700 : // Return a backend expression for VAL.
701 : Bexpression*
702 6051042 : Expression::backend_numeric_constant_expression(Translate_context* context,
703 : Numeric_constant* val)
704 : {
705 6051042 : Gogo* gogo = context->gogo();
706 6051042 : Type* type = val->type();
707 6051042 : if (type == NULL)
708 0 : return gogo->backend()->error_expression();
709 :
710 6051042 : Btype* btype = type->get_backend(gogo);
711 6051042 : Bexpression* ret;
712 6051042 : if (type->integer_type() != NULL)
713 : {
714 6014674 : mpz_t ival;
715 6014674 : if (!val->to_int(&ival))
716 : {
717 0 : go_assert(saw_errors());
718 0 : return gogo->backend()->error_expression();
719 : }
720 6014674 : ret = gogo->backend()->integer_constant_expression(btype, ival);
721 6014674 : mpz_clear(ival);
722 : }
723 36368 : else if (type->float_type() != NULL)
724 : {
725 33424 : mpfr_t fval;
726 33424 : if (!val->to_float(&fval))
727 : {
728 0 : go_assert(saw_errors());
729 0 : return gogo->backend()->error_expression();
730 : }
731 33424 : ret = gogo->backend()->float_constant_expression(btype, fval);
732 33424 : mpfr_clear(fval);
733 : }
734 2944 : else if (type->complex_type() != NULL)
735 : {
736 2944 : mpc_t cval;
737 2944 : if (!val->to_complex(&cval))
738 : {
739 0 : go_assert(saw_errors());
740 0 : return gogo->backend()->error_expression();
741 : }
742 2944 : ret = gogo->backend()->complex_constant_expression(btype, cval);
743 2944 : mpc_clear(cval);
744 : }
745 : else
746 0 : go_unreachable();
747 :
748 : return ret;
749 : }
750 :
751 : // Insert bounds checks for an index expression. Check that that VAL
752 : // >= 0 and that it fits in an int. Then check that VAL OP BOUND is
753 : // true. If any condition is false, call one of the CODE runtime
754 : // functions, which will panic.
755 :
756 : void
757 224475 : Expression::check_bounds(Gogo* gogo, Expression* val, Operator op,
758 : Expression* bound,
759 : Runtime::Function code,
760 : Runtime::Function code_u,
761 : Runtime::Function code_extend,
762 : Runtime::Function code_extend_u,
763 : Statement_inserter* inserter,
764 : Location loc)
765 : {
766 224475 : go_assert(val->is_multi_eval_safe());
767 224475 : go_assert(bound->is_multi_eval_safe());
768 :
769 224475 : Type* int_type = Type::lookup_integer_type("int");
770 448950 : int int_type_size = int_type->integer_type()->bits();
771 :
772 224475 : Type* val_type = val->type();
773 224475 : if (val_type->integer_type() == NULL)
774 : {
775 0 : go_assert(saw_errors());
776 : return;
777 : }
778 448950 : int val_type_size = val_type->integer_type()->bits();
779 448950 : bool val_is_unsigned = val_type->integer_type()->is_unsigned();
780 :
781 : // Check that VAL >= 0.
782 224475 : Expression* check = NULL;
783 224475 : if (!val_is_unsigned)
784 : {
785 213394 : Expression* zero = Expression::make_integer_ul(0, val_type, loc);
786 213394 : check = Expression::make_binary(OPERATOR_GE, val->copy(), zero, loc);
787 : }
788 :
789 : // If VAL's type is larger than int, check that VAL fits in an int.
790 224475 : if (val_type_size > int_type_size
791 223780 : || (val_type_size == int_type_size
792 223780 : && val_is_unsigned))
793 : {
794 5511 : mpz_t one;
795 5511 : mpz_init_set_ui(one, 1UL);
796 :
797 : // maxval = 2^(int_type_size - 1) - 1
798 5511 : mpz_t maxval;
799 5511 : mpz_init(maxval);
800 5511 : mpz_mul_2exp(maxval, one, int_type_size - 1);
801 5511 : mpz_sub_ui(maxval, maxval, 1);
802 5511 : Expression* max = Expression::make_integer_z(&maxval, val_type, loc);
803 5511 : mpz_clear(one);
804 5511 : mpz_clear(maxval);
805 :
806 5511 : Expression* cmp = Expression::make_binary(OPERATOR_LE, val->copy(),
807 : max, loc);
808 5511 : if (check == NULL)
809 : check = cmp;
810 : else
811 311 : check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc);
812 : }
813 :
814 : // For the final check we can assume that VAL fits in an int.
815 224475 : Expression* ival;
816 224475 : if (val_type == int_type)
817 188567 : ival = val->copy();
818 : else
819 35908 : ival = Expression::make_cast(int_type, val->copy(), loc);
820 :
821 : // BOUND is assumed to fit in an int. Either it comes from len or
822 : // cap, or it was checked by an earlier call.
823 224475 : Expression* ibound;
824 224475 : if (bound->type() == int_type)
825 205360 : ibound = bound->copy();
826 : else
827 19115 : ibound = Expression::make_cast(int_type, bound->copy(), loc);
828 :
829 224475 : Expression* cmp = Expression::make_binary(op, ival, ibound, loc);
830 224475 : if (check == NULL)
831 : check = cmp;
832 : else
833 218594 : check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc);
834 :
835 224475 : Runtime::Function c;
836 224475 : if (val_type_size > int_type_size)
837 : {
838 695 : if (val_is_unsigned)
839 : c = code_extend_u;
840 : else
841 311 : c = code_extend;
842 : }
843 : else
844 : {
845 223780 : if (val_is_unsigned)
846 : c = code_u;
847 : else
848 213083 : c = code;
849 : }
850 :
851 224475 : Expression* ignore = Expression::make_boolean(true, loc);
852 224475 : Expression* crash = Runtime::make_call(gogo, c, loc, 2,
853 : val->copy(), bound->copy());
854 224475 : Expression* cond = Expression::make_conditional(check, ignore, crash, loc);
855 224475 : Statement* s = Statement::make_statement(cond, true);
856 224475 : s->determine_types(gogo);
857 224475 : inserter->insert(s);
858 : }
859 :
860 : void
861 0 : Expression::dump_expression(Ast_dump_context* ast_dump_context) const
862 : {
863 0 : this->do_dump_expression(ast_dump_context);
864 0 : }
865 :
866 : // Error expressions. This are used to avoid cascading errors.
867 :
868 : class Error_expression : public Expression
869 : {
870 : public:
871 9856 : Error_expression(Location location)
872 19712 : : Expression(EXPRESSION_ERROR, location)
873 : { }
874 :
875 : protected:
876 : bool
877 62 : do_is_constant() const
878 62 : { return true; }
879 :
880 : bool
881 25 : do_is_untyped(Type**) const
882 25 : { return false; }
883 :
884 : bool
885 30 : do_numeric_constant_value(Numeric_constant*)
886 30 : { return false; }
887 :
888 : bool
889 6 : do_discarding_value()
890 6 : { return true; }
891 :
892 : Type*
893 12537 : do_type()
894 12537 : { return Type::make_error_type(); }
895 :
896 : void
897 160 : do_determine_type(Gogo*, const Type_context*)
898 160 : { }
899 :
900 : Expression*
901 0 : do_copy()
902 0 : { return this; }
903 :
904 : bool
905 9 : do_is_addressable() const
906 9 : { return true; }
907 :
908 : Bexpression*
909 0 : do_get_backend(Translate_context* context)
910 0 : { return context->backend()->error_expression(); }
911 :
912 : void
913 : do_dump_expression(Ast_dump_context*) const;
914 : };
915 :
916 : // Dump the ast representation for an error expression to a dump context.
917 :
918 : void
919 0 : Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
920 : {
921 0 : ast_dump_context->ostream() << "_Error_" ;
922 0 : }
923 :
924 : Expression*
925 9856 : Expression::make_error(Location location)
926 : {
927 9856 : return new Error_expression(location);
928 : }
929 :
930 : // An expression which is really a type. This is used during parsing.
931 : // It is an error if these survive after lowering.
932 :
933 : class Type_expression : public Expression
934 : {
935 : public:
936 254305 : Type_expression(Type* type, Location location)
937 254305 : : Expression(EXPRESSION_TYPE, location),
938 508610 : type_(type)
939 : { }
940 :
941 : protected:
942 : int
943 143431 : do_traverse(Traverse* traverse)
944 143431 : { return Type::traverse(this->type_, traverse); }
945 :
946 : Type*
947 476268 : do_type()
948 476268 : { return this->type_; }
949 :
950 : void
951 21109 : do_determine_type(Gogo*, const Type_context*)
952 21109 : { }
953 :
954 : void
955 : do_check_types(Gogo*);
956 :
957 : Expression*
958 0 : do_copy()
959 0 : { return this; }
960 :
961 : Bexpression*
962 : do_get_backend(Translate_context*);
963 :
964 : void do_dump_expression(Ast_dump_context*) const;
965 :
966 : private:
967 : // The type which we are representing as an expression.
968 : Type* type_;
969 : };
970 :
971 : void
972 23066 : Type_expression::do_check_types(Gogo*)
973 : {
974 23066 : if (this->type_->is_error())
975 : {
976 2 : go_assert(saw_errors());
977 2 : this->set_is_error();
978 : }
979 23066 : }
980 :
981 : Bexpression*
982 2 : Type_expression::do_get_backend(Translate_context* context)
983 : {
984 2 : if (!this->is_error_expression())
985 2 : this->report_error("invalid use of type");
986 2 : return context->backend()->error_expression();
987 : }
988 :
989 : void
990 0 : Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
991 : {
992 0 : ast_dump_context->dump_type(this->type_);
993 0 : }
994 :
995 : Expression*
996 254305 : Expression::make_type(Type* type, Location location)
997 : {
998 254305 : return new Type_expression(type, location);
999 : }
1000 :
1001 : // Class Var_expression.
1002 :
1003 : // Lower a variable expression. Here we just make sure that the
1004 : // initialization expression of the variable has been lowered. This
1005 : // ensures that we will be able to determine the type of the variable
1006 : // if necessary.
1007 :
1008 : Expression*
1009 6402656 : Var_expression::do_lower(Gogo* gogo, Named_object* function,
1010 : Statement_inserter* inserter)
1011 : {
1012 6402656 : if (this->variable_->is_variable())
1013 : {
1014 5668157 : Variable* var = this->variable_->var_value();
1015 : // This is either a local variable or a global variable. A
1016 : // reference to a variable which is local to an enclosing
1017 : // function will be a reference to a field in a closure.
1018 5668157 : if (var->is_global())
1019 : {
1020 446324 : function = NULL;
1021 446324 : inserter = NULL;
1022 : }
1023 5668157 : var->lower_init_expression(gogo, function, inserter);
1024 : }
1025 6402656 : return this;
1026 : }
1027 :
1028 : // Return the type of a reference to a variable.
1029 :
1030 : Type*
1031 51500701 : Var_expression::do_type()
1032 : {
1033 51500701 : if (this->variable_->is_variable())
1034 45961541 : return this->variable_->var_value()->type();
1035 5539160 : else if (this->variable_->is_result_variable())
1036 5539160 : return this->variable_->result_var_value()->type();
1037 : else
1038 0 : go_unreachable();
1039 : }
1040 :
1041 : // Determine the type of a reference to a variable.
1042 :
1043 : void
1044 6261234 : Var_expression::do_determine_type(Gogo* gogo, const Type_context*)
1045 : {
1046 6261234 : if (this->variable_->is_variable())
1047 5609315 : this->variable_->var_value()->determine_type(gogo);
1048 6261234 : }
1049 :
1050 : // Something takes the address of this variable. This means that we
1051 : // may want to move the variable onto the heap.
1052 :
1053 : void
1054 1421692 : Var_expression::do_address_taken(bool escapes)
1055 : {
1056 1421692 : if (!escapes)
1057 : {
1058 1072633 : if (this->variable_->is_variable())
1059 1069616 : this->variable_->var_value()->set_non_escaping_address_taken();
1060 3017 : else if (this->variable_->is_result_variable())
1061 3017 : this->variable_->result_var_value()->set_non_escaping_address_taken();
1062 : else
1063 0 : go_unreachable();
1064 : }
1065 : else
1066 : {
1067 349059 : if (this->variable_->is_variable())
1068 348722 : this->variable_->var_value()->set_address_taken();
1069 337 : else if (this->variable_->is_result_variable())
1070 337 : this->variable_->result_var_value()->set_address_taken();
1071 : else
1072 0 : go_unreachable();
1073 : }
1074 :
1075 1421692 : if (this->variable_->is_variable()
1076 1421692 : && this->variable_->var_value()->is_in_heap())
1077 : {
1078 1167227 : Node::make_node(this)->set_encoding(Node::ESCAPE_HEAP);
1079 1167227 : Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
1080 : }
1081 1421692 : }
1082 :
1083 : // Export a reference to a variable.
1084 :
1085 : void
1086 54719 : Var_expression::do_export(Export_function_body* efb) const
1087 : {
1088 54719 : Named_object* no = this->variable_;
1089 54719 : if (no->is_result_variable() || !no->var_value()->is_global())
1090 52210 : efb->write_string(Gogo::unpack_hidden_name(no->name()));
1091 : else
1092 2509 : Expression::export_name(efb, no);
1093 54719 : }
1094 :
1095 : // Get the backend representation for a reference to a variable.
1096 :
1097 : Bexpression*
1098 4054421 : Var_expression::do_get_backend(Translate_context* context)
1099 : {
1100 4054421 : Bvariable* bvar = this->variable_->get_backend_variable(context->gogo(),
1101 : context->function());
1102 4054421 : bool is_in_heap;
1103 4054421 : Location loc = this->location();
1104 4054421 : Btype* btype;
1105 4054421 : Gogo* gogo = context->gogo();
1106 4054421 : if (this->variable_->is_variable())
1107 : {
1108 3144125 : is_in_heap = this->variable_->var_value()->is_in_heap();
1109 3144125 : btype = this->variable_->var_value()->type()->get_backend(gogo);
1110 : }
1111 910296 : else if (this->variable_->is_result_variable())
1112 : {
1113 910296 : is_in_heap = this->variable_->result_var_value()->is_in_heap();
1114 910296 : btype = this->variable_->result_var_value()->type()->get_backend(gogo);
1115 : }
1116 : else
1117 0 : go_unreachable();
1118 :
1119 4054421 : Bexpression* ret =
1120 4054421 : context->backend()->var_expression(bvar, loc);
1121 4054421 : if (is_in_heap)
1122 66925 : ret = context->backend()->indirect_expression(btype, ret, true, loc);
1123 4054421 : return ret;
1124 : }
1125 :
1126 : // Ast dump for variable expression.
1127 :
1128 : void
1129 0 : Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1130 : {
1131 0 : ast_dump_context->ostream() << this->variable_->message_name() ;
1132 0 : }
1133 :
1134 : // Make a reference to a variable in an expression.
1135 :
1136 : Expression*
1137 3521311 : Expression::make_var_reference(Named_object* var, Location location)
1138 : {
1139 3521311 : if (var->is_sink())
1140 19221 : return Expression::make_sink(location);
1141 3502090 : if (var->is_redefinition())
1142 0 : return Expression::make_error(location);
1143 :
1144 : // FIXME: Creating a new object for each reference to a variable is
1145 : // wasteful.
1146 3502090 : return new Var_expression(var, location);
1147 : }
1148 :
1149 : // Class Enclosed_var_expression.
1150 :
1151 : int
1152 822673 : Enclosed_var_expression::do_traverse(Traverse*)
1153 : {
1154 822673 : return TRAVERSE_CONTINUE;
1155 : }
1156 :
1157 : // Lower the reference to the enclosed variable.
1158 :
1159 : Expression*
1160 92066 : Enclosed_var_expression::do_lower(Gogo* gogo, Named_object* function,
1161 : Statement_inserter* inserter)
1162 : {
1163 92066 : gogo->lower_expression(function, inserter, &this->reference_);
1164 92066 : return this;
1165 : }
1166 :
1167 : // Flatten the reference to the enclosed variable.
1168 :
1169 : Expression*
1170 46835 : Enclosed_var_expression::do_flatten(Gogo* gogo, Named_object* function,
1171 : Statement_inserter* inserter)
1172 : {
1173 46835 : gogo->flatten_expression(function, inserter, &this->reference_);
1174 46835 : return this;
1175 : }
1176 :
1177 : void
1178 28424 : Enclosed_var_expression::do_address_taken(bool escapes)
1179 : {
1180 28424 : if (!escapes)
1181 : {
1182 23149 : if (this->variable_->is_variable())
1183 23080 : this->variable_->var_value()->set_non_escaping_address_taken();
1184 69 : else if (this->variable_->is_result_variable())
1185 69 : this->variable_->result_var_value()->set_non_escaping_address_taken();
1186 : else
1187 0 : go_unreachable();
1188 : }
1189 : else
1190 : {
1191 5275 : if (this->variable_->is_variable())
1192 5266 : this->variable_->var_value()->set_address_taken();
1193 9 : else if (this->variable_->is_result_variable())
1194 9 : this->variable_->result_var_value()->set_address_taken();
1195 : else
1196 0 : go_unreachable();
1197 : }
1198 :
1199 28424 : if (this->variable_->is_variable()
1200 28424 : && this->variable_->var_value()->is_in_heap())
1201 22115 : Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
1202 28424 : }
1203 :
1204 : // Ast dump for enclosed variable expression.
1205 :
1206 : void
1207 0 : Enclosed_var_expression::do_dump_expression(Ast_dump_context* adc) const
1208 : {
1209 0 : adc->ostream() << this->variable_->message_name();
1210 0 : }
1211 :
1212 : // Make a reference to a variable within an enclosing function.
1213 :
1214 : Expression*
1215 43132 : Expression::make_enclosing_var_reference(Expression* reference,
1216 : Named_object* var, Location location)
1217 : {
1218 43132 : return new Enclosed_var_expression(reference, var, location);
1219 : }
1220 :
1221 : // Class Temporary_reference_expression.
1222 :
1223 : // The type.
1224 :
1225 : Type*
1226 18795086 : Temporary_reference_expression::do_type()
1227 : {
1228 18795086 : return this->statement_->type();
1229 : }
1230 :
1231 : // Called if something takes the address of this temporary variable.
1232 : // We never have to move temporary variables to the heap, but we do
1233 : // need to know that they must live in the stack rather than in a
1234 : // register.
1235 :
1236 : void
1237 33962 : Temporary_reference_expression::do_address_taken(bool)
1238 : {
1239 33962 : this->statement_->set_is_address_taken();
1240 33962 : }
1241 :
1242 : // Export a reference to a temporary.
1243 :
1244 : void
1245 6731 : Temporary_reference_expression::do_export(Export_function_body* efb) const
1246 : {
1247 6731 : unsigned int idx = efb->temporary_index(this->statement_);
1248 6731 : char buf[50];
1249 6731 : snprintf(buf, sizeof buf, "$t%u", idx);
1250 6731 : efb->write_c_string(buf);
1251 6731 : }
1252 :
1253 : // Import a reference to a temporary.
1254 :
1255 : Expression*
1256 3923 : Temporary_reference_expression::do_import(Import_function_body* ifb,
1257 : Location loc)
1258 : {
1259 3923 : std::string id = ifb->read_identifier();
1260 3923 : go_assert(id[0] == '$' && id[1] == 't');
1261 3923 : const char *p = id.c_str();
1262 3923 : char *end;
1263 3923 : long idx = strtol(p + 2, &end, 10);
1264 3923 : if (*end != '\0' || idx > 0x7fffffff)
1265 : {
1266 0 : if (!ifb->saw_error())
1267 0 : go_error_at(loc,
1268 : ("invalid export data for %qs: "
1269 : "invalid temporary reference index at %lu"),
1270 0 : ifb->name().c_str(),
1271 0 : static_cast<unsigned long>(ifb->off()));
1272 0 : ifb->set_saw_error();
1273 0 : return Expression::make_error(loc);
1274 : }
1275 :
1276 3923 : Temporary_statement* temp =
1277 3923 : ifb->temporary_statement(static_cast<unsigned int>(idx));
1278 3923 : if (temp == NULL)
1279 : {
1280 0 : if (!ifb->saw_error())
1281 0 : go_error_at(loc,
1282 : ("invalid export data for %qs: "
1283 : "undefined temporary reference index at %lu"),
1284 0 : ifb->name().c_str(),
1285 0 : static_cast<unsigned long>(ifb->off()));
1286 0 : ifb->set_saw_error();
1287 0 : return Expression::make_error(loc);
1288 : }
1289 :
1290 3923 : return Expression::make_temporary_reference(temp, loc);
1291 3923 : }
1292 :
1293 : // Get a backend expression referring to the variable.
1294 :
1295 : Bexpression*
1296 3793779 : Temporary_reference_expression::do_get_backend(Translate_context* context)
1297 : {
1298 3793779 : Gogo* gogo = context->gogo();
1299 3793779 : Bvariable* bvar = this->statement_->get_backend_variable(context);
1300 3793779 : Bexpression* ret = gogo->backend()->var_expression(bvar, this->location());
1301 :
1302 : // The backend can't always represent the same set of recursive types
1303 : // that the Go frontend can. In some cases this means that a
1304 : // temporary variable won't have the right backend type. Correct
1305 : // that here by adding a type cast. We need to use base() to push
1306 : // the circularity down one level.
1307 3793779 : Type* stype = this->statement_->type();
1308 3793779 : if (!this->is_lvalue_
1309 3699405 : && stype->points_to() != NULL
1310 4264401 : && stype->points_to()->is_void_type())
1311 : {
1312 18132 : Btype* btype = this->type()->base()->get_backend(gogo);
1313 18132 : ret = gogo->backend()->convert_expression(btype, ret, this->location());
1314 : }
1315 3793779 : return ret;
1316 : }
1317 :
1318 : // Ast dump for temporary reference.
1319 :
1320 : void
1321 0 : Temporary_reference_expression::do_dump_expression(
1322 : Ast_dump_context* ast_dump_context) const
1323 : {
1324 0 : ast_dump_context->dump_temp_variable_name(this->statement_);
1325 0 : }
1326 :
1327 : // Make a reference to a temporary variable.
1328 :
1329 : Temporary_reference_expression*
1330 3860104 : Expression::make_temporary_reference(Temporary_statement* statement,
1331 : Location location)
1332 : {
1333 3860104 : statement->add_use();
1334 3860104 : return new Temporary_reference_expression(statement, location);
1335 : }
1336 :
1337 : // Class Set_and_use_temporary_expression.
1338 :
1339 : // Return the type.
1340 :
1341 : Type*
1342 326051 : Set_and_use_temporary_expression::do_type()
1343 : {
1344 326051 : return this->statement_->type();
1345 : }
1346 :
1347 : // Determine the type of the expression.
1348 :
1349 : void
1350 20883 : Set_and_use_temporary_expression::do_determine_type(
1351 : Gogo* gogo,
1352 : const Type_context* context)
1353 : {
1354 20883 : this->expr_->determine_type(gogo, context);
1355 20883 : }
1356 :
1357 : // Take the address.
1358 :
1359 : void
1360 0 : Set_and_use_temporary_expression::do_address_taken(bool)
1361 : {
1362 0 : this->statement_->set_is_address_taken();
1363 0 : }
1364 :
1365 : // Return the backend representation.
1366 :
1367 : Bexpression*
1368 16126 : Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
1369 : {
1370 16126 : Location loc = this->location();
1371 16126 : Gogo* gogo = context->gogo();
1372 16126 : Bvariable* bvar = this->statement_->get_backend_variable(context);
1373 16126 : Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, loc);
1374 :
1375 16126 : Named_object* fn = context->function();
1376 16126 : go_assert(fn != NULL);
1377 16126 : Bfunction* bfn = fn->func_value()->get_or_make_decl(gogo, fn);
1378 16126 : Bexpression* bexpr = this->expr_->get_backend(context);
1379 16126 : Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref,
1380 : bexpr, loc);
1381 16126 : Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc);
1382 16126 : Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
1383 16126 : return ret;
1384 : }
1385 :
1386 : // Dump.
1387 :
1388 : void
1389 0 : Set_and_use_temporary_expression::do_dump_expression(
1390 : Ast_dump_context* ast_dump_context) const
1391 : {
1392 0 : ast_dump_context->ostream() << '(';
1393 0 : ast_dump_context->dump_temp_variable_name(this->statement_);
1394 0 : ast_dump_context->ostream() << " = ";
1395 0 : this->expr_->dump_expression(ast_dump_context);
1396 0 : ast_dump_context->ostream() << ')';
1397 0 : }
1398 :
1399 : // Make a set-and-use temporary.
1400 :
1401 : Set_and_use_temporary_expression*
1402 19060 : Expression::make_set_and_use_temporary(Temporary_statement* statement,
1403 : Expression* expr, Location location)
1404 : {
1405 19060 : return new Set_and_use_temporary_expression(statement, expr, location);
1406 : }
1407 :
1408 : // A sink expression--a use of the blank identifier _.
1409 :
1410 : class Sink_expression : public Expression
1411 : {
1412 : public:
1413 27627 : Sink_expression(Location location)
1414 27627 : : Expression(EXPRESSION_SINK, location),
1415 0 : type_(NULL), bvar_(NULL)
1416 : { }
1417 :
1418 : protected:
1419 : bool
1420 0 : do_discarding_value()
1421 0 : { return true; }
1422 :
1423 : Type*
1424 : do_type();
1425 :
1426 : void
1427 : do_determine_type(Gogo*, const Type_context*);
1428 :
1429 : Expression*
1430 0 : do_copy()
1431 0 : { return new Sink_expression(this->location()); }
1432 :
1433 : Bexpression*
1434 : do_get_backend(Translate_context*);
1435 :
1436 : void
1437 : do_dump_expression(Ast_dump_context*) const;
1438 :
1439 : private:
1440 : // The type of this sink variable.
1441 : Type* type_;
1442 : // The temporary variable we generate.
1443 : Bvariable* bvar_;
1444 : };
1445 :
1446 : // Return the type of a sink expression.
1447 :
1448 : Type*
1449 189204 : Sink_expression::do_type()
1450 : {
1451 189204 : if (this->type_ == NULL)
1452 189204 : return Type::make_sink_type();
1453 : return this->type_;
1454 : }
1455 :
1456 : // Determine the type of a sink expression.
1457 :
1458 : void
1459 63873 : Sink_expression::do_determine_type(Gogo*, const Type_context* context)
1460 : {
1461 63873 : if (context->type != NULL)
1462 0 : this->type_ = context->type;
1463 63873 : }
1464 :
1465 : // Return a temporary variable for a sink expression. This will
1466 : // presumably be a write-only variable which the middle-end will drop.
1467 :
1468 : Bexpression*
1469 0 : Sink_expression::do_get_backend(Translate_context* context)
1470 : {
1471 0 : Location loc = this->location();
1472 0 : Gogo* gogo = context->gogo();
1473 0 : if (this->bvar_ == NULL)
1474 : {
1475 0 : if (this->type_ == NULL || this->type_->is_sink_type())
1476 : {
1477 0 : go_assert(saw_errors());
1478 0 : return gogo->backend()->error_expression();
1479 : }
1480 :
1481 0 : Named_object* fn = context->function();
1482 0 : go_assert(fn != NULL);
1483 0 : Bfunction* fn_ctx = fn->func_value()->get_or_make_decl(gogo, fn);
1484 0 : Btype* bt = this->type_->get_backend(context->gogo());
1485 0 : Bstatement* decl;
1486 0 : this->bvar_ =
1487 0 : gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL,
1488 : 0, loc, &decl);
1489 0 : Bexpression* var_ref =
1490 0 : gogo->backend()->var_expression(this->bvar_, loc);
1491 0 : var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
1492 0 : return var_ref;
1493 : }
1494 0 : return gogo->backend()->var_expression(this->bvar_, loc);
1495 : }
1496 :
1497 : // Ast dump for sink expression.
1498 :
1499 : void
1500 0 : Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1501 : {
1502 0 : ast_dump_context->ostream() << "_" ;
1503 0 : }
1504 :
1505 : // Make a sink expression.
1506 :
1507 : Expression*
1508 27627 : Expression::make_sink(Location location)
1509 : {
1510 27627 : return new Sink_expression(location);
1511 : }
1512 :
1513 : // Class Func_expression.
1514 :
1515 : // FIXME: Can a function expression appear in a constant expression?
1516 : // The value is unchanging. Initializing a constant to the address of
1517 : // a function seems like it could work, though there might be little
1518 : // point to it.
1519 :
1520 : // Traversal.
1521 :
1522 : int
1523 14463672 : Func_expression::do_traverse(Traverse* traverse)
1524 : {
1525 14463672 : return (this->closure_ == NULL
1526 14463672 : ? TRAVERSE_CONTINUE
1527 232320 : : Expression::traverse(&this->closure_, traverse));
1528 : }
1529 :
1530 : // Return the type of a function expression.
1531 :
1532 : Type*
1533 24389210 : Func_expression::do_type()
1534 : {
1535 24389210 : if (this->function_->is_function())
1536 11179566 : return this->function_->func_value()->type();
1537 13209644 : else if (this->function_->is_function_declaration())
1538 13209644 : return this->function_->func_declaration_value()->type();
1539 : else
1540 0 : go_unreachable();
1541 : }
1542 :
1543 : // Get the backend representation for the code of a function expression.
1544 :
1545 : Bexpression*
1546 2137860 : Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc)
1547 : {
1548 2137860 : Function_type* fntype;
1549 2137860 : if (no->is_function())
1550 612754 : fntype = no->func_value()->type();
1551 1525106 : else if (no->is_function_declaration())
1552 1525106 : fntype = no->func_declaration_value()->type();
1553 : else
1554 0 : go_unreachable();
1555 :
1556 : // Builtin functions are handled specially by Call_expression. We
1557 : // can't take their address.
1558 2137860 : if (fntype->is_builtin())
1559 : {
1560 0 : go_error_at(loc,
1561 : ("invalid use of special built-in function %qs; "
1562 : "must be called"),
1563 0 : no->message_name().c_str());
1564 0 : return gogo->backend()->error_expression();
1565 : }
1566 :
1567 2137860 : Bfunction* fndecl;
1568 2137860 : if (no->is_function())
1569 612754 : fndecl = no->func_value()->get_or_make_decl(gogo, no);
1570 1525106 : else if (no->is_function_declaration())
1571 1525106 : fndecl = no->func_declaration_value()->get_or_make_decl(gogo, no);
1572 : else
1573 : go_unreachable();
1574 :
1575 2137860 : return gogo->backend()->function_code_expression(fndecl, loc);
1576 : }
1577 :
1578 : // Get the backend representation for a function expression. This is used when
1579 : // we take the address of a function rather than simply calling it. A func
1580 : // value is represented as a pointer to a block of memory. The first
1581 : // word of that memory is a pointer to the function code. The
1582 : // remaining parts of that memory are the addresses of variables that
1583 : // the function closes over.
1584 :
1585 : Bexpression*
1586 155520 : Func_expression::do_get_backend(Translate_context* context)
1587 : {
1588 : // If there is no closure, just use the function descriptor.
1589 155520 : if (this->closure_ == NULL)
1590 : {
1591 142718 : Gogo* gogo = context->gogo();
1592 142718 : Named_object* no = this->function_;
1593 142718 : Expression* descriptor;
1594 142718 : if (no->is_function())
1595 37923 : descriptor = no->func_value()->descriptor(gogo, no);
1596 104795 : else if (no->is_function_declaration())
1597 : {
1598 104795 : if (no->func_declaration_value()->type()->is_builtin())
1599 : {
1600 1 : go_error_at(this->location(),
1601 : ("invalid use of special built-in function %qs; "
1602 : "must be called"),
1603 1 : no->message_name().c_str());
1604 1 : return gogo->backend()->error_expression();
1605 : }
1606 104794 : descriptor = no->func_declaration_value()->descriptor(gogo, no);
1607 : }
1608 : else
1609 0 : go_unreachable();
1610 :
1611 142717 : Bexpression* bdesc = descriptor->get_backend(context);
1612 142717 : return gogo->backend()->address_expression(bdesc, this->location());
1613 : }
1614 :
1615 12802 : go_assert(this->function_->func_value()->enclosing() != NULL);
1616 :
1617 : // If there is a closure, then the closure is itself the function
1618 : // expression. It is a pointer to a struct whose first field points
1619 : // to the function code and whose remaining fields are the addresses
1620 : // of the closed-over variables.
1621 12802 : Bexpression *bexpr = this->closure_->get_backend(context);
1622 :
1623 : // Introduce a backend type conversion, to account for any differences
1624 : // between the argument type (function descriptor, struct with a
1625 : // single field) and the closure (struct with multiple fields).
1626 12802 : Gogo* gogo = context->gogo();
1627 12802 : Btype *btype = this->type()->get_backend(gogo);
1628 12802 : return gogo->backend()->convert_expression(btype, bexpr, this->location());
1629 : }
1630 :
1631 : // The cost of inlining a function reference.
1632 :
1633 : int
1634 570556 : Func_expression::do_inlining_cost() const
1635 : {
1636 : // FIXME: We don't inline references to nested functions.
1637 570556 : if (this->closure_ != NULL)
1638 : return 0x100000;
1639 560412 : if (this->function_->is_function()
1640 560412 : && this->function_->func_value()->enclosing() != NULL)
1641 2780 : return 0x100000;
1642 :
1643 : return 1;
1644 : }
1645 :
1646 : // Export a reference to a function.
1647 :
1648 : void
1649 10918 : Func_expression::do_export(Export_function_body* efb) const
1650 : {
1651 10918 : Expression::export_name(efb, this->function_);
1652 10918 : }
1653 :
1654 : // Ast dump for function.
1655 :
1656 : void
1657 0 : Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
1658 : {
1659 0 : ast_dump_context->ostream() << this->function_->name();
1660 0 : if (this->closure_ != NULL)
1661 : {
1662 0 : ast_dump_context->ostream() << " {closure = ";
1663 0 : this->closure_->dump_expression(ast_dump_context);
1664 0 : ast_dump_context->ostream() << "}";
1665 : }
1666 0 : }
1667 :
1668 : // Make a reference to a function in an expression.
1669 :
1670 : Expression*
1671 2156076 : Expression::make_func_reference(Named_object* function, Expression* closure,
1672 : Location location)
1673 : {
1674 2156076 : Func_expression* fe = new Func_expression(function, closure, location);
1675 :
1676 : // Detect references to builtin functions and set the runtime code if
1677 : // appropriate.
1678 2156076 : if (function->is_function_declaration())
1679 1798779 : fe->set_runtime_code(Runtime::name_to_code(function->name()));
1680 2156076 : return fe;
1681 : }
1682 :
1683 : // Class Func_descriptor_expression.
1684 :
1685 : // Constructor.
1686 :
1687 259784 : Func_descriptor_expression::Func_descriptor_expression(Named_object* fn)
1688 : : Expression(EXPRESSION_FUNC_DESCRIPTOR, fn->location()),
1689 259784 : fn_(fn), dvar_(NULL)
1690 : {
1691 259784 : go_assert(!fn->is_function() || !fn->func_value()->needs_closure());
1692 259784 : }
1693 :
1694 : // Traversal.
1695 :
1696 : int
1697 0 : Func_descriptor_expression::do_traverse(Traverse*)
1698 : {
1699 0 : return TRAVERSE_CONTINUE;
1700 : }
1701 :
1702 : // All function descriptors have the same type.
1703 :
1704 : Type* Func_descriptor_expression::descriptor_type;
1705 :
1706 : void
1707 408426 : Func_descriptor_expression::make_func_descriptor_type()
1708 : {
1709 408426 : if (Func_descriptor_expression::descriptor_type != NULL)
1710 : return;
1711 4646 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
1712 4646 : Type* struct_type = Type::make_builtin_struct_type(1, "fn", uintptr_type);
1713 4646 : Func_descriptor_expression::descriptor_type =
1714 4646 : Type::make_builtin_named_type("functionDescriptor", struct_type);
1715 : }
1716 :
1717 : Type*
1718 403780 : Func_descriptor_expression::do_type()
1719 : {
1720 403780 : Func_descriptor_expression::make_func_descriptor_type();
1721 403780 : return Func_descriptor_expression::descriptor_type;
1722 : }
1723 :
1724 : // The backend representation for a function descriptor.
1725 :
1726 : Bexpression*
1727 298003 : Func_descriptor_expression::do_get_backend(Translate_context* context)
1728 : {
1729 298003 : Named_object* no = this->fn_;
1730 298003 : Location loc = no->location();
1731 298003 : if (this->dvar_ != NULL)
1732 38228 : return context->backend()->var_expression(this->dvar_, loc);
1733 :
1734 259775 : Gogo* gogo = context->gogo();
1735 259775 : Backend_name bname;
1736 259775 : gogo->function_descriptor_backend_name(no, &bname);
1737 259775 : bool is_descriptor = false;
1738 259775 : if (no->is_function_declaration()
1739 105139 : && !no->func_declaration_value()->asm_name().empty()
1740 349886 : && Linemap::is_predeclared_location(no->location()))
1741 : is_descriptor = true;
1742 :
1743 : // The runtime package implements some functions defined in the
1744 : // syscall package. Let the syscall package define the descriptor
1745 : // in this case.
1746 259775 : if (gogo->compiling_runtime()
1747 21484 : && gogo->package_name() == "runtime"
1748 14786 : && no->is_function()
1749 5496 : && !no->func_value()->asm_name().empty()
1750 263620 : && no->func_value()->asm_name().compare(0, 8, "syscall.") == 0)
1751 : is_descriptor = true;
1752 :
1753 259775 : Btype* btype = this->type()->get_backend(gogo);
1754 :
1755 259775 : Bvariable* bvar;
1756 259775 : if (no->package() != NULL || is_descriptor)
1757 115770 : bvar =
1758 115770 : context->backend()->immutable_struct_reference(bname.name(),
1759 231540 : bname.optional_asm_name(),
1760 : btype, loc);
1761 : else
1762 : {
1763 144005 : Location bloc = Linemap::predeclared_location();
1764 :
1765 : // The runtime package has hash/equality functions that are
1766 : // referenced by type descriptors outside of the runtime, so the
1767 : // function descriptors must be visible even though they are not
1768 : // exported.
1769 144005 : bool is_exported_runtime = false;
1770 144005 : if (gogo->compiling_runtime()
1771 8866 : && gogo->package_name() == "runtime"
1772 149465 : && (no->name().find("hash") != std::string::npos
1773 5355 : || no->name().find("equal") != std::string::npos))
1774 : is_exported_runtime = true;
1775 :
1776 144005 : bool is_hidden = ((no->is_function()
1777 143355 : && no->func_value()->enclosing() != NULL)
1778 133240 : || (Gogo::is_hidden_name(no->name())
1779 7957 : && !is_exported_runtime)
1780 269491 : || Gogo::is_thunk(no));
1781 :
1782 144005 : if (no->is_function() && no->func_value()->is_referenced_by_inline())
1783 : is_hidden = false;
1784 :
1785 142409 : unsigned int flags = 0;
1786 142409 : if (is_hidden)
1787 144005 : flags |= Backend::variable_is_hidden;
1788 144005 : bvar = context->backend()->immutable_struct(bname.name(),
1789 144005 : bname.optional_asm_name(),
1790 : flags, btype, bloc);
1791 144005 : Expression_list* vals = new Expression_list();
1792 144005 : vals->push_back(Expression::make_func_code_reference(this->fn_, bloc));
1793 144005 : Expression* init =
1794 144005 : Expression::make_struct_composite_literal(this->type(), vals, bloc);
1795 144005 : Translate_context bcontext(gogo, NULL, NULL, NULL);
1796 144005 : bcontext.set_is_const();
1797 144005 : Bexpression* binit = init->get_backend(&bcontext);
1798 144005 : context->backend()->immutable_struct_set_init(bvar, bname.name(),
1799 : flags, btype, bloc, binit);
1800 : }
1801 :
1802 259775 : this->dvar_ = bvar;
1803 259775 : return gogo->backend()->var_expression(bvar, loc);
1804 259775 : }
1805 :
1806 : // Print a function descriptor expression.
1807 :
1808 : void
1809 0 : Func_descriptor_expression::do_dump_expression(Ast_dump_context* context) const
1810 : {
1811 0 : context->ostream() << "[descriptor " << this->fn_->name() << "]";
1812 0 : }
1813 :
1814 : // Make a function descriptor expression.
1815 :
1816 : Func_descriptor_expression*
1817 259784 : Expression::make_func_descriptor(Named_object* fn)
1818 : {
1819 259784 : return new Func_descriptor_expression(fn);
1820 : }
1821 :
1822 : // Make the function descriptor type, so that it can be converted.
1823 :
1824 : void
1825 4646 : Expression::make_func_descriptor_type()
1826 : {
1827 4646 : Func_descriptor_expression::make_func_descriptor_type();
1828 4646 : }
1829 :
1830 : // A reference to just the code of a function.
1831 :
1832 : class Func_code_reference_expression : public Expression
1833 : {
1834 : public:
1835 2357830 : Func_code_reference_expression(Named_object* function, Location location)
1836 2357830 : : Expression(EXPRESSION_FUNC_CODE_REFERENCE, location),
1837 4715660 : function_(function)
1838 : { }
1839 :
1840 : protected:
1841 : int
1842 221665 : do_traverse(Traverse*)
1843 221665 : { return TRAVERSE_CONTINUE; }
1844 :
1845 : bool
1846 318868 : do_is_static_initializer() const
1847 318868 : { return true; }
1848 :
1849 : Type*
1850 457275 : do_type()
1851 457275 : { return Type::make_pointer_type(Type::make_void_type()); }
1852 :
1853 : void
1854 549002 : do_determine_type(Gogo*, const Type_context*)
1855 549002 : { }
1856 :
1857 : Expression*
1858 0 : do_copy()
1859 : {
1860 0 : return Expression::make_func_code_reference(this->function_,
1861 0 : this->location());
1862 : }
1863 :
1864 : Bexpression*
1865 : do_get_backend(Translate_context*);
1866 :
1867 : void
1868 0 : do_dump_expression(Ast_dump_context* context) const
1869 0 : { context->ostream() << "[raw " << this->function_->name() << "]" ; }
1870 :
1871 : private:
1872 : // The function.
1873 : Named_object* function_;
1874 : };
1875 :
1876 : // Get the backend representation for a reference to function code.
1877 :
1878 : Bexpression*
1879 2137860 : Func_code_reference_expression::do_get_backend(Translate_context* context)
1880 : {
1881 2137860 : return Func_expression::get_code_pointer(context->gogo(), this->function_,
1882 2137860 : this->location());
1883 : }
1884 :
1885 : // Make a reference to the code of a function.
1886 :
1887 : Expression*
1888 2357830 : Expression::make_func_code_reference(Named_object* function, Location location)
1889 : {
1890 2357830 : return new Func_code_reference_expression(function, location);
1891 : }
1892 :
1893 : // Class Unknown_expression.
1894 :
1895 : // Return the name of an unknown expression.
1896 :
1897 : const std::string&
1898 5232 : Unknown_expression::name() const
1899 : {
1900 5232 : return this->named_object_->name();
1901 : }
1902 :
1903 : // Set the iota value if this could be a reference to iota.
1904 :
1905 : void
1906 17225 : Unknown_expression::set_iota_value(int iota_value)
1907 : {
1908 17225 : this->iota_value_ = iota_value;
1909 17225 : this->is_iota_ = true;
1910 17225 : }
1911 :
1912 : // Traversal.
1913 :
1914 : int
1915 2179207 : Unknown_expression::do_traverse(Traverse* traverse)
1916 : {
1917 2179207 : if (this->lowered_ != NULL)
1918 : {
1919 1131206 : if (Expression::traverse(&this->lowered_, traverse) == TRAVERSE_EXIT)
1920 : return TRAVERSE_EXIT;
1921 : }
1922 : return TRAVERSE_CONTINUE;
1923 : }
1924 :
1925 : // Determine the type of a reference to an unknown name. At this
1926 : // point we have to figure out what the name refers to.
1927 :
1928 : void
1929 451116 : Unknown_expression::do_determine_type(Gogo* gogo, const Type_context* context)
1930 : {
1931 451116 : if (this->is_error_expression())
1932 11143 : return;
1933 :
1934 451116 : if (this->lowered_ != NULL)
1935 : {
1936 11097 : this->lowered_->determine_type(gogo, context);
1937 11097 : return;
1938 : }
1939 :
1940 440019 : Location loc = this->location();
1941 :
1942 440019 : Named_object* no = this->named_object_;
1943 440019 : if (no->is_unknown())
1944 : {
1945 439491 : Named_object* real = no->unknown_value()->real_named_object();
1946 439491 : if (real == NULL)
1947 : {
1948 46 : if (!this->no_error_message_)
1949 45 : go_error_at(loc, "reference to undefined name %qs",
1950 90 : no->message_name().c_str());
1951 46 : this->set_is_error();
1952 46 : return;
1953 : }
1954 439445 : no = real;
1955 439445 : this->named_object_ = real;
1956 : }
1957 :
1958 439973 : switch (no->classification())
1959 : {
1960 91849 : case Named_object::NAMED_OBJECT_TYPE:
1961 91849 : this->lowered_ = Expression::make_type(no->type_value(), loc);
1962 91849 : break;
1963 70720 : case Named_object::NAMED_OBJECT_FUNC:
1964 70720 : case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
1965 70720 : this->lowered_ = Expression::make_func_reference(no, NULL, loc);
1966 70720 : break;
1967 256281 : case Named_object::NAMED_OBJECT_CONST:
1968 256281 : this->lowered_ = Expression::make_const_reference(no, loc);
1969 256281 : this->lowered_->determine_type(gogo, context);
1970 256281 : if (this->is_iota_)
1971 11 : this->lowered_->const_expression()->set_iota_value(this->iota_value_);
1972 : break;
1973 21123 : case Named_object::NAMED_OBJECT_VAR:
1974 21123 : this->lowered_ = Expression::make_var_reference(no, loc);
1975 21123 : no->var_value()->set_is_used();
1976 21123 : this->lowered_->determine_type(gogo, context);
1977 21123 : break;
1978 0 : case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
1979 0 : if (!this->no_error_message_)
1980 0 : go_error_at(this->location(), "reference to undefined type %qs",
1981 0 : no->message_name().c_str());
1982 0 : this->set_is_error();
1983 0 : break;
1984 0 : case Named_object::NAMED_OBJECT_PACKAGE:
1985 0 : if (!this->no_error_message_)
1986 0 : this->report_error(_("unexpected reference to package"));
1987 0 : this->set_is_error();
1988 0 : break;
1989 0 : default:
1990 0 : go_unreachable();
1991 : }
1992 : }
1993 :
1994 : Type*
1995 1083816 : Unknown_expression::do_type()
1996 : {
1997 1083816 : if (this->is_error_expression())
1998 55 : return Type::make_error_type();
1999 1083761 : go_assert(this->lowered_ != NULL);
2000 1083761 : return this->lowered_->type();
2001 : }
2002 :
2003 : bool
2004 111569 : Unknown_expression::do_is_constant() const
2005 : {
2006 111569 : if (this->is_error_expression())
2007 : return true;
2008 111563 : if (this->lowered_ != NULL)
2009 17914 : return this->lowered_->is_constant();
2010 :
2011 : // This can be called before do_determine_types by
2012 : // Binary_expression::do_determine_type, which needs to know which
2013 : // values are constant before it works out the appropriate
2014 : // Type_context to pass down.
2015 93649 : Named_object* no = this->named_object_;
2016 93649 : if (no->is_unknown())
2017 : {
2018 93649 : no = no->unknown_value()->real_named_object();
2019 93649 : if (no == NULL)
2020 : return true;
2021 : }
2022 93644 : return no->is_const();
2023 : }
2024 :
2025 : bool
2026 94096 : Unknown_expression::do_is_untyped(Type** ptype) const
2027 : {
2028 94096 : if (this->is_error_expression())
2029 : return false;
2030 94096 : if (this->lowered_ != NULL)
2031 0 : return this->lowered_->is_untyped(ptype);
2032 :
2033 94096 : Named_object* no = this->named_object_;
2034 94096 : if (no->is_unknown())
2035 : {
2036 94096 : no = no->unknown_value()->real_named_object();
2037 94096 : if (no == NULL)
2038 : return false;
2039 : }
2040 :
2041 94091 : if (!no->is_const())
2042 : return false;
2043 92796 : Type* t = no->const_value()->type();
2044 92796 : if (t != NULL)
2045 87680 : return Expression::is_untyped_type(t, ptype);
2046 5116 : return no->const_value()->expr()->is_untyped(ptype);
2047 : }
2048 :
2049 : bool
2050 69210 : Unknown_expression::do_numeric_constant_value(Numeric_constant* nc)
2051 : {
2052 69210 : if (this->is_error_expression())
2053 : return false;
2054 69210 : if (this->lowered_ != NULL)
2055 69138 : return this->lowered_->numeric_constant_value(nc);
2056 :
2057 : // This can be called before the determine_types pass.
2058 72 : Named_object* no = this->named_object_;
2059 72 : if (no->is_unknown())
2060 : {
2061 72 : no = no->unknown_value()->real_named_object();
2062 72 : if (no == NULL)
2063 : return false;
2064 : }
2065 72 : if (!no->is_const())
2066 : return false;
2067 72 : return no->const_value()->expr()->numeric_constant_value(nc);
2068 : }
2069 :
2070 : bool
2071 259 : Unknown_expression::do_string_constant_value(std::string* val)
2072 : {
2073 259 : if (this->is_error_expression())
2074 : return false;
2075 259 : go_assert(this->lowered_ != NULL);
2076 259 : return this->lowered_->string_constant_value(val);
2077 : }
2078 :
2079 : bool
2080 0 : Unknown_expression::do_boolean_constant_value(bool* val)
2081 : {
2082 0 : if (this->is_error_expression())
2083 : return false;
2084 0 : go_assert(this->lowered_ != NULL);
2085 0 : return this->lowered_->boolean_constant_value(val);
2086 : }
2087 :
2088 : bool
2089 12895 : Unknown_expression::do_is_addressable() const
2090 : {
2091 12895 : if (this->is_error_expression())
2092 : return true;
2093 12893 : go_assert(this->lowered_ != NULL);
2094 12893 : return this->lowered_->is_addressable();
2095 : }
2096 :
2097 : // Lower a reference to an unknown name.
2098 :
2099 : Expression*
2100 358115 : Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
2101 : {
2102 358115 : if (this->is_error_expression())
2103 29 : return Expression::make_error(this->location());
2104 358086 : go_assert(this->lowered_ != NULL);
2105 : return this->lowered_;
2106 : }
2107 :
2108 : // Dump the ast representation for an unknown expression to a dump context.
2109 :
2110 : void
2111 0 : Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2112 : {
2113 0 : if (this->lowered_ != NULL)
2114 0 : this->lowered_->dump_expression(ast_dump_context);
2115 : else
2116 0 : ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
2117 0 : << ")";
2118 0 : }
2119 :
2120 : // Make a reference to an unknown name.
2121 :
2122 : Unknown_expression*
2123 592258 : Expression::make_unknown_reference(Named_object* no, Location location)
2124 : {
2125 592258 : return new Unknown_expression(no, location);
2126 : }
2127 :
2128 : // Start exporting a type conversion for a constant, if needed. This
2129 : // returns whether we need to export a closing parenthesis.
2130 :
2131 : bool
2132 65870 : Expression::export_constant_type(Export_function_body* efb, Type* type)
2133 : {
2134 65870 : if (type == NULL
2135 62463 : || type->is_abstract()
2136 96198 : || type == efb->type_context())
2137 52364 : return false;
2138 13506 : efb->write_c_string("$convert(");
2139 13506 : efb->write_type(type);
2140 13506 : efb->write_c_string(", ");
2141 13506 : return true;
2142 : }
2143 :
2144 : // Finish a type conversion for a constant.
2145 :
2146 : void
2147 65870 : Expression::finish_export_constant_type(Export_function_body* efb, bool needed)
2148 : {
2149 65870 : if (needed)
2150 13506 : efb->write_c_string(")");
2151 65870 : }
2152 :
2153 : // A boolean expression.
2154 :
2155 : class Boolean_expression : public Expression
2156 : {
2157 : public:
2158 594735 : Boolean_expression(bool val, Location location)
2159 594735 : : Expression(EXPRESSION_BOOLEAN, location),
2160 1189470 : val_(val), type_(NULL)
2161 : { }
2162 :
2163 : static Expression*
2164 : do_import(Import_expression*, Location);
2165 :
2166 : protected:
2167 : int
2168 : do_traverse(Traverse*);
2169 :
2170 : bool
2171 24916 : do_is_constant() const
2172 24916 : { return true; }
2173 :
2174 : bool
2175 : do_is_untyped(Type**) const;
2176 :
2177 : bool
2178 0 : do_is_zero_value() const
2179 0 : { return this->val_ == false; }
2180 :
2181 : bool
2182 9479 : do_boolean_constant_value(bool* val)
2183 : {
2184 9479 : *val = this->val_;
2185 9479 : return true;
2186 : }
2187 :
2188 : bool
2189 11 : do_is_static_initializer() const
2190 11 : { return true; }
2191 :
2192 : Type*
2193 : do_type();
2194 :
2195 : void
2196 : do_determine_type(Gogo*, const Type_context*);
2197 :
2198 : Expression*
2199 0 : do_copy()
2200 0 : { return this; }
2201 :
2202 : Bexpression*
2203 652831 : do_get_backend(Translate_context* context)
2204 652831 : { return context->backend()->boolean_constant_expression(this->val_); }
2205 :
2206 : int
2207 47347 : do_inlining_cost() const
2208 47347 : { return 1; }
2209 :
2210 : void
2211 : do_export(Export_function_body* efb) const;
2212 :
2213 : void
2214 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
2215 0 : { ast_dump_context->ostream() << (this->val_ ? "true" : "false"); }
2216 :
2217 : private:
2218 : // The constant.
2219 : bool val_;
2220 : // The type as determined by context.
2221 : Type* type_;
2222 : };
2223 :
2224 : // Traverse a boolean expression. We just need to traverse the type
2225 : // if there is one.
2226 :
2227 : int
2228 1399401 : Boolean_expression::do_traverse(Traverse* traverse)
2229 : {
2230 1399401 : if (this->type_ != NULL)
2231 1364439 : return Type::traverse(this->type_, traverse);
2232 : return TRAVERSE_CONTINUE;
2233 : }
2234 :
2235 : bool
2236 24131 : Boolean_expression::do_is_untyped(Type** ptype) const
2237 : {
2238 24131 : if (this->type_ != NULL)
2239 44 : return Expression::is_untyped_type(this->type_, ptype);
2240 24087 : *ptype = Type::make_boolean_type();
2241 24087 : return true;
2242 : }
2243 :
2244 : // Get the type.
2245 :
2246 : Type*
2247 1545765 : Boolean_expression::do_type()
2248 : {
2249 1545765 : if (this->type_ == NULL)
2250 15257 : this->type_ = Type::make_boolean_type();
2251 1545765 : return this->type_;
2252 : }
2253 :
2254 : // Set the type from the context.
2255 :
2256 : void
2257 656191 : Boolean_expression::do_determine_type(Gogo*, const Type_context* context)
2258 : {
2259 656191 : if (this->type_ != NULL && !this->type_->is_abstract())
2260 : ;
2261 566862 : else if (context->type != NULL && context->type->is_boolean_type())
2262 189034 : this->type_ = context->type;
2263 377828 : else if (!context->may_be_abstract)
2264 377185 : this->type_ = Type::lookup_bool_type();
2265 656191 : }
2266 :
2267 : // Export a boolean constant.
2268 :
2269 : void
2270 3836 : Boolean_expression::do_export(Export_function_body* efb) const
2271 : {
2272 3836 : bool exported_type = Expression::export_constant_type(efb, this->type_);
2273 5839 : efb->write_c_string(this->val_ ? "$true" : "$false");
2274 3836 : Expression::finish_export_constant_type(efb, exported_type);
2275 3836 : }
2276 :
2277 : // Import a boolean constant.
2278 :
2279 : Expression*
2280 2859 : Boolean_expression::do_import(Import_expression* imp, Location loc)
2281 : {
2282 2859 : if (imp->version() >= EXPORT_FORMAT_V3)
2283 2859 : imp->require_c_string("$");
2284 2859 : if (imp->peek_char() == 't')
2285 : {
2286 1370 : imp->require_c_string("true");
2287 1370 : return Expression::make_boolean(true, loc);
2288 : }
2289 : else
2290 : {
2291 1489 : imp->require_c_string("false");
2292 1489 : return Expression::make_boolean(false, loc);
2293 : }
2294 : }
2295 :
2296 : // Make a boolean expression.
2297 :
2298 : Expression*
2299 594735 : Expression::make_boolean(bool val, Location location)
2300 : {
2301 594735 : return new Boolean_expression(val, location);
2302 : }
2303 :
2304 : // Class String_expression.
2305 :
2306 : // Traverse a string expression. We just need to traverse the type
2307 : // if there is one.
2308 :
2309 : int
2310 7998434 : String_expression::do_traverse(Traverse* traverse)
2311 : {
2312 7998434 : if (this->type_ != NULL)
2313 7103489 : return Type::traverse(this->type_, traverse);
2314 : return TRAVERSE_CONTINUE;
2315 : }
2316 :
2317 : bool
2318 102798683 : String_expression::do_is_untyped(Type** ptype) const
2319 : {
2320 102798683 : if (this->type_ != NULL)
2321 8255 : return Expression::is_untyped_type(this->type_, ptype);
2322 102790428 : *ptype = Type::make_string_type();
2323 102790428 : return true;
2324 : }
2325 :
2326 : // Get the type.
2327 :
2328 : Type*
2329 5384288 : String_expression::do_type()
2330 : {
2331 5384288 : if (this->type_ == NULL)
2332 17815 : this->type_ = Type::make_string_type();
2333 5384288 : return this->type_;
2334 : }
2335 :
2336 : // Set the type from the context.
2337 :
2338 : void
2339 2325620 : String_expression::do_determine_type(Gogo*, const Type_context* context)
2340 : {
2341 2325620 : if (this->type_ != NULL && !this->type_->is_abstract())
2342 : ;
2343 1587306 : else if (context->type != NULL && context->type->is_string_type())
2344 1540724 : this->type_ = context->type;
2345 46582 : else if (!context->may_be_abstract)
2346 28914 : this->type_ = Type::lookup_string_type();
2347 2325620 : }
2348 :
2349 : // Build a string constant.
2350 :
2351 : Bexpression*
2352 1012121 : String_expression::do_get_backend(Translate_context* context)
2353 : {
2354 1012121 : Gogo* gogo = context->gogo();
2355 1012121 : Btype* btype = Type::make_string_type()->get_backend(gogo);
2356 :
2357 1012121 : Location loc = this->location();
2358 1012121 : std::vector<Bexpression*> init(2);
2359 :
2360 1012121 : if (this->val_.size() == 0)
2361 25731 : init[0] = gogo->backend()->nil_pointer_expression();
2362 : else
2363 : {
2364 986390 : Bexpression* str_cst =
2365 986390 : gogo->backend()->string_constant_expression(this->val_);
2366 986390 : init[0] = gogo->backend()->address_expression(str_cst, loc);
2367 : }
2368 :
2369 1012121 : Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo);
2370 1012121 : mpz_t lenval;
2371 1012121 : mpz_init_set_ui(lenval, this->val_.length());
2372 1012121 : init[1] = gogo->backend()->integer_constant_expression(int_btype, lenval);
2373 1012121 : mpz_clear(lenval);
2374 :
2375 1012121 : return gogo->backend()->constructor_expression(btype, init, loc);
2376 1012121 : }
2377 :
2378 : // Write string literal to string dump.
2379 :
2380 : void
2381 6474 : String_expression::export_string(String_dump* exp,
2382 : const String_expression* str)
2383 : {
2384 6474 : std::string s;
2385 6474 : s.reserve(str->val_.length() * 4 + 2);
2386 6474 : s += '"';
2387 175078 : for (std::string::const_iterator p = str->val_.begin();
2388 175078 : p != str->val_.end();
2389 168604 : ++p)
2390 : {
2391 168604 : if (*p == '\\' || *p == '"')
2392 : {
2393 6998 : s += '\\';
2394 6998 : s += *p;
2395 : }
2396 161606 : else if (*p >= 0x20 && *p < 0x7f)
2397 120717 : s += *p;
2398 40889 : else if (*p == '\n')
2399 1036 : s += "\\n";
2400 39853 : else if (*p == '\t')
2401 360 : s += "\\t";
2402 : else
2403 : {
2404 39493 : s += "\\x";
2405 39493 : unsigned char c = *p;
2406 39493 : unsigned int dig = c >> 4;
2407 39493 : s += dig < 10 ? '0' + dig : 'A' + dig - 10;
2408 39493 : dig = c & 0xf;
2409 39493 : s += dig < 10 ? '0' + dig : 'A' + dig - 10;
2410 : }
2411 : }
2412 6474 : s += '"';
2413 6474 : exp->write_string(s);
2414 6474 : }
2415 :
2416 : // Export a string expression.
2417 :
2418 : void
2419 6474 : String_expression::do_export(Export_function_body* efb) const
2420 : {
2421 6474 : bool exported_type = Expression::export_constant_type(efb, this->type_);
2422 6474 : String_expression::export_string(efb, this);
2423 6474 : Expression::finish_export_constant_type(efb, exported_type);
2424 6474 : }
2425 :
2426 : // Import a string expression.
2427 :
2428 : Expression*
2429 31862 : String_expression::do_import(Import_expression* imp, Location loc)
2430 : {
2431 31862 : imp->require_c_string("\"");
2432 31862 : std::string val;
2433 633891 : while (true)
2434 : {
2435 633891 : int c = imp->get_char();
2436 633891 : if (c == '"' || c == -1)
2437 : break;
2438 602029 : if (c != '\\')
2439 555673 : val += static_cast<char>(c);
2440 : else
2441 : {
2442 46356 : c = imp->get_char();
2443 46356 : if (c == '\\' || c == '"')
2444 19650 : val += static_cast<char>(c);
2445 26706 : else if (c == 'n')
2446 1074 : val += '\n';
2447 25632 : else if (c == 't')
2448 517 : val += '\t';
2449 25115 : else if (c == 'x')
2450 : {
2451 25115 : c = imp->get_char();
2452 25115 : unsigned int vh = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
2453 25115 : c = imp->get_char();
2454 25115 : unsigned int vl = c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
2455 25115 : char v = (vh << 4) | vl;
2456 25115 : val += v;
2457 : }
2458 : else
2459 : {
2460 0 : go_error_at(imp->location(), "bad string constant");
2461 0 : return Expression::make_error(loc);
2462 : }
2463 : }
2464 : }
2465 31862 : return Expression::make_string(val, loc);
2466 31862 : }
2467 :
2468 : // Ast dump for string expression.
2469 :
2470 : void
2471 0 : String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
2472 : {
2473 0 : String_expression::export_string(ast_dump_context, this);
2474 0 : }
2475 :
2476 : // Make a string expression with abstract string type (common case).
2477 :
2478 : Expression*
2479 1560200 : Expression::make_string(const std::string& val, Location location)
2480 : {
2481 1560200 : return new String_expression(val, NULL, location);
2482 : }
2483 :
2484 : // Make a string expression with a specific string type.
2485 :
2486 : Expression*
2487 38286 : Expression::make_string_typed(const std::string& val, Type* type, Location location)
2488 : {
2489 38286 : return new String_expression(val, type, location);
2490 : }
2491 :
2492 : // An expression that evaluates to some characteristic of a string.
2493 : // This is used when indexing, bound-checking, or nil checking a string.
2494 :
2495 : class String_info_expression : public Expression
2496 : {
2497 : public:
2498 441698 : String_info_expression(Expression* string, String_info string_info,
2499 : Location location)
2500 441698 : : Expression(EXPRESSION_STRING_INFO, location),
2501 883396 : string_(string), string_info_(string_info)
2502 : { }
2503 :
2504 : protected:
2505 : Type*
2506 : do_type();
2507 :
2508 : void
2509 755952 : do_determine_type(Gogo*, const Type_context*)
2510 755952 : { }
2511 :
2512 : Expression*
2513 140063 : do_copy()
2514 : {
2515 140063 : return new String_info_expression(this->string_->copy(), this->string_info_,
2516 140063 : this->location());
2517 : }
2518 :
2519 : Bexpression*
2520 : do_get_backend(Translate_context* context);
2521 :
2522 : void
2523 : do_dump_expression(Ast_dump_context*) const;
2524 :
2525 : void
2526 0 : do_issue_nil_check()
2527 0 : { this->string_->issue_nil_check(); }
2528 :
2529 : private:
2530 : // The string for which we are getting information.
2531 : Expression* string_;
2532 : // What information we want.
2533 : String_info string_info_;
2534 : };
2535 :
2536 : // Return the type of the string info.
2537 :
2538 : Type*
2539 1103159 : String_info_expression::do_type()
2540 : {
2541 1103159 : switch (this->string_info_)
2542 : {
2543 610412 : case STRING_INFO_DATA:
2544 610412 : {
2545 610412 : Type* byte_type = Type::lookup_integer_type("uint8");
2546 610412 : return Type::make_pointer_type(byte_type);
2547 : }
2548 492747 : case STRING_INFO_LENGTH:
2549 492747 : return Type::lookup_integer_type("int");
2550 0 : default:
2551 0 : go_unreachable();
2552 : }
2553 : }
2554 :
2555 : // Return string information in GENERIC.
2556 :
2557 : Bexpression*
2558 443347 : String_info_expression::do_get_backend(Translate_context* context)
2559 : {
2560 443347 : Gogo* gogo = context->gogo();
2561 :
2562 443347 : Bexpression* bstring = this->string_->get_backend(context);
2563 443347 : switch (this->string_info_)
2564 : {
2565 443347 : case STRING_INFO_DATA:
2566 443347 : case STRING_INFO_LENGTH:
2567 443347 : return gogo->backend()->struct_field_expression(bstring,
2568 : this->string_info_,
2569 443347 : this->location());
2570 0 : break;
2571 0 : default:
2572 0 : go_unreachable();
2573 : }
2574 : }
2575 :
2576 : // Dump ast representation for a type info expression.
2577 :
2578 : void
2579 0 : String_info_expression::do_dump_expression(
2580 : Ast_dump_context* ast_dump_context) const
2581 : {
2582 0 : ast_dump_context->ostream() << "stringinfo(";
2583 0 : this->string_->dump_expression(ast_dump_context);
2584 0 : ast_dump_context->ostream() << ",";
2585 0 : ast_dump_context->ostream() <<
2586 0 : (this->string_info_ == STRING_INFO_DATA ? "data"
2587 0 : : this->string_info_ == STRING_INFO_LENGTH ? "length"
2588 0 : : "unknown");
2589 0 : ast_dump_context->ostream() << ")";
2590 0 : }
2591 :
2592 : // Make a string info expression.
2593 :
2594 : Expression*
2595 301635 : Expression::make_string_info(Expression* string, String_info string_info,
2596 : Location location)
2597 : {
2598 301635 : return new String_info_expression(string, string_info, location);
2599 : }
2600 :
2601 : // An expression that represents an string value: a struct with value pointer
2602 : // and length fields.
2603 :
2604 : class String_value_expression : public Expression
2605 : {
2606 : public:
2607 1689 : String_value_expression(Expression* valptr, Expression* len, Location location)
2608 1689 : : Expression(EXPRESSION_STRING_VALUE, location),
2609 3378 : valptr_(valptr), len_(len)
2610 : { }
2611 :
2612 : protected:
2613 : int
2614 : do_traverse(Traverse*);
2615 :
2616 : Type*
2617 0 : do_type()
2618 0 : { return Type::make_string_type(); }
2619 :
2620 : void
2621 0 : do_determine_type(Gogo*, const Type_context*)
2622 0 : { go_unreachable(); }
2623 :
2624 : Expression*
2625 0 : do_copy()
2626 : {
2627 0 : return new String_value_expression(this->valptr_->copy(),
2628 0 : this->len_->copy(),
2629 0 : this->location());
2630 : }
2631 :
2632 : Bexpression*
2633 : do_get_backend(Translate_context* context);
2634 :
2635 : void
2636 : do_dump_expression(Ast_dump_context*) const;
2637 :
2638 : private:
2639 : // The value pointer.
2640 : Expression* valptr_;
2641 : // The length.
2642 : Expression* len_;
2643 : };
2644 :
2645 : int
2646 0 : String_value_expression::do_traverse(Traverse* traverse)
2647 : {
2648 0 : if (Expression::traverse(&this->valptr_, traverse) == TRAVERSE_EXIT
2649 0 : || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT)
2650 0 : return TRAVERSE_EXIT;
2651 : return TRAVERSE_CONTINUE;
2652 : }
2653 :
2654 : Bexpression*
2655 1689 : String_value_expression::do_get_backend(Translate_context* context)
2656 : {
2657 1689 : std::vector<Bexpression*> vals(2);
2658 1689 : vals[0] = this->valptr_->get_backend(context);
2659 1689 : vals[1] = this->len_->get_backend(context);
2660 :
2661 1689 : Gogo* gogo = context->gogo();
2662 1689 : Btype* btype = Type::make_string_type()->get_backend(gogo);
2663 1689 : return gogo->backend()->constructor_expression(btype, vals, this->location());
2664 1689 : }
2665 :
2666 : void
2667 0 : String_value_expression::do_dump_expression(
2668 : Ast_dump_context* ast_dump_context) const
2669 : {
2670 0 : ast_dump_context->ostream() << "stringvalue(";
2671 0 : ast_dump_context->ostream() << "value: ";
2672 0 : this->valptr_->dump_expression(ast_dump_context);
2673 0 : ast_dump_context->ostream() << ", length: ";
2674 0 : this->len_->dump_expression(ast_dump_context);
2675 0 : ast_dump_context->ostream() << ")";
2676 0 : }
2677 :
2678 : Expression*
2679 1689 : Expression::make_string_value(Expression* valptr, Expression* len,
2680 : Location location)
2681 : {
2682 1689 : return new String_value_expression(valptr, len, location);
2683 : }
2684 :
2685 : // Make an integer expression.
2686 :
2687 : class Integer_expression : public Expression
2688 : {
2689 : public:
2690 8465685 : Integer_expression(const mpz_t* val, Type* type, bool is_character_constant,
2691 : Location location)
2692 8465685 : : Expression(EXPRESSION_INTEGER, location),
2693 8465685 : type_(type), is_character_constant_(is_character_constant)
2694 8465685 : { mpz_init_set(this->val_, *val); }
2695 :
2696 : static Expression*
2697 : do_import(Import_expression*, Location);
2698 :
2699 : // Write VAL to string dump.
2700 : static void
2701 : export_integer(String_dump* exp, const mpz_t val);
2702 :
2703 : // Write VAL to dump context.
2704 : static void
2705 : dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val);
2706 :
2707 : protected:
2708 : int
2709 : do_traverse(Traverse*);
2710 :
2711 : bool
2712 3482869 : do_is_constant() const
2713 3482869 : { return true; }
2714 :
2715 : bool
2716 : do_is_untyped(Type**) const;
2717 :
2718 : bool
2719 448 : do_is_zero_value() const
2720 448 : { return mpz_sgn(this->val_) == 0; }
2721 :
2722 : bool
2723 1539153 : do_is_static_initializer() const
2724 1539153 : { return true; }
2725 :
2726 : bool
2727 : do_numeric_constant_value(Numeric_constant* nc);
2728 :
2729 : Type*
2730 : do_type();
2731 :
2732 : void
2733 : do_determine_type(Gogo*, const Type_context* context);
2734 :
2735 : void
2736 : do_check_types(Gogo*);
2737 :
2738 : Bexpression*
2739 : do_get_backend(Translate_context*);
2740 :
2741 : Expression*
2742 478159 : do_copy()
2743 : {
2744 478159 : if (this->is_character_constant_)
2745 241 : return Expression::make_character(&this->val_,
2746 121 : (this->type_ == NULL
2747 : ? NULL
2748 120 : : this->type_->copy_expressions()),
2749 121 : this->location());
2750 : else
2751 941087 : return Expression::make_integer_z(&this->val_,
2752 478038 : (this->type_ == NULL
2753 : ? NULL
2754 463049 : : this->type_->copy_expressions()),
2755 478038 : this->location());
2756 : }
2757 :
2758 : int
2759 1686006 : do_inlining_cost() const
2760 1686006 : { return 1; }
2761 :
2762 : void
2763 : do_export(Export_function_body*) const;
2764 :
2765 : void
2766 : do_dump_expression(Ast_dump_context*) const;
2767 :
2768 : private:
2769 : // The integer value.
2770 : mpz_t val_;
2771 : // The type so far.
2772 : Type* type_;
2773 : // Whether this is a character constant.
2774 : bool is_character_constant_;
2775 : };
2776 :
2777 : // Traverse an integer expression. We just need to traverse the type
2778 : // if there is one.
2779 :
2780 : int
2781 50913948 : Integer_expression::do_traverse(Traverse* traverse)
2782 : {
2783 50913948 : if (this->type_ != NULL)
2784 46071105 : return Type::traverse(this->type_, traverse);
2785 : return TRAVERSE_CONTINUE;
2786 : }
2787 :
2788 : // Return a numeric constant for this expression. We have to mark
2789 : // this as a character when appropriate.
2790 :
2791 : bool
2792 26537412 : Integer_expression::do_numeric_constant_value(Numeric_constant* nc)
2793 : {
2794 26537412 : if (this->is_character_constant_)
2795 37209 : nc->set_rune(this->type_, this->val_);
2796 : else
2797 26500203 : nc->set_int(this->type_, this->val_);
2798 26537412 : return true;
2799 : }
2800 :
2801 : bool
2802 1505715 : Integer_expression::do_is_untyped(Type** ptype) const
2803 : {
2804 1505715 : if (this->type_ != NULL)
2805 1195888 : return Expression::is_untyped_type(this->type_, ptype);
2806 309827 : if (this->is_character_constant_)
2807 16451 : *ptype = Type::make_abstract_character_type();
2808 : else
2809 293376 : *ptype = Type::make_abstract_integer_type();
2810 : return true;
2811 : }
2812 :
2813 : // Return the current type. If we haven't set the type yet, we return
2814 : // an abstract integer type.
2815 :
2816 : Type*
2817 20320332 : Integer_expression::do_type()
2818 : {
2819 20320332 : if (this->type_ == NULL)
2820 : {
2821 815511 : if (this->is_character_constant_)
2822 5997 : this->type_ = Type::make_abstract_character_type();
2823 : else
2824 809514 : this->type_ = Type::make_abstract_integer_type();
2825 : }
2826 20320332 : return this->type_;
2827 : }
2828 :
2829 : // Set the type of the integer value. Here we may switch from an
2830 : // abstract type to a real type.
2831 :
2832 : void
2833 6712823 : Integer_expression::do_determine_type(Gogo*, const Type_context* context)
2834 : {
2835 6712823 : if (this->type_ != NULL && !this->type_->is_abstract())
2836 : ;
2837 2489431 : else if (context->type != NULL && context->type->is_numeric_type())
2838 1647597 : this->type_ = context->type;
2839 841834 : else if (!context->may_be_abstract)
2840 : {
2841 41910 : if (this->is_character_constant_)
2842 361 : this->type_ = Type::lookup_integer_type("int32");
2843 : else
2844 41549 : this->type_ = Type::lookup_integer_type("int");
2845 : }
2846 6712823 : }
2847 :
2848 : // Check the type of an integer constant.
2849 :
2850 : void
2851 2467356 : Integer_expression::do_check_types(Gogo*)
2852 : {
2853 2467356 : Type* type = this->type_;
2854 2467356 : if (type == NULL)
2855 1 : return;
2856 2467355 : Numeric_constant nc;
2857 2467355 : if (this->is_character_constant_)
2858 54823 : nc.set_rune(NULL, this->val_);
2859 : else
2860 2412532 : nc.set_int(NULL, this->val_);
2861 2467355 : if (!nc.set_type(type, true, this->location()))
2862 28 : this->set_is_error();
2863 2467355 : }
2864 :
2865 : // Get the backend representation for an integer constant.
2866 :
2867 : Bexpression*
2868 6027983 : Integer_expression::do_get_backend(Translate_context* context)
2869 : {
2870 6027983 : if (this->is_error_expression()
2871 6027983 : || (this->type_ != NULL && this->type_->is_error_type()))
2872 : {
2873 0 : go_assert(saw_errors());
2874 0 : return context->gogo()->backend()->error_expression();
2875 : }
2876 :
2877 6027983 : Type* resolved_type = NULL;
2878 6027983 : if (this->type_ != NULL && !this->type_->is_abstract())
2879 5982471 : resolved_type = this->type_;
2880 45512 : else if (this->type_ != NULL && this->type_->float_type() != NULL)
2881 : {
2882 : // We are converting to an abstract floating point type.
2883 0 : resolved_type = Type::lookup_float_type("float64");
2884 : }
2885 45512 : else if (this->type_ != NULL && this->type_->complex_type() != NULL)
2886 : {
2887 : // We are converting to an abstract complex type.
2888 0 : resolved_type = Type::lookup_complex_type("complex128");
2889 : }
2890 : else
2891 : {
2892 : // If we still have an abstract type here, then this is being
2893 : // used in a constant expression which didn't get reduced for
2894 : // some reason. Use a type which will fit the value. We use <,
2895 : // not <=, because we need an extra bit for the sign bit.
2896 45512 : int bits = mpz_sizeinbase(this->val_, 2);
2897 45512 : Type* int_type = Type::lookup_integer_type("int");
2898 91024 : if (bits < int_type->integer_type()->bits())
2899 : resolved_type = int_type;
2900 1 : else if (bits < 64)
2901 0 : resolved_type = Type::lookup_integer_type("int64");
2902 : else
2903 : {
2904 1 : if (!saw_errors())
2905 1 : go_error_at(this->location(), "integer constant overflow");
2906 1 : return context->gogo()->backend()->error_expression();
2907 : }
2908 : }
2909 6027982 : Numeric_constant nc;
2910 6027982 : nc.set_int(resolved_type, this->val_);
2911 6027982 : return Expression::backend_numeric_constant_expression(context, &nc);
2912 6027982 : }
2913 :
2914 : // Write VAL to export data.
2915 :
2916 : void
2917 54986 : Integer_expression::export_integer(String_dump* exp, const mpz_t val)
2918 : {
2919 54986 : char* s = mpz_get_str(NULL, 10, val);
2920 54986 : exp->write_c_string(s);
2921 54986 : free(s);
2922 54986 : }
2923 :
2924 : // Export an integer in a constant expression.
2925 :
2926 : void
2927 54986 : Integer_expression::do_export(Export_function_body* efb) const
2928 : {
2929 54986 : bool exported_type = Expression::export_constant_type(efb, this->type_);
2930 :
2931 54986 : Integer_expression::export_integer(efb, this->val_);
2932 54986 : if (this->is_character_constant_)
2933 1421 : efb->write_c_string("'");
2934 : // A trailing space lets us reliably identify the end of the number.
2935 54986 : efb->write_c_string(" ");
2936 :
2937 54986 : Expression::finish_export_constant_type(efb, exported_type);
2938 54986 : }
2939 :
2940 : // Import an integer, floating point, or complex value. This handles
2941 : // all these types because they all start with digits.
2942 :
2943 : Expression*
2944 979371 : Integer_expression::do_import(Import_expression* imp, Location loc)
2945 : {
2946 979371 : std::string num = imp->read_identifier();
2947 979371 : imp->require_c_string(" ");
2948 1958742 : if (!num.empty() && num[num.length() - 1] == 'i')
2949 : {
2950 3 : mpfr_t real;
2951 3 : size_t plus_pos = num.find('+', 1);
2952 3 : size_t minus_pos = num.find('-', 1);
2953 3 : size_t pos;
2954 3 : if (plus_pos == std::string::npos)
2955 : pos = minus_pos;
2956 2 : else if (minus_pos == std::string::npos)
2957 : pos = plus_pos;
2958 : else
2959 : {
2960 0 : go_error_at(imp->location(), "bad number in import data: %qs",
2961 : num.c_str());
2962 0 : return Expression::make_error(loc);
2963 : }
2964 3 : if (pos == std::string::npos)
2965 0 : mpfr_init_set_ui(real, 0, MPFR_RNDN);
2966 : else
2967 : {
2968 3 : std::string real_str = num.substr(0, pos);
2969 3 : if (mpfr_init_set_str(real, real_str.c_str(), 10, MPFR_RNDN) != 0)
2970 : {
2971 0 : go_error_at(imp->location(), "bad number in import data: %qs",
2972 : real_str.c_str());
2973 0 : return Expression::make_error(loc);
2974 : }
2975 3 : }
2976 :
2977 3 : std::string imag_str;
2978 3 : if (pos == std::string::npos)
2979 0 : imag_str = num;
2980 : else
2981 3 : imag_str = num.substr(pos);
2982 3 : imag_str = imag_str.substr(0, imag_str.size() - 1);
2983 3 : mpfr_t imag;
2984 3 : if (mpfr_init_set_str(imag, imag_str.c_str(), 10, MPFR_RNDN) != 0)
2985 : {
2986 0 : go_error_at(imp->location(), "bad number in import data: %qs",
2987 : imag_str.c_str());
2988 0 : return Expression::make_error(loc);
2989 : }
2990 3 : mpc_t cval;
2991 3 : mpc_init2(cval, mpc_precision);
2992 3 : mpc_set_fr_fr(cval, real, imag, MPC_RNDNN);
2993 3 : mpfr_clear(real);
2994 3 : mpfr_clear(imag);
2995 3 : Expression* ret = Expression::make_complex(&cval, NULL, loc);
2996 3 : mpc_clear(cval);
2997 3 : return ret;
2998 3 : }
2999 979368 : else if (num.find('.') == std::string::npos
3000 979368 : && num.find('E') == std::string::npos)
3001 : {
3002 975115 : bool is_character_constant = (!num.empty()
3003 1950230 : && num[num.length() - 1] == '\'');
3004 6646 : if (is_character_constant)
3005 6646 : num = num.substr(0, num.length() - 1);
3006 975115 : mpz_t val;
3007 975115 : if (mpz_init_set_str(val, num.c_str(), 10) != 0)
3008 : {
3009 0 : go_error_at(imp->location(), "bad number in import data: %qs",
3010 : num.c_str());
3011 0 : return Expression::make_error(loc);
3012 : }
3013 975115 : Expression* ret;
3014 975115 : if (is_character_constant)
3015 6646 : ret = Expression::make_character(&val, NULL, loc);
3016 : else
3017 968469 : ret = Expression::make_integer_z(&val, NULL, loc);
3018 975115 : mpz_clear(val);
3019 975115 : return ret;
3020 : }
3021 : else
3022 : {
3023 4253 : mpfr_t val;
3024 4253 : if (mpfr_init_set_str(val, num.c_str(), 10, MPFR_RNDN) != 0)
3025 : {
3026 0 : go_error_at(imp->location(), "bad number in import data: %qs",
3027 : num.c_str());
3028 0 : return Expression::make_error(loc);
3029 : }
3030 4253 : Expression* ret = Expression::make_float(&val, NULL, loc);
3031 4253 : mpfr_clear(val);
3032 4253 : return ret;
3033 : }
3034 979371 : }
3035 : // Ast dump for integer expression.
3036 :
3037 : void
3038 0 : Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3039 : {
3040 0 : if (this->is_character_constant_)
3041 0 : ast_dump_context->ostream() << '\'';
3042 0 : Integer_expression::export_integer(ast_dump_context, this->val_);
3043 0 : if (this->is_character_constant_)
3044 0 : ast_dump_context->ostream() << '\'';
3045 0 : }
3046 :
3047 : // Build a new integer value from a multi-precision integer.
3048 :
3049 : Expression*
3050 8405501 : Expression::make_integer_z(const mpz_t* val, Type* type, Location location)
3051 : {
3052 8405501 : return new Integer_expression(val, type, false, location);
3053 : }
3054 :
3055 : // Build a new integer value from an unsigned long.
3056 :
3057 : Expression*
3058 4214610 : Expression::make_integer_ul(unsigned long val, Type *type, Location location)
3059 : {
3060 4214610 : mpz_t zval;
3061 4214610 : mpz_init_set_ui(zval, val);
3062 4214610 : Expression* ret = Expression::make_integer_z(&zval, type, location);
3063 4214610 : mpz_clear(zval);
3064 4214610 : return ret;
3065 : }
3066 :
3067 : // Build a new integer value from a signed long.
3068 :
3069 : Expression*
3070 16515 : Expression::make_integer_sl(long val, Type *type, Location location)
3071 : {
3072 16515 : mpz_t zval;
3073 16515 : mpz_init_set_si(zval, val);
3074 16515 : Expression* ret = Expression::make_integer_z(&zval, type, location);
3075 16515 : mpz_clear(zval);
3076 16515 : return ret;
3077 : }
3078 :
3079 : // Store an int64_t in an uninitialized mpz_t.
3080 :
3081 : static void
3082 1220049 : set_mpz_from_int64(mpz_t* zval, int64_t val)
3083 : {
3084 1220049 : if (val >= 0)
3085 : {
3086 1220049 : unsigned long ul = static_cast<unsigned long>(val);
3087 1220049 : if (static_cast<int64_t>(ul) == val)
3088 : {
3089 1220049 : mpz_init_set_ui(*zval, ul);
3090 1220049 : return;
3091 : }
3092 : }
3093 0 : uint64_t uv;
3094 0 : if (val >= 0)
3095 : uv = static_cast<uint64_t>(val);
3096 : else
3097 0 : uv = static_cast<uint64_t>(- val);
3098 0 : unsigned long ul = uv & 0xffffffffUL;
3099 0 : mpz_init_set_ui(*zval, ul);
3100 0 : mpz_t hval;
3101 0 : mpz_init_set_ui(hval, static_cast<unsigned long>(uv >> 32));
3102 0 : mpz_mul_2exp(hval, hval, 32);
3103 0 : mpz_add(*zval, *zval, hval);
3104 0 : mpz_clear(hval);
3105 0 : if (val < 0)
3106 0 : mpz_neg(*zval, *zval);
3107 : }
3108 :
3109 : // Build a new integer value from an int64_t.
3110 :
3111 : Expression*
3112 1217923 : Expression::make_integer_int64(int64_t val, Type* type, Location location)
3113 : {
3114 1217923 : mpz_t zval;
3115 1217923 : set_mpz_from_int64(&zval, val);
3116 1217923 : Expression* ret = Expression::make_integer_z(&zval, type, location);
3117 1217923 : mpz_clear(zval);
3118 1217923 : return ret;
3119 : }
3120 :
3121 : // Build a new character constant value.
3122 :
3123 : Expression*
3124 60184 : Expression::make_character(const mpz_t* val, Type* type, Location location)
3125 : {
3126 60184 : return new Integer_expression(val, type, true, location);
3127 : }
3128 :
3129 : // Floats.
3130 :
3131 : class Float_expression : public Expression
3132 : {
3133 : public:
3134 32243 : Float_expression(const mpfr_t* val, Type* type, Location location)
3135 32243 : : Expression(EXPRESSION_FLOAT, location),
3136 32243 : type_(type)
3137 : {
3138 32243 : mpfr_init_set(this->val_, *val, MPFR_RNDN);
3139 32243 : }
3140 :
3141 : // Write VAL to export data.
3142 : static void
3143 : export_float(String_dump* exp, const mpfr_t val);
3144 :
3145 : // Write VAL to dump file.
3146 : static void
3147 : dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
3148 :
3149 : protected:
3150 : int
3151 : do_traverse(Traverse*);
3152 :
3153 : bool
3154 17418 : do_is_constant() const
3155 17418 : { return true; }
3156 :
3157 : bool
3158 : do_is_untyped(Type**) const;
3159 :
3160 : bool
3161 4 : do_is_zero_value() const
3162 : {
3163 4 : return mpfr_zero_p(this->val_) != 0
3164 4 : && mpfr_signbit(this->val_) == 0;
3165 : }
3166 :
3167 : bool
3168 13963 : do_is_static_initializer() const
3169 13963 : { return true; }
3170 :
3171 : bool
3172 20066 : do_numeric_constant_value(Numeric_constant* nc)
3173 : {
3174 20066 : nc->set_float(this->type_, this->val_);
3175 20066 : return true;
3176 : }
3177 :
3178 : Type*
3179 : do_type();
3180 :
3181 : void
3182 : do_determine_type(Gogo*, const Type_context*);
3183 :
3184 : void
3185 : do_check_types(Gogo*);
3186 :
3187 : Expression*
3188 73 : do_copy()
3189 144 : { return Expression::make_float(&this->val_,
3190 73 : (this->type_ == NULL
3191 : ? NULL
3192 71 : : this->type_->copy_expressions()),
3193 73 : this->location()); }
3194 :
3195 : Bexpression*
3196 : do_get_backend(Translate_context*);
3197 :
3198 : int
3199 4765 : do_inlining_cost() const
3200 4765 : { return 1; }
3201 :
3202 : void
3203 : do_export(Export_function_body*) const;
3204 :
3205 : void
3206 : do_dump_expression(Ast_dump_context*) const;
3207 :
3208 : private:
3209 : // The floating point value.
3210 : mpfr_t val_;
3211 : // The type so far.
3212 : Type* type_;
3213 : };
3214 :
3215 : // Traverse a float expression. We just need to traverse the type if
3216 : // there is one.
3217 :
3218 : int
3219 431792 : Float_expression::do_traverse(Traverse* traverse)
3220 : {
3221 431792 : if (this->type_ != NULL)
3222 385194 : return Type::traverse(this->type_, traverse);
3223 : return TRAVERSE_CONTINUE;
3224 : }
3225 :
3226 : bool
3227 7828 : Float_expression::do_is_untyped(Type** ptype) const
3228 : {
3229 7828 : if (this->type_ != NULL)
3230 130 : return Expression::is_untyped_type(this->type_, ptype);
3231 7698 : *ptype = Type::make_abstract_float_type();
3232 7698 : return true;
3233 : }
3234 :
3235 : // Return the current type. If we haven't set the type yet, we return
3236 : // an abstract float type.
3237 :
3238 : Type*
3239 149905 : Float_expression::do_type()
3240 : {
3241 149905 : if (this->type_ == NULL)
3242 8272 : this->type_ = Type::make_abstract_float_type();
3243 149905 : return this->type_;
3244 : }
3245 :
3246 : // Set the type of the float value. Here we may switch from an
3247 : // abstract type to a real type.
3248 :
3249 : void
3250 31815 : Float_expression::do_determine_type(Gogo*, const Type_context* context)
3251 : {
3252 31815 : if (this->type_ != NULL && !this->type_->is_abstract())
3253 : ;
3254 26734 : else if (context->type != NULL
3255 26734 : && (context->type->integer_type() != NULL
3256 33750 : || context->type->float_type() != NULL
3257 18531 : || context->type->complex_type() != NULL))
3258 17567 : this->type_ = context->type;
3259 9167 : else if (!context->may_be_abstract)
3260 895 : this->type_ = Type::lookup_float_type("float64");
3261 31815 : }
3262 :
3263 : // Check the type of a float value.
3264 :
3265 : void
3266 26516 : Float_expression::do_check_types(Gogo*)
3267 : {
3268 26516 : Type* type = this->type_;
3269 26516 : if (type == NULL)
3270 1 : return;
3271 26515 : Numeric_constant nc;
3272 26515 : nc.set_float(NULL, this->val_);
3273 26515 : if (!nc.set_type(this->type_, true, this->location()))
3274 55 : this->set_is_error();
3275 26515 : }
3276 :
3277 : // Get the backend representation for a float constant.
3278 :
3279 : Bexpression*
3280 20531 : Float_expression::do_get_backend(Translate_context* context)
3281 : {
3282 20531 : if (this->is_error_expression()
3283 20531 : || (this->type_ != NULL && this->type_->is_error_type()))
3284 : {
3285 0 : go_assert(saw_errors());
3286 0 : return context->gogo()->backend()->error_expression();
3287 : }
3288 :
3289 20531 : Type* resolved_type;
3290 20531 : if (this->type_ != NULL && !this->type_->is_abstract())
3291 20512 : resolved_type = this->type_;
3292 19 : else if (this->type_ != NULL && this->type_->integer_type() != NULL)
3293 : {
3294 : // We have an abstract integer type. We just hope for the best.
3295 0 : resolved_type = Type::lookup_integer_type("int");
3296 : }
3297 19 : else if (this->type_ != NULL && this->type_->complex_type() != NULL)
3298 : {
3299 : // We are converting to an abstract complex type.
3300 0 : resolved_type = Type::lookup_complex_type("complex128");
3301 : }
3302 : else
3303 : {
3304 : // If we still have an abstract type here, then this is being
3305 : // used in a constant expression which didn't get reduced. We
3306 : // just use float64 and hope for the best.
3307 19 : resolved_type = Type::lookup_float_type("float64");
3308 : }
3309 :
3310 20531 : Numeric_constant nc;
3311 20531 : nc.set_float(resolved_type, this->val_);
3312 20531 : return Expression::backend_numeric_constant_expression(context, &nc);
3313 20531 : }
3314 :
3315 : // Write a floating point number to a string dump.
3316 :
3317 : void
3318 593 : Float_expression::export_float(String_dump *exp, const mpfr_t val)
3319 : {
3320 593 : mpfr_exp_t exponent;
3321 593 : char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, MPFR_RNDN);
3322 593 : if (*s == '-')
3323 53 : exp->write_c_string("-");
3324 593 : exp->write_c_string("0.");
3325 593 : exp->write_c_string(*s == '-' ? s + 1 : s);
3326 593 : mpfr_free_str(s);
3327 593 : char buf[30];
3328 593 : snprintf(buf, sizeof buf, "E%ld", exponent);
3329 593 : exp->write_c_string(buf);
3330 593 : }
3331 :
3332 : // Export a floating point number in a constant expression.
3333 :
3334 : void
3335 549 : Float_expression::do_export(Export_function_body* efb) const
3336 : {
3337 549 : bool exported_type = Expression::export_constant_type(efb, this->type_);
3338 :
3339 549 : Float_expression::export_float(efb, this->val_);
3340 : // A trailing space lets us reliably identify the end of the number.
3341 549 : efb->write_c_string(" ");
3342 :
3343 549 : Expression::finish_export_constant_type(efb, exported_type);
3344 549 : }
3345 :
3346 : // Dump a floating point number to the dump file.
3347 :
3348 : void
3349 0 : Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3350 : {
3351 0 : Float_expression::export_float(ast_dump_context, this->val_);
3352 0 : }
3353 :
3354 : // Make a float expression.
3355 :
3356 : Expression*
3357 32243 : Expression::make_float(const mpfr_t* val, Type* type, Location location)
3358 : {
3359 32243 : return new Float_expression(val, type, location);
3360 : }
3361 :
3362 : // Complex numbers.
3363 :
3364 : class Complex_expression : public Expression
3365 : {
3366 : public:
3367 3600 : Complex_expression(const mpc_t* val, Type* type, Location location)
3368 3600 : : Expression(EXPRESSION_COMPLEX, location),
3369 3600 : type_(type)
3370 : {
3371 3600 : mpc_init2(this->val_, mpc_precision);
3372 3600 : mpc_set(this->val_, *val, MPC_RNDNN);
3373 3600 : }
3374 :
3375 : // Write VAL to string dump.
3376 : static void
3377 : export_complex(String_dump* exp, const mpc_t val);
3378 :
3379 : // Write REAL/IMAG to dump context.
3380 : static void
3381 : dump_complex(Ast_dump_context* ast_dump_context, const mpc_t val);
3382 :
3383 : protected:
3384 : int
3385 : do_traverse(Traverse*);
3386 :
3387 : bool
3388 1594 : do_is_constant() const
3389 1594 : { return true; }
3390 :
3391 : bool
3392 : do_is_untyped(Type**) const;
3393 :
3394 : bool
3395 4 : do_is_zero_value() const
3396 : {
3397 4 : return mpfr_zero_p(mpc_realref(this->val_)) != 0
3398 0 : && mpfr_signbit(mpc_realref(this->val_)) == 0
3399 0 : && mpfr_zero_p(mpc_imagref(this->val_)) != 0
3400 4 : && mpfr_signbit(mpc_imagref(this->val_)) == 0;
3401 : }
3402 :
3403 : bool
3404 1688 : do_is_static_initializer() const
3405 1688 : { return true; }
3406 :
3407 : bool
3408 1251 : do_numeric_constant_value(Numeric_constant* nc)
3409 : {
3410 1251 : nc->set_complex(this->type_, this->val_);
3411 1251 : return true;
3412 : }
3413 :
3414 : Type*
3415 : do_type();
3416 :
3417 : void
3418 : do_determine_type(Gogo*, const Type_context*);
3419 :
3420 : void
3421 : do_check_types(Gogo*);
3422 :
3423 : Expression*
3424 12 : do_copy()
3425 : {
3426 24 : return Expression::make_complex(&this->val_,
3427 12 : (this->type_ == NULL
3428 : ? NULL
3429 12 : : this->type_->copy_expressions()),
3430 12 : this->location());
3431 : }
3432 :
3433 : Bexpression*
3434 : do_get_backend(Translate_context*);
3435 :
3436 : int
3437 125 : do_inlining_cost() const
3438 125 : { return 2; }
3439 :
3440 : void
3441 : do_export(Export_function_body*) const;
3442 :
3443 : void
3444 : do_dump_expression(Ast_dump_context*) const;
3445 :
3446 : private:
3447 : // The complex value.
3448 : mpc_t val_;
3449 : // The type if known.
3450 : Type* type_;
3451 : };
3452 :
3453 : // Traverse a complex expression. We just need to traverse the type
3454 : // if there is one.
3455 :
3456 : int
3457 43990 : Complex_expression::do_traverse(Traverse* traverse)
3458 : {
3459 43990 : if (this->type_ != NULL)
3460 42004 : return Type::traverse(this->type_, traverse);
3461 : return TRAVERSE_CONTINUE;
3462 : }
3463 :
3464 : bool
3465 945 : Complex_expression::do_is_untyped(Type** ptype) const
3466 : {
3467 945 : if (this->type_ != NULL)
3468 25 : return Expression::is_untyped_type(this->type_, ptype);
3469 920 : *ptype = Type::make_abstract_complex_type();
3470 920 : return true;
3471 : }
3472 :
3473 : // Return the current type. If we haven't set the type yet, we return
3474 : // an abstract complex type.
3475 :
3476 : Type*
3477 18583 : Complex_expression::do_type()
3478 : {
3479 18583 : if (this->type_ == NULL)
3480 21 : this->type_ = Type::make_abstract_complex_type();
3481 18583 : return this->type_;
3482 : }
3483 :
3484 : // Set the type of the complex value. Here we may switch from an
3485 : // abstract type to a real type.
3486 :
3487 : void
3488 5406 : Complex_expression::do_determine_type(Gogo*, const Type_context* context)
3489 : {
3490 5406 : if (this->type_ != NULL && !this->type_->is_abstract())
3491 : ;
3492 1837 : else if (context->type != NULL && context->type->is_numeric_type())
3493 1768 : this->type_ = context->type;
3494 69 : else if (!context->may_be_abstract)
3495 48 : this->type_ = Type::lookup_complex_type("complex128");
3496 5406 : }
3497 :
3498 : // Check the type of a complex value.
3499 :
3500 : void
3501 1854 : Complex_expression::do_check_types(Gogo*)
3502 : {
3503 1854 : Type* type = this->type_;
3504 1854 : if (type == NULL)
3505 0 : return;
3506 1854 : Numeric_constant nc;
3507 1854 : nc.set_complex(NULL, this->val_);
3508 1854 : if (!nc.set_type(this->type_, true, this->location()))
3509 4 : this->set_is_error();
3510 1854 : }
3511 :
3512 : // Get the backend representation for a complex constant.
3513 :
3514 : Bexpression*
3515 2529 : Complex_expression::do_get_backend(Translate_context* context)
3516 : {
3517 2529 : if (this->is_error_expression()
3518 2529 : || (this->type_ != NULL && this->type_->is_error_type()))
3519 : {
3520 0 : go_assert(saw_errors());
3521 0 : return context->gogo()->backend()->error_expression();
3522 : }
3523 :
3524 2529 : Type* resolved_type;
3525 2529 : if (this->type_ != NULL && !this->type_->is_abstract())
3526 2507 : resolved_type = this->type_;
3527 22 : else if (this->type_ != NULL && this->type_->integer_type() != NULL)
3528 : {
3529 : // We are converting to an abstract integer type.
3530 0 : resolved_type = Type::lookup_integer_type("int");
3531 : }
3532 22 : else if (this->type_ != NULL && this->type_->float_type() != NULL)
3533 : {
3534 : // We are converting to an abstract float type.
3535 0 : resolved_type = Type::lookup_float_type("float64");
3536 : }
3537 : else
3538 : {
3539 : // If we still have an abstract type here, this is being
3540 : // used in a constant expression which didn't get reduced. We
3541 : // just use complex128 and hope for the best.
3542 22 : resolved_type = Type::lookup_complex_type("complex128");
3543 : }
3544 :
3545 2529 : Numeric_constant nc;
3546 2529 : nc.set_complex(resolved_type, this->val_);
3547 2529 : return Expression::backend_numeric_constant_expression(context, &nc);
3548 2529 : }
3549 :
3550 : // Write REAL/IMAG to export data.
3551 :
3552 : void
3553 25 : Complex_expression::export_complex(String_dump* exp, const mpc_t val)
3554 : {
3555 25 : if (!mpfr_zero_p(mpc_realref(val)))
3556 : {
3557 19 : Float_expression::export_float(exp, mpc_realref(val));
3558 19 : if (mpfr_sgn(mpc_imagref(val)) >= 0)
3559 14 : exp->write_c_string("+");
3560 : }
3561 25 : Float_expression::export_float(exp, mpc_imagref(val));
3562 25 : exp->write_c_string("i");
3563 25 : }
3564 :
3565 : // Export a complex number in a constant expression.
3566 :
3567 : void
3568 25 : Complex_expression::do_export(Export_function_body* efb) const
3569 : {
3570 25 : bool exported_type = Expression::export_constant_type(efb, this->type_);
3571 :
3572 25 : Complex_expression::export_complex(efb, this->val_);
3573 : // A trailing space lets us reliably identify the end of the number.
3574 25 : efb->write_c_string(" ");
3575 :
3576 25 : Expression::finish_export_constant_type(efb, exported_type);
3577 25 : }
3578 :
3579 : // Dump a complex expression to the dump file.
3580 :
3581 : void
3582 0 : Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3583 : {
3584 0 : Complex_expression::export_complex(ast_dump_context, this->val_);
3585 0 : }
3586 :
3587 : // Make a complex expression.
3588 :
3589 : Expression*
3590 3600 : Expression::make_complex(const mpc_t* val, Type* type, Location location)
3591 : {
3592 3600 : return new Complex_expression(val, type, location);
3593 : }
3594 :
3595 : // Find a named object in an expression.
3596 :
3597 416851 : class Find_named_object : public Traverse
3598 : {
3599 : public:
3600 416851 : Find_named_object(Named_object* no)
3601 416851 : : Traverse(traverse_expressions),
3602 416851 : no_(no), found_(false)
3603 : { }
3604 :
3605 : // Whether we found the object.
3606 : bool
3607 416851 : found() const
3608 416851 : { return this->found_; }
3609 :
3610 : protected:
3611 : int
3612 : expression(Expression**);
3613 :
3614 : private:
3615 : // The object we are looking for.
3616 : Named_object* no_;
3617 : // Whether we found it.
3618 : bool found_;
3619 : };
3620 :
3621 : // Class Const_expression.
3622 :
3623 : // Traversal.
3624 :
3625 : int
3626 7798338 : Const_expression::do_traverse(Traverse* traverse)
3627 : {
3628 7798338 : if (this->type_ != NULL)
3629 7453269 : return Type::traverse(this->type_, traverse);
3630 : return TRAVERSE_CONTINUE;
3631 : }
3632 :
3633 : // Whether this is the zero value.
3634 :
3635 : bool
3636 32 : Const_expression::do_is_zero_value() const
3637 : {
3638 32 : return this->constant_->const_value()->expr()->is_zero_value();
3639 : }
3640 :
3641 : // Lower a constant expression. This is where we convert the
3642 : // predeclared constant iota into an integer value.
3643 :
3644 : Expression*
3645 1204689 : Const_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*)
3646 : {
3647 1204689 : Location loc = this->location();
3648 :
3649 1204689 : if (this->is_error_expression())
3650 874 : return Expression::make_error(loc);
3651 1203815 : if (this->constant_->const_value()->expr()->is_error_expression())
3652 191 : return Expression::make_error(loc);
3653 :
3654 1203624 : if (this->is_iota_)
3655 10365 : return Expression::make_integer_ul(this->iota_value_, NULL, loc);
3656 :
3657 : // Make sure that the constant itself has been lowered.
3658 1193259 : gogo->lower_constant(this->constant_);
3659 :
3660 1193259 : return this;
3661 : }
3662 :
3663 : // Return a numeric constant value.
3664 :
3665 : bool
3666 549250 : Const_expression::do_numeric_constant_value(Numeric_constant* nc)
3667 : {
3668 549250 : if (this->seen_)
3669 : return false;
3670 :
3671 549250 : Type* ctype;
3672 549250 : if (this->type_ != NULL)
3673 : ctype = this->type_;
3674 : else
3675 234 : ctype = this->constant_->const_value()->type();
3676 :
3677 549250 : if (this->is_iota_)
3678 : {
3679 54473 : nc->set_unsigned_long(ctype,
3680 54473 : static_cast<unsigned long>(this->iota_value_));
3681 54473 : return true;
3682 : }
3683 :
3684 494777 : Expression* e = this->constant_->const_value()->expr();
3685 :
3686 494777 : this->seen_ = true;
3687 :
3688 494777 : bool r = e->numeric_constant_value(nc);
3689 :
3690 494777 : this->seen_ = false;
3691 :
3692 494777 : if (r && ctype != NULL)
3693 : {
3694 481498 : if (!nc->set_type(ctype, false, this->location()))
3695 : return false;
3696 : }
3697 :
3698 : return r;
3699 : }
3700 :
3701 : bool
3702 10533 : Const_expression::do_string_constant_value(std::string* val)
3703 : {
3704 10533 : if (this->seen_)
3705 : return false;
3706 10533 : if (this->is_iota_)
3707 : return false;
3708 :
3709 10533 : Expression* e = this->constant_->const_value()->expr();
3710 :
3711 10533 : this->seen_ = true;
3712 10533 : bool ok = e->string_constant_value(val);
3713 10533 : this->seen_ = false;
3714 :
3715 10533 : return ok;
3716 : }
3717 :
3718 : bool
3719 6822 : Const_expression::do_boolean_constant_value(bool* val)
3720 : {
3721 6822 : if (this->seen_)
3722 : return false;
3723 6822 : if (this->is_iota_)
3724 : return false;
3725 :
3726 6822 : Expression* e = this->constant_->const_value()->expr();
3727 :
3728 6822 : this->seen_ = true;
3729 6822 : bool ok = e->boolean_constant_value(val);
3730 6822 : this->seen_ = false;
3731 :
3732 6822 : return ok;
3733 : }
3734 :
3735 : // Whether this is untyped.
3736 :
3737 : bool
3738 87888 : Const_expression::do_is_untyped(Type** ptype) const
3739 : {
3740 87888 : if (this->type_ != NULL)
3741 16888 : return Expression::is_untyped_type(this->type_, ptype);
3742 :
3743 71000 : Named_constant* nc = this->constant_->const_value();
3744 71000 : if (nc->type() != NULL)
3745 67984 : return Expression::is_untyped_type(nc->type(), ptype);
3746 :
3747 3016 : return nc->expr()->is_untyped(ptype);
3748 : }
3749 :
3750 : // Return the type of the const reference.
3751 :
3752 : Type*
3753 3901938 : Const_expression::do_type()
3754 : {
3755 3901938 : if (this->type_ == NULL)
3756 : {
3757 0 : go_assert(saw_errors());
3758 0 : return Type::make_error_type();
3759 : }
3760 :
3761 : return this->type_;
3762 : }
3763 :
3764 : // Set the type of the const reference.
3765 :
3766 : void
3767 645837 : Const_expression::do_determine_type(Gogo* gogo, const Type_context* context)
3768 : {
3769 645837 : if (this->type_ != NULL)
3770 : return;
3771 :
3772 : // The type may depend on the type of other constants. Avoid an
3773 : // endless loop.
3774 427474 : if (this->seen_)
3775 : {
3776 0 : if (!saw_errors())
3777 0 : go_error_at(this->location(), "constant refers to itself");
3778 0 : this->set_is_error();
3779 0 : this->type_ = Type::make_error_type();
3780 0 : return;
3781 : }
3782 :
3783 427474 : this->seen_ = true;
3784 :
3785 427474 : Named_constant* nc = this->constant_->const_value();
3786 427474 : nc->determine_type(gogo);
3787 :
3788 427474 : Type* ctype = nc->type();
3789 :
3790 427474 : this->seen_ = false;
3791 :
3792 427474 : if (ctype == NULL)
3793 : {
3794 2 : go_error_at(nc->expr()->location(), "constant refers to itself");
3795 2 : this->set_is_error();
3796 2 : this->type_ = Type::make_error_type();
3797 : }
3798 427472 : else if (!ctype->is_abstract())
3799 224088 : this->type_ = ctype;
3800 203384 : else if (context->type != NULL
3801 149195 : && context->type->is_numeric_type()
3802 271564 : && ctype->is_numeric_type())
3803 68165 : this->type_ = context->type;
3804 135219 : else if (context->type != NULL
3805 81030 : && context->type->is_string_type()
3806 142757 : && ctype->is_string_type())
3807 7283 : this->type_ = context->type;
3808 127936 : else if (context->type != NULL
3809 73747 : && context->type->is_boolean_type()
3810 199582 : && ctype->is_boolean_type())
3811 71646 : this->type_ = context->type;
3812 56290 : else if (!context->may_be_abstract)
3813 : {
3814 9022 : if (ctype->is_abstract())
3815 9022 : ctype = ctype->make_non_abstract_type();
3816 9022 : this->type_ = ctype;
3817 : }
3818 : else
3819 47268 : this->type_ = ctype;
3820 : }
3821 :
3822 : // Check for a loop in which the initializer of a constant refers to
3823 : // the constant itself.
3824 :
3825 : void
3826 416851 : Const_expression::check_for_init_loop()
3827 : {
3828 416851 : if (this->is_error_expression())
3829 0 : return;
3830 416851 : if (this->type_ != NULL && this->type_->is_error())
3831 : return;
3832 416851 : if (this->constant_->const_value()->expr()->is_error_expression())
3833 : {
3834 0 : this->set_is_error();
3835 0 : return;
3836 : }
3837 :
3838 416851 : if (this->seen_)
3839 : {
3840 0 : this->report_error(_("constant refers to itself"));
3841 0 : this->type_ = Type::make_error_type();
3842 0 : return;
3843 : }
3844 :
3845 416851 : Expression* init = this->constant_->const_value()->expr();
3846 416851 : Find_named_object find_named_object(this->constant_);
3847 :
3848 416851 : this->seen_ = true;
3849 416851 : Expression::traverse(&init, &find_named_object);
3850 416851 : this->seen_ = false;
3851 :
3852 416851 : if (find_named_object.found())
3853 : {
3854 0 : if (this->type_ == NULL || !this->type_->is_error())
3855 : {
3856 0 : this->report_error(_("constant refers to itself"));
3857 0 : this->type_ = Type::make_error_type();
3858 : }
3859 0 : return;
3860 : }
3861 416851 : }
3862 :
3863 : // Set the iota value if this is a reference to iota.
3864 :
3865 : void
3866 46842 : Const_expression::set_iota_value(int iota_value)
3867 : {
3868 46842 : Named_constant* nc = this->constant_->const_value();
3869 46842 : if (nc->expr()->classification() == EXPRESSION_IOTA)
3870 : {
3871 10363 : this->is_iota_ = true;
3872 10363 : this->iota_value_ = iota_value;
3873 : }
3874 46842 : }
3875 :
3876 : // Check types of a const reference.
3877 :
3878 : void
3879 427219 : Const_expression::do_check_types(Gogo*)
3880 : {
3881 427219 : if (this->is_error_expression())
3882 : return;
3883 427219 : if (this->type_ != NULL && this->type_->is_error())
3884 : return;
3885 427217 : if (this->constant_->const_value()->expr()->is_error_expression())
3886 : {
3887 1 : this->set_is_error();
3888 1 : return;
3889 : }
3890 :
3891 427216 : Expression* expr = this->constant_->const_value()->expr();
3892 427216 : if (expr->classification() == EXPRESSION_IOTA && !this->is_iota_)
3893 : {
3894 4 : go_error_at(this->location(),
3895 : "iota is only defined in const declarations");
3896 : // Avoid knock-on errors.
3897 4 : this->is_iota_ = true;
3898 4 : this->iota_value_ = 0;
3899 : }
3900 :
3901 427216 : if (this->is_iota_ && this->type_->is_numeric_type())
3902 : {
3903 10365 : Numeric_constant nc;
3904 10365 : nc.set_unsigned_long(Type::make_abstract_integer_type(),
3905 10365 : static_cast<unsigned long>(this->iota_value_));
3906 10365 : if (!nc.set_type(this->type_, true, this->location()))
3907 0 : this->set_is_error();
3908 10365 : return;
3909 10365 : }
3910 :
3911 416851 : this->check_for_init_loop();
3912 :
3913 : // Check that numeric constant fits in type.
3914 416851 : if (this->type_->is_numeric_type())
3915 : {
3916 190624 : Numeric_constant nc;
3917 190624 : if (expr->numeric_constant_value(&nc))
3918 : {
3919 189898 : if (!nc.set_type(this->type_, true, this->location()))
3920 873 : this->set_is_error();
3921 : }
3922 190624 : }
3923 : }
3924 :
3925 : // Return the backend representation for a const reference.
3926 :
3927 : Bexpression*
3928 259212 : Const_expression::do_get_backend(Translate_context* context)
3929 : {
3930 259212 : if (this->is_error_expression()
3931 259212 : || (this->type_ != NULL && this->type_->is_error()))
3932 : {
3933 0 : go_assert(saw_errors());
3934 0 : return context->backend()->error_expression();
3935 : }
3936 :
3937 259212 : go_assert(!this->is_iota_);
3938 :
3939 : // If the type has been set for this expression, but the underlying
3940 : // object is an abstract int or float, we try to get the abstract
3941 : // value. Otherwise we may lose something in the conversion.
3942 259212 : Expression* expr = this->constant_->const_value()->expr();
3943 259212 : if (this->type_ != NULL
3944 235813 : && this->type_->is_numeric_type()
3945 403440 : && (this->constant_->const_value()->type() == NULL
3946 144228 : || this->constant_->const_value()->type()->is_abstract()))
3947 : {
3948 82314 : Numeric_constant nc;
3949 82314 : if (expr->numeric_constant_value(&nc)
3950 82314 : && nc.set_type(this->type_, false, this->location()))
3951 : {
3952 82314 : Expression* e = nc.expression(this->location());
3953 82314 : return e->get_backend(context);
3954 : }
3955 82314 : }
3956 :
3957 176898 : if (this->type_ != NULL)
3958 153499 : expr = Expression::make_cast(this->type_, expr, this->location());
3959 176898 : return expr->get_backend(context);
3960 : }
3961 :
3962 : // When exporting a reference to a const as part of a const
3963 : // expression, we export the value. We ignore the fact that it has
3964 : // a name.
3965 :
3966 : void
3967 30346 : Const_expression::do_export(Export_function_body* efb) const
3968 : {
3969 30346 : this->constant_->const_value()->expr()->export_expression(efb);
3970 30346 : }
3971 :
3972 : // Dump ast representation for constant expression.
3973 :
3974 : void
3975 0 : Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
3976 : {
3977 0 : ast_dump_context->ostream() << this->constant_->name();
3978 0 : }
3979 :
3980 : // Make a reference to a constant in an expression.
3981 :
3982 : Expression*
3983 450984 : Expression::make_const_reference(Named_object* constant,
3984 : Location location)
3985 : {
3986 450984 : return new Const_expression(constant, location);
3987 : }
3988 :
3989 : // Find a named object in an expression.
3990 :
3991 : int
3992 663121 : Find_named_object::expression(Expression** pexpr)
3993 : {
3994 663121 : switch ((*pexpr)->classification())
3995 : {
3996 75037 : case Expression::EXPRESSION_CONST_REFERENCE:
3997 75037 : {
3998 75037 : Const_expression* ce = static_cast<Const_expression*>(*pexpr);
3999 75037 : if (ce->named_object() == this->no_)
4000 : break;
4001 : return TRAVERSE_CONTINUE;
4002 : }
4003 :
4004 173 : case Expression::EXPRESSION_VAR_REFERENCE:
4005 173 : if ((*pexpr)->var_expression()->named_object() == this->no_)
4006 : break;
4007 : return TRAVERSE_CONTINUE;
4008 1414 : case Expression::EXPRESSION_FUNC_REFERENCE:
4009 1414 : if ((*pexpr)->func_expression()->named_object() == this->no_)
4010 : break;
4011 : return TRAVERSE_CONTINUE;
4012 : case Expression::EXPRESSION_ERROR:
4013 : return TRAVERSE_EXIT;
4014 : default:
4015 : return TRAVERSE_CONTINUE;
4016 : }
4017 0 : this->found_ = true;
4018 0 : return TRAVERSE_EXIT;
4019 : }
4020 :
4021 : // The nil value.
4022 :
4023 : class Nil_expression : public Expression
4024 : {
4025 : public:
4026 2349183 : Nil_expression(Location location)
4027 4698366 : : Expression(EXPRESSION_NIL, location)
4028 : { }
4029 :
4030 : static Expression*
4031 : do_import(Import_expression*, Location);
4032 :
4033 : protected:
4034 : bool
4035 59824 : do_is_constant() const
4036 59824 : { return true; }
4037 :
4038 : bool
4039 : do_untyped_type(Type** ptype) const
4040 : {
4041 : *ptype = Type::make_nil_type();
4042 : return true;
4043 : }
4044 :
4045 : bool
4046 18 : do_is_zero_value() const
4047 18 : { return true; }
4048 :
4049 : bool
4050 593355 : do_is_static_initializer() const
4051 593355 : { return true; }
4052 :
4053 : Type*
4054 2019129 : do_type()
4055 2019129 : { return Type::make_nil_type(); }
4056 :
4057 : void
4058 2948142 : do_determine_type(Gogo*, const Type_context*)
4059 2948142 : { }
4060 :
4061 : Expression*
4062 0 : do_copy()
4063 0 : { return this; }
4064 :
4065 : Bexpression*
4066 1202879 : do_get_backend(Translate_context* context)
4067 1202879 : { return context->backend()->nil_pointer_expression(); }
4068 :
4069 : int
4070 17529 : do_inlining_cost() const
4071 17529 : { return 1; }
4072 :
4073 : void
4074 1456 : do_export(Export_function_body* efb) const
4075 1456 : { efb->write_c_string("$nil"); }
4076 :
4077 : void
4078 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
4079 0 : { ast_dump_context->ostream() << "nil"; }
4080 : };
4081 :
4082 : // Import a nil expression.
4083 :
4084 : Expression*
4085 621 : Nil_expression::do_import(Import_expression* imp, Location loc)
4086 : {
4087 621 : if (imp->version() >= EXPORT_FORMAT_V3)
4088 621 : imp->require_c_string("$");
4089 621 : imp->require_c_string("nil");
4090 621 : return Expression::make_nil(loc);
4091 : }
4092 :
4093 : // Make a nil expression.
4094 :
4095 : Expression*
4096 2349183 : Expression::make_nil(Location location)
4097 : {
4098 2349183 : return new Nil_expression(location);
4099 : }
4100 :
4101 : // The value of the predeclared constant iota. This is little more
4102 : // than a marker. This will be lowered to an integer in
4103 : // Const_expression::do_lower, which is where we know the value that
4104 : // it should have.
4105 :
4106 : class Iota_expression : public Parser_expression
4107 : {
4108 : public:
4109 4646 : Iota_expression(Location location)
4110 4646 : : Parser_expression(EXPRESSION_IOTA, location)
4111 4646 : { }
4112 :
4113 : protected:
4114 : Type*
4115 0 : do_type()
4116 0 : { return Type::make_abstract_integer_type(); }
4117 :
4118 : void
4119 471 : do_determine_type(Gogo*, const Type_context*)
4120 471 : { }
4121 :
4122 : Expression*
4123 0 : do_lower(Gogo*, Named_object*, Statement_inserter*)
4124 0 : { go_unreachable(); }
4125 :
4126 : // There should only ever be one of these.
4127 : Expression*
4128 0 : do_copy()
4129 0 : { go_unreachable(); }
4130 :
4131 : void
4132 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
4133 0 : { ast_dump_context->ostream() << "iota"; }
4134 : };
4135 :
4136 : // Make an iota expression. This is only called for one case: the
4137 : // value of the predeclared constant iota.
4138 :
4139 : Expression*
4140 4646 : Expression::make_iota()
4141 : {
4142 6351 : static Iota_expression iota_expression(Linemap::unknown_location());
4143 4646 : return &iota_expression;
4144 : }
4145 :
4146 : // Class Type_conversion_expression.
4147 :
4148 : // Traversal.
4149 :
4150 : int
4151 6427874 : Type_conversion_expression::do_traverse(Traverse* traverse)
4152 : {
4153 6427874 : if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
4154 6427874 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
4155 75690 : return TRAVERSE_EXIT;
4156 : return TRAVERSE_CONTINUE;
4157 : }
4158 :
4159 : // Return the type of the expression.
4160 :
4161 : Type*
4162 6939482 : Type_conversion_expression::do_type()
4163 : {
4164 6939482 : if (this->is_error_expression() || this->expr_->is_error_expression())
4165 259 : return Type::make_error_type();
4166 6939223 : return this->type_;
4167 : }
4168 :
4169 : // Convert to a constant at lowering time. Also lower conversions
4170 : // from slice to pointer-to-array, as they can panic.
4171 :
4172 : Expression*
4173 464083 : Type_conversion_expression::do_lower(Gogo* gogo, Named_object*,
4174 : Statement_inserter* inserter)
4175 : {
4176 464083 : Type* type = this->type_;
4177 464083 : Expression* val = this->expr_;
4178 464083 : Location location = this->location();
4179 :
4180 464083 : if (type->is_numeric_type())
4181 : {
4182 293860 : Numeric_constant nc;
4183 293860 : if (val->numeric_constant_value(&nc))
4184 : {
4185 31348 : if (!nc.set_type(type, true, location))
4186 19 : return Expression::make_error(location);
4187 31329 : return nc.expression(location);
4188 : }
4189 293860 : }
4190 :
4191 : // According to the language specification on string conversions
4192 : // (http://golang.org/ref/spec#Conversions_to_and_from_a_string_type):
4193 : // When converting an integer into a string, the string will be a UTF-8
4194 : // representation of the integer and integers "outside the range of valid
4195 : // Unicode code points are converted to '\uFFFD'."
4196 432735 : if (type->is_string_type())
4197 : {
4198 27230 : Numeric_constant nc;
4199 27230 : if (val->numeric_constant_value(&nc) && nc.is_int())
4200 : {
4201 : // An integer value doesn't fit in the Unicode code point range if it
4202 : // overflows the Go "int" type or is negative.
4203 418 : unsigned long ul;
4204 418 : if (!nc.set_type(Type::lookup_integer_type("int"), false, location)
4205 418 : || nc.to_unsigned_long(&ul) == Numeric_constant::NC_UL_NEGATIVE)
4206 6 : return Expression::make_string("\ufffd", location);
4207 : }
4208 27230 : }
4209 :
4210 432729 : if (type->is_slice_type())
4211 : {
4212 25664 : Type* element_type = type->array_type()->element_type()->forwarded();
4213 24656 : bool is_byte = (element_type->integer_type() != NULL
4214 11824 : && element_type->integer_type()->is_byte());
4215 24656 : bool is_rune = (element_type->integer_type() != NULL
4216 11824 : && element_type->integer_type()->is_rune());
4217 12628 : if (is_byte || is_rune)
4218 : {
4219 9918 : std::string s;
4220 9918 : if (val->string_constant_value(&s))
4221 : {
4222 4887 : Expression_list* vals = new Expression_list();
4223 4887 : if (is_byte)
4224 : {
4225 4831 : for (std::string::const_iterator p = s.begin();
4226 164092 : p != s.end();
4227 159261 : p++)
4228 : {
4229 159261 : unsigned char c = static_cast<unsigned char>(*p);
4230 159261 : vals->push_back(Expression::make_integer_ul(c,
4231 : element_type,
4232 : location));
4233 : }
4234 : }
4235 : else
4236 : {
4237 56 : const char *p = s.data();
4238 56 : const char *pend = s.data() + s.length();
4239 609 : while (p < pend)
4240 : {
4241 553 : unsigned int c;
4242 553 : int adv = Lex::fetch_char(p, &c);
4243 553 : if (adv == 0)
4244 : {
4245 4 : go_warning_at(this->location(), 0,
4246 : "invalid UTF-8 encoding");
4247 4 : adv = 1;
4248 : }
4249 553 : p += adv;
4250 553 : vals->push_back(Expression::make_integer_ul(c,
4251 : element_type,
4252 : location));
4253 : }
4254 : }
4255 :
4256 4887 : return Expression::make_slice_composite_literal(type, vals,
4257 : location);
4258 : }
4259 9918 : }
4260 : }
4261 :
4262 427842 : if (type->points_to() != NULL
4263 121169 : && type->points_to()->array_type() != NULL
4264 3503 : && !type->points_to()->is_slice_type()
4265 1545 : && val->type()->is_slice_type()
4266 427934 : && Type::are_identical(type->points_to()->array_type()->element_type(),
4267 92 : val->type()->array_type()->element_type(),
4268 : 0, NULL))
4269 : {
4270 46 : Temporary_statement* val_temp = NULL;
4271 46 : if (!val->is_multi_eval_safe())
4272 : {
4273 25 : val_temp = Statement::make_temporary(val->type(), NULL, location);
4274 25 : inserter->insert(val_temp);
4275 25 : val = Expression::make_set_and_use_temporary(val_temp, val,
4276 : location);
4277 : }
4278 :
4279 46 : Type* int_type = Type::lookup_integer_type("int");
4280 46 : Temporary_statement* vallen_temp =
4281 46 : Statement::make_temporary(int_type, NULL, location);
4282 46 : inserter->insert(vallen_temp);
4283 :
4284 92 : Expression* arrlen = type->points_to()->array_type()->length();
4285 46 : Expression* vallen =
4286 46 : Expression::make_slice_info(val, Expression::SLICE_INFO_LENGTH,
4287 : location);
4288 46 : vallen = Expression::make_set_and_use_temporary(vallen_temp, vallen,
4289 : location);
4290 46 : Expression* cond = Expression::make_binary(OPERATOR_GT, arrlen, vallen,
4291 : location);
4292 :
4293 46 : vallen = Expression::make_temporary_reference(vallen_temp, location);
4294 46 : Expression* panic = Runtime::make_call(gogo,
4295 : Runtime::PANIC_SLICE_CONVERT,
4296 : location, 2, arrlen, vallen);
4297 :
4298 46 : Expression* nil = Expression::make_nil(location);
4299 46 : Expression* check = Expression::make_conditional(cond, panic, nil,
4300 : location);
4301 :
4302 46 : if (val_temp == NULL)
4303 21 : val = val->copy();
4304 : else
4305 25 : val = Expression::make_temporary_reference(val_temp, location);
4306 46 : Expression* ptr =
4307 46 : Expression::make_slice_info(val, Expression::SLICE_INFO_VALUE_POINTER,
4308 : location);
4309 46 : ptr = Expression::make_unsafe_cast(type, ptr, location);
4310 :
4311 46 : Expression* ret = Expression::make_compound(check, ptr, location);
4312 46 : ret->determine_type_no_context(gogo);
4313 46 : return ret;
4314 : }
4315 :
4316 427796 : return this;
4317 : }
4318 :
4319 : // Flatten a type conversion by using a temporary variable for the slice
4320 : // in slice to string conversions.
4321 :
4322 : Expression*
4323 846814 : Type_conversion_expression::do_flatten(Gogo*, Named_object*,
4324 : Statement_inserter* inserter)
4325 : {
4326 846814 : if (this->type()->is_error_type() || this->expr_->is_error_expression())
4327 : {
4328 723 : go_assert(saw_errors());
4329 723 : return Expression::make_error(this->location());
4330 : }
4331 :
4332 846091 : if (((this->type()->is_string_type()
4333 22867 : && this->expr_->type()->is_slice_type())
4334 840340 : || this->expr_->type()->interface_type() != NULL)
4335 883084 : && !this->expr_->is_multi_eval_safe())
4336 : {
4337 7268 : Temporary_statement* temp =
4338 7268 : Statement::make_temporary(NULL, this->expr_, this->location());
4339 7268 : inserter->insert(temp);
4340 7268 : this->expr_ = Expression::make_temporary_reference(temp, this->location());
4341 : }
4342 :
4343 : // For interface conversion and string to/from slice conversions,
4344 : // decide if we can allocate on stack.
4345 1438394 : if (this->type()->interface_type() != NULL
4346 592303 : || this->type()->is_string_type()
4347 569436 : || this->expr_->type()->is_string_type())
4348 : {
4349 278526 : Node* n = Node::make_node(this);
4350 278526 : if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
4351 10302 : this->no_escape_ = true;
4352 : }
4353 846091 : return this;
4354 : }
4355 :
4356 : // Return whether a type conversion is a constant.
4357 :
4358 : bool
4359 380572 : Type_conversion_expression::do_is_constant() const
4360 : {
4361 380572 : if (!this->expr_->is_constant())
4362 : return false;
4363 :
4364 : // A conversion to a type that may not be used as a constant is not
4365 : // a constant. For example, []byte(nil).
4366 63191 : Type* type = this->type_;
4367 85345 : if (type->integer_type() == NULL
4368 21995 : && type->float_type() == NULL
4369 21982 : && type->complex_type() == NULL
4370 21982 : && !type->is_boolean_type()
4371 21885 : && !type->is_string_type())
4372 : return false;
4373 :
4374 : return true;
4375 : }
4376 :
4377 : // Return whether a type conversion is a zero value.
4378 :
4379 : bool
4380 183 : Type_conversion_expression::do_is_zero_value() const
4381 : {
4382 183 : if (!this->expr_->is_zero_value())
4383 : return false;
4384 :
4385 : // Some type conversion from zero value is still not zero value.
4386 : // For example, []byte("") or interface{}(0).
4387 : // Conservatively, only report true if the RHS is nil.
4388 0 : Type* type = this->type_;
4389 0 : if (type->integer_type() == NULL
4390 0 : && type->float_type() == NULL
4391 0 : && type->complex_type() == NULL
4392 0 : && !type->is_boolean_type()
4393 0 : && !type->is_string_type())
4394 0 : return this->expr_->is_nil_expression();
4395 :
4396 : return true;
4397 : }
4398 :
4399 : // Return whether a type conversion can be used in a constant
4400 : // initializer.
4401 :
4402 : bool
4403 47536 : Type_conversion_expression::do_is_static_initializer() const
4404 : {
4405 47536 : Type* type = this->type_;
4406 47536 : Type* expr_type = this->expr_->type();
4407 :
4408 91784 : if (type->interface_type() != NULL
4409 47536 : || expr_type->interface_type() != NULL)
4410 3288 : return false;
4411 :
4412 44248 : if (!this->expr_->is_static_initializer())
4413 : return false;
4414 :
4415 34847 : if (Type::are_identical(type, expr_type,
4416 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
4417 : NULL))
4418 : return true;
4419 :
4420 22312 : if (type->is_string_type() && expr_type->is_string_type())
4421 : return true;
4422 :
4423 22241 : if ((type->is_numeric_type()
4424 22212 : || type->is_boolean_type()
4425 22212 : || type->points_to() != NULL)
4426 44371 : && (expr_type->is_numeric_type()
4427 22094 : || expr_type->is_boolean_type()
4428 22094 : || expr_type->points_to() != NULL))
4429 22117 : return true;
4430 :
4431 : return false;
4432 : }
4433 :
4434 : // Return the constant numeric value if there is one.
4435 :
4436 : bool
4437 105449 : Type_conversion_expression::do_numeric_constant_value(
4438 : Numeric_constant* nc)
4439 : {
4440 105449 : if (!this->type_->is_numeric_type())
4441 : return false;
4442 96627 : if (!this->expr_->numeric_constant_value(nc))
4443 : return false;
4444 10669 : return nc->set_type(this->type_, false, this->location());
4445 : }
4446 :
4447 : // Return the constant string value if there is one.
4448 :
4449 : bool
4450 7974 : Type_conversion_expression::do_string_constant_value(std::string* val)
4451 : {
4452 7974 : if (this->type_->is_string_type() && this->expr_->type()->is_string_type())
4453 126 : return this->expr_->string_constant_value(val);
4454 :
4455 7848 : if (this->type_->is_string_type()
4456 7848 : && this->expr_->type()->integer_type() != NULL)
4457 : {
4458 207 : Numeric_constant nc;
4459 207 : if (this->expr_->numeric_constant_value(&nc))
4460 : {
4461 122 : unsigned long ival;
4462 122 : if (nc.to_unsigned_long(&ival) == Numeric_constant::NC_UL_VALID)
4463 : {
4464 122 : unsigned int cval = static_cast<unsigned int>(ival);
4465 122 : if (static_cast<unsigned long>(cval) != ival)
4466 : {
4467 1 : go_warning_at(this->location(), 0,
4468 : "unicode code point 0x%lx out of range",
4469 : ival);
4470 1 : cval = 0xfffd; // Unicode "replacement character."
4471 : }
4472 122 : val->clear();
4473 122 : Lex::append_char(cval, true, val, this->location());
4474 122 : return true;
4475 : }
4476 : }
4477 207 : }
4478 :
4479 : // FIXME: Could handle conversion from const []int here.
4480 :
4481 : return false;
4482 : }
4483 :
4484 : // Return the constant boolean value if there is one.
4485 :
4486 : bool
4487 6048 : Type_conversion_expression::do_boolean_constant_value(bool* val)
4488 : {
4489 6048 : if (!this->type_->is_boolean_type())
4490 : return false;
4491 12 : return this->expr_->boolean_constant_value(val);
4492 : }
4493 :
4494 : // Determine the resulting type of the conversion.
4495 :
4496 : void
4497 2505712 : Type_conversion_expression::do_determine_type(Gogo* gogo, const Type_context*)
4498 : {
4499 2505712 : Type_context subcontext(this->type_, false);
4500 2505712 : this->expr_->determine_type(gogo, &subcontext);
4501 2505712 : }
4502 :
4503 : // Check that types are convertible.
4504 :
4505 : void
4506 126355 : Type_conversion_expression::do_check_types(Gogo*)
4507 : {
4508 126355 : Type* type = this->type_;
4509 126355 : Type* expr_type = this->expr_->type();
4510 126355 : std::string reason;
4511 :
4512 126355 : if (type->is_error() || expr_type->is_error())
4513 : {
4514 2 : this->set_is_error();
4515 2 : return;
4516 : }
4517 :
4518 126353 : if (this->may_convert_function_types_
4519 0 : && type->function_type() != NULL
4520 252611 : && expr_type->function_type() != NULL)
4521 : return;
4522 :
4523 126353 : if (Type::are_convertible(type, expr_type, &reason))
4524 : return;
4525 :
4526 : // We can convert all numeric types if the value is a constant.
4527 102 : if (type->is_numeric_type()
4528 17 : && expr_type->is_numeric_type()
4529 107 : && this->expr_->is_constant())
4530 : return;
4531 :
4532 97 : go_error_at(this->location(), "%s", reason.c_str());
4533 97 : this->set_is_error();
4534 126355 : }
4535 :
4536 : // Copy.
4537 :
4538 : Expression*
4539 5949 : Type_conversion_expression::do_copy()
4540 : {
4541 11898 : Expression* ret = new Type_conversion_expression(this->type_->copy_expressions(),
4542 5949 : this->expr_->copy(),
4543 5949 : this->location());
4544 5949 : ret->conversion_expression()->set_no_copy(this->no_copy_);
4545 5949 : return ret;
4546 : }
4547 :
4548 : // Get the backend representation for a type conversion.
4549 :
4550 : Bexpression*
4551 2943669 : Type_conversion_expression::do_get_backend(Translate_context* context)
4552 : {
4553 2943669 : Type* type = this->type_;
4554 2943669 : Type* expr_type = this->expr_->type();
4555 2943669 : Type_context tcontext(type, false);
4556 :
4557 2943669 : Gogo* gogo = context->gogo();
4558 2943669 : Btype* btype = type->get_backend(gogo);
4559 2943669 : Location loc = this->location();
4560 :
4561 2943669 : if (Type::are_identical(type, expr_type,
4562 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
4563 : NULL))
4564 : {
4565 1104847 : Bexpression* bexpr = this->expr_->get_backend(context);
4566 1104847 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4567 : }
4568 2066046 : else if (type->interface_type() != NULL
4569 1838822 : && expr_type->interface_type() == NULL)
4570 : {
4571 201200 : Expression* conversion =
4572 402400 : Expression::convert_type_to_interface(type, this->expr_,
4573 201200 : this->no_escape_, loc);
4574 201200 : conversion->determine_type(gogo, &tcontext);
4575 201200 : return conversion->get_backend(context);
4576 : }
4577 3249220 : else if (type->interface_type() != NULL
4578 1637622 : || expr_type->interface_type() != NULL)
4579 : {
4580 26024 : Expression* conversion =
4581 26024 : Expression::convert_for_assignment(gogo, type, this->expr_,
4582 : loc);
4583 26024 : conversion->determine_type(gogo, &tcontext);
4584 26024 : return conversion->get_backend(context);
4585 : }
4586 1611598 : else if (type->is_string_type()
4587 1611598 : && expr_type->integer_type() != NULL)
4588 : {
4589 648 : mpz_t intval;
4590 648 : Numeric_constant nc;
4591 648 : if (this->expr_->numeric_constant_value(&nc)
4592 648 : && nc.to_int(&intval))
4593 : {
4594 380 : std::string s;
4595 380 : unsigned int x;
4596 380 : if (mpz_fits_uint_p(intval))
4597 381 : x = mpz_get_ui(intval);
4598 : else
4599 : {
4600 1 : char* ms = mpz_get_str(NULL, 16, intval);
4601 1 : go_warning_at(loc, 0,
4602 : "unicode code point 0x%s out of range in string",
4603 : ms);
4604 1 : free(ms);
4605 1 : x = 0xfffd;
4606 : }
4607 380 : Lex::append_char(x, true, &s, loc);
4608 380 : mpz_clear(intval);
4609 380 : Expression* se = Expression::make_string(s, loc);
4610 380 : se->determine_type(gogo, &tcontext);
4611 380 : return se->get_backend(context);
4612 380 : }
4613 :
4614 268 : Expression* buf;
4615 268 : if (this->no_escape_)
4616 : {
4617 200 : Type* byte_type = Type::lookup_integer_type("uint8");
4618 200 : Expression* buflen =
4619 200 : Expression::make_integer_ul(4, NULL, loc);
4620 200 : Type* array_type = Type::make_array_type(byte_type, buflen);
4621 200 : buf = Expression::make_allocation(array_type, loc);
4622 200 : buf->allocation_expression()->set_allocate_on_stack();
4623 200 : buf->allocation_expression()->set_no_zero();
4624 : }
4625 : else
4626 68 : buf = Expression::make_nil(loc);
4627 268 : Expression* i2s_expr =
4628 268 : Runtime::make_call(gogo, Runtime::INTSTRING, loc, 2, buf, this->expr_);
4629 268 : Expression* ret = Expression::make_cast(type, i2s_expr, loc);
4630 268 : Type_context tcontext(type, false);
4631 268 : ret->determine_type(gogo, &tcontext);
4632 268 : return ret->get_backend(context);
4633 648 : }
4634 1610950 : else if (type->is_string_type() && expr_type->is_slice_type())
4635 : {
4636 5289 : Array_type* a = expr_type->array_type();
4637 5289 : Type* e = a->element_type()->forwarded();
4638 5289 : go_assert(e->integer_type() != NULL);
4639 5289 : go_assert(this->expr_->is_multi_eval_safe());
4640 :
4641 5289 : Expression* buf;
4642 5289 : if (this->no_escape_ && !this->no_copy_)
4643 : {
4644 408 : Type* byte_type = Type::lookup_integer_type("uint8");
4645 408 : Expression* buflen =
4646 408 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
4647 408 : Type* array_type = Type::make_array_type(byte_type, buflen);
4648 408 : buf = Expression::make_allocation(array_type, loc);
4649 408 : buf->allocation_expression()->set_allocate_on_stack();
4650 408 : buf->allocation_expression()->set_no_zero();
4651 : }
4652 : else
4653 4881 : buf = Expression::make_nil(loc);
4654 :
4655 10578 : if (e->integer_type()->is_byte())
4656 : {
4657 5155 : Expression* ptr =
4658 5155 : Expression::make_slice_info(this->expr_, SLICE_INFO_VALUE_POINTER,
4659 : loc);
4660 5155 : Expression* len =
4661 5155 : Expression::make_slice_info(this->expr_, SLICE_INFO_LENGTH, loc);
4662 5155 : if (this->no_copy_)
4663 : {
4664 1689 : if (gogo->debug_optimization())
4665 6 : go_debug(loc, "no copy string([]byte)");
4666 1689 : Expression* str = Expression::make_string_value(ptr, len, loc);
4667 1689 : return str->get_backend(context);
4668 : }
4669 3466 : Expression* ret = Runtime::make_call(gogo, Runtime::SLICEBYTETOSTRING,
4670 : loc, 3, buf, ptr, len);
4671 3466 : Type_context tcontext(type, false);
4672 3466 : ret->determine_type(gogo, &tcontext);
4673 3466 : return ret->get_backend(context);
4674 : }
4675 : else
4676 : {
4677 268 : go_assert(e->integer_type()->is_rune());
4678 134 : Expression* ret = Runtime::make_call(gogo, Runtime::SLICERUNETOSTRING,
4679 : loc, 2, buf, this->expr_);
4680 134 : Type_context tcontext(type, false);
4681 134 : ret->determine_type(gogo, &tcontext);
4682 134 : return ret->get_backend(context);
4683 : }
4684 : }
4685 1609294 : else if (type->is_slice_type() && expr_type->is_string_type())
4686 : {
4687 3128 : Type* e = type->array_type()->element_type()->forwarded();
4688 1564 : go_assert(e->integer_type() != NULL);
4689 :
4690 1564 : Runtime::Function code;
4691 3128 : if (e->integer_type()->is_byte())
4692 : code = Runtime::STRINGTOSLICEBYTE;
4693 : else
4694 : {
4695 90 : go_assert(e->integer_type()->is_rune());
4696 : code = Runtime::STRINGTOSLICERUNE;
4697 : }
4698 :
4699 1564 : Expression* buf;
4700 1564 : if (this->no_escape_)
4701 : {
4702 524 : Expression* buflen =
4703 524 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
4704 524 : Type* array_type = Type::make_array_type(e, buflen);
4705 524 : buf = Expression::make_allocation(array_type, loc);
4706 524 : buf->allocation_expression()->set_allocate_on_stack();
4707 524 : buf->allocation_expression()->set_no_zero();
4708 : }
4709 : else
4710 1040 : buf = Expression::make_nil(loc);
4711 1564 : Expression* s2a = Runtime::make_call(gogo, code, loc, 2, buf,
4712 : this->expr_);
4713 1564 : Expression* ret = Expression::make_unsafe_cast(type, s2a, loc);
4714 1564 : Type_context tcontext(type, false);
4715 1564 : ret->determine_type(gogo, &tcontext);
4716 1564 : return ret->get_backend(context);
4717 : }
4718 1604097 : else if (type->is_numeric_type())
4719 : {
4720 412225 : go_assert(Type::are_convertible(type, expr_type, NULL));
4721 412225 : Bexpression* bexpr = this->expr_->get_backend(context);
4722 412225 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4723 : }
4724 1191872 : else if ((type->is_unsafe_pointer_type()
4725 770030 : && (expr_type->points_to() != NULL
4726 1406304 : || expr_type->integer_type()))
4727 436895 : || (expr_type->is_unsafe_pointer_type()
4728 214432 : && type->points_to() != NULL)
4729 1414335 : || (this->may_convert_function_types_
4730 0 : && type->function_type() != NULL
4731 969409 : && expr_type->function_type() != NULL))
4732 : {
4733 969409 : Bexpression* bexpr = this->expr_->get_backend(context);
4734 969409 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4735 : }
4736 : else
4737 : {
4738 222463 : Expression* conversion =
4739 222463 : Expression::convert_for_assignment(gogo, type, this->expr_, loc);
4740 222463 : conversion->determine_type(gogo, &tcontext);
4741 222463 : return conversion->get_backend(context);
4742 : }
4743 : }
4744 :
4745 : // Cost of inlining a type conversion.
4746 :
4747 : int
4748 289413 : Type_conversion_expression::do_inlining_cost() const
4749 : {
4750 289413 : Type* type = this->type_;
4751 289413 : Type* expr_type = this->expr_->type();
4752 491515 : if (type->interface_type() != NULL || expr_type->interface_type() != NULL)
4753 87311 : return 10;
4754 298377 : else if (type->is_string_type() && expr_type->integer_type() != NULL)
4755 : return 10;
4756 201934 : else if (type->is_string_type() && expr_type->is_slice_type())
4757 : return 10;
4758 199427 : else if (type->is_slice_type() && expr_type->is_string_type())
4759 : return 10;
4760 : else
4761 193138 : return 1;
4762 : }
4763 :
4764 : // Output a type conversion in a constant expression.
4765 :
4766 : void
4767 10254 : Type_conversion_expression::do_export(Export_function_body* efb) const
4768 : {
4769 10254 : efb->write_c_string("$convert(");
4770 10254 : efb->write_type(this->type_);
4771 10254 : efb->write_c_string(", ");
4772 :
4773 10254 : Type* old_context = efb->type_context();
4774 10254 : efb->set_type_context(this->type_);
4775 :
4776 10254 : this->expr_->export_expression(efb);
4777 :
4778 10254 : efb->set_type_context(old_context);
4779 :
4780 10254 : efb->write_c_string(")");
4781 10254 : }
4782 :
4783 : // Import a type conversion or a struct construction.
4784 :
4785 : Expression*
4786 18058 : Type_conversion_expression::do_import(Import_expression* imp, Location loc)
4787 : {
4788 18058 : imp->require_c_string("$convert(");
4789 18058 : Type* type = imp->read_type();
4790 18058 : imp->require_c_string(", ");
4791 18058 : Expression* val = Expression::import_expression(imp, loc);
4792 18058 : imp->require_c_string(")");
4793 18058 : return Expression::make_cast(type, val, loc);
4794 : }
4795 :
4796 : // Dump ast representation for a type conversion expression.
4797 :
4798 : void
4799 0 : Type_conversion_expression::do_dump_expression(
4800 : Ast_dump_context* ast_dump_context) const
4801 : {
4802 0 : ast_dump_context->dump_type(this->type_);
4803 0 : ast_dump_context->ostream() << "(";
4804 0 : ast_dump_context->dump_expression(this->expr_);
4805 0 : ast_dump_context->ostream() << ") ";
4806 0 : }
4807 :
4808 : // Make a type cast expression.
4809 :
4810 : Expression*
4811 3012628 : Expression::make_cast(Type* type, Expression* val, Location location)
4812 : {
4813 3012628 : if (type->is_error_type() || val->is_error_expression())
4814 512 : return Expression::make_error(location);
4815 3012116 : return new Type_conversion_expression(type, val, location);
4816 : }
4817 :
4818 : // Class Unsafe_type_conversion_expression.
4819 :
4820 : // Traversal.
4821 :
4822 : int
4823 1435754 : Unsafe_type_conversion_expression::do_traverse(Traverse* traverse)
4824 : {
4825 1435754 : if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
4826 1435754 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
4827 70884 : return TRAVERSE_EXIT;
4828 : return TRAVERSE_CONTINUE;
4829 : }
4830 :
4831 : // Return whether an unsafe type conversion can be used as a constant
4832 : // initializer.
4833 :
4834 : bool
4835 184 : Unsafe_type_conversion_expression::do_is_static_initializer() const
4836 : {
4837 184 : Type* type = this->type_;
4838 184 : Type* expr_type = this->expr_->type();
4839 :
4840 368 : if (type->interface_type() != NULL
4841 184 : || expr_type->interface_type() != NULL)
4842 0 : return false;
4843 :
4844 184 : if (!this->expr_->is_static_initializer())
4845 : return false;
4846 :
4847 0 : if (Type::are_convertible(type, expr_type, NULL))
4848 : return true;
4849 :
4850 0 : if (type->is_string_type() && expr_type->is_string_type())
4851 : return true;
4852 :
4853 0 : if ((type->is_numeric_type()
4854 0 : || type->is_boolean_type()
4855 0 : || type->points_to() != NULL)
4856 0 : && (expr_type->is_numeric_type()
4857 0 : || expr_type->is_boolean_type()
4858 0 : || expr_type->points_to() != NULL))
4859 0 : return true;
4860 :
4861 : return false;
4862 : }
4863 :
4864 : // Copy.
4865 :
4866 : Expression*
4867 0 : Unsafe_type_conversion_expression::do_copy()
4868 : {
4869 0 : return new Unsafe_type_conversion_expression(this->type_->copy_expressions(),
4870 0 : this->expr_->copy(),
4871 0 : this->location());
4872 : }
4873 :
4874 : // Convert to backend representation.
4875 :
4876 : Bexpression*
4877 741101 : Unsafe_type_conversion_expression::do_get_backend(Translate_context* context)
4878 : {
4879 : // We are only called for a limited number of cases.
4880 :
4881 741101 : Type* t = this->type_;
4882 741101 : Type* et = this->expr_->type();
4883 :
4884 741101 : if (t->is_error_type()
4885 741101 : || this->expr_->is_error_expression()
4886 1482202 : || et->is_error_type())
4887 : {
4888 0 : go_assert(saw_errors());
4889 0 : return context->backend()->error_expression();
4890 : }
4891 :
4892 741101 : if (t->array_type() != NULL)
4893 58490 : go_assert(et->array_type() != NULL
4894 : && t->is_slice_type() == et->is_slice_type());
4895 711856 : else if (t->struct_type() != NULL)
4896 : {
4897 36 : if (t->named_type() != NULL
4898 30 : && et->named_type() != NULL
4899 58 : && !Type::are_convertible(t, et, NULL))
4900 : {
4901 0 : go_assert(saw_errors());
4902 0 : return context->backend()->error_expression();
4903 : }
4904 :
4905 72 : go_assert(et->struct_type() != NULL
4906 : && Type::are_convertible(t, et, NULL));
4907 : }
4908 711820 : else if (t->map_type() != NULL)
4909 21419 : go_assert(et->map_type() != NULL || et->points_to() != NULL);
4910 690799 : else if (t->channel_type() != NULL)
4911 9220 : go_assert(et->channel_type() != NULL || et->points_to() != NULL);
4912 681692 : else if (t->points_to() != NULL)
4913 615272 : go_assert(et->points_to() != NULL
4914 : || et->channel_type() != NULL
4915 : || et->map_type() != NULL
4916 : || et->function_type() != NULL
4917 : || et->integer_type() != NULL
4918 : || et->is_nil_type());
4919 114544 : else if (t->function_type() != NULL)
4920 1343 : go_assert(et->points_to() != NULL);
4921 113201 : else if (et->is_unsafe_pointer_type())
4922 44766 : go_assert(t->points_to() != NULL
4923 : || (t->integer_type() != NULL
4924 : && t->integer_type() == Type::lookup_integer_type("uintptr")->real_type()));
4925 98279 : else if (t->interface_type() != NULL)
4926 : {
4927 79976 : bool empty_iface = t->interface_type()->is_empty();
4928 119964 : go_assert(et->interface_type() != NULL
4929 : && et->interface_type()->is_empty() == empty_iface);
4930 : }
4931 58291 : else if (t->integer_type() != NULL)
4932 866509 : go_assert(et->is_boolean_type()
4933 : || et->integer_type() != NULL
4934 : || et->function_type() != NULL
4935 : || et->points_to() != NULL
4936 : || et->map_type() != NULL
4937 : || et->channel_type() != NULL
4938 : || et->is_nil_type());
4939 : else
4940 0 : go_unreachable();
4941 :
4942 741101 : Gogo* gogo = context->gogo();
4943 741101 : Btype* btype = t->get_backend(gogo);
4944 741101 : Bexpression* bexpr = this->expr_->get_backend(context);
4945 741101 : Location loc = this->location();
4946 741101 : return gogo->backend()->convert_expression(btype, bexpr, loc);
4947 : }
4948 :
4949 : // Dump ast representation for an unsafe type conversion expression.
4950 :
4951 : void
4952 0 : Unsafe_type_conversion_expression::do_dump_expression(
4953 : Ast_dump_context* ast_dump_context) const
4954 : {
4955 0 : ast_dump_context->dump_type(this->type_);
4956 0 : ast_dump_context->ostream() << "(";
4957 0 : ast_dump_context->dump_expression(this->expr_);
4958 0 : ast_dump_context->ostream() << ") ";
4959 0 : }
4960 :
4961 : // Make an unsafe type conversion expression.
4962 :
4963 : Expression*
4964 780304 : Expression::make_unsafe_cast(Type* type, Expression* expr,
4965 : Location location)
4966 : {
4967 780304 : return new Unsafe_type_conversion_expression(type, expr, location);
4968 : }
4969 :
4970 : // Class Unary_expression.
4971 :
4972 : // Call the address_taken method of the operand if needed. This is
4973 : // called after escape analysis but before inserting write barriers.
4974 :
4975 : void
4976 826646 : Unary_expression::check_operand_address_taken(Gogo*)
4977 : {
4978 826646 : if (this->op_ != OPERATOR_AND)
4979 : return;
4980 :
4981 : // If this->escapes_ is false at this point, then it was set to
4982 : // false by an explicit call to set_does_not_escape, and the value
4983 : // does not escape. If this->escapes_ is true, we may be able to
4984 : // set it to false based on the escape analysis pass.
4985 205342 : if (this->escapes_)
4986 : {
4987 176931 : Node* n = Node::make_node(this);
4988 176931 : if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
4989 129243 : this->escapes_ = false;
4990 : }
4991 :
4992 205342 : this->expr_->address_taken(this->escapes_);
4993 : }
4994 :
4995 : // If we are taking the address of a composite literal, and the
4996 : // contents are not constant, then we want to make a heap expression
4997 : // instead.
4998 :
4999 : Expression*
5000 1637015 : Unary_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*)
5001 : {
5002 1637015 : Location loc = this->location();
5003 :
5004 1637015 : if (this->is_error_expression())
5005 7 : return Expression::make_error(loc);
5006 :
5007 1637008 : Operator op = this->op_;
5008 1637008 : Expression* expr = this->expr_;
5009 :
5010 1637008 : if (expr->is_error_expression())
5011 2 : return Expression::make_error(loc);
5012 :
5013 1637006 : if (op == OPERATOR_MULT && expr->is_type_expression())
5014 : {
5015 163 : Expression* ret =
5016 163 : Expression::make_type(Type::make_pointer_type(expr->type()), loc);
5017 163 : ret->determine_type_no_context(gogo);
5018 163 : return ret;
5019 : }
5020 :
5021 : // *&x simplifies to x. *(*T)(unsafe.Pointer)(&x) does not require
5022 : // moving x to the heap. FIXME: Is it worth doing a real escape
5023 : // analysis here? This case is found in math/unsafe.go and is
5024 : // therefore worth special casing.
5025 1636843 : if (op == OPERATOR_MULT)
5026 : {
5027 : Expression* e = expr;
5028 1187271 : while (e->classification() == EXPRESSION_CONVERSION)
5029 : {
5030 20844 : Type_conversion_expression* te
5031 : = static_cast<Type_conversion_expression*>(e);
5032 20844 : e = te->expr();
5033 : }
5034 :
5035 1166427 : if (e->classification() == EXPRESSION_UNARY)
5036 : {
5037 2957 : Unary_expression* ue = static_cast<Unary_expression*>(e);
5038 2957 : if (ue->op_ == OPERATOR_AND)
5039 : {
5040 1069 : if (e == expr)
5041 : {
5042 : // *&x == x.
5043 24 : if (!ue->expr_->is_addressable() && !ue->create_temp_)
5044 : {
5045 0 : go_error_at(ue->location(),
5046 : "invalid operand for unary %<&%>");
5047 0 : this->set_is_error();
5048 : }
5049 24 : return ue->expr_;
5050 : }
5051 1045 : ue->set_does_not_escape();
5052 : }
5053 : }
5054 : }
5055 :
5056 : // Check for an invalid pointer dereference. We need to do this
5057 : // here because Unary_expression::do_type will return an error type
5058 : // in this case. That can cause code to appear erroneous, and
5059 : // therefore disappear at lowering time, without any error message.
5060 1166403 : if (op == OPERATOR_MULT && expr->type()->points_to() == NULL)
5061 : {
5062 0 : this->report_error(_("expected pointer"));
5063 0 : return Expression::make_error(this->location());
5064 : }
5065 :
5066 1636819 : if (op == OPERATOR_PLUS || op == OPERATOR_MINUS || op == OPERATOR_XOR)
5067 : {
5068 87866 : Numeric_constant nc;
5069 87866 : if (expr->numeric_constant_value(&nc))
5070 : {
5071 64140 : Numeric_constant result;
5072 64140 : bool issued_error;
5073 64140 : if (Unary_expression::eval_constant(this->type_, op, &nc, loc,
5074 : &result, &issued_error))
5075 : {
5076 64140 : Expression* ret = result.expression(loc);
5077 64140 : Type_context subcontext(this->type_, this->type_->is_abstract());
5078 64140 : ret->determine_type(gogo, &subcontext);
5079 64140 : ret->check_types(gogo);
5080 64140 : return ret;
5081 : }
5082 0 : else if (issued_error)
5083 0 : return Expression::make_error(this->location());
5084 64140 : }
5085 87866 : }
5086 :
5087 1572679 : return this;
5088 : }
5089 :
5090 : // Flatten expression if a nil check must be performed and create temporary
5091 : // variables if necessary.
5092 :
5093 : Expression*
5094 1372791 : Unary_expression::do_flatten(Gogo* gogo, Named_object*,
5095 : Statement_inserter* inserter)
5096 : {
5097 1372791 : if (this->is_error_expression()
5098 1372791 : || this->expr_->is_error_expression()
5099 2745582 : || this->expr_->type()->is_error_type())
5100 : {
5101 0 : go_assert(saw_errors());
5102 0 : return Expression::make_error(this->location());
5103 : }
5104 :
5105 1372791 : Location location = this->location();
5106 1372791 : if (this->op_ == OPERATOR_MULT
5107 1372791 : && !this->expr_->is_multi_eval_safe())
5108 : {
5109 176462 : go_assert(this->expr_->type()->points_to() != NULL);
5110 176462 : switch (this->requires_nil_check(gogo))
5111 : {
5112 0 : case NIL_CHECK_ERROR_ENCOUNTERED:
5113 0 : {
5114 0 : go_assert(saw_errors());
5115 0 : return Expression::make_error(this->location());
5116 : }
5117 : case NIL_CHECK_NOT_NEEDED:
5118 : break;
5119 4142 : case NIL_CHECK_NEEDED:
5120 4142 : this->create_temp_ = true;
5121 4142 : break;
5122 0 : case NIL_CHECK_DEFAULT:
5123 0 : go_unreachable();
5124 : }
5125 : }
5126 :
5127 1372791 : if (this->create_temp_ && !this->expr_->is_multi_eval_safe())
5128 : {
5129 12729 : Temporary_statement* temp =
5130 12729 : Statement::make_temporary(NULL, this->expr_, location);
5131 12729 : inserter->insert(temp);
5132 12729 : this->expr_ = Expression::make_temporary_reference(temp, location);
5133 : }
5134 :
5135 1372791 : return this;
5136 : }
5137 :
5138 : // Return whether a unary expression is a constant.
5139 :
5140 : bool
5141 334011 : Unary_expression::do_is_constant() const
5142 : {
5143 334011 : if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND)
5144 : {
5145 : // These are not constant by Go language rules.
5146 : return false;
5147 : }
5148 : else
5149 39276 : return this->expr_->is_constant();
5150 : }
5151 :
5152 : bool
5153 234004 : Unary_expression::do_is_untyped(Type** ptype) const
5154 : {
5155 234004 : if (this->type_ != NULL)
5156 144 : return Expression::is_untyped_type(this->type_, ptype);
5157 :
5158 233860 : if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND)
5159 : return false;
5160 28276 : return this->expr_->is_untyped(ptype);
5161 : }
5162 :
5163 : // Return whether a unary expression can be used as a constant
5164 : // initializer.
5165 :
5166 : bool
5167 1022986 : Unary_expression::do_is_static_initializer() const
5168 : {
5169 1022986 : if (this->op_ == OPERATOR_MULT)
5170 : return false;
5171 1022971 : else if (this->op_ == OPERATOR_AND)
5172 1022965 : return Unary_expression::base_is_static_initializer(this->expr_);
5173 : else
5174 6 : return this->expr_->is_static_initializer();
5175 : }
5176 :
5177 : // Return whether the address of EXPR can be used as a static
5178 : // initializer.
5179 :
5180 : bool
5181 1023017 : Unary_expression::base_is_static_initializer(Expression* expr)
5182 : {
5183 : // The address of a field reference can be a static initializer if
5184 : // the base can be a static initializer.
5185 1023837 : Field_reference_expression* fre = expr->field_reference_expression();
5186 1023837 : if (fre != NULL)
5187 820 : return Unary_expression::base_is_static_initializer(fre->expr());
5188 :
5189 : // The address of an index expression can be a static initializer if
5190 : // the base can be a static initializer and the index is constant.
5191 1023017 : Array_index_expression* aind = expr->array_index_expression();
5192 1023017 : if (aind != NULL)
5193 52 : return (aind->end() == NULL
5194 52 : && aind->start()->is_constant()
5195 104 : && Unary_expression::base_is_static_initializer(aind->array()));
5196 :
5197 : // The address of a global variable can be a static initializer.
5198 1022965 : Var_expression* ve = expr->var_expression();
5199 1022965 : if (ve != NULL)
5200 : {
5201 20906 : Named_object* no = ve->named_object();
5202 20906 : return no->is_variable() && no->var_value()->is_global();
5203 : }
5204 :
5205 : // The address of a composite literal can be used as a static
5206 : // initializer if the composite literal is itself usable as a
5207 : // static initializer.
5208 1002059 : if (expr->is_composite_literal() && expr->is_static_initializer())
5209 : return true;
5210 :
5211 : // The address of a string constant can be used as a static
5212 : // initializer. This can not be written in Go itself but this is
5213 : // used when building a type descriptor.
5214 1022640 : if (expr->string_expression() != NULL)
5215 : return true;
5216 :
5217 : return false;
5218 : }
5219 :
5220 : // Return whether this dereference expression requires an explicit nil
5221 : // check. If we are dereferencing the pointer to a large struct
5222 : // (greater than the specified size threshold), we need to check for
5223 : // nil. We don't bother to check for small structs because we expect
5224 : // the system to crash on a nil pointer dereference. However, if we
5225 : // know the address of this expression is being taken, we must always
5226 : // check for nil.
5227 : Unary_expression::Nil_check_classification
5228 1277339 : Unary_expression::requires_nil_check(Gogo* gogo)
5229 : {
5230 1277339 : go_assert(this->op_ == OPERATOR_MULT);
5231 1277339 : go_assert(this->expr_->type()->points_to() != NULL);
5232 :
5233 1277339 : if (this->issue_nil_check_ == NIL_CHECK_NEEDED)
5234 : return NIL_CHECK_NEEDED;
5235 1208709 : else if (this->issue_nil_check_ == NIL_CHECK_NOT_NEEDED)
5236 : return NIL_CHECK_NOT_NEEDED;
5237 :
5238 560928 : Type* ptype = this->expr_->type()->points_to();
5239 560928 : int64_t type_size = -1;
5240 560928 : if (!ptype->is_void_type())
5241 : {
5242 560928 : bool ok = ptype->backend_type_size(gogo, &type_size);
5243 560928 : if (!ok)
5244 : return NIL_CHECK_ERROR_ENCOUNTERED;
5245 : }
5246 :
5247 560928 : int64_t size_cutoff = gogo->nil_check_size_threshold();
5248 560928 : if (size_cutoff == -1 || (type_size != -1 && type_size >= size_cutoff))
5249 15662 : this->issue_nil_check_ = NIL_CHECK_NEEDED;
5250 : else
5251 545266 : this->issue_nil_check_ = NIL_CHECK_NOT_NEEDED;
5252 560928 : return this->issue_nil_check_;
5253 : }
5254 :
5255 : // Apply unary opcode OP to UNC, setting NC. Return true if this
5256 : // could be done, false if not. On overflow, issues an error and sets
5257 : // *ISSUED_ERROR.
5258 :
5259 : bool
5260 81587 : Unary_expression::eval_constant(Type* type, Operator op,
5261 : const Numeric_constant* unc,
5262 : Location location, Numeric_constant* nc,
5263 : bool* issued_error)
5264 : {
5265 81587 : *issued_error = false;
5266 81587 : switch (op)
5267 : {
5268 1029 : case OPERATOR_PLUS:
5269 1029 : *nc = *unc;
5270 1029 : return true;
5271 :
5272 71496 : case OPERATOR_MINUS:
5273 71496 : if (unc->is_int() || unc->is_rune())
5274 : break;
5275 4061 : else if (unc->is_float())
5276 : {
5277 4051 : mpfr_t uval;
5278 4051 : unc->get_float(&uval);
5279 4051 : mpfr_t val;
5280 4051 : mpfr_init(val);
5281 4051 : mpfr_neg(val, uval, MPFR_RNDN);
5282 4051 : Type* utype = unc->type();
5283 4051 : if (type != NULL
5284 4051 : && type->is_abstract()
5285 6024 : && type->is_numeric_type())
5286 : utype = type;
5287 4051 : nc->set_float(utype, val);
5288 4051 : mpfr_clear(uval);
5289 4051 : mpfr_clear(val);
5290 4051 : return true;
5291 : }
5292 10 : else if (unc->is_complex())
5293 : {
5294 10 : mpc_t uval;
5295 10 : unc->get_complex(&uval);
5296 10 : mpc_t val;
5297 10 : mpc_init2(val, mpc_precision);
5298 10 : mpc_neg(val, uval, MPC_RNDNN);
5299 10 : Type* utype = unc->type();
5300 10 : if (type != NULL
5301 10 : && type->is_abstract()
5302 16 : && type->is_numeric_type())
5303 : utype = type;
5304 10 : nc->set_complex(utype, val);
5305 10 : mpc_clear(uval);
5306 10 : mpc_clear(val);
5307 10 : return true;
5308 : }
5309 : else
5310 0 : go_unreachable();
5311 :
5312 : case OPERATOR_XOR:
5313 : break;
5314 :
5315 : case OPERATOR_NOT:
5316 : case OPERATOR_AND:
5317 : case OPERATOR_MULT:
5318 : return false;
5319 :
5320 0 : default:
5321 0 : go_unreachable();
5322 : }
5323 :
5324 76497 : if (!unc->is_int() && !unc->is_rune())
5325 : return false;
5326 :
5327 76497 : mpz_t uval;
5328 76497 : if (unc->is_rune())
5329 0 : unc->get_rune(&uval);
5330 : else
5331 76497 : unc->get_int(&uval);
5332 76497 : mpz_t val;
5333 76497 : mpz_init(val);
5334 :
5335 76497 : switch (op)
5336 : {
5337 67435 : case OPERATOR_MINUS:
5338 67435 : mpz_neg(val, uval);
5339 67435 : break;
5340 :
5341 : case OPERATOR_NOT:
5342 : mpz_set_ui(val, mpz_cmp_si(uval, 0) == 0 ? 1 : 0);
5343 : break;
5344 :
5345 9062 : case OPERATOR_XOR:
5346 9062 : {
5347 9062 : Type* utype = unc->type();
5348 18124 : if (utype->integer_type() == NULL
5349 9062 : || utype->integer_type()->is_abstract())
5350 124 : mpz_com(val, uval);
5351 : else
5352 : {
5353 : // The number of HOST_WIDE_INTs that it takes to represent
5354 : // UVAL.
5355 8938 : size_t count = ((mpz_sizeinbase(uval, 2)
5356 : + HOST_BITS_PER_WIDE_INT
5357 8938 : - 1)
5358 : / HOST_BITS_PER_WIDE_INT);
5359 :
5360 8938 : unsigned HOST_WIDE_INT* phwi = new unsigned HOST_WIDE_INT[count];
5361 8938 : memset(phwi, 0, count * sizeof(HOST_WIDE_INT));
5362 :
5363 17876 : size_t obits = utype->integer_type()->bits();
5364 :
5365 17876 : if (!utype->integer_type()->is_unsigned() && mpz_sgn(uval) < 0)
5366 : {
5367 0 : mpz_t adj;
5368 0 : mpz_init_set_ui(adj, 1);
5369 0 : mpz_mul_2exp(adj, adj, obits);
5370 0 : mpz_add(uval, uval, adj);
5371 0 : mpz_clear(adj);
5372 : }
5373 :
5374 8938 : size_t ecount;
5375 8938 : mpz_export(phwi, &ecount, -1, sizeof(HOST_WIDE_INT), 0, 0, uval);
5376 8938 : go_assert(ecount <= count);
5377 :
5378 : // Trim down to the number of words required by the type.
5379 8938 : size_t ocount = ((obits + HOST_BITS_PER_WIDE_INT - 1)
5380 : / HOST_BITS_PER_WIDE_INT);
5381 8938 : go_assert(ocount <= count);
5382 :
5383 17876 : for (size_t i = 0; i < ocount; ++i)
5384 8938 : phwi[i] = ~phwi[i];
5385 :
5386 8938 : size_t clearbits = ocount * HOST_BITS_PER_WIDE_INT - obits;
5387 8938 : if (clearbits != 0)
5388 4176 : phwi[ocount - 1] &= (((unsigned HOST_WIDE_INT) (HOST_WIDE_INT) -1)
5389 4176 : >> clearbits);
5390 :
5391 8938 : mpz_import(val, ocount, -1, sizeof(HOST_WIDE_INT), 0, 0, phwi);
5392 :
5393 17876 : if (!utype->integer_type()->is_unsigned()
5394 8938 : && mpz_tstbit(val, obits - 1))
5395 : {
5396 7 : mpz_t adj;
5397 7 : mpz_init_set_ui(adj, 1);
5398 7 : mpz_mul_2exp(adj, adj, obits);
5399 7 : mpz_sub(val, val, adj);
5400 7 : mpz_clear(adj);
5401 : }
5402 :
5403 8938 : delete[] phwi;
5404 : }
5405 : }
5406 : break;
5407 :
5408 0 : default:
5409 0 : go_unreachable();
5410 : }
5411 :
5412 76497 : if (unc->is_rune())
5413 0 : nc->set_rune(NULL, val);
5414 : else
5415 76497 : nc->set_int(NULL, val);
5416 :
5417 76497 : mpz_clear(uval);
5418 76497 : mpz_clear(val);
5419 :
5420 76497 : if (!nc->set_type(unc->type(), true, location))
5421 : {
5422 0 : *issued_error = true;
5423 0 : return false;
5424 : }
5425 : return true;
5426 : }
5427 :
5428 : // Return the integral constant value of a unary expression, if it has one.
5429 :
5430 : bool
5431 38877 : Unary_expression::do_numeric_constant_value(Numeric_constant* nc)
5432 : {
5433 38877 : if (this->is_error_expression())
5434 : return false;
5435 :
5436 38877 : Numeric_constant unc;
5437 38877 : if (!this->expr_->numeric_constant_value(&unc))
5438 : return false;
5439 17447 : bool issued_error;
5440 17447 : bool r = Unary_expression::eval_constant(this->type_, this->op_, &unc,
5441 : this->location(), nc,
5442 : &issued_error);
5443 17447 : if (issued_error)
5444 0 : this->set_is_error();
5445 : return r;
5446 38877 : }
5447 :
5448 : // Return the boolean constant value of a unary expression, if it has one.
5449 :
5450 : bool
5451 57888 : Unary_expression::do_boolean_constant_value(bool* val)
5452 : {
5453 57888 : if (this->op_ == OPERATOR_NOT
5454 57888 : && this->expr_->boolean_constant_value(val))
5455 : {
5456 295 : *val = !*val;
5457 295 : return true;
5458 : }
5459 : return false;
5460 : }
5461 :
5462 : // Return the type of a unary expression.
5463 :
5464 : Type*
5465 20088562 : Unary_expression::do_type()
5466 : {
5467 20088562 : if (this->type_ == NULL)
5468 : {
5469 19590261 : switch (this->op_)
5470 : {
5471 3929967 : case OPERATOR_AND:
5472 3929967 : return Type::make_pointer_type(this->expr_->type());
5473 :
5474 15660294 : case OPERATOR_MULT:
5475 15660294 : {
5476 15660294 : if (this->expr_->is_type_expression())
5477 10468 : return Type::make_pointer_type(this->expr_->type());
5478 :
5479 15649826 : Type* subtype = this->expr_->type();
5480 15649826 : Type* points_to = subtype->points_to();
5481 15649826 : if (points_to == NULL)
5482 : {
5483 1 : this->report_error(_("expected pointer"));
5484 1 : this->type_ = Type::make_error_type();
5485 1 : return this->type_;
5486 : }
5487 : return points_to;
5488 : }
5489 :
5490 0 : default:
5491 0 : go_assert(saw_errors());
5492 0 : return Type::make_error_type();
5493 : }
5494 : }
5495 :
5496 : return this->type_;
5497 : }
5498 :
5499 : // Determine abstract types for a unary expression.
5500 :
5501 : void
5502 4815751 : Unary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
5503 : {
5504 4815751 : switch (this->op_)
5505 : {
5506 187668 : case OPERATOR_PLUS:
5507 187668 : case OPERATOR_MINUS:
5508 187668 : case OPERATOR_NOT:
5509 187668 : case OPERATOR_XOR:
5510 187668 : {
5511 187668 : if (this->type_ != NULL)
5512 20904 : return;
5513 :
5514 166764 : Type* dummy;
5515 166764 : Type_context subcontext(*context);
5516 166764 : if (this->expr_->is_untyped(&dummy) && this->expr_->is_constant())
5517 : {
5518 : // We evaluate an untyped operator as untyped. Then we
5519 : // convert it to the desired type. Otherwise we may, for
5520 : // example, give a useless error for one more than the
5521 : // most positive integer when it is the operand of a unary
5522 : // minus.
5523 62919 : subcontext.type = NULL;
5524 62919 : subcontext.may_be_abstract = true;
5525 : }
5526 166764 : this->expr_->determine_type(gogo, &subcontext);
5527 :
5528 166764 : this->type_ = this->expr_->type();
5529 :
5530 : // If this is an untyped expression in a typed context, use
5531 : // the context type. If this doesn't work we'll report an
5532 : // error later.
5533 166764 : if (this->type_->is_abstract()
5534 63184 : && !context->may_be_abstract
5535 220765 : && context->type != NULL)
5536 : {
5537 53524 : if (context->type->interface_type() == NULL)
5538 53296 : this->type_ = context->type;
5539 : else
5540 228 : this->type_ = this->type_->make_non_abstract_type();
5541 : }
5542 : }
5543 166764 : break;
5544 :
5545 2929077 : case OPERATOR_AND:
5546 : // Taking the address of something.
5547 2929077 : {
5548 2929077 : Type* subtype = (context->type == NULL
5549 2929077 : ? NULL
5550 2629573 : : context->type->points_to());
5551 2929077 : Type_context subcontext(subtype, false);
5552 2929077 : this->expr_->determine_type(gogo, &subcontext);
5553 : }
5554 2929077 : break;
5555 :
5556 1699006 : case OPERATOR_MULT:
5557 1699006 : {
5558 1699006 : if (this->expr_->is_type_expression())
5559 : {
5560 4891 : this->expr_->determine_type_no_context(gogo);
5561 4891 : return;
5562 : }
5563 :
5564 : // Indirecting through a pointer.
5565 1694115 : Type* subtype = (context->type == NULL
5566 1694115 : ? NULL
5567 53160 : : Type::make_pointer_type(context->type));
5568 1694115 : Type_context subcontext(subtype, false);
5569 1694115 : this->expr_->determine_type(gogo, &subcontext);
5570 : }
5571 1694115 : break;
5572 :
5573 0 : default:
5574 0 : go_unreachable();
5575 : }
5576 : }
5577 :
5578 : // Check types for a unary expression.
5579 :
5580 : void
5581 322830 : Unary_expression::do_check_types(Gogo*)
5582 : {
5583 322830 : if (this->is_error_expression())
5584 : return;
5585 :
5586 322828 : Type* type = this->expr_->type();
5587 322828 : if (type->is_error())
5588 : {
5589 0 : this->set_is_error();
5590 0 : return;
5591 : }
5592 :
5593 322828 : switch (this->op_)
5594 : {
5595 68635 : case OPERATOR_PLUS:
5596 68635 : case OPERATOR_MINUS:
5597 76490 : if (type->integer_type() == NULL
5598 103 : && type->float_type() == NULL
5599 322832 : && type->complex_type() == NULL)
5600 2 : this->report_error(_("expected numeric type"));
5601 : break;
5602 :
5603 32185 : case OPERATOR_NOT:
5604 32185 : if (!type->is_boolean_type())
5605 0 : this->report_error(_("expected boolean type"));
5606 : break;
5607 :
5608 2582 : case OPERATOR_XOR:
5609 2582 : if (type->integer_type() == NULL)
5610 2 : this->report_error(_("expected integer"));
5611 : break;
5612 :
5613 181054 : case OPERATOR_AND:
5614 181054 : if (!this->expr_->is_addressable())
5615 : {
5616 4826 : if (!this->create_temp_)
5617 : {
5618 1 : go_error_at(this->location(), "invalid operand for unary %<&%>");
5619 1 : this->set_is_error();
5620 : }
5621 : }
5622 : else
5623 176228 : this->expr_->issue_nil_check();
5624 : break;
5625 :
5626 38372 : case OPERATOR_MULT:
5627 38372 : if (this->expr_->is_type_expression())
5628 : break;
5629 :
5630 : // Catching an invalid indirection of unsafe.Pointer here avoid
5631 : // having to deal with TYPE_VOID in other places.
5632 38209 : if (this->expr_->type()->is_unsafe_pointer_type())
5633 : {
5634 1 : go_error_at(this->location(),
5635 : "invalid indirect of %<unsafe.Pointer%>");
5636 1 : this->set_is_error();
5637 1 : return;
5638 : }
5639 :
5640 : // Indirecting through a pointer.
5641 38208 : if (type->points_to() == NULL)
5642 0 : this->report_error(_("expected pointer"));
5643 38208 : if (type->points_to()->is_error())
5644 1 : this->set_is_error();
5645 : break;
5646 :
5647 0 : default:
5648 0 : go_unreachable();
5649 : }
5650 : }
5651 :
5652 : // Get the backend representation for a unary expression.
5653 :
5654 : Bexpression*
5655 3040376 : Unary_expression::do_get_backend(Translate_context* context)
5656 : {
5657 3040376 : Gogo* gogo = context->gogo();
5658 3040376 : Location loc = this->location();
5659 :
5660 : // Taking the address of a set-and-use-temporary expression requires
5661 : // setting the temporary and then taking the address.
5662 3040376 : if (this->op_ == OPERATOR_AND)
5663 : {
5664 1831097 : Set_and_use_temporary_expression* sut =
5665 1831097 : this->expr_->set_and_use_temporary_expression();
5666 619 : if (sut != NULL)
5667 : {
5668 619 : Temporary_statement* temp = sut->temporary();
5669 619 : Bvariable* bvar = temp->get_backend_variable(context);
5670 619 : Bexpression* bvar_expr =
5671 619 : gogo->backend()->var_expression(bvar, loc);
5672 619 : Bexpression* bval = sut->expression()->get_backend(context);
5673 :
5674 619 : Named_object* fn = context->function();
5675 619 : go_assert(fn != NULL);
5676 619 : Bfunction* bfn =
5677 619 : fn->func_value()->get_or_make_decl(gogo, fn);
5678 619 : Bstatement* bassign =
5679 619 : gogo->backend()->assignment_statement(bfn, bvar_expr, bval, loc);
5680 619 : Bexpression* bvar_addr =
5681 619 : gogo->backend()->address_expression(bvar_expr, loc);
5682 619 : return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
5683 : }
5684 : }
5685 :
5686 3039757 : Bexpression* ret;
5687 3039757 : Bexpression* bexpr = this->expr_->get_backend(context);
5688 3039757 : Btype* btype = (this->type_ == NULL
5689 3039757 : ? this->expr_->type()->get_backend(gogo)
5690 102250 : : this->type_->get_backend(gogo));
5691 3039757 : switch (this->op_)
5692 : {
5693 116 : case OPERATOR_PLUS:
5694 116 : ret = gogo->backend()->convert_expression(btype, bexpr, loc);
5695 116 : break;
5696 :
5697 10894 : case OPERATOR_MINUS:
5698 10894 : ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
5699 10894 : ret = gogo->backend()->convert_expression(btype, ret, loc);
5700 10894 : break;
5701 :
5702 97392 : case OPERATOR_NOT:
5703 97392 : case OPERATOR_XOR:
5704 97392 : ret = gogo->backend()->unary_expression(this->op_, bexpr, loc);
5705 97392 : ret = gogo->backend()->convert_expression(btype, ret, loc);
5706 97392 : break;
5707 :
5708 1830478 : case OPERATOR_AND:
5709 1830478 : if (!this->create_temp_)
5710 : {
5711 : // We should not see a non-constant constructor here; cases
5712 : // where we would see one should have been moved onto the
5713 : // heap at parse time. Taking the address of a nonconstant
5714 : // constructor will not do what the programmer expects.
5715 :
5716 1795139 : go_assert(!this->expr_->is_composite_literal()
5717 : || this->expr_->is_static_initializer());
5718 1795139 : if (this->expr_->classification() == EXPRESSION_UNARY)
5719 : {
5720 3790 : Unary_expression* ue =
5721 : static_cast<Unary_expression*>(this->expr_);
5722 3790 : go_assert(ue->op() != OPERATOR_AND);
5723 : }
5724 : }
5725 :
5726 1830478 : if (this->is_gc_root_ || this->is_slice_init_)
5727 : {
5728 289255 : std::string var_name;
5729 289255 : bool copy_to_heap = false;
5730 289255 : if (this->is_gc_root_)
5731 : {
5732 : // Build a decl for a GC root variable. GC roots are mutable, so
5733 : // they cannot be represented as an immutable_struct in the
5734 : // backend.
5735 2111 : var_name = gogo->gc_root_name();
5736 : }
5737 : else
5738 : {
5739 : // Build a decl for a slice value initializer. An immutable slice
5740 : // value initializer may have to be copied to the heap if it
5741 : // contains pointers in a non-constant context.
5742 287144 : var_name = gogo->initializer_name();
5743 :
5744 287144 : Array_type* at = this->expr_->type()->array_type();
5745 0 : go_assert(at != NULL);
5746 :
5747 : // If we are not copying the value to the heap, we will only
5748 : // initialize the value once, so we can use this directly
5749 : // rather than copying it. In that case we can't make it
5750 : // read-only, because the program is permitted to change it.
5751 287144 : copy_to_heap = (context->function() != NULL
5752 287144 : || context->is_const());
5753 : }
5754 2111 : unsigned int flags = (Backend::variable_is_hidden
5755 : | Backend::variable_address_is_taken);
5756 2111 : if (copy_to_heap)
5757 : flags |= Backend::variable_is_constant;
5758 289255 : Bvariable* implicit =
5759 289255 : gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
5760 289255 : gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
5761 : flags, bexpr);
5762 289255 : bexpr = gogo->backend()->var_expression(implicit, loc);
5763 :
5764 : // If we are not copying a slice initializer to the heap,
5765 : // then it can be changed by the program, so if it can
5766 : // contain pointers we must register it as a GC root.
5767 289255 : if (this->is_slice_init_
5768 287144 : && !copy_to_heap
5769 298118 : && this->expr_->type()->has_pointer())
5770 : {
5771 2660 : Bexpression* root =
5772 2660 : gogo->backend()->var_expression(implicit, loc);
5773 2660 : root = gogo->backend()->address_expression(root, loc);
5774 2660 : Type* type = Type::make_pointer_type(this->expr_->type());
5775 2660 : gogo->add_gc_root(Expression::make_backend(root, type, loc));
5776 : }
5777 289255 : }
5778 1541223 : else if ((this->expr_->is_composite_literal()
5779 1485772 : || this->expr_->string_expression() != NULL)
5780 2193134 : && this->expr_->is_static_initializer())
5781 : {
5782 707362 : std::string var_name(gogo->initializer_name());
5783 707362 : unsigned int flags = (Backend::variable_is_hidden
5784 : | Backend::variable_address_is_taken);
5785 707362 : Bvariable* decl =
5786 707362 : gogo->backend()->immutable_struct(var_name, "", flags, btype, loc);
5787 707362 : gogo->backend()->immutable_struct_set_init(decl, var_name, flags,
5788 : btype, loc, bexpr);
5789 707362 : bexpr = gogo->backend()->var_expression(decl, loc);
5790 707362 : }
5791 833861 : else if (this->expr_->is_constant())
5792 : {
5793 14716 : std::string var_name(gogo->initializer_name());
5794 14716 : unsigned int flags = (Backend::variable_is_hidden
5795 : | Backend::variable_is_constant
5796 : | Backend::variable_address_is_taken);
5797 14716 : Bvariable* decl =
5798 14716 : gogo->backend()->implicit_variable(var_name, "", btype, flags, 0);
5799 14716 : gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
5800 : flags, bexpr);
5801 14716 : bexpr = gogo->backend()->var_expression(decl, loc);
5802 14716 : }
5803 :
5804 1830478 : go_assert(!this->create_temp_ || this->expr_->is_multi_eval_safe());
5805 1830478 : ret = gogo->backend()->address_expression(bexpr, loc);
5806 1830478 : break;
5807 :
5808 1100877 : case OPERATOR_MULT:
5809 1100877 : {
5810 1100877 : go_assert(this->expr_->type()->points_to() != NULL);
5811 :
5812 1100877 : Type* ptype = this->expr_->type()->points_to();
5813 1100877 : Btype* pbtype = ptype->get_backend(gogo);
5814 1100877 : switch (this->requires_nil_check(gogo))
5815 : {
5816 : case NIL_CHECK_NOT_NEEDED:
5817 : break;
5818 0 : case NIL_CHECK_ERROR_ENCOUNTERED:
5819 0 : {
5820 0 : go_assert(saw_errors());
5821 0 : return gogo->backend()->error_expression();
5822 : }
5823 80150 : case NIL_CHECK_NEEDED:
5824 80150 : {
5825 80150 : go_assert(this->expr_->is_multi_eval_safe());
5826 :
5827 : // If we're nil-checking the result of a set-and-use-temporary
5828 : // expression, then pick out the target temp and use that
5829 : // for the final result of the conditional.
5830 80150 : Bexpression* tbexpr = bexpr;
5831 80150 : Bexpression* ubexpr = bexpr;
5832 80150 : Set_and_use_temporary_expression* sut =
5833 80150 : this->expr_->set_and_use_temporary_expression();
5834 0 : if (sut != NULL) {
5835 0 : Temporary_statement* temp = sut->temporary();
5836 0 : Bvariable* bvar = temp->get_backend_variable(context);
5837 0 : ubexpr = gogo->backend()->var_expression(bvar, loc);
5838 : }
5839 80150 : Bexpression* nil =
5840 80150 : Expression::make_nil(loc)->get_backend(context);
5841 80150 : Bexpression* compare =
5842 80150 : gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr,
5843 : nil, loc);
5844 80150 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM,
5845 : loc, 0);
5846 80150 : crash->determine_type_no_context(gogo);
5847 80150 : Bexpression* bcrash = crash->get_backend(context);
5848 80150 : Bfunction* bfn = context->function()->func_value()->get_decl();
5849 80150 : bexpr = gogo->backend()->conditional_expression(bfn, btype,
5850 : compare,
5851 : bcrash, ubexpr,
5852 : loc);
5853 80150 : break;
5854 : }
5855 0 : case NIL_CHECK_DEFAULT:
5856 0 : go_unreachable();
5857 : }
5858 1100877 : ret = gogo->backend()->indirect_expression(pbtype, bexpr, false, loc);
5859 : }
5860 1100877 : break;
5861 :
5862 0 : default:
5863 0 : go_unreachable();
5864 : }
5865 :
5866 : return ret;
5867 : }
5868 :
5869 : // Export a unary expression.
5870 :
5871 : void
5872 3143 : Unary_expression::do_export(Export_function_body* efb) const
5873 : {
5874 3143 : switch (this->op_)
5875 : {
5876 0 : case OPERATOR_PLUS:
5877 0 : efb->write_c_string("+");
5878 0 : break;
5879 112 : case OPERATOR_MINUS:
5880 112 : efb->write_c_string("-");
5881 112 : break;
5882 304 : case OPERATOR_NOT:
5883 304 : efb->write_c_string("!");
5884 304 : break;
5885 44 : case OPERATOR_XOR:
5886 44 : efb->write_c_string("^");
5887 44 : break;
5888 1003 : case OPERATOR_AND:
5889 1003 : efb->write_c_string("&");
5890 1003 : break;
5891 1680 : case OPERATOR_MULT:
5892 1680 : efb->write_c_string("*");
5893 1680 : break;
5894 0 : default:
5895 0 : go_unreachable();
5896 : }
5897 3143 : this->expr_->export_expression(efb);
5898 3143 : }
5899 :
5900 : // Import a unary expression.
5901 :
5902 : Expression*
5903 9449 : Unary_expression::do_import(Import_expression* imp, Location loc)
5904 : {
5905 9449 : Operator op;
5906 9449 : switch (imp->get_char())
5907 : {
5908 : case '+':
5909 : op = OPERATOR_PLUS;
5910 : break;
5911 7704 : case '-':
5912 7704 : op = OPERATOR_MINUS;
5913 7704 : break;
5914 537 : case '!':
5915 537 : op = OPERATOR_NOT;
5916 537 : break;
5917 74 : case '^':
5918 74 : op = OPERATOR_XOR;
5919 74 : break;
5920 640 : case '&':
5921 640 : op = OPERATOR_AND;
5922 640 : break;
5923 494 : case '*':
5924 494 : op = OPERATOR_MULT;
5925 494 : break;
5926 0 : default:
5927 0 : go_unreachable();
5928 : }
5929 9449 : if (imp->version() < EXPORT_FORMAT_V3)
5930 0 : imp->require_c_string(" ");
5931 9449 : Expression* expr = Expression::import_expression(imp, loc);
5932 9449 : return Expression::make_unary(op, expr, loc);
5933 : }
5934 :
5935 : // Dump ast representation of an unary expression.
5936 :
5937 : void
5938 0 : Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
5939 : {
5940 0 : ast_dump_context->dump_operator(this->op_);
5941 0 : ast_dump_context->ostream() << "(";
5942 0 : ast_dump_context->dump_expression(this->expr_);
5943 0 : ast_dump_context->ostream() << ") ";
5944 0 : }
5945 :
5946 : // Make a unary expression.
5947 :
5948 : Expression*
5949 3785625 : Expression::make_unary(Operator op, Expression* expr, Location location)
5950 : {
5951 3785625 : return new Unary_expression(op, expr, location);
5952 : }
5953 :
5954 : Expression*
5955 998873 : Expression::make_dereference(Expression* ptr,
5956 : Nil_check_classification docheck,
5957 : Location location)
5958 : {
5959 998873 : Expression* deref = Expression::make_unary(OPERATOR_MULT, ptr, location);
5960 998873 : if (docheck == NIL_CHECK_NEEDED)
5961 13135 : deref->unary_expression()->set_requires_nil_check(true);
5962 985738 : else if (docheck == NIL_CHECK_NOT_NEEDED)
5963 434317 : deref->unary_expression()->set_requires_nil_check(false);
5964 998873 : return deref;
5965 : }
5966 :
5967 : // If this is an indirection through a pointer, return the expression
5968 : // being pointed through. Otherwise return this.
5969 :
5970 : Expression*
5971 9703 : Expression::deref()
5972 : {
5973 9703 : if (this->classification_ == EXPRESSION_UNARY)
5974 : {
5975 4510 : Unary_expression* ue = static_cast<Unary_expression*>(this);
5976 4510 : if (ue->op() == OPERATOR_MULT)
5977 4510 : return ue->operand();
5978 : }
5979 : return this;
5980 : }
5981 :
5982 : // Class Binary_expression.
5983 :
5984 : // Traversal.
5985 :
5986 : int
5987 13844198 : Binary_expression::do_traverse(Traverse* traverse)
5988 : {
5989 13844198 : int t = Expression::traverse(&this->left_, traverse);
5990 13844198 : if (t == TRAVERSE_EXIT)
5991 : return TRAVERSE_EXIT;
5992 13462706 : return Expression::traverse(&this->right_, traverse);
5993 : }
5994 :
5995 : // Return whether a binary expression is untyped.
5996 :
5997 : bool
5998 103762724 : Binary_expression::do_is_untyped(Type** ptype) const
5999 : {
6000 103762724 : if (this->type_ != NULL)
6001 13270 : return Expression::is_untyped_type(this->type_, ptype);
6002 :
6003 103749454 : switch (this->op_)
6004 : {
6005 670841 : case OPERATOR_EQEQ:
6006 670841 : case OPERATOR_NOTEQ:
6007 670841 : case OPERATOR_LT:
6008 670841 : case OPERATOR_LE:
6009 670841 : case OPERATOR_GT:
6010 670841 : case OPERATOR_GE:
6011 : // Comparisons are untyped by default.
6012 670841 : *ptype = Type::make_boolean_type();
6013 670841 : return true;
6014 :
6015 205429 : case OPERATOR_LSHIFT:
6016 205429 : case OPERATOR_RSHIFT:
6017 : // A shift operation is untyped if the left hand expression is
6018 : // untyped. The right hand expression is irrelevant.
6019 205429 : return this->left_->is_untyped(ptype);
6020 :
6021 102873184 : default:
6022 102873184 : break;
6023 : }
6024 :
6025 102873184 : Type* tleft;
6026 102873184 : Type* tright;
6027 102873184 : if (!this->left_->is_untyped(&tleft)
6028 102873184 : || !this->right_->is_untyped(&tright))
6029 114848 : return false;
6030 :
6031 : // If both sides are numeric, pick a type based on the kind.
6032 102758336 : enum kind { INT, RUNE, FLOAT, COMPLEX };
6033 102758336 : enum kind kleft, kright;
6034 :
6035 102758336 : if (tleft->integer_type() != NULL)
6036 35030 : kleft = tleft->integer_type()->is_rune() ? RUNE : INT;
6037 102740821 : else if (tleft->float_type() != NULL)
6038 : kleft = FLOAT;
6039 102758337 : else if (tleft->complex_type() != NULL)
6040 : kleft = COMPLEX;
6041 : else
6042 : {
6043 : // Not numeric. If the types are different, we will report an
6044 : // error later.
6045 102740473 : *ptype = tleft;
6046 102740473 : return true;
6047 : }
6048 :
6049 17863 : if (tright->integer_type() != NULL)
6050 34622 : kright = tright->integer_type()->is_rune() ? RUNE : INT;
6051 552 : else if (tright->float_type() != NULL)
6052 : kright = FLOAT;
6053 17925 : else if (tright->complex_type() != NULL)
6054 : kright = COMPLEX;
6055 : else
6056 : {
6057 : // Types are different. We will report an error later.
6058 0 : *ptype = tleft;
6059 0 : return true;
6060 : }
6061 :
6062 17863 : if (kleft > kright)
6063 303 : *ptype = tleft;
6064 : else
6065 17560 : *ptype = tright;
6066 :
6067 : return true;
6068 : }
6069 :
6070 : // Return whether this expression may be used as a static initializer.
6071 :
6072 : bool
6073 473455 : Binary_expression::do_is_static_initializer() const
6074 : {
6075 473455 : if (!this->left_->is_static_initializer()
6076 473455 : || !this->right_->is_static_initializer())
6077 351 : return false;
6078 :
6079 : // Addresses can be static initializers, but we can't implement
6080 : // arbitray binary expressions of them.
6081 473104 : Unary_expression* lu = this->left_->unary_expression();
6082 473104 : Unary_expression* ru = this->right_->unary_expression();
6083 473104 : if (lu != NULL && lu->op() == OPERATOR_AND)
6084 : {
6085 0 : if (ru != NULL && ru->op() == OPERATOR_AND)
6086 0 : return this->op_ == OPERATOR_MINUS;
6087 : else
6088 0 : return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
6089 : }
6090 473104 : else if (ru != NULL && ru->op() == OPERATOR_AND)
6091 0 : return this->op_ == OPERATOR_PLUS || this->op_ == OPERATOR_MINUS;
6092 :
6093 : // Other cases should resolve in the backend.
6094 : return true;
6095 : }
6096 :
6097 : // Return the type to use for a binary operation on operands of
6098 : // LEFT_TYPE and RIGHT_TYPE. These are the types of constants and as
6099 : // such may be NULL or abstract.
6100 :
6101 : bool
6102 1303987 : Binary_expression::operation_type(Operator op, Type* left_type,
6103 : Type* right_type, Type** result_type)
6104 : {
6105 1303987 : if (left_type != right_type
6106 185638 : && !left_type->is_abstract()
6107 81373 : && !right_type->is_abstract()
6108 81090 : && left_type->base() != right_type->base()
6109 : && op != OPERATOR_LSHIFT
6110 1310631 : && op != OPERATOR_RSHIFT)
6111 : {
6112 : // May be a type error--let it be diagnosed elsewhere.
6113 : return false;
6114 : }
6115 :
6116 1303976 : if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
6117 : {
6118 110800 : if (left_type->integer_type() != NULL)
6119 110791 : *result_type = left_type;
6120 : else
6121 9 : *result_type = Type::make_abstract_integer_type();
6122 : }
6123 1193176 : else if (!left_type->is_abstract() && left_type->named_type() != NULL)
6124 912031 : *result_type = left_type;
6125 281145 : else if (!right_type->is_abstract() && right_type->named_type() != NULL)
6126 306 : *result_type = right_type;
6127 280839 : else if (!left_type->is_abstract())
6128 0 : *result_type = left_type;
6129 280839 : else if (!right_type->is_abstract())
6130 0 : *result_type = right_type;
6131 280839 : else if (left_type->complex_type() != NULL)
6132 1431 : *result_type = left_type;
6133 279408 : else if (right_type->complex_type() != NULL)
6134 400 : *result_type = right_type;
6135 279008 : else if (left_type->float_type() != NULL)
6136 2613 : *result_type = left_type;
6137 276395 : else if (right_type->float_type() != NULL)
6138 148 : *result_type = right_type;
6139 463386 : else if (left_type->integer_type() != NULL
6140 187139 : && left_type->integer_type()->is_rune())
6141 2104 : *result_type = left_type;
6142 459178 : else if (right_type->integer_type() != NULL
6143 185035 : && right_type->integer_type()->is_rune())
6144 65 : *result_type = right_type;
6145 : else
6146 274078 : *result_type = left_type;
6147 :
6148 : return true;
6149 : }
6150 :
6151 : // Convert an integer comparison code and an operator to a boolean
6152 : // value.
6153 :
6154 : bool
6155 2996 : Binary_expression::cmp_to_bool(Operator op, int cmp)
6156 : {
6157 2996 : switch (op)
6158 : {
6159 2268 : case OPERATOR_EQEQ:
6160 2268 : return cmp == 0;
6161 696 : break;
6162 696 : case OPERATOR_NOTEQ:
6163 696 : return cmp != 0;
6164 14 : break;
6165 14 : case OPERATOR_LT:
6166 14 : return cmp < 0;
6167 0 : break;
6168 0 : case OPERATOR_LE:
6169 0 : return cmp <= 0;
6170 8 : case OPERATOR_GT:
6171 8 : return cmp > 0;
6172 10 : case OPERATOR_GE:
6173 10 : return cmp >= 0;
6174 0 : default:
6175 0 : go_unreachable();
6176 : }
6177 : }
6178 :
6179 : // Compare constants according to OP.
6180 :
6181 : bool
6182 936 : Binary_expression::compare_constant(Operator op, Numeric_constant* left_nc,
6183 : Numeric_constant* right_nc,
6184 : Location location, bool* result)
6185 : {
6186 936 : Type* left_type = left_nc->type();
6187 936 : Type* right_type = right_nc->type();
6188 :
6189 936 : Type* type;
6190 936 : if (!Binary_expression::operation_type(op, left_type, right_type, &type))
6191 : return false;
6192 :
6193 : // When comparing an untyped operand to a typed operand, we are
6194 : // effectively coercing the untyped operand to the other operand's
6195 : // type, so make sure that is valid.
6196 936 : if (!left_nc->set_type(type, true, location)
6197 936 : || !right_nc->set_type(type, true, location))
6198 0 : return false;
6199 :
6200 936 : bool ret;
6201 936 : int cmp;
6202 936 : if (type->complex_type() != NULL)
6203 : {
6204 7 : if (op != OPERATOR_EQEQ && op != OPERATOR_NOTEQ)
6205 : return false;
6206 7 : ret = Binary_expression::compare_complex(left_nc, right_nc, &cmp);
6207 : }
6208 929 : else if (type->float_type() != NULL)
6209 28 : ret = Binary_expression::compare_float(left_nc, right_nc, &cmp);
6210 : else
6211 901 : ret = Binary_expression::compare_integer(left_nc, right_nc, &cmp);
6212 :
6213 936 : if (ret)
6214 936 : *result = Binary_expression::cmp_to_bool(op, cmp);
6215 :
6216 : return ret;
6217 : }
6218 :
6219 : // Compare integer constants.
6220 :
6221 : bool
6222 901 : Binary_expression::compare_integer(const Numeric_constant* left_nc,
6223 : const Numeric_constant* right_nc,
6224 : int* cmp)
6225 : {
6226 901 : mpz_t left_val;
6227 901 : if (!left_nc->to_int(&left_val))
6228 : return false;
6229 901 : mpz_t right_val;
6230 901 : if (!right_nc->to_int(&right_val))
6231 : {
6232 0 : mpz_clear(left_val);
6233 0 : return false;
6234 : }
6235 :
6236 901 : *cmp = mpz_cmp(left_val, right_val);
6237 :
6238 901 : mpz_clear(left_val);
6239 901 : mpz_clear(right_val);
6240 :
6241 901 : return true;
6242 : }
6243 :
6244 : // Compare floating point constants.
6245 :
6246 : bool
6247 28 : Binary_expression::compare_float(const Numeric_constant* left_nc,
6248 : const Numeric_constant* right_nc,
6249 : int* cmp)
6250 : {
6251 28 : mpfr_t left_val;
6252 28 : if (!left_nc->to_float(&left_val))
6253 : return false;
6254 28 : mpfr_t right_val;
6255 28 : if (!right_nc->to_float(&right_val))
6256 : {
6257 0 : mpfr_clear(left_val);
6258 0 : return false;
6259 : }
6260 :
6261 : // We already coerced both operands to the same type. If that type
6262 : // is not an abstract type, we need to round the values accordingly.
6263 28 : Type* type = left_nc->type();
6264 28 : if (!type->is_abstract() && type->float_type() != NULL)
6265 : {
6266 30 : int bits = type->float_type()->bits();
6267 15 : mpfr_prec_round(left_val, bits, MPFR_RNDN);
6268 15 : mpfr_prec_round(right_val, bits, MPFR_RNDN);
6269 : }
6270 :
6271 28 : *cmp = mpfr_cmp(left_val, right_val);
6272 :
6273 28 : mpfr_clear(left_val);
6274 28 : mpfr_clear(right_val);
6275 :
6276 28 : return true;
6277 : }
6278 :
6279 : // Compare complex constants. Complex numbers may only be compared
6280 : // for equality.
6281 :
6282 : bool
6283 7 : Binary_expression::compare_complex(const Numeric_constant* left_nc,
6284 : const Numeric_constant* right_nc,
6285 : int* cmp)
6286 : {
6287 7 : mpc_t left_val;
6288 7 : if (!left_nc->to_complex(&left_val))
6289 : return false;
6290 7 : mpc_t right_val;
6291 7 : if (!right_nc->to_complex(&right_val))
6292 : {
6293 0 : mpc_clear(left_val);
6294 0 : return false;
6295 : }
6296 :
6297 : // We already coerced both operands to the same type. If that type
6298 : // is not an abstract type, we need to round the values accordingly.
6299 7 : Type* type = left_nc->type();
6300 7 : if (!type->is_abstract() && type->complex_type() != NULL)
6301 : {
6302 4 : int bits = type->complex_type()->bits();
6303 2 : mpfr_prec_round(mpc_realref(left_val), bits / 2, MPFR_RNDN);
6304 2 : mpfr_prec_round(mpc_imagref(left_val), bits / 2, MPFR_RNDN);
6305 2 : mpfr_prec_round(mpc_realref(right_val), bits / 2, MPFR_RNDN);
6306 2 : mpfr_prec_round(mpc_imagref(right_val), bits / 2, MPFR_RNDN);
6307 : }
6308 :
6309 7 : *cmp = mpc_cmp(left_val, right_val) != 0;
6310 :
6311 7 : mpc_clear(left_val);
6312 7 : mpc_clear(right_val);
6313 :
6314 7 : return true;
6315 : }
6316 :
6317 : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. Return
6318 : // true if this could be done, false if not. Issue errors at LOCATION
6319 : // as appropriate, and sets *ISSUED_ERROR if it did.
6320 :
6321 : bool
6322 293931 : Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
6323 : Numeric_constant* right_nc,
6324 : Location location, Numeric_constant* nc,
6325 : bool* issued_error)
6326 : {
6327 293931 : *issued_error = false;
6328 293931 : switch (op)
6329 : {
6330 : case OPERATOR_OROR:
6331 : case OPERATOR_ANDAND:
6332 : case OPERATOR_EQEQ:
6333 : case OPERATOR_NOTEQ:
6334 : case OPERATOR_LT:
6335 : case OPERATOR_LE:
6336 : case OPERATOR_GT:
6337 : case OPERATOR_GE:
6338 : // These return boolean values, not numeric.
6339 : return false;
6340 293931 : default:
6341 293931 : break;
6342 : }
6343 :
6344 293931 : Type* left_type = left_nc->type();
6345 293931 : Type* right_type = right_nc->type();
6346 :
6347 293931 : Type* type;
6348 293931 : if (!Binary_expression::operation_type(op, left_type, right_type, &type))
6349 : return false;
6350 :
6351 293931 : bool is_shift = op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT;
6352 :
6353 : // When combining an untyped operand with a typed operand, we are
6354 : // effectively coercing the untyped operand to the other operand's
6355 : // type, so make sure that is valid.
6356 293931 : if (!left_nc->set_type(type, true, location))
6357 : return false;
6358 293931 : if (!is_shift && !right_nc->set_type(type, true, location))
6359 : return false;
6360 293931 : if (is_shift
6361 293931 : && right_type->integer_type() == NULL
6362 293931 : && !right_type->is_abstract())
6363 : return false;
6364 :
6365 293931 : bool r;
6366 293931 : if (type->complex_type() != NULL)
6367 1017 : r = Binary_expression::eval_complex(op, left_nc, right_nc, location, nc,
6368 : issued_error);
6369 292914 : else if (type->float_type() != NULL)
6370 1832 : r = Binary_expression::eval_float(op, left_nc, right_nc, location, nc,
6371 : issued_error);
6372 : else
6373 291082 : r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc,
6374 : issued_error);
6375 :
6376 293931 : if (r)
6377 : {
6378 293931 : r = nc->set_type(type, true, location);
6379 293931 : if (!r)
6380 12 : *issued_error = true;
6381 : }
6382 :
6383 : return r;
6384 : }
6385 :
6386 : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
6387 : // integer operations. Return true if this could be done, false if
6388 : // not.
6389 :
6390 : bool
6391 291082 : Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
6392 : const Numeric_constant* right_nc,
6393 : Location location, Numeric_constant* nc,
6394 : bool* issued_error)
6395 : {
6396 291082 : mpz_t left_val;
6397 291082 : if (!left_nc->to_int(&left_val))
6398 : return false;
6399 291082 : mpz_t right_val;
6400 291082 : if (!right_nc->to_int(&right_val))
6401 : {
6402 0 : mpz_clear(left_val);
6403 0 : return false;
6404 : }
6405 :
6406 291082 : mpz_t val;
6407 291082 : mpz_init(val);
6408 :
6409 291082 : switch (op)
6410 : {
6411 37520 : case OPERATOR_PLUS:
6412 37520 : mpz_add(val, left_val, right_val);
6413 37520 : if (mpz_sizeinbase(val, 2) > 0x100000)
6414 : {
6415 0 : go_error_at(location, "constant addition overflow");
6416 0 : nc->set_invalid();
6417 0 : mpz_set_ui(val, 1);
6418 0 : *issued_error = true;
6419 : }
6420 : break;
6421 27168 : case OPERATOR_MINUS:
6422 27168 : mpz_sub(val, left_val, right_val);
6423 27168 : if (mpz_sizeinbase(val, 2) > 0x100000)
6424 : {
6425 0 : go_error_at(location, "constant subtraction overflow");
6426 0 : nc->set_invalid();
6427 0 : mpz_set_ui(val, 1);
6428 0 : *issued_error = true;
6429 : }
6430 : break;
6431 6898 : case OPERATOR_OR:
6432 6898 : mpz_ior(val, left_val, right_val);
6433 6898 : break;
6434 22 : case OPERATOR_XOR:
6435 22 : mpz_xor(val, left_val, right_val);
6436 22 : break;
6437 95431 : case OPERATOR_MULT:
6438 95431 : mpz_mul(val, left_val, right_val);
6439 95431 : if (mpz_sizeinbase(val, 2) > 0x100000)
6440 : {
6441 1 : go_error_at(location, "constant multiplication overflow");
6442 1 : nc->set_invalid();
6443 1 : mpz_set_ui(val, 1);
6444 1 : *issued_error = true;
6445 : }
6446 : break;
6447 12095 : case OPERATOR_DIV:
6448 12095 : if (mpz_sgn(right_val) != 0)
6449 12095 : mpz_tdiv_q(val, left_val, right_val);
6450 : else
6451 : {
6452 0 : go_error_at(location, "division by zero");
6453 0 : nc->set_invalid();
6454 0 : mpz_set_ui(val, 0);
6455 0 : *issued_error = true;
6456 : }
6457 : break;
6458 118 : case OPERATOR_MOD:
6459 118 : if (mpz_sgn(right_val) != 0)
6460 118 : mpz_tdiv_r(val, left_val, right_val);
6461 : else
6462 : {
6463 0 : go_error_at(location, "division by zero");
6464 0 : nc->set_invalid();
6465 0 : mpz_set_ui(val, 0);
6466 0 : *issued_error = true;
6467 : }
6468 : break;
6469 103231 : case OPERATOR_LSHIFT:
6470 103231 : {
6471 103231 : unsigned long shift = mpz_get_ui(right_val);
6472 103231 : if (mpz_cmp_ui(right_val, shift) == 0 && shift <= 0x100000)
6473 103231 : mpz_mul_2exp(val, left_val, shift);
6474 : else
6475 : {
6476 0 : go_error_at(location, "shift count overflow");
6477 0 : nc->set_invalid();
6478 0 : mpz_set_ui(val, 1);
6479 0 : *issued_error = true;
6480 : }
6481 : break;
6482 : }
6483 : break;
6484 7569 : case OPERATOR_RSHIFT:
6485 7569 : {
6486 7569 : unsigned long shift = mpz_get_ui(right_val);
6487 7569 : if (mpz_cmp_ui(right_val, shift) != 0)
6488 : {
6489 0 : go_error_at(location, "shift count overflow");
6490 0 : nc->set_invalid();
6491 0 : mpz_set_ui(val, 1);
6492 0 : *issued_error = true;
6493 : }
6494 : else
6495 : {
6496 7569 : if (mpz_cmp_ui(left_val, 0) >= 0)
6497 7557 : mpz_tdiv_q_2exp(val, left_val, shift);
6498 : else
6499 12 : mpz_fdiv_q_2exp(val, left_val, shift);
6500 : }
6501 : break;
6502 : }
6503 : break;
6504 964 : case OPERATOR_AND:
6505 964 : mpz_and(val, left_val, right_val);
6506 964 : break;
6507 66 : case OPERATOR_BITCLEAR:
6508 66 : {
6509 66 : mpz_t tval;
6510 66 : mpz_init(tval);
6511 66 : mpz_com(tval, right_val);
6512 66 : mpz_and(val, left_val, tval);
6513 66 : mpz_clear(tval);
6514 : }
6515 66 : break;
6516 0 : default:
6517 0 : go_unreachable();
6518 : }
6519 :
6520 291082 : mpz_clear(left_val);
6521 291082 : mpz_clear(right_val);
6522 :
6523 291082 : if (left_nc->is_rune()
6524 291082 : || (op != OPERATOR_LSHIFT
6525 289428 : && op != OPERATOR_RSHIFT
6526 178630 : && right_nc->is_rune()))
6527 1703 : nc->set_rune(NULL, val);
6528 : else
6529 289379 : nc->set_int(NULL, val);
6530 :
6531 291082 : mpz_clear(val);
6532 :
6533 291082 : return true;
6534 : }
6535 :
6536 : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
6537 : // floating point operations. Return true if this could be done,
6538 : // false if not.
6539 :
6540 : bool
6541 1832 : Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
6542 : const Numeric_constant* right_nc,
6543 : Location location, Numeric_constant* nc,
6544 : bool* issued_error)
6545 : {
6546 1832 : mpfr_t left_val;
6547 1832 : if (!left_nc->to_float(&left_val))
6548 : return false;
6549 1832 : mpfr_t right_val;
6550 1832 : if (!right_nc->to_float(&right_val))
6551 : {
6552 0 : mpfr_clear(left_val);
6553 0 : return false;
6554 : }
6555 :
6556 1832 : mpfr_t val;
6557 1832 : mpfr_init(val);
6558 :
6559 1832 : bool ret = true;
6560 1832 : switch (op)
6561 : {
6562 261 : case OPERATOR_PLUS:
6563 261 : mpfr_add(val, left_val, right_val, MPFR_RNDN);
6564 261 : break;
6565 179 : case OPERATOR_MINUS:
6566 179 : mpfr_sub(val, left_val, right_val, MPFR_RNDN);
6567 179 : break;
6568 0 : case OPERATOR_OR:
6569 0 : case OPERATOR_XOR:
6570 0 : case OPERATOR_AND:
6571 0 : case OPERATOR_BITCLEAR:
6572 0 : case OPERATOR_MOD:
6573 0 : case OPERATOR_LSHIFT:
6574 0 : case OPERATOR_RSHIFT:
6575 0 : mpfr_set_ui(val, 0, MPFR_RNDN);
6576 0 : ret = false;
6577 0 : break;
6578 480 : case OPERATOR_MULT:
6579 480 : mpfr_mul(val, left_val, right_val, MPFR_RNDN);
6580 480 : break;
6581 912 : case OPERATOR_DIV:
6582 912 : if (!mpfr_zero_p(right_val))
6583 911 : mpfr_div(val, left_val, right_val, MPFR_RNDN);
6584 : else
6585 : {
6586 1 : go_error_at(location, "division by zero");
6587 1 : nc->set_invalid();
6588 1 : mpfr_set_ui(val, 0, MPFR_RNDN);
6589 1 : *issued_error = true;
6590 : }
6591 : break;
6592 0 : default:
6593 0 : go_unreachable();
6594 : }
6595 :
6596 1832 : mpfr_clear(left_val);
6597 1832 : mpfr_clear(right_val);
6598 :
6599 1832 : nc->set_float(NULL, val);
6600 1832 : mpfr_clear(val);
6601 :
6602 1832 : return ret;
6603 : }
6604 :
6605 : // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
6606 : // complex operations. Return true if this could be done, false if
6607 : // not.
6608 :
6609 : bool
6610 1017 : Binary_expression::eval_complex(Operator op, const Numeric_constant* left_nc,
6611 : const Numeric_constant* right_nc,
6612 : Location location, Numeric_constant* nc,
6613 : bool* issued_error)
6614 : {
6615 1017 : mpc_t left_val;
6616 1017 : if (!left_nc->to_complex(&left_val))
6617 : return false;
6618 1017 : mpc_t right_val;
6619 1017 : if (!right_nc->to_complex(&right_val))
6620 : {
6621 0 : mpc_clear(left_val);
6622 0 : return false;
6623 : }
6624 :
6625 1017 : mpc_t val;
6626 1017 : mpc_init2(val, mpc_precision);
6627 :
6628 1017 : bool ret = true;
6629 1017 : switch (op)
6630 : {
6631 702 : case OPERATOR_PLUS:
6632 702 : mpc_add(val, left_val, right_val, MPC_RNDNN);
6633 702 : break;
6634 266 : case OPERATOR_MINUS:
6635 266 : mpc_sub(val, left_val, right_val, MPC_RNDNN);
6636 266 : break;
6637 0 : case OPERATOR_OR:
6638 0 : case OPERATOR_XOR:
6639 0 : case OPERATOR_AND:
6640 0 : case OPERATOR_BITCLEAR:
6641 0 : case OPERATOR_MOD:
6642 0 : case OPERATOR_LSHIFT:
6643 0 : case OPERATOR_RSHIFT:
6644 0 : mpc_set_ui(val, 0, MPC_RNDNN);
6645 0 : ret = false;
6646 0 : break;
6647 13 : case OPERATOR_MULT:
6648 13 : mpc_mul(val, left_val, right_val, MPC_RNDNN);
6649 13 : break;
6650 36 : case OPERATOR_DIV:
6651 36 : if (mpc_cmp_si(right_val, 0) == 0)
6652 : {
6653 5 : go_error_at(location, "division by zero");
6654 5 : nc->set_invalid();
6655 5 : mpc_set_ui(val, 0, MPC_RNDNN);
6656 5 : *issued_error = true;
6657 5 : break;
6658 : }
6659 31 : mpc_div(val, left_val, right_val, MPC_RNDNN);
6660 31 : break;
6661 0 : default:
6662 0 : go_unreachable();
6663 : }
6664 :
6665 1017 : mpc_clear(left_val);
6666 1017 : mpc_clear(right_val);
6667 :
6668 1017 : nc->set_complex(NULL, val);
6669 1017 : mpc_clear(val);
6670 :
6671 1017 : return ret;
6672 : }
6673 :
6674 : // Lower a binary expression. We have to evaluate constant
6675 : // expressions now, in order to implement Go's unlimited precision
6676 : // constants.
6677 :
6678 : Expression*
6679 1496442 : Binary_expression::do_lower(Gogo* gogo, Named_object*,
6680 : Statement_inserter* inserter)
6681 : {
6682 1496442 : Location location = this->location();
6683 :
6684 1496442 : if (this->is_error_expression())
6685 360 : return Expression::make_error(location);
6686 :
6687 1496082 : Operator op = this->op_;
6688 1496082 : Expression* left = this->left_;
6689 1496082 : Expression* right = this->right_;
6690 :
6691 1496082 : if (left->is_error_expression() || right->is_error_expression())
6692 186 : return Expression::make_error(location);
6693 :
6694 1495896 : const bool is_comparison = (op == OPERATOR_EQEQ
6695 : || op == OPERATOR_NOTEQ
6696 : || op == OPERATOR_LT
6697 : || op == OPERATOR_LE
6698 : || op == OPERATOR_GT
6699 1495896 : || op == OPERATOR_GE);
6700 :
6701 : // Numeric constant expressions.
6702 1495896 : {
6703 1495896 : Numeric_constant left_nc;
6704 1495896 : Numeric_constant right_nc;
6705 1495896 : if (left->numeric_constant_value(&left_nc)
6706 1573131 : && right->numeric_constant_value(&right_nc))
6707 : {
6708 42654 : Expression* ret;
6709 42654 : if (is_comparison)
6710 : {
6711 936 : bool result;
6712 936 : if (!Binary_expression::compare_constant(op, &left_nc,
6713 : &right_nc, location,
6714 : &result))
6715 0 : return this;
6716 936 : ret = Expression::make_boolean(result, location);
6717 : }
6718 : else
6719 : {
6720 41718 : Numeric_constant nc;
6721 41718 : bool issued_error;
6722 41718 : if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
6723 : location, &nc,
6724 : &issued_error))
6725 : {
6726 12 : if (issued_error)
6727 12 : return Expression::make_error(location);
6728 0 : return this;
6729 : }
6730 41706 : ret = nc.expression(location);
6731 41718 : }
6732 :
6733 42642 : Type_context subcontext(this->type_, this->type_->is_abstract());
6734 42642 : ret->determine_type(gogo, &subcontext);
6735 42642 : ret->check_types(gogo);
6736 42642 : return ret;
6737 : }
6738 1495896 : }
6739 :
6740 : // String constant expressions.
6741 : //
6742 : // Avoid constant folding here if the left and right types are incompatible
6743 : // (leave the operation intact so that the type checker can complain about it
6744 : // later on). If concatenating an abstract string with a named string type,
6745 : // result type needs to be of the named type (see issue 31412).
6746 1453242 : if (left->type()->is_string_type()
6747 131954 : && right->type()->is_string_type()
6748 1585188 : && (left->type()->named_type() == NULL
6749 93524 : || right->type()->named_type() == NULL
6750 93524 : || left->type()->named_type() == right->type()->named_type()))
6751 : {
6752 131946 : std::string left_string;
6753 131946 : std::string right_string;
6754 131946 : if (left->string_constant_value(&left_string)
6755 178147 : && right->string_constant_value(&right_string))
6756 : {
6757 40346 : Expression* ret = NULL;
6758 40346 : if (op == OPERATOR_PLUS)
6759 : {
6760 38286 : delete left;
6761 38286 : delete right;
6762 38286 : ret = Expression::make_string_typed(left_string + right_string,
6763 : this->type_, location);
6764 : }
6765 2060 : else if (is_comparison)
6766 : {
6767 2060 : int cmp = left_string.compare(right_string);
6768 2060 : bool r = Binary_expression::cmp_to_bool(op, cmp);
6769 2060 : delete left;
6770 2060 : delete right;
6771 2060 : ret = Expression::make_boolean(r, location);
6772 : }
6773 :
6774 40346 : if (ret != NULL)
6775 : {
6776 40346 : Type_context subcontext(this->type_, this->type_->is_abstract());
6777 40346 : ret->determine_type(gogo, &subcontext);
6778 40346 : ret->check_types(gogo);
6779 40346 : return ret;
6780 : }
6781 : }
6782 131946 : }
6783 :
6784 : // Lower struct, array, and some interface comparisons.
6785 1412896 : if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
6786 : {
6787 493638 : if (left->type()->struct_type() != NULL
6788 8053 : && right->type()->struct_type() != NULL)
6789 8038 : return this->lower_struct_comparison(gogo, inserter);
6790 491926 : else if (left->type()->array_type() != NULL
6791 14379 : && !left->type()->is_slice_type()
6792 17804 : && right->type()->array_type() != NULL
6793 8895 : && !right->type()->is_slice_type())
6794 8895 : return this->lower_array_comparison(gogo, inserter);
6795 557939 : else if ((left->type()->interface_type() != NULL
6796 479082 : && right->type()->interface_type() == NULL)
6797 769160 : || (left->type()->interface_type() == NULL
6798 379365 : && right->type()->interface_type() != NULL))
6799 79140 : return this->lower_interface_value_comparison(gogo, inserter);
6800 : }
6801 :
6802 : // Lower string concatenation to String_concat_expression, so that
6803 : // we can group sequences of string additions.
6804 1316823 : if (this->left_->type()->is_string_type() && this->op_ == OPERATOR_PLUS)
6805 : {
6806 16280 : Expression_list* exprs;
6807 16280 : String_concat_expression* left_sce =
6808 16280 : this->left_->string_concat_expression();
6809 16280 : if (left_sce != NULL)
6810 5359 : exprs = left_sce->exprs();
6811 : else
6812 : {
6813 10921 : exprs = new Expression_list();
6814 10921 : exprs->push_back(this->left_);
6815 : }
6816 :
6817 16280 : String_concat_expression* right_sce =
6818 16280 : this->right_->string_concat_expression();
6819 16280 : if (right_sce != NULL)
6820 401 : exprs->append(right_sce->exprs());
6821 : else
6822 15879 : exprs->push_back(this->right_);
6823 :
6824 16280 : return Expression::make_string_concat(exprs);
6825 : }
6826 :
6827 1300543 : return this;
6828 : }
6829 :
6830 : // Lower a struct comparison.
6831 :
6832 : Expression*
6833 8038 : Binary_expression::lower_struct_comparison(Gogo* gogo,
6834 : Statement_inserter* inserter)
6835 : {
6836 8038 : Struct_type* st = this->left_->type()->struct_type();
6837 8038 : Struct_type* st2 = this->right_->type()->struct_type();
6838 8038 : if (st2 == NULL)
6839 0 : return this;
6840 8038 : if (st != st2
6841 8038 : && !Type::are_identical(st, st2,
6842 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
6843 : NULL))
6844 0 : return this;
6845 8038 : if (!Type::are_compatible_for_comparison(true, this->left_->type(),
6846 8038 : this->right_->type(), NULL))
6847 0 : return this;
6848 :
6849 : // See if we can compare using memcmp. As a heuristic, we use
6850 : // memcmp rather than field references and comparisons if there are
6851 : // more than two fields.
6852 8038 : if (st->compare_is_identity(gogo) && st->total_field_count() > 2)
6853 549 : return this->lower_compare_to_memcmp(gogo, inserter);
6854 :
6855 7489 : Location loc = this->location();
6856 :
6857 7489 : Expression* left = this->left_;
6858 7489 : Temporary_statement* left_temp = NULL;
6859 7489 : if (left->var_expression() == NULL
6860 7489 : && left->temporary_reference_expression() == NULL)
6861 : {
6862 7170 : left_temp = Statement::make_temporary(left->type(), NULL, loc);
6863 7170 : inserter->insert(left_temp);
6864 7170 : left = Expression::make_set_and_use_temporary(left_temp, left, loc);
6865 : }
6866 :
6867 7489 : Expression* right = this->right_;
6868 7489 : Temporary_statement* right_temp = NULL;
6869 7489 : if (right->var_expression() == NULL
6870 7489 : && right->temporary_reference_expression() == NULL)
6871 : {
6872 7304 : right_temp = Statement::make_temporary(right->type(), NULL, loc);
6873 7304 : inserter->insert(right_temp);
6874 7304 : right = Expression::make_set_and_use_temporary(right_temp, right, loc);
6875 : }
6876 :
6877 7489 : Expression* ret = Expression::make_boolean(true, loc);
6878 7489 : const Struct_field_list* fields = st->fields();
6879 7489 : unsigned int field_index = 0;
6880 7489 : for (Struct_field_list::const_iterator pf = fields->begin();
6881 25275 : pf != fields->end();
6882 17786 : ++pf, ++field_index)
6883 : {
6884 17786 : if (Gogo::is_sink_name(pf->field_name()))
6885 128 : continue;
6886 :
6887 17658 : if (field_index > 0)
6888 : {
6889 10486 : if (left_temp == NULL)
6890 554 : left = left->copy();
6891 : else
6892 9932 : left = Expression::make_temporary_reference(left_temp, loc);
6893 10486 : if (right_temp == NULL)
6894 365 : right = right->copy();
6895 : else
6896 10121 : right = Expression::make_temporary_reference(right_temp, loc);
6897 : }
6898 17658 : Expression* f1 = Expression::make_field_reference(left, field_index,
6899 : loc);
6900 17658 : Expression* f2 = Expression::make_field_reference(right, field_index,
6901 : loc);
6902 17658 : Expression* cond = Expression::make_binary(OPERATOR_EQEQ, f1, f2, loc);
6903 17658 : ret = Expression::make_binary(OPERATOR_ANDAND, ret, cond, loc);
6904 : }
6905 :
6906 7489 : if (this->op_ == OPERATOR_NOTEQ)
6907 6403 : ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
6908 :
6909 7489 : ret->determine_type_no_context(gogo);
6910 :
6911 7489 : return ret;
6912 : }
6913 :
6914 : // Lower an array comparison.
6915 :
6916 : Expression*
6917 8895 : Binary_expression::lower_array_comparison(Gogo* gogo,
6918 : Statement_inserter* inserter)
6919 : {
6920 8895 : Array_type* at = this->left_->type()->array_type();
6921 8895 : Array_type* at2 = this->right_->type()->array_type();
6922 8895 : if (at2 == NULL)
6923 0 : return this;
6924 8895 : if (at != at2
6925 8895 : && !Type::are_identical(at, at2,
6926 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
6927 : NULL))
6928 0 : return this;
6929 8895 : if (!Type::are_compatible_for_comparison(true, this->left_->type(),
6930 8895 : this->right_->type(), NULL))
6931 0 : return this;
6932 :
6933 : // Call memcmp directly if possible. This may let the middle-end
6934 : // optimize the call.
6935 8895 : if (at->compare_is_identity(gogo))
6936 7934 : return this->lower_compare_to_memcmp(gogo, inserter);
6937 :
6938 : // Call the array comparison function.
6939 961 : Named_object* equal_fn =
6940 961 : at->equal_function(gogo, this->left_->type()->named_type(), NULL);
6941 :
6942 961 : Location loc = this->location();
6943 :
6944 961 : Expression* func = Expression::make_func_reference(equal_fn, NULL, loc);
6945 :
6946 961 : Expression_list* args = new Expression_list();
6947 961 : args->push_back(this->operand_address(inserter, this->left_));
6948 961 : args->push_back(this->operand_address(inserter, this->right_));
6949 :
6950 961 : Call_expression* ce = Expression::make_call(func, args, false, loc);
6951 :
6952 : // Record that this is a call to a generated equality function. We
6953 : // need to do this because a comparison returns an abstract boolean
6954 : // type, but the function necessarily returns "bool". The
6955 : // difference shows up in code like
6956 : // type mybool bool
6957 : // var b mybool = [10]string{} == [10]string{}
6958 : // The comparison function returns "bool", but since a comparison
6959 : // has an abstract boolean type we need an implicit conversion to
6960 : // "mybool". The implicit conversion is inserted in
6961 : // Call_expression::do_flatten.
6962 961 : ce->set_is_equal_function();
6963 :
6964 961 : Expression* ret = ce;
6965 961 : if (this->op_ == OPERATOR_NOTEQ)
6966 485 : ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
6967 :
6968 961 : ret->determine_type_no_context(gogo);
6969 :
6970 961 : return ret;
6971 : }
6972 :
6973 : // Lower an interface to value comparison.
6974 :
6975 : Expression*
6976 79140 : Binary_expression::lower_interface_value_comparison(Gogo*,
6977 : Statement_inserter* inserter)
6978 : {
6979 79140 : Type* left_type = this->left_->type();
6980 79140 : Type* right_type = this->right_->type();
6981 79140 : Interface_type* ift;
6982 79140 : if (left_type->interface_type() != NULL)
6983 : {
6984 78857 : ift = left_type->interface_type();
6985 78857 : if (!ift->implements_interface(right_type, NULL))
6986 74700 : return this;
6987 : }
6988 : else
6989 : {
6990 283 : ift = right_type->interface_type();
6991 283 : if (!ift->implements_interface(left_type, NULL))
6992 0 : return this;
6993 : }
6994 4440 : if (!Type::are_compatible_for_comparison(true, left_type, right_type, NULL))
6995 0 : return this;
6996 :
6997 4440 : Location loc = this->location();
6998 :
6999 4440 : if (left_type->interface_type() == NULL
7000 283 : && left_type->points_to() == NULL
7001 89 : && !this->left_->is_addressable())
7002 : {
7003 4 : Temporary_statement* temp =
7004 4 : Statement::make_temporary(left_type, NULL, loc);
7005 4 : inserter->insert(temp);
7006 4 : this->left_ =
7007 4 : Expression::make_set_and_use_temporary(temp, this->left_, loc);
7008 : }
7009 :
7010 4440 : if (right_type->interface_type() == NULL
7011 4157 : && right_type->points_to() == NULL
7012 3326 : && !this->right_->is_addressable())
7013 : {
7014 2317 : Temporary_statement* temp =
7015 2317 : Statement::make_temporary(right_type, NULL, loc);
7016 2317 : inserter->insert(temp);
7017 2317 : this->right_ =
7018 2317 : Expression::make_set_and_use_temporary(temp, this->right_, loc);
7019 : }
7020 :
7021 4440 : return this;
7022 : }
7023 :
7024 : // Lower a struct or array comparison to a call to memcmp.
7025 :
7026 : Expression*
7027 8483 : Binary_expression::lower_compare_to_memcmp(Gogo* gogo,
7028 : Statement_inserter* inserter)
7029 : {
7030 8483 : Location loc = this->location();
7031 :
7032 8483 : Expression* a1 = this->operand_address(inserter, this->left_);
7033 8483 : Expression* a2 = this->operand_address(inserter, this->right_);
7034 8483 : Expression* len = Expression::make_type_info(this->left_->type(),
7035 : TYPE_INFO_SIZE);
7036 :
7037 8483 : Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP, loc, 3,
7038 : a1, a2, len);
7039 8483 : Type* int32_type = Type::lookup_integer_type("int32");
7040 8483 : Expression* zero = Expression::make_integer_ul(0, int32_type, loc);
7041 8483 : Expression* ret = Expression::make_binary(this->op_, call, zero, loc);
7042 8483 : Type_context context(this->type_, this->type_->is_abstract());
7043 8483 : ret->determine_type(gogo, &context);
7044 8483 : return ret;
7045 : }
7046 :
7047 : Expression*
7048 868869 : Binary_expression::do_flatten(Gogo* gogo, Named_object*,
7049 : Statement_inserter* inserter)
7050 : {
7051 868869 : Location loc = this->location();
7052 868869 : if (this->left_->type()->is_error_type()
7053 868869 : || this->right_->type()->is_error_type()
7054 868869 : || this->left_->is_error_expression()
7055 1737738 : || this->right_->is_error_expression())
7056 : {
7057 0 : go_assert(saw_errors());
7058 0 : return Expression::make_error(loc);
7059 : }
7060 :
7061 868869 : Temporary_statement* temp;
7062 :
7063 868869 : Type* left_type = this->left_->type();
7064 868869 : bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
7065 868869 : || this->op_ == OPERATOR_RSHIFT);
7066 868869 : bool is_idiv_op = ((this->op_ == OPERATOR_DIV &&
7067 1730164 : left_type->integer_type() != NULL)
7068 870470 : || this->op_ == OPERATOR_MOD);
7069 868869 : bool is_string_op = (left_type->is_string_type()
7070 1737738 : && this->right_->type()->is_string_type());
7071 :
7072 46743 : if (is_string_op)
7073 : {
7074 : // Mark string([]byte) operands to reuse the backing store.
7075 : // String comparison does not keep the reference, so it is safe.
7076 46743 : Type_conversion_expression* lce =
7077 46743 : this->left_->conversion_expression();
7078 1100 : if (lce != NULL && lce->expr()->type()->is_slice_type())
7079 1080 : lce->set_no_copy(true);
7080 46743 : Type_conversion_expression* rce =
7081 46743 : this->right_->conversion_expression();
7082 885 : if (rce != NULL && rce->expr()->type()->is_slice_type())
7083 395 : rce->set_no_copy(true);
7084 : }
7085 :
7086 868869 : if (is_shift_op
7087 843131 : || (is_idiv_op
7088 11890 : && (gogo->check_divide_by_zero() || gogo->check_divide_overflow()))
7089 1700110 : || is_string_op)
7090 : {
7091 84371 : if (!this->left_->is_multi_eval_safe())
7092 : {
7093 38136 : temp = Statement::make_temporary(NULL, this->left_, loc);
7094 38136 : inserter->insert(temp);
7095 38136 : this->left_ = Expression::make_temporary_reference(temp, loc);
7096 : }
7097 84371 : if (!this->right_->is_multi_eval_safe())
7098 : {
7099 43290 : temp =
7100 43290 : Statement::make_temporary(NULL, this->right_, loc);
7101 43290 : this->right_ = Expression::make_temporary_reference(temp, loc);
7102 43290 : inserter->insert(temp);
7103 : }
7104 : }
7105 868869 : return this;
7106 : }
7107 :
7108 :
7109 : // Return the address of EXPR, cast to unsafe.Pointer.
7110 :
7111 : Expression*
7112 18888 : Binary_expression::operand_address(Statement_inserter* inserter,
7113 : Expression* expr)
7114 : {
7115 18888 : Location loc = this->location();
7116 :
7117 18888 : if (!expr->is_addressable())
7118 : {
7119 2194 : Temporary_statement* temp = Statement::make_temporary(expr->type(), NULL,
7120 : loc);
7121 2194 : inserter->insert(temp);
7122 2194 : expr = Expression::make_set_and_use_temporary(temp, expr, loc);
7123 : }
7124 18888 : expr = Expression::make_unary(OPERATOR_AND, expr, loc);
7125 18888 : static_cast<Unary_expression*>(expr)->set_does_not_escape();
7126 18888 : Type* void_type = Type::make_void_type();
7127 18888 : Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
7128 18888 : return Expression::make_cast(unsafe_pointer_type, expr, loc);
7129 : }
7130 :
7131 : // Return the numeric constant value, if it has one.
7132 :
7133 : bool
7134 731469 : Binary_expression::do_numeric_constant_value(Numeric_constant* nc)
7135 : {
7136 731469 : if (this->is_error_expression())
7137 : return false;
7138 :
7139 731272 : Numeric_constant left_nc;
7140 731272 : if (!this->left_->numeric_constant_value(&left_nc))
7141 : return false;
7142 276414 : Numeric_constant right_nc;
7143 276414 : if (!this->right_->numeric_constant_value(&right_nc))
7144 : return false;
7145 252213 : bool issued_error;
7146 252213 : bool r = Binary_expression::eval_constant(this->op_, &left_nc, &right_nc,
7147 : this->location(), nc,
7148 : &issued_error);
7149 252213 : if (issued_error)
7150 1 : this->set_is_error();
7151 : return r;
7152 731272 : }
7153 :
7154 : // Return the boolean constant value, if it has one.
7155 :
7156 : bool
7157 1103404 : Binary_expression::do_boolean_constant_value(bool* val)
7158 : {
7159 1103404 : if (this->is_error_expression())
7160 : return false;
7161 :
7162 1103404 : bool is_comparison = false;
7163 1103404 : switch (this->op_)
7164 : {
7165 672060 : case OPERATOR_EQEQ:
7166 672060 : case OPERATOR_NOTEQ:
7167 672060 : case OPERATOR_LT:
7168 672060 : case OPERATOR_LE:
7169 672060 : case OPERATOR_GT:
7170 672060 : case OPERATOR_GE:
7171 672060 : is_comparison = true;
7172 672060 : break;
7173 : case OPERATOR_ANDAND:
7174 : case OPERATOR_OROR:
7175 : break;
7176 : default:
7177 : return false;
7178 : }
7179 :
7180 1675802 : Numeric_constant left_nc, right_nc;
7181 837901 : if (is_comparison
7182 672060 : && this->left_->numeric_constant_value(&left_nc)
7183 846499 : && this->right_->numeric_constant_value(&right_nc))
7184 0 : return Binary_expression::compare_constant(this->op_, &left_nc,
7185 : &right_nc,
7186 : this->location(),
7187 0 : val);
7188 :
7189 1675802 : std::string left_str, right_str;
7190 837901 : if (is_comparison
7191 672060 : && this->left_->string_constant_value(&left_str)
7192 837965 : && this->right_->string_constant_value(&right_str))
7193 : {
7194 0 : *val = Binary_expression::cmp_to_bool(this->op_,
7195 : left_str.compare(right_str));
7196 0 : return true;
7197 : }
7198 :
7199 837901 : bool left_bval;
7200 837901 : if (this->left_->boolean_constant_value(&left_bval))
7201 : {
7202 5727 : if (this->op_ == OPERATOR_ANDAND && !left_bval)
7203 : {
7204 1789 : *val = false;
7205 2797 : return true;
7206 : }
7207 3938 : else if (this->op_ == OPERATOR_OROR && left_bval)
7208 : {
7209 167 : *val = true;
7210 167 : return true;
7211 : }
7212 :
7213 3771 : bool right_bval;
7214 3771 : if (this->right_->boolean_constant_value(&right_bval))
7215 : {
7216 841 : switch (this->op_)
7217 : {
7218 2 : case OPERATOR_EQEQ:
7219 2 : *val = (left_bval == right_bval);
7220 2 : return true;
7221 0 : case OPERATOR_NOTEQ:
7222 0 : *val = (left_bval != right_bval);
7223 0 : return true;
7224 839 : case OPERATOR_ANDAND:
7225 839 : case OPERATOR_OROR:
7226 839 : *val = right_bval;
7227 839 : return true;
7228 0 : default:
7229 0 : go_unreachable();
7230 : }
7231 : }
7232 : }
7233 :
7234 : return false;
7235 : }
7236 :
7237 : // Note that the value is being discarded.
7238 :
7239 : bool
7240 2 : Binary_expression::do_discarding_value()
7241 : {
7242 2 : if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
7243 0 : return this->right_->discarding_value();
7244 : else
7245 : {
7246 2 : this->unused_value_error();
7247 2 : return false;
7248 : }
7249 : }
7250 :
7251 : // Get type.
7252 :
7253 : Type*
7254 7253083 : Binary_expression::do_type()
7255 : {
7256 7253083 : if (this->type_ == NULL)
7257 : {
7258 157 : go_assert(saw_errors());
7259 157 : return Type::make_error_type();
7260 : }
7261 :
7262 : return this->type_;
7263 : }
7264 :
7265 : // Set type for a binary expression.
7266 :
7267 : void
7268 2880813 : Binary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
7269 : {
7270 2880813 : if (this->type_ != NULL)
7271 539095 : return;
7272 :
7273 : // For a shift operation, the type of the binary expression is the
7274 : // type of the left operand. If the left operand is a constant,
7275 : // then it gets its type from the context.
7276 2341836 : bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
7277 2341836 : || this->op_ == OPERATOR_RSHIFT);
7278 :
7279 : // For a comparison operation, the type of the binary expression is
7280 : // a boolean type.
7281 2341836 : bool is_comparison = (this->op_ == OPERATOR_EQEQ
7282 : || this->op_ == OPERATOR_NOTEQ
7283 : || this->op_ == OPERATOR_LT
7284 : || this->op_ == OPERATOR_LE
7285 : || this->op_ == OPERATOR_GT
7286 2341836 : || this->op_ == OPERATOR_GE);
7287 :
7288 : // For constant expressions, the context of the result is not useful in
7289 : // determining the types of the operands. It is only legal to use abstract
7290 : // boolean, numeric, and string constants as operands where it is legal to
7291 : // use non-abstract boolean, numeric, and string constants, respectively.
7292 : // Any issues with the operation will be resolved in the check_types pass.
7293 2341836 : bool left_is_constant = this->left_->is_constant();
7294 2341836 : bool right_is_constant = this->right_->is_constant();
7295 2341836 : bool is_constant_expr = left_is_constant && right_is_constant;
7296 :
7297 2341836 : Type_context subcontext(*context);
7298 2341836 : if (is_comparison)
7299 1291780 : subcontext.type = NULL;
7300 :
7301 2341836 : Type* tleft;
7302 2341836 : bool left_is_untyped = this->left_->is_untyped(&tleft);
7303 2341836 : if (!left_is_untyped)
7304 : {
7305 1955194 : this->left_->determine_type(gogo, &subcontext);
7306 1955194 : tleft = this->left_->type();
7307 : }
7308 :
7309 2341836 : Type* tright;
7310 2341836 : bool right_is_untyped = this->right_->is_untyped(&tright);
7311 2341836 : if (!right_is_untyped)
7312 : {
7313 : // For a shift operation, the right operand should always be an
7314 : // integer.
7315 1768703 : if (is_shift_op)
7316 : {
7317 192174 : subcontext.type = Type::lookup_integer_type("uint");
7318 192174 : subcontext.may_be_abstract = false;
7319 : }
7320 :
7321 1768703 : this->right_->determine_type(gogo, &subcontext);
7322 1768703 : tright = this->right_->type();
7323 : }
7324 :
7325 : // For each operand we have the real type or, if the operand is a
7326 : // untyped, a guess at the type. Use this to determine the types of
7327 : // untyped operands.
7328 :
7329 2341836 : subcontext = *context;
7330 2341836 : if (left_is_untyped && (right_is_untyped || is_shift_op) && is_constant_expr)
7331 : {
7332 : // We evaluate the operands of an untyped expression as untyped
7333 : // values. Then we convert to the desired type. Otherwise we
7334 : // may, for example, mishandle a floating-point constant
7335 : // division as an integer division.
7336 123559 : subcontext.type = NULL;
7337 123559 : subcontext.may_be_abstract = true;
7338 : }
7339 2218277 : else if (is_comparison)
7340 : {
7341 : // In a comparison, the context does not determine the types of
7342 : // the operands.
7343 1290807 : subcontext.type = NULL;
7344 : }
7345 :
7346 : // Set the context for the left hand operand.
7347 :
7348 2341836 : if (is_shift_op)
7349 : {
7350 : // The right hand operand of a shift plays no role in
7351 : // determining the type of the left hand operand.
7352 222363 : if (subcontext.type == NULL
7353 17187 : && right_is_constant
7354 16137 : && context->may_be_abstract)
7355 5785 : subcontext.type = Type::make_abstract_integer_type();
7356 : }
7357 2119473 : else if (!tleft->is_abstract())
7358 1745704 : subcontext.type = tleft;
7359 373769 : else if (!tright->is_abstract())
7360 30915 : subcontext.type = tright;
7361 342854 : else if (subcontext.type == NULL)
7362 : {
7363 324651 : if ((tleft->integer_type() != NULL && tright->integer_type() != NULL)
7364 2625422 : || (tleft->float_type() != NULL && tright->float_type() != NULL)
7365 2623905 : || (tleft->complex_type() != NULL && tright->complex_type() != NULL)
7366 282017 : || (tleft->is_boolean_type() && tright->is_boolean_type()))
7367 : {
7368 : // Both sides have an abstract integer, abstract float,
7369 : // abstract complex, or abstract boolean type. Just let
7370 : // CONTEXT determine whether they may remain abstract or not.
7371 : }
7372 40093 : else if (tleft->complex_type() != NULL)
7373 8 : subcontext.type = tleft;
7374 40085 : else if (tright->complex_type() != NULL)
7375 818 : subcontext.type = tright;
7376 39267 : else if (tleft->float_type() != NULL)
7377 478 : subcontext.type = tleft;
7378 38789 : else if (tright->float_type() != NULL)
7379 360 : subcontext.type = tright;
7380 : else
7381 38429 : subcontext.type = tleft;
7382 : }
7383 :
7384 2341836 : if (left_is_untyped)
7385 : {
7386 386642 : this->left_->determine_type(gogo, &subcontext);
7387 386642 : tleft = this->left_->type();
7388 : }
7389 :
7390 2341836 : if (is_shift_op)
7391 : {
7392 : // We may have inherited an unusable type for the shift operand.
7393 : // Give a useful error if that happened.
7394 222363 : if (left_is_untyped
7395 222363 : && !is_constant_expr
7396 1497 : && subcontext.type != NULL
7397 1402 : && !subcontext.may_be_abstract
7398 1402 : && subcontext.type->interface_type() == NULL
7399 223753 : && subcontext.type->integer_type() == NULL
7400 123 : && !tleft->is_error()
7401 222486 : && !tright->is_error())
7402 123 : this->report_error(("invalid context-determined non-integer type "
7403 : "for left operand of shift"));
7404 :
7405 : // The context for the right hand operand is the same as for the
7406 : // left hand operand, except for a shift operator.
7407 222363 : subcontext.type = Type::lookup_integer_type("uint");
7408 222363 : subcontext.may_be_abstract = false;
7409 : }
7410 :
7411 2341836 : if (right_is_untyped)
7412 : {
7413 573133 : this->right_->determine_type(gogo, &subcontext);
7414 573133 : tright = this->right_->type();
7415 : }
7416 :
7417 2341836 : if (this->left_->is_error_expression()
7418 2341747 : || tleft->is_error()
7419 2341746 : || this->right_->is_error_expression()
7420 4683565 : || tright->is_error())
7421 : {
7422 107 : this->set_is_error();
7423 107 : return;
7424 : }
7425 :
7426 2341729 : if (is_comparison)
7427 : {
7428 1291729 : if (context->type != NULL && context->type->is_boolean_type())
7429 543376 : this->type_ = context->type;
7430 748353 : else if (!context->may_be_abstract)
7431 646396 : this->type_ = Type::lookup_bool_type();
7432 : else
7433 101957 : this->type_ = Type::make_boolean_type();
7434 : }
7435 : else
7436 : {
7437 1050000 : if (is_shift_op)
7438 : {
7439 : // Shifts only work with integers, so force an abstract
7440 : // floating-point type (such as 1.0 << 1) into an integer.
7441 222356 : if (tleft->is_abstract()
7442 11454 : && tleft->integer_type() == NULL
7443 222444 : && context->type == NULL)
7444 : {
7445 2 : this->type_ = Type::make_abstract_integer_type();
7446 2 : if (!context->may_be_abstract)
7447 2 : this->type_ = this->type_->make_non_abstract_type();
7448 : }
7449 : else
7450 222354 : this->type_ = tleft;
7451 : }
7452 : else
7453 : {
7454 827644 : if (!Binary_expression::operation_type(this->op_, tleft, tright,
7455 : &this->type_))
7456 : {
7457 11 : this->report_error("incompatible types in binary expression");
7458 11 : this->type_ = Type::make_error_type();
7459 11 : return;
7460 : }
7461 : }
7462 :
7463 : // If this is an untyped expression in a typed context, use the
7464 : // context type. If this doesn't work we'll report an error
7465 : // later.
7466 1049989 : if (this->type_->is_abstract()
7467 122662 : && !context->may_be_abstract
7468 1121918 : && context->type != NULL)
7469 : {
7470 21121 : if (context->type->interface_type() == NULL
7471 20884 : && ((this->type_->is_numeric_type()
7472 19294 : && context->type->is_numeric_type())
7473 1602 : || (this->type_->is_string_type()
7474 1253 : && context->type->is_string_type())
7475 381 : || (this->type_->is_boolean_type()
7476 337 : && context->type->is_boolean_type())))
7477 20840 : this->type_ = context->type;
7478 2341999 : else if (context->type->interface_type() != NULL)
7479 237 : this->type_ = this->type_->make_non_abstract_type();
7480 : }
7481 : }
7482 : }
7483 :
7484 : // Report an error if the binary operator OP does not support TYPE.
7485 : // OTYPE is the type of the other operand. Return whether the
7486 : // operation is OK. This should not be used for shift.
7487 :
7488 : bool
7489 869128 : Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
7490 : Location location)
7491 : {
7492 869128 : switch (op)
7493 : {
7494 64063 : case OPERATOR_OROR:
7495 64063 : case OPERATOR_ANDAND:
7496 64063 : if (!type->is_boolean_type()
7497 128126 : || !otype->is_boolean_type())
7498 : {
7499 0 : go_error_at(location, "expected boolean type");
7500 0 : return false;
7501 : }
7502 : break;
7503 :
7504 417882 : case OPERATOR_EQEQ:
7505 417882 : case OPERATOR_NOTEQ:
7506 417882 : {
7507 417882 : std::string reason;
7508 417882 : if (!Type::are_compatible_for_comparison(true, type, otype, &reason))
7509 : {
7510 32 : go_error_at(location, "%s", reason.c_str());
7511 32 : return false;
7512 : }
7513 32 : }
7514 417850 : break;
7515 :
7516 152884 : case OPERATOR_LT:
7517 152884 : case OPERATOR_LE:
7518 152884 : case OPERATOR_GT:
7519 152884 : case OPERATOR_GE:
7520 152884 : {
7521 152884 : std::string reason;
7522 152884 : if (!Type::are_compatible_for_comparison(false, type, otype, &reason))
7523 : {
7524 20 : go_error_at(location, "%s", reason.c_str());
7525 20 : return false;
7526 : }
7527 20 : }
7528 152864 : break;
7529 :
7530 118413 : case OPERATOR_PLUS:
7531 118413 : case OPERATOR_PLUSEQ:
7532 173006 : if ((!type->is_numeric_type() && !type->is_string_type())
7533 291419 : || (!otype->is_numeric_type() && !otype->is_string_type()))
7534 : {
7535 0 : go_error_at(location,
7536 : "expected integer, floating, complex, or string type");
7537 0 : return false;
7538 : }
7539 : break;
7540 :
7541 76621 : case OPERATOR_MINUS:
7542 76621 : case OPERATOR_MINUSEQ:
7543 76621 : case OPERATOR_MULT:
7544 76621 : case OPERATOR_MULTEQ:
7545 76621 : case OPERATOR_DIV:
7546 76621 : case OPERATOR_DIVEQ:
7547 153241 : if (!type->is_numeric_type() || !otype->is_numeric_type())
7548 : {
7549 1 : go_error_at(location, "expected integer, floating, or complex type");
7550 1 : return false;
7551 : }
7552 : break;
7553 :
7554 39265 : case OPERATOR_MOD:
7555 39265 : case OPERATOR_MODEQ:
7556 39265 : case OPERATOR_OR:
7557 39265 : case OPERATOR_OREQ:
7558 39265 : case OPERATOR_AND:
7559 39265 : case OPERATOR_ANDEQ:
7560 39265 : case OPERATOR_XOR:
7561 39265 : case OPERATOR_XOREQ:
7562 39265 : case OPERATOR_BITCLEAR:
7563 39265 : case OPERATOR_BITCLEAREQ:
7564 78518 : if (type->integer_type() == NULL || otype->integer_type() == NULL)
7565 : {
7566 12 : go_error_at(location, "expected integer type");
7567 12 : return false;
7568 : }
7569 : break;
7570 :
7571 0 : default:
7572 0 : go_unreachable();
7573 : }
7574 :
7575 : return true;
7576 : }
7577 :
7578 : // Check types.
7579 :
7580 : void
7581 594868 : Binary_expression::do_check_types(Gogo*)
7582 : {
7583 594868 : if (this->classification() == EXPRESSION_ERROR)
7584 : return;
7585 :
7586 594636 : Type* left_type = this->left_->type();
7587 594636 : Type* right_type = this->right_->type();
7588 594636 : if (left_type->is_error() || right_type->is_error())
7589 : {
7590 1 : this->set_is_error();
7591 1 : return;
7592 : }
7593 :
7594 594635 : if (this->op_ == OPERATOR_EQEQ
7595 : || this->op_ == OPERATOR_NOTEQ
7596 : || this->op_ == OPERATOR_LT
7597 : || this->op_ == OPERATOR_LE
7598 : || this->op_ == OPERATOR_GT
7599 594635 : || this->op_ == OPERATOR_GE)
7600 : {
7601 285441 : if (left_type->is_nil_type() && right_type->is_nil_type())
7602 : {
7603 2 : this->report_error(_("invalid comparison of nil with nil"));
7604 2 : return;
7605 : }
7606 285439 : if (!Type::are_assignable(left_type, right_type, NULL)
7607 285439 : && !Type::are_assignable(right_type, left_type, NULL))
7608 : {
7609 32 : this->report_error(_("incompatible types in binary expression"));
7610 32 : return;
7611 : }
7612 285407 : if (!Binary_expression::check_operator_type(this->op_, left_type,
7613 : right_type,
7614 : this->location())
7615 285407 : || !Binary_expression::check_operator_type(this->op_, right_type,
7616 : left_type,
7617 : this->location()))
7618 : {
7619 52 : this->set_is_error();
7620 52 : return;
7621 : }
7622 : }
7623 309194 : else if (this->op_ != OPERATOR_LSHIFT && this->op_ != OPERATOR_RSHIFT)
7624 : {
7625 274770 : if (!Type::are_compatible_for_binop(left_type, right_type))
7626 : {
7627 16 : this->report_error(_("incompatible types in binary expression"));
7628 16 : return;
7629 : }
7630 274754 : if (!Binary_expression::check_operator_type(this->op_, left_type,
7631 : right_type,
7632 : this->location()))
7633 : {
7634 12 : this->set_is_error();
7635 12 : return;
7636 : }
7637 274742 : if (this->op_ == OPERATOR_DIV || this->op_ == OPERATOR_MOD)
7638 : {
7639 : // Division by a zero integer constant is an error.
7640 15069 : Numeric_constant rconst;
7641 15069 : unsigned long rval;
7642 15069 : if (left_type->integer_type() != NULL
7643 12915 : && this->right_->numeric_constant_value(&rconst)
7644 9862 : && rconst.to_unsigned_long(&rval) == Numeric_constant::NC_UL_VALID
7645 9673 : && rval == 0)
7646 : {
7647 2 : this->report_error(_("integer division by zero"));
7648 2 : return;
7649 : }
7650 15069 : }
7651 : }
7652 : else
7653 : {
7654 34424 : if (left_type->integer_type() == NULL
7655 41 : && !left_type->is_abstract()
7656 32 : && !this->is_constant())
7657 32 : this->report_error(_("shift of non-integer operand"));
7658 :
7659 34424 : if (right_type->is_string_type())
7660 0 : this->report_error(_("shift count not integer"));
7661 34424 : else if (!right_type->is_abstract()
7662 34424 : && right_type->integer_type() == NULL)
7663 0 : this->report_error(_("shift count not integer"));
7664 : else
7665 : {
7666 34424 : Numeric_constant nc;
7667 34424 : if (this->right_->numeric_constant_value(&nc))
7668 : {
7669 30682 : mpz_t val;
7670 30682 : if (!nc.to_int(&val))
7671 0 : this->report_error(_("shift count not integer"));
7672 : else
7673 : {
7674 30682 : if (mpz_sgn(val) < 0)
7675 : {
7676 1 : this->report_error(_("negative shift count"));
7677 1 : Location rloc = this->right_->location();
7678 1 : this->right_ = Expression::make_integer_ul(0, right_type,
7679 : rloc);
7680 : }
7681 30682 : mpz_clear(val);
7682 : }
7683 : }
7684 34424 : }
7685 : }
7686 : }
7687 :
7688 : // Get the backend representation for a binary expression.
7689 :
7690 : Bexpression*
7691 1996101 : Binary_expression::do_get_backend(Translate_context* context)
7692 : {
7693 1996101 : Gogo* gogo = context->gogo();
7694 1996101 : Location loc = this->location();
7695 1996101 : Type* left_type = this->left_->type();
7696 1996101 : Type* right_type = this->right_->type();
7697 :
7698 1996101 : bool use_left_type = true;
7699 1996101 : bool is_shift_op = false;
7700 1996101 : bool is_idiv_op = false;
7701 1996101 : switch (this->op_)
7702 : {
7703 1266990 : case OPERATOR_EQEQ:
7704 1266990 : case OPERATOR_NOTEQ:
7705 1266990 : case OPERATOR_LT:
7706 1266990 : case OPERATOR_LE:
7707 1266990 : case OPERATOR_GT:
7708 1266990 : case OPERATOR_GE:
7709 1266990 : return Expression::comparison(context, this->type_, this->op_,
7710 1266990 : this->left_, this->right_, loc);
7711 :
7712 : case OPERATOR_OROR:
7713 : case OPERATOR_ANDAND:
7714 729111 : use_left_type = false;
7715 : break;
7716 : case OPERATOR_PLUS:
7717 : case OPERATOR_MINUS:
7718 : case OPERATOR_OR:
7719 : case OPERATOR_XOR:
7720 : case OPERATOR_MULT:
7721 : break;
7722 8928 : case OPERATOR_DIV:
7723 745409 : if (left_type->float_type() != NULL || left_type->complex_type() != NULL)
7724 : break;
7725 : // Fall through.
7726 : case OPERATOR_MOD:
7727 : is_idiv_op = true;
7728 : break;
7729 143543 : case OPERATOR_LSHIFT:
7730 143543 : case OPERATOR_RSHIFT:
7731 143543 : is_shift_op = true;
7732 143543 : break;
7733 2018 : case OPERATOR_BITCLEAR:
7734 2018 : this->right_ = Expression::make_unary(OPERATOR_XOR, this->right_, loc);
7735 : case OPERATOR_AND:
7736 : break;
7737 0 : default:
7738 0 : go_unreachable();
7739 : }
7740 :
7741 : // The only binary operation for string is +, and that should have
7742 : // been converted to a String_concat_expression in do_lower.
7743 729111 : go_assert(!left_type->is_string_type());
7744 :
7745 729111 : Bexpression* left = this->left_->get_backend(context);
7746 729111 : Bexpression* right = this->right_->get_backend(context);
7747 :
7748 729111 : Type* type = use_left_type ? left_type : right_type;
7749 729111 : Btype* btype = type->get_backend(gogo);
7750 :
7751 729111 : Bexpression* ret =
7752 729111 : gogo->backend()->binary_expression(this->op_, left, right, loc);
7753 729111 : ret = gogo->backend()->convert_expression(btype, ret, loc);
7754 :
7755 : // Initialize overflow constants.
7756 729111 : Bexpression* overflow;
7757 729111 : mpz_t zero;
7758 729111 : mpz_init_set_ui(zero, 0UL);
7759 729111 : mpz_t one;
7760 729111 : mpz_init_set_ui(one, 1UL);
7761 729111 : mpz_t neg_one;
7762 729111 : mpz_init_set_si(neg_one, -1);
7763 :
7764 729111 : Btype* left_btype = left_type->get_backend(gogo);
7765 729111 : Btype* right_btype = right_type->get_backend(gogo);
7766 :
7767 : // In Go, a shift larger than the size of the type is well-defined.
7768 : // This is not true in C, so we need to insert a conditional.
7769 : // We also need to check for a negative shift count.
7770 729111 : if (is_shift_op)
7771 : {
7772 143543 : go_assert(left_type->integer_type() != NULL);
7773 143543 : go_assert(right_type->integer_type() != NULL);
7774 :
7775 287086 : int bits = left_type->integer_type()->bits();
7776 :
7777 143543 : Numeric_constant nc;
7778 143543 : unsigned long ul;
7779 143543 : if (!this->right_->numeric_constant_value(&nc)
7780 139593 : || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID
7781 283136 : || ul >= static_cast<unsigned long>(bits))
7782 : {
7783 4368 : mpz_t bitsval;
7784 4368 : mpz_init_set_ui(bitsval, bits);
7785 4368 : Bexpression* bits_expr =
7786 4368 : gogo->backend()->integer_constant_expression(right_btype, bitsval);
7787 4368 : Bexpression* compare =
7788 4368 : gogo->backend()->binary_expression(OPERATOR_LT,
7789 : right, bits_expr, loc);
7790 :
7791 4368 : Bexpression* zero_expr =
7792 4368 : gogo->backend()->integer_constant_expression(left_btype, zero);
7793 4368 : overflow = zero_expr;
7794 4368 : Bfunction* bfn = context->function()->func_value()->get_decl();
7795 4368 : if (this->op_ == OPERATOR_RSHIFT
7796 5848 : && !left_type->integer_type()->is_unsigned())
7797 : {
7798 344 : Bexpression* neg_expr =
7799 344 : gogo->backend()->binary_expression(OPERATOR_LT, left,
7800 : zero_expr, loc);
7801 344 : Bexpression* neg_one_expr =
7802 344 : gogo->backend()->integer_constant_expression(left_btype,
7803 : neg_one);
7804 344 : overflow = gogo->backend()->conditional_expression(bfn,
7805 : btype,
7806 : neg_expr,
7807 : neg_one_expr,
7808 : zero_expr,
7809 : loc);
7810 : }
7811 4368 : ret = gogo->backend()->conditional_expression(bfn, btype, compare,
7812 : ret, overflow, loc);
7813 4368 : mpz_clear(bitsval);
7814 : }
7815 :
7816 287086 : if (!right_type->integer_type()->is_unsigned()
7817 143543 : && (!this->right_->numeric_constant_value(&nc)
7818 425 : || nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID))
7819 : {
7820 133 : Bexpression* zero_expr =
7821 133 : gogo->backend()->integer_constant_expression(right_btype, zero);
7822 133 : Bexpression* compare =
7823 133 : gogo->backend()->binary_expression(OPERATOR_LT, right, zero_expr,
7824 : loc);
7825 133 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_SHIFT,
7826 : loc, 0);
7827 133 : crash->determine_type_no_context(gogo);
7828 133 : Bexpression* bcrash = crash->get_backend(context);
7829 133 : Bfunction* bfn = context->function()->func_value()->get_decl();
7830 133 : ret = gogo->backend()->conditional_expression(bfn, btype, compare,
7831 : bcrash, ret, loc);
7832 : }
7833 143543 : }
7834 :
7835 : // Add checks for division by zero and division overflow as needed.
7836 729111 : if (is_idiv_op)
7837 : {
7838 11583 : if (gogo->check_divide_by_zero())
7839 : {
7840 : // right == 0
7841 11583 : Bexpression* zero_expr =
7842 11583 : gogo->backend()->integer_constant_expression(right_btype, zero);
7843 11583 : Bexpression* check =
7844 11583 : gogo->backend()->binary_expression(OPERATOR_EQEQ,
7845 : right, zero_expr, loc);
7846 :
7847 11583 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_DIVIDE,
7848 : loc, 0);
7849 11583 : crash->determine_type_no_context(gogo);
7850 11583 : Bexpression* bcrash = crash->get_backend(context);
7851 :
7852 : // right == 0 ? (panicdivide(), 0) : ret
7853 11583 : Bfunction* bfn = context->function()->func_value()->get_decl();
7854 11583 : ret = gogo->backend()->conditional_expression(bfn, btype,
7855 : check, bcrash,
7856 : ret, loc);
7857 : }
7858 :
7859 11583 : if (gogo->check_divide_overflow())
7860 : {
7861 : // right == -1
7862 : // FIXME: It would be nice to say that this test is expected
7863 : // to return false.
7864 :
7865 11583 : Bexpression* neg_one_expr =
7866 11583 : gogo->backend()->integer_constant_expression(right_btype, neg_one);
7867 11583 : Bexpression* check =
7868 11583 : gogo->backend()->binary_expression(OPERATOR_EQEQ,
7869 : right, neg_one_expr, loc);
7870 :
7871 11583 : Bexpression* zero_expr =
7872 11583 : gogo->backend()->integer_constant_expression(btype, zero);
7873 11583 : Bexpression* one_expr =
7874 11583 : gogo->backend()->integer_constant_expression(btype, one);
7875 11583 : Bfunction* bfn = context->function()->func_value()->get_decl();
7876 :
7877 23166 : if (type->integer_type()->is_unsigned())
7878 : {
7879 : // An unsigned -1 is the largest possible number, so
7880 : // dividing is always 1 or 0.
7881 :
7882 5288 : Bexpression* cmp =
7883 5288 : gogo->backend()->binary_expression(OPERATOR_EQEQ,
7884 : left, right, loc);
7885 5288 : if (this->op_ == OPERATOR_DIV)
7886 3207 : overflow =
7887 3207 : gogo->backend()->conditional_expression(bfn, btype, cmp,
7888 : one_expr, zero_expr,
7889 : loc);
7890 : else
7891 2081 : overflow =
7892 2081 : gogo->backend()->conditional_expression(bfn, btype, cmp,
7893 : zero_expr, left,
7894 : loc);
7895 : }
7896 : else
7897 : {
7898 : // Computing left / -1 is the same as computing - left,
7899 : // which does not overflow since Go sets -fwrapv.
7900 6295 : if (this->op_ == OPERATOR_DIV)
7901 : {
7902 4134 : Expression* negate_expr =
7903 4134 : Expression::make_unary(OPERATOR_MINUS, this->left_, loc);
7904 4134 : overflow = negate_expr->get_backend(context);
7905 : }
7906 : else
7907 : overflow = zero_expr;
7908 : }
7909 11583 : overflow = gogo->backend()->convert_expression(btype, overflow, loc);
7910 :
7911 : // right == -1 ? - left : ret
7912 11583 : ret = gogo->backend()->conditional_expression(bfn, btype,
7913 : check, overflow,
7914 : ret, loc);
7915 : }
7916 : }
7917 :
7918 729111 : mpz_clear(zero);
7919 729111 : mpz_clear(one);
7920 729111 : mpz_clear(neg_one);
7921 729111 : return ret;
7922 : }
7923 :
7924 : // Export a binary expression.
7925 :
7926 : void
7927 16026 : Binary_expression::do_export(Export_function_body* efb) const
7928 : {
7929 16026 : efb->write_c_string("(");
7930 16026 : this->left_->export_expression(efb);
7931 16026 : switch (this->op_)
7932 : {
7933 607 : case OPERATOR_OROR:
7934 607 : efb->write_c_string(" || ");
7935 607 : break;
7936 1193 : case OPERATOR_ANDAND:
7937 1193 : efb->write_c_string(" && ");
7938 1193 : break;
7939 2323 : case OPERATOR_EQEQ:
7940 2323 : efb->write_c_string(" == ");
7941 2323 : break;
7942 872 : case OPERATOR_NOTEQ:
7943 872 : efb->write_c_string(" != ");
7944 872 : break;
7945 1526 : case OPERATOR_LT:
7946 1526 : efb->write_c_string(" < ");
7947 1526 : break;
7948 785 : case OPERATOR_LE:
7949 785 : efb->write_c_string(" <= ");
7950 785 : break;
7951 355 : case OPERATOR_GT:
7952 355 : efb->write_c_string(" > ");
7953 355 : break;
7954 1052 : case OPERATOR_GE:
7955 1052 : efb->write_c_string(" >= ");
7956 1052 : break;
7957 1746 : case OPERATOR_PLUS:
7958 1746 : efb->write_c_string(" + ");
7959 1746 : break;
7960 1185 : case OPERATOR_MINUS:
7961 1185 : efb->write_c_string(" - ");
7962 1185 : break;
7963 430 : case OPERATOR_OR:
7964 430 : efb->write_c_string(" | ");
7965 430 : break;
7966 163 : case OPERATOR_XOR:
7967 163 : efb->write_c_string(" ^ ");
7968 163 : break;
7969 534 : case OPERATOR_MULT:
7970 534 : efb->write_c_string(" * ");
7971 534 : break;
7972 430 : case OPERATOR_DIV:
7973 430 : efb->write_c_string(" / ");
7974 430 : break;
7975 187 : case OPERATOR_MOD:
7976 187 : efb->write_c_string(" % ");
7977 187 : break;
7978 386 : case OPERATOR_LSHIFT:
7979 386 : efb->write_c_string(" << ");
7980 386 : break;
7981 1125 : case OPERATOR_RSHIFT:
7982 1125 : efb->write_c_string(" >> ");
7983 1125 : break;
7984 1046 : case OPERATOR_AND:
7985 1046 : efb->write_c_string(" & ");
7986 1046 : break;
7987 81 : case OPERATOR_BITCLEAR:
7988 81 : efb->write_c_string(" &^ ");
7989 81 : break;
7990 0 : default:
7991 0 : go_unreachable();
7992 : }
7993 16026 : this->right_->export_expression(efb);
7994 16026 : efb->write_c_string(")");
7995 16026 : }
7996 :
7997 : // Import a binary expression.
7998 :
7999 : Expression*
8000 22026 : Binary_expression::do_import(Import_expression* imp, Location loc)
8001 : {
8002 22026 : imp->require_c_string("(");
8003 :
8004 22026 : Expression* left = Expression::import_expression(imp, loc);
8005 :
8006 22026 : Operator op;
8007 22026 : if (imp->match_c_string(" || "))
8008 : {
8009 652 : op = OPERATOR_OROR;
8010 652 : imp->advance(4);
8011 : }
8012 21374 : else if (imp->match_c_string(" && "))
8013 : {
8014 1823 : op = OPERATOR_ANDAND;
8015 1823 : imp->advance(4);
8016 : }
8017 19551 : else if (imp->match_c_string(" == "))
8018 : {
8019 3241 : op = OPERATOR_EQEQ;
8020 3241 : imp->advance(4);
8021 : }
8022 16310 : else if (imp->match_c_string(" != "))
8023 : {
8024 843 : op = OPERATOR_NOTEQ;
8025 843 : imp->advance(4);
8026 : }
8027 15467 : else if (imp->match_c_string(" < "))
8028 : {
8029 1154 : op = OPERATOR_LT;
8030 1154 : imp->advance(3);
8031 : }
8032 14313 : else if (imp->match_c_string(" <= "))
8033 : {
8034 988 : op = OPERATOR_LE;
8035 988 : imp->advance(4);
8036 : }
8037 13325 : else if (imp->match_c_string(" > "))
8038 : {
8039 226 : op = OPERATOR_GT;
8040 226 : imp->advance(3);
8041 : }
8042 13099 : else if (imp->match_c_string(" >= "))
8043 : {
8044 2482 : op = OPERATOR_GE;
8045 2482 : imp->advance(4);
8046 : }
8047 10617 : else if (imp->match_c_string(" + "))
8048 : {
8049 1789 : op = OPERATOR_PLUS;
8050 1789 : imp->advance(3);
8051 : }
8052 8828 : else if (imp->match_c_string(" - "))
8053 : {
8054 1554 : op = OPERATOR_MINUS;
8055 1554 : imp->advance(3);
8056 : }
8057 7274 : else if (imp->match_c_string(" | "))
8058 : {
8059 347 : op = OPERATOR_OR;
8060 347 : imp->advance(3);
8061 : }
8062 6927 : else if (imp->match_c_string(" ^ "))
8063 : {
8064 152 : op = OPERATOR_XOR;
8065 152 : imp->advance(3);
8066 : }
8067 6775 : else if (imp->match_c_string(" * "))
8068 : {
8069 573 : op = OPERATOR_MULT;
8070 573 : imp->advance(3);
8071 : }
8072 6202 : else if (imp->match_c_string(" / "))
8073 : {
8074 223 : op = OPERATOR_DIV;
8075 223 : imp->advance(3);
8076 : }
8077 5979 : else if (imp->match_c_string(" % "))
8078 : {
8079 40 : op = OPERATOR_MOD;
8080 40 : imp->advance(3);
8081 : }
8082 5939 : else if (imp->match_c_string(" << "))
8083 : {
8084 120 : op = OPERATOR_LSHIFT;
8085 120 : imp->advance(4);
8086 : }
8087 5819 : else if (imp->match_c_string(" >> "))
8088 : {
8089 941 : op = OPERATOR_RSHIFT;
8090 941 : imp->advance(4);
8091 : }
8092 4878 : else if (imp->match_c_string(" & "))
8093 : {
8094 940 : op = OPERATOR_AND;
8095 940 : imp->advance(3);
8096 : }
8097 3938 : else if (imp->match_c_string(" &^ "))
8098 : {
8099 74 : op = OPERATOR_BITCLEAR;
8100 74 : imp->advance(4);
8101 : }
8102 3864 : else if (imp->match_c_string(")"))
8103 : {
8104 : // Not a binary operator after all.
8105 3864 : imp->advance(1);
8106 3864 : return left;
8107 : }
8108 : else
8109 : {
8110 0 : go_error_at(imp->location(), "unrecognized binary operator");
8111 0 : return Expression::make_error(loc);
8112 : }
8113 :
8114 18162 : Expression* right = Expression::import_expression(imp, loc);
8115 :
8116 18162 : imp->require_c_string(")");
8117 :
8118 18162 : return Expression::make_binary(op, left, right, loc);
8119 : }
8120 :
8121 : // Dump ast representation of a binary expression.
8122 :
8123 : void
8124 0 : Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
8125 : {
8126 0 : ast_dump_context->ostream() << "(";
8127 0 : ast_dump_context->dump_expression(this->left_);
8128 0 : ast_dump_context->ostream() << " ";
8129 0 : ast_dump_context->dump_operator(this->op_);
8130 0 : ast_dump_context->ostream() << " ";
8131 0 : ast_dump_context->dump_expression(this->right_);
8132 0 : ast_dump_context->ostream() << ") ";
8133 0 : }
8134 :
8135 : // Make a binary expression.
8136 :
8137 : Expression*
8138 2341942 : Expression::make_binary(Operator op, Expression* left, Expression* right,
8139 : Location location)
8140 : {
8141 2341942 : return new Binary_expression(op, left, right, location);
8142 : }
8143 :
8144 : // Implement a comparison.
8145 :
8146 : Bexpression*
8147 1266990 : Expression::comparison(Translate_context* context, Type* result_type,
8148 : Operator op, Expression* left, Expression* right,
8149 : Location location)
8150 : {
8151 1266990 : Gogo* gogo = context->gogo();
8152 1266990 : Type* left_type = left->type();
8153 1266990 : Type* right_type = right->type();
8154 :
8155 1266990 : Expression* zexpr = Expression::make_integer_ul(0, NULL, location);
8156 :
8157 1266990 : if (left_type->is_string_type() && right_type->is_string_type())
8158 : {
8159 45351 : go_assert(left->is_multi_eval_safe());
8160 45351 : go_assert(right->is_multi_eval_safe());
8161 :
8162 45351 : if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
8163 : {
8164 : // (l.len == r.len
8165 : // ? (l.ptr == r.ptr ? true : memcmp(l.ptr, r.ptr, r.len) == 0)
8166 : // : false)
8167 44859 : Expression* llen = Expression::make_string_info(left,
8168 : STRING_INFO_LENGTH,
8169 : location);
8170 44859 : Expression* rlen = Expression::make_string_info(right,
8171 : STRING_INFO_LENGTH,
8172 : location);
8173 44859 : Expression* leneq = Expression::make_binary(OPERATOR_EQEQ, llen, rlen,
8174 : location);
8175 44859 : Expression* lptr = Expression::make_string_info(left->copy(),
8176 : STRING_INFO_DATA,
8177 : location);
8178 44859 : Expression* rptr = Expression::make_string_info(right->copy(),
8179 : STRING_INFO_DATA,
8180 : location);
8181 44859 : Expression* ptreq = Expression::make_binary(OPERATOR_EQEQ, lptr, rptr,
8182 : location);
8183 44859 : Expression* btrue = Expression::make_boolean(true, location);
8184 44859 : Expression* call = Runtime::make_call(gogo, Runtime::MEMCMP,
8185 : location, 3,
8186 : lptr->copy(), rptr->copy(),
8187 : rlen->copy());
8188 44859 : Type* int32_type = Type::lookup_integer_type("int32");
8189 44859 : Expression* zero = Expression::make_integer_ul(0, int32_type, location);
8190 44859 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, call, zero,
8191 : location);
8192 44859 : Expression* cond = Expression::make_conditional(ptreq, btrue, cmp,
8193 : location);
8194 44859 : Expression* bfalse = Expression::make_boolean(false, location);
8195 44859 : left = Expression::make_conditional(leneq, cond, bfalse, location);
8196 44859 : right = Expression::make_boolean(true, location);
8197 : }
8198 : else
8199 : {
8200 492 : left = Runtime::make_call(gogo, Runtime::CMPSTRING, location, 2,
8201 : left, right);
8202 492 : right = zexpr;
8203 : }
8204 : }
8205 1221639 : else if ((left_type->interface_type() != NULL
8206 60274 : && right_type->interface_type() == NULL
8207 52571 : && !right_type->is_nil_type())
8208 1220095 : || (left_type->interface_type() == NULL
8209 1161365 : && !left_type->is_nil_type()
8210 1161361 : && right_type->interface_type() != NULL))
8211 : {
8212 : // Comparing an interface value to a non-interface value.
8213 3236 : if (left_type->interface_type() == NULL)
8214 : {
8215 : std::swap(left_type, right_type);
8216 : std::swap(left, right);
8217 : }
8218 :
8219 : // The right operand is not an interface. We need to take its
8220 : // address if it is not a direct interface type.
8221 1692 : Expression* pointer_arg = NULL;
8222 1692 : if (right_type->is_direct_iface_type())
8223 565 : pointer_arg = Expression::unpack_direct_iface(right, location);
8224 : else
8225 : {
8226 1127 : go_assert(right->is_addressable());
8227 1127 : pointer_arg = Expression::make_unary(OPERATOR_AND, right,
8228 : location);
8229 : }
8230 :
8231 1692 : Expression* descriptor =
8232 1692 : Expression::make_type_descriptor(right_type, location);
8233 2990 : left = Runtime::make_call(gogo,
8234 3384 : (left_type->interface_type()->is_empty()
8235 : ? Runtime::EFACEVALEQ
8236 : : Runtime::IFACEVALEQ),
8237 : location, 3, left, descriptor,
8238 : pointer_arg);
8239 1692 : go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
8240 1692 : right = Expression::make_boolean(true, location);
8241 : }
8242 1219947 : else if (left_type->interface_type() != NULL
8243 58730 : && right_type->interface_type() != NULL)
8244 : {
8245 7703 : Runtime::Function compare_function;
8246 15406 : if (left_type->interface_type()->is_empty()
8247 8573 : && right_type->interface_type()->is_empty())
8248 : compare_function = Runtime::EFACEEQ;
8249 13766 : else if (!left_type->interface_type()->is_empty()
8250 13716 : && !right_type->interface_type()->is_empty())
8251 : compare_function = Runtime::IFACEEQ;
8252 : else
8253 : {
8254 104 : if (left_type->interface_type()->is_empty())
8255 : {
8256 50 : std::swap(left_type, right_type);
8257 50 : std::swap(left, right);
8258 : }
8259 104 : go_assert(!left_type->interface_type()->is_empty());
8260 104 : go_assert(right_type->interface_type()->is_empty());
8261 : compare_function = Runtime::IFACEEFACEEQ;
8262 : }
8263 :
8264 7703 : left = Runtime::make_call(gogo, compare_function, location, 2,
8265 : left, right);
8266 7703 : go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
8267 7703 : right = Expression::make_boolean(true, location);
8268 : }
8269 :
8270 1266990 : if (left_type->is_nil_type()
8271 1266990 : && (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ))
8272 : {
8273 : std::swap(left_type, right_type);
8274 : std::swap(left, right);
8275 : }
8276 :
8277 1266990 : if (right_type->is_nil_type())
8278 : {
8279 124823 : right = Expression::make_nil(location);
8280 124823 : if (left_type->array_type() != NULL
8281 6666 : && left_type->array_type()->length() == NULL)
8282 : {
8283 3333 : Array_type* at = left_type->array_type();
8284 3333 : left = at->get_value_pointer(context->gogo(), left);
8285 : }
8286 121490 : else if (left_type->interface_type() != NULL)
8287 : {
8288 : // An interface is nil if the first field is nil.
8289 51028 : left = Expression::make_field_reference(left, 0, location);
8290 : }
8291 : }
8292 :
8293 1266990 : left->determine_type_no_context(gogo);
8294 1266990 : right->determine_type_no_context(gogo);
8295 :
8296 1266990 : Bexpression* left_bexpr = left->get_backend(context);
8297 1266990 : Bexpression* right_bexpr = right->get_backend(context);
8298 :
8299 1266990 : Bexpression* ret = gogo->backend()->binary_expression(op, left_bexpr,
8300 : right_bexpr, location);
8301 1266990 : if (result_type != NULL)
8302 1266885 : ret = gogo->backend()->convert_expression(result_type->get_backend(gogo),
8303 : ret, location);
8304 1266990 : return ret;
8305 : }
8306 :
8307 : // Class String_concat_expression.
8308 :
8309 : bool
8310 1461 : String_concat_expression::do_is_constant() const
8311 : {
8312 2295 : for (Expression_list::const_iterator pe = this->exprs_->begin();
8313 2295 : pe != this->exprs_->end();
8314 834 : ++pe)
8315 : {
8316 2295 : if (!(*pe)->is_constant())
8317 1461 : return false;
8318 : }
8319 : return true;
8320 : }
8321 :
8322 : bool
8323 403 : String_concat_expression::do_is_untyped(Type** ptype) const
8324 : {
8325 403 : for (Expression_list::iterator pe = this->exprs_->begin();
8326 403 : pe != this->exprs_->end();
8327 0 : ++pe)
8328 : {
8329 403 : if (!(*pe)->is_untyped(ptype))
8330 403 : return false;
8331 : }
8332 :
8333 0 : *ptype = Type::make_string_type();
8334 0 : return true;
8335 : }
8336 :
8337 : bool
8338 6 : String_concat_expression::do_is_zero_value() const
8339 : {
8340 6 : for (Expression_list::const_iterator pe = this->exprs_->begin();
8341 6 : pe != this->exprs_->end();
8342 0 : ++pe)
8343 : {
8344 6 : if (!(*pe)->is_zero_value())
8345 6 : return false;
8346 : }
8347 : return true;
8348 : }
8349 :
8350 : bool
8351 39 : String_concat_expression::do_is_static_initializer() const
8352 : {
8353 52 : for (Expression_list::const_iterator pe = this->exprs_->begin();
8354 52 : pe != this->exprs_->end();
8355 13 : ++pe)
8356 : {
8357 52 : if (!(*pe)->is_static_initializer())
8358 39 : return false;
8359 : }
8360 : return true;
8361 : }
8362 :
8363 : Type*
8364 109310 : String_concat_expression::do_type()
8365 : {
8366 109310 : Type* t = this->exprs_->front()->type();
8367 109310 : Expression_list::iterator pe = this->exprs_->begin();
8368 109310 : ++pe;
8369 290786 : for (; pe != this->exprs_->end(); ++pe)
8370 : {
8371 181476 : Type* t1;
8372 181476 : if (!Binary_expression::operation_type(OPERATOR_PLUS, t,
8373 181476 : (*pe)->type(),
8374 : &t1))
8375 0 : return Type::make_error_type();
8376 181476 : t = t1;
8377 : }
8378 : return t;
8379 : }
8380 :
8381 : void
8382 3795 : String_concat_expression::do_determine_type(Gogo* gogo,
8383 : const Type_context* context)
8384 : {
8385 3795 : Type_context subcontext(*context);
8386 3795 : for (Expression_list::iterator pe = this->exprs_->begin();
8387 3795 : pe != this->exprs_->end();
8388 0 : ++pe)
8389 : {
8390 3795 : Type* t = (*pe)->type();
8391 3795 : if (!t->is_abstract())
8392 : {
8393 3795 : subcontext.type = t;
8394 3795 : break;
8395 : }
8396 : }
8397 3795 : if (subcontext.type == NULL)
8398 0 : subcontext.type = this->exprs_->front()->type();
8399 14101 : for (Expression_list::iterator pe = this->exprs_->begin();
8400 14101 : pe != this->exprs_->end();
8401 10306 : ++pe)
8402 10306 : (*pe)->determine_type(gogo, &subcontext);
8403 3795 : }
8404 :
8405 : void
8406 21 : String_concat_expression::do_check_types(Gogo*)
8407 : {
8408 21 : if (this->is_error_expression())
8409 : return;
8410 21 : Type* t = this->exprs_->front()->type();
8411 21 : if (t->is_error())
8412 : {
8413 0 : this->set_is_error();
8414 0 : return;
8415 : }
8416 21 : Expression_list::iterator pe = this->exprs_->begin();
8417 21 : ++pe;
8418 48 : for (; pe != this->exprs_->end(); ++pe)
8419 : {
8420 27 : Type* t1 = (*pe)->type();
8421 27 : if (!Type::are_compatible_for_binop(t, t1))
8422 : {
8423 0 : this->report_error("incompatible types in binary expression");
8424 0 : return;
8425 : }
8426 27 : if (!Binary_expression::check_operator_type(OPERATOR_PLUS, t, t1,
8427 : this->location()))
8428 : {
8429 0 : this->set_is_error();
8430 0 : return;
8431 : }
8432 : }
8433 : }
8434 :
8435 : Expression*
8436 10472 : String_concat_expression::do_flatten(Gogo* gogo, Named_object*,
8437 : Statement_inserter* inserter)
8438 : {
8439 10472 : if (this->is_error_expression())
8440 0 : return this;
8441 10472 : Location loc = this->location();
8442 10472 : Type* type = this->type();
8443 :
8444 : // Mark string([]byte) operands to reuse the backing store.
8445 : // runtime.concatstrings does not keep the reference.
8446 : //
8447 : // Note: in the gc runtime, if all but one inputs are empty,
8448 : // concatstrings returns the only nonempty input without copy.
8449 : // So it is not safe to reuse the backing store if it is a
8450 : // string([]byte) conversion. So the gc compiler does the
8451 : // no-copy optimization only when there is at least one
8452 : // constant nonempty input. Currently the gccgo runtime
8453 : // doesn't do this, so we don't do the check.
8454 10472 : for (Expression_list::iterator p = this->exprs_->begin();
8455 37161 : p != this->exprs_->end();
8456 26689 : ++p)
8457 : {
8458 27106 : Type_conversion_expression* tce = (*p)->conversion_expression();
8459 417 : if (tce != NULL)
8460 417 : tce->set_no_copy(true);
8461 : }
8462 :
8463 10472 : Expression* buf = NULL;
8464 10472 : Node* n = Node::make_node(this);
8465 10472 : if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
8466 : {
8467 1205 : size_t size = 0;
8468 1205 : for (Expression_list::iterator p = this->exprs_->begin();
8469 4128 : p != this->exprs_->end();
8470 2923 : ++p)
8471 : {
8472 2923 : std::string s;
8473 2923 : if ((*p)->string_constant_value(&s))
8474 1342 : size += s.length();
8475 2923 : }
8476 : // Make a buffer on stack if the result does not escape.
8477 : // But don't do this if we know it won't fit.
8478 1205 : if (size < (size_t)tmp_string_buf_size)
8479 : {
8480 1129 : Type* byte_type = Type::lookup_integer_type("uint8");
8481 1129 : Expression* buflen =
8482 1129 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
8483 1129 : Expression::make_integer_ul(tmp_string_buf_size, NULL, loc);
8484 1129 : Type* array_type = Type::make_array_type(byte_type, buflen);
8485 1129 : buf = Expression::make_allocation(array_type, loc);
8486 1129 : buf->allocation_expression()->set_allocate_on_stack();
8487 1129 : buf->allocation_expression()->set_no_zero();
8488 : }
8489 : }
8490 1129 : if (buf == NULL)
8491 9343 : buf = Expression::make_nil(loc);
8492 10472 : go_assert(this->exprs_->size() > 1);
8493 10472 : Expression* len =
8494 10472 : Expression::make_integer_ul(this->exprs_->size(), NULL, loc);
8495 10472 : Array_type* array_type = Type::make_array_type(type, len);
8496 10472 : array_type->set_is_array_incomparable();
8497 10472 : Expression* array =
8498 10472 : Expression::make_array_composite_literal(array_type, this->exprs_,
8499 : loc);
8500 10472 : Temporary_statement* ts =
8501 10472 : Statement::make_temporary(array_type, array, loc);
8502 10472 : ts->determine_types(gogo);
8503 10472 : inserter->insert(ts);
8504 10472 : Expression* ref = Expression::make_temporary_reference(ts, loc);
8505 10472 : ref = Expression::make_unary(OPERATOR_AND, ref, loc);
8506 10472 : Expression* call =
8507 10472 : Runtime::make_call(gogo, Runtime::CONCATSTRINGS, loc, 3, buf,
8508 : ref, len->copy());
8509 10472 : Expression* ret = Expression::make_cast(type, call, loc);
8510 10472 : Type_context context(type, false);
8511 10472 : ret->determine_type(gogo, &context);
8512 10472 : return ret;
8513 : }
8514 :
8515 : void
8516 0 : String_concat_expression::do_dump_expression(
8517 : Ast_dump_context* ast_dump_context) const
8518 : {
8519 0 : ast_dump_context->ostream() << "concat(";
8520 0 : ast_dump_context->dump_expression_list(this->exprs_, false);
8521 0 : ast_dump_context->ostream() << ")";
8522 0 : }
8523 :
8524 : Expression*
8525 16280 : Expression::make_string_concat(Expression_list* exprs)
8526 : {
8527 16280 : return new String_concat_expression(exprs);
8528 : }
8529 :
8530 : // Class Bound_method_expression.
8531 :
8532 : // Traversal.
8533 :
8534 : int
8535 401478 : Bound_method_expression::do_traverse(Traverse* traverse)
8536 : {
8537 401478 : return Expression::traverse(&this->expr_, traverse);
8538 : }
8539 :
8540 : // Return the type of a bound method expression. The type of this
8541 : // object is simply the type of the method with no receiver.
8542 :
8543 : Type*
8544 2418516 : Bound_method_expression::do_type()
8545 : {
8546 2418516 : Named_object* fn = this->method_->named_object();
8547 2418516 : Function_type* fntype;
8548 2418516 : if (fn->is_function())
8549 1356007 : fntype = fn->func_value()->type();
8550 1062509 : else if (fn->is_function_declaration())
8551 1062509 : fntype = fn->func_declaration_value()->type();
8552 : else
8553 0 : return Type::make_error_type();
8554 2418516 : return fntype->copy_without_receiver();
8555 : }
8556 :
8557 : // Determine the types of a method expression.
8558 :
8559 : void
8560 264971 : Bound_method_expression::do_determine_type(Gogo* gogo, const Type_context*)
8561 : {
8562 264971 : Named_object* fn = this->method_->named_object();
8563 264971 : Function_type* fntype;
8564 264971 : if (fn->is_function())
8565 137245 : fntype = fn->func_value()->type();
8566 127726 : else if (fn->is_function_declaration())
8567 127726 : fntype = fn->func_declaration_value()->type();
8568 : else
8569 : fntype = NULL;
8570 264971 : if (fntype == NULL || !fntype->is_method())
8571 0 : this->expr_->determine_type_no_context(gogo);
8572 : else
8573 : {
8574 264971 : Type_context subcontext(fntype->receiver()->type(), false);
8575 264971 : this->expr_->determine_type(gogo, &subcontext);
8576 : }
8577 264971 : }
8578 :
8579 : // Check the types of a method expression.
8580 :
8581 : void
8582 23671 : Bound_method_expression::do_check_types(Gogo*)
8583 : {
8584 23671 : Named_object* fn = this->function();
8585 23671 : if (!fn->is_function() && !fn->is_function_declaration())
8586 : {
8587 0 : this->report_error(_("object is not a method"));
8588 0 : return;
8589 : }
8590 :
8591 23671 : Function_type* fntype;
8592 23671 : if (fn->is_function())
8593 10989 : fntype = fn->func_value()->type();
8594 12682 : else if (fn->is_function_declaration())
8595 12682 : fntype = fn->func_declaration_value()->type();
8596 : else
8597 : go_unreachable();
8598 23671 : Type* rtype = fntype->receiver()->type()->deref();
8599 23671 : Type* etype = (this->expr_type_ != NULL
8600 23671 : ? this->expr_type_
8601 23671 : : this->expr_->type());
8602 23671 : etype = etype->deref();
8603 23671 : if (!Type::are_identical(rtype, etype, Type::COMPARE_TAGS, NULL))
8604 0 : this->report_error(_("method type does not match object type"));
8605 : }
8606 :
8607 : // If a bound method expression is not simply called, then it is
8608 : // represented as a closure. The closure will hold a single variable,
8609 : // the receiver to pass to the method. The function will be a simple
8610 : // thunk that pulls that value from the closure and calls the method
8611 : // with the remaining arguments.
8612 : //
8613 : // Because method values are not common, we don't build all thunks for
8614 : // every methods, but instead only build them as we need them. In
8615 : // particular, we even build them on demand for methods defined in
8616 : // other packages.
8617 :
8618 : Bound_method_expression::Method_value_thunks
8619 : Bound_method_expression::method_value_thunks;
8620 :
8621 : // Find or create the thunk for FN.
8622 :
8623 : Named_object*
8624 934 : Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
8625 : Named_object* fn)
8626 : {
8627 934 : std::pair<Named_object*, Named_object*> val(fn, NULL);
8628 934 : std::pair<Method_value_thunks::iterator, bool> ins =
8629 934 : Bound_method_expression::method_value_thunks.insert(val);
8630 934 : if (!ins.second)
8631 : {
8632 : // We have seen this method before.
8633 287 : go_assert(ins.first->second != NULL);
8634 : return ins.first->second;
8635 : }
8636 :
8637 647 : Location loc = fn->location();
8638 :
8639 647 : Function_type* orig_fntype;
8640 647 : if (fn->is_function())
8641 541 : orig_fntype = fn->func_value()->type();
8642 106 : else if (fn->is_function_declaration())
8643 106 : orig_fntype = fn->func_declaration_value()->type();
8644 : else
8645 : orig_fntype = NULL;
8646 :
8647 647 : if (orig_fntype == NULL || !orig_fntype->is_method())
8648 : {
8649 0 : ins.first->second =
8650 0 : Named_object::make_erroneous_name(gogo->thunk_name());
8651 0 : return ins.first->second;
8652 : }
8653 :
8654 647 : Struct_field_list* sfl = new Struct_field_list();
8655 : // The type here is wrong--it should be the C function type. But it
8656 : // doesn't really matter.
8657 647 : Type* vt = Type::make_pointer_type(Type::make_void_type());
8658 1294 : sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
8659 1294 : sfl->push_back(Struct_field(Typed_identifier("val",
8660 : orig_fntype->receiver()->type(),
8661 1294 : loc)));
8662 647 : Struct_type* st = Type::make_struct_type(sfl, loc);
8663 647 : st->set_is_struct_incomparable();
8664 647 : Type* closure_type = Type::make_pointer_type(st);
8665 :
8666 647 : Function_type* new_fntype = orig_fntype->copy_with_names();
8667 :
8668 647 : std::string thunk_name = gogo->thunk_name();
8669 647 : Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
8670 : false, loc);
8671 :
8672 647 : Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
8673 647 : cvar->set_is_used();
8674 647 : cvar->set_is_closure();
8675 647 : Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
8676 : NULL, cvar);
8677 647 : new_no->func_value()->set_closure_var(cp);
8678 :
8679 647 : gogo->start_block(loc);
8680 :
8681 : // Field 0 of the closure is the function code pointer, field 1 is
8682 : // the value on which to invoke the method.
8683 647 : Expression* arg = Expression::make_var_reference(cp, loc);
8684 647 : arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
8685 647 : arg = Expression::make_field_reference(arg, 1, loc);
8686 :
8687 647 : Expression* bme = Expression::make_bound_method(arg, method, fn, loc);
8688 :
8689 647 : const Typed_identifier_list* orig_params = orig_fntype->parameters();
8690 647 : Expression_list* args;
8691 647 : if (orig_params == NULL || orig_params->empty())
8692 : args = NULL;
8693 : else
8694 : {
8695 386 : const Typed_identifier_list* new_params = new_fntype->parameters();
8696 386 : args = new Expression_list();
8697 386 : for (Typed_identifier_list::const_iterator p = new_params->begin();
8698 1135 : p != new_params->end();
8699 749 : ++p)
8700 : {
8701 749 : Named_object* p_no = gogo->lookup(p->name(), NULL);
8702 749 : go_assert(p_no != NULL
8703 : && p_no->is_variable()
8704 : && p_no->var_value()->is_parameter());
8705 749 : args->push_back(Expression::make_var_reference(p_no, loc));
8706 : }
8707 : }
8708 :
8709 647 : Call_expression* call = Expression::make_call(bme, args,
8710 647 : orig_fntype->is_varargs(),
8711 : loc);
8712 647 : call->set_varargs_are_lowered();
8713 :
8714 647 : Statement* s = Statement::make_return_from_call(new_no, call, loc);
8715 647 : s->determine_types(gogo);
8716 647 : gogo->add_statement(s);
8717 647 : Block* b = gogo->finish_block(loc);
8718 647 : gogo->add_block(b, loc);
8719 :
8720 : // This is called after lowering.
8721 647 : gogo->lower_block(new_no, b);
8722 :
8723 647 : gogo->finish_function(loc);
8724 :
8725 647 : ins.first->second = new_no;
8726 647 : return new_no;
8727 647 : }
8728 :
8729 : // Look up a thunk for FN.
8730 :
8731 : Named_object*
8732 934 : Bound_method_expression::lookup_thunk(Named_object* fn)
8733 : {
8734 934 : Method_value_thunks::const_iterator p =
8735 934 : Bound_method_expression::method_value_thunks.find(fn);
8736 934 : if (p == Bound_method_expression::method_value_thunks.end())
8737 : return NULL;
8738 934 : return p->second;
8739 : }
8740 :
8741 : // Return an expression to check *REF for nil while dereferencing
8742 : // according to FIELD_INDEXES. Update *REF to build up the field
8743 : // reference. This is a static function so that we don't have to
8744 : // worry about declaring Field_indexes in expressions.h.
8745 :
8746 : static Expression*
8747 31 : bme_check_nil(const Method::Field_indexes* field_indexes, Location loc,
8748 : Expression** ref)
8749 : {
8750 31 : if (field_indexes == NULL)
8751 14 : return Expression::make_boolean(false, loc);
8752 17 : Expression* cond = bme_check_nil(field_indexes->next, loc, ref);
8753 34 : Struct_type* stype = (*ref)->type()->deref()->struct_type();
8754 17 : go_assert(stype != NULL
8755 : && field_indexes->field_index < stype->field_count());
8756 17 : if ((*ref)->type()->struct_type() == NULL)
8757 : {
8758 10 : go_assert((*ref)->type()->points_to() != NULL);
8759 10 : Expression* n = Expression::make_binary(OPERATOR_EQEQ, *ref,
8760 : Expression::make_nil(loc),
8761 : loc);
8762 10 : cond = Expression::make_binary(OPERATOR_OROR, cond, n, loc);
8763 10 : *ref = Expression::make_dereference(*ref, Expression::NIL_CHECK_DEFAULT,
8764 : loc);
8765 20 : go_assert((*ref)->type()->struct_type() == stype);
8766 : }
8767 17 : *ref = Expression::make_field_reference(*ref, field_indexes->field_index,
8768 : loc);
8769 17 : return cond;
8770 : }
8771 :
8772 : // Flatten a method value into a struct with nil checks. We can't do
8773 : // this in the lowering phase, because if the method value is called
8774 : // directly we don't need a thunk. That case will have been handled
8775 : // by Call_expression::do_lower, so if we get here then we do need a
8776 : // thunk.
8777 :
8778 : Expression*
8779 934 : Bound_method_expression::do_flatten(Gogo* gogo, Named_object*,
8780 : Statement_inserter* inserter)
8781 : {
8782 934 : Location loc = this->location();
8783 :
8784 934 : Named_object* thunk = Bound_method_expression::lookup_thunk(this->function_);
8785 :
8786 : // The thunk should have been created during the
8787 : // create_function_descriptors pass.
8788 934 : if (thunk == NULL || thunk->is_erroneous())
8789 : {
8790 0 : go_assert(saw_errors());
8791 0 : return Expression::make_error(loc);
8792 : }
8793 :
8794 : // Force the expression into a variable. This is only necessary if
8795 : // we are going to do nil checks below, but it's easy enough to
8796 : // always do it.
8797 934 : Expression* expr = this->expr_;
8798 934 : if (!expr->is_multi_eval_safe())
8799 : {
8800 292 : Temporary_statement* etemp = Statement::make_temporary(NULL, expr, loc);
8801 292 : inserter->insert(etemp);
8802 292 : expr = Expression::make_temporary_reference(etemp, loc);
8803 : }
8804 :
8805 : // If the method expects a value, and we have a pointer, we need to
8806 : // dereference the pointer.
8807 :
8808 934 : Named_object* fn = this->method_->named_object();
8809 934 : Function_type *fntype;
8810 934 : if (fn->is_function())
8811 814 : fntype = fn->func_value()->type();
8812 120 : else if (fn->is_function_declaration())
8813 120 : fntype = fn->func_declaration_value()->type();
8814 : else
8815 0 : go_unreachable();
8816 :
8817 934 : Expression* val = expr;
8818 934 : if (fntype->receiver()->type()->points_to() == NULL
8819 1135 : && val->type()->points_to() != NULL)
8820 25 : val = Expression::make_dereference(val, NIL_CHECK_DEFAULT, loc);
8821 :
8822 : // Note that we are ignoring this->expr_type_ here. The thunk will
8823 : // expect a closure whose second field has type this->expr_type_ (if
8824 : // that is not NULL). We are going to pass it a closure whose
8825 : // second field has type this->expr_->type(). Since
8826 : // this->expr_type_ is only not-NULL for pointer types, we can get
8827 : // away with this.
8828 :
8829 934 : Struct_field_list* fields = new Struct_field_list();
8830 1868 : fields->push_back(Struct_field(Typed_identifier("fn",
8831 934 : thunk->func_value()->type(),
8832 934 : loc)));
8833 1868 : fields->push_back(Struct_field(Typed_identifier("val", val->type(), loc)));
8834 934 : Struct_type* st = Type::make_struct_type(fields, loc);
8835 934 : st->set_is_struct_incomparable();
8836 :
8837 934 : Expression_list* vals = new Expression_list();
8838 934 : vals->push_back(Expression::make_func_code_reference(thunk, loc));
8839 934 : vals->push_back(val);
8840 :
8841 934 : Expression* ret = Expression::make_struct_composite_literal(st, vals, loc);
8842 934 : ret = Expression::make_heap_expression(ret, loc);
8843 :
8844 934 : Node* node = Node::make_node(this);
8845 934 : if ((node->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
8846 417 : ret->heap_expression()->set_allocate_on_stack();
8847 517 : else if (gogo->compiling_runtime()
8848 0 : && gogo->package_name() == "runtime"
8849 517 : && !saw_errors())
8850 0 : go_error_at(loc, "%s escapes to heap, not allowed in runtime",
8851 0 : node->ast_format(gogo).c_str());
8852 :
8853 : // If necessary, check whether the expression or any embedded
8854 : // pointers are nil.
8855 :
8856 934 : Expression* nil_check = NULL;
8857 934 : if (this->method_->field_indexes() != NULL)
8858 : {
8859 14 : Expression* ref = expr;
8860 14 : nil_check = bme_check_nil(this->method_->field_indexes(), loc, &ref);
8861 14 : expr = ref;
8862 : }
8863 :
8864 1135 : if (this->method_->is_value_method() && expr->type()->points_to() != NULL)
8865 : {
8866 27 : Expression* n = Expression::make_binary(OPERATOR_EQEQ, expr,
8867 : Expression::make_nil(loc),
8868 : loc);
8869 27 : if (nil_check == NULL)
8870 : nil_check = n;
8871 : else
8872 6 : nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc);
8873 : }
8874 :
8875 934 : if (nil_check != NULL)
8876 : {
8877 35 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
8878 : // Fix the type of the conditional expression by pretending to
8879 : // evaluate to RET either way through the conditional.
8880 35 : crash->determine_type_no_context(gogo);
8881 35 : crash = Expression::make_compound(crash, ret, loc);
8882 35 : ret = Expression::make_conditional(nil_check, crash, ret, loc);
8883 : }
8884 :
8885 : // RET is a pointer to a struct, but we want a function type.
8886 934 : ret = Expression::make_unsafe_cast(this->type(), ret, loc);
8887 :
8888 934 : ret->determine_type_no_context(gogo);
8889 :
8890 934 : return ret;
8891 : }
8892 :
8893 : // Dump ast representation of a bound method expression.
8894 :
8895 : void
8896 0 : Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
8897 : const
8898 : {
8899 0 : if (this->expr_type_ != NULL)
8900 0 : ast_dump_context->ostream() << "(";
8901 0 : ast_dump_context->dump_expression(this->expr_);
8902 0 : if (this->expr_type_ != NULL)
8903 : {
8904 0 : ast_dump_context->ostream() << ":";
8905 0 : ast_dump_context->dump_type(this->expr_type_);
8906 0 : ast_dump_context->ostream() << ")";
8907 : }
8908 :
8909 0 : ast_dump_context->ostream() << "." << this->function_->name();
8910 0 : }
8911 :
8912 : // Make a method expression.
8913 :
8914 : Bound_method_expression*
8915 264730 : Expression::make_bound_method(Expression* expr, const Method* method,
8916 : Named_object* function, Location location)
8917 : {
8918 264730 : return new Bound_method_expression(expr, method, function, location);
8919 : }
8920 :
8921 : // A general selector. This is a Parser_expression for LEFT.NAME. It
8922 : // is lowered after we know the type of the left hand side.
8923 :
8924 : class Selector_expression : public Parser_expression
8925 : {
8926 : public:
8927 700127 : Selector_expression(Expression* left, const std::string& name,
8928 : Location location)
8929 700127 : : Parser_expression(EXPRESSION_SELECTOR, location),
8930 700127 : left_(left), name_(name), resolved_(NULL)
8931 700127 : { }
8932 :
8933 : // Return the resolved selector. This will typically be a
8934 : // Field_reference_expression or a Bound_method_expression or an
8935 : // Interface_field_reference_expression.
8936 : Expression*
8937 1156 : resolved()
8938 1156 : { return this->resolved_; }
8939 :
8940 : protected:
8941 : int
8942 3601519 : do_traverse(Traverse* traverse)
8943 3601519 : { return Expression::traverse(&this->left_, traverse); }
8944 :
8945 : Type*
8946 : do_type();
8947 :
8948 : void
8949 : do_determine_type(Gogo*, const Type_context*);
8950 :
8951 : bool
8952 : do_is_addressable() const;
8953 :
8954 : void
8955 : do_issue_nil_check();
8956 :
8957 : Expression*
8958 : do_lower(Gogo*, Named_object*, Statement_inserter*);
8959 :
8960 : Expression*
8961 0 : do_copy()
8962 : {
8963 0 : return new Selector_expression(this->left_->copy(), this->name_,
8964 0 : this->location());
8965 : }
8966 :
8967 : void
8968 : do_dump_expression(Ast_dump_context* ast_dump_context) const;
8969 :
8970 : private:
8971 : Expression*
8972 : lower_method_expression(Gogo*);
8973 :
8974 : // The expression on the left hand side.
8975 : Expression* left_;
8976 : // The name on the right hand side.
8977 : std::string name_;
8978 : // The resolved expression.
8979 : Expression* resolved_;
8980 : };
8981 :
8982 : void
8983 807096 : Selector_expression::do_determine_type(Gogo* gogo, const Type_context* context)
8984 : {
8985 807096 : if (this->is_error_expression() || this->resolved_ != NULL)
8986 : return;
8987 700125 : Expression* left = this->left_;
8988 700125 : left->determine_type_no_context(gogo);
8989 700125 : if (left->is_error_expression())
8990 7 : this->set_is_error();
8991 : else
8992 : {
8993 700118 : if (left->is_type_expression())
8994 602 : this->resolved_ = this->lower_method_expression(gogo);
8995 : else
8996 699516 : this->resolved_ = Type::bind_field_or_method(gogo, left->type(), left,
8997 699516 : this->name_,
8998 : this->location());
8999 700118 : this->resolved_->determine_type(gogo, context);
9000 : }
9001 : }
9002 :
9003 : Type*
9004 2874842 : Selector_expression::do_type()
9005 : {
9006 2874842 : if (this->is_error_expression())
9007 12 : return Type::make_error_type();
9008 2874830 : go_assert(this->resolved_ != NULL);
9009 2874830 : return this->resolved_->type();
9010 : }
9011 :
9012 : bool
9013 141725 : Selector_expression::do_is_addressable() const
9014 : {
9015 141725 : if (this->is_error_expression())
9016 : return true;
9017 141724 : go_assert(this->resolved_ != NULL);
9018 141724 : return this->resolved_->is_addressable();
9019 : }
9020 :
9021 : void
9022 16436 : Selector_expression::do_issue_nil_check()
9023 : {
9024 16436 : if (this->is_error_expression())
9025 : return;
9026 16436 : go_assert(this->resolved_ != NULL);
9027 16436 : this->resolved_->issue_nil_check();
9028 : }
9029 :
9030 : // Lower a selector expression to the resolved value.
9031 :
9032 : Expression*
9033 771980 : Selector_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
9034 : {
9035 771980 : if (this->is_error_expression() || this->resolved_ == NULL)
9036 5 : return Expression::make_error(this->location());
9037 : return this->resolved_;
9038 : }
9039 :
9040 : // Lower a method expression T.M or (*T).M. We turn this into a
9041 : // function literal.
9042 :
9043 : Expression*
9044 602 : Selector_expression::lower_method_expression(Gogo* gogo)
9045 : {
9046 602 : Location location = this->location();
9047 602 : Type* left_type = this->left_->type();
9048 602 : Type* type = left_type;
9049 602 : const std::string& name(this->name_);
9050 :
9051 602 : bool is_pointer;
9052 602 : if (type->points_to() == NULL)
9053 : is_pointer = false;
9054 : else
9055 : {
9056 407 : is_pointer = true;
9057 407 : type = type->points_to();
9058 : }
9059 :
9060 602 : Named_type* nt = type->named_type();
9061 602 : Struct_type* st = type->struct_type();
9062 602 : bool is_ambiguous = false;
9063 602 : Method* method = NULL;
9064 602 : if (nt != NULL)
9065 599 : method = nt->method_function(name, &is_ambiguous);
9066 3 : else if (st != NULL)
9067 1 : method = st->method_function(name, &is_ambiguous);
9068 602 : const Typed_identifier* imethod = NULL;
9069 602 : if (method == NULL && !is_pointer)
9070 : {
9071 28 : Interface_type* it = type->interface_type();
9072 28 : if (it != NULL)
9073 28 : imethod = it->find_method(name);
9074 : }
9075 :
9076 602 : if ((method == NULL && imethod == NULL)
9077 602 : || (left_type->named_type() != NULL && left_type->points_to() != NULL))
9078 : {
9079 3 : if (nt != NULL)
9080 : {
9081 2 : if (!is_ambiguous)
9082 2 : go_error_at(location, "type %<%s%s%> has no method %qs",
9083 : is_pointer ? "*" : "",
9084 4 : nt->message_name().c_str(),
9085 4 : Gogo::message_name(name).c_str());
9086 : else
9087 0 : go_error_at(location, "method %<%s%s%> is ambiguous in type %qs",
9088 0 : Gogo::message_name(name).c_str(),
9089 : is_pointer ? "*" : "",
9090 0 : nt->message_name().c_str());
9091 : }
9092 : else
9093 : {
9094 1 : if (!is_ambiguous)
9095 1 : go_error_at(location, "type has no method %qs",
9096 2 : Gogo::message_name(name).c_str());
9097 : else
9098 0 : go_error_at(location, "method %qs is ambiguous",
9099 0 : Gogo::message_name(name).c_str());
9100 : }
9101 3 : return Expression::make_error(location);
9102 : }
9103 :
9104 599 : if (method != NULL && !is_pointer && !method->is_value_method())
9105 : {
9106 1 : go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
9107 2 : nt->message_name().c_str(),
9108 1 : Gogo::message_name(name).c_str());
9109 1 : return Expression::make_error(location);
9110 : }
9111 :
9112 : // Build a new function type in which the receiver becomes the first
9113 : // argument.
9114 598 : Function_type* method_type;
9115 598 : if (method != NULL)
9116 : {
9117 570 : method_type = method->type();
9118 570 : go_assert(method_type->is_method());
9119 : }
9120 : else
9121 : {
9122 28 : method_type = imethod->type()->function_type();
9123 28 : go_assert(method_type != NULL && !method_type->is_method());
9124 : }
9125 :
9126 598 : const char* const receiver_name = "$this";
9127 598 : Typed_identifier_list* parameters = new Typed_identifier_list();
9128 1196 : parameters->push_back(Typed_identifier(receiver_name, this->left_->type(),
9129 1196 : location));
9130 :
9131 598 : const Typed_identifier_list* method_parameters = method_type->parameters();
9132 598 : if (method_parameters != NULL)
9133 : {
9134 272 : int i = 0;
9135 272 : for (Typed_identifier_list::const_iterator p = method_parameters->begin();
9136 730 : p != method_parameters->end();
9137 458 : ++p, ++i)
9138 : {
9139 458 : if (!p->name().empty() && !Gogo::is_sink_name(p->name()))
9140 439 : parameters->push_back(*p);
9141 : else
9142 : {
9143 19 : char buf[20];
9144 19 : snprintf(buf, sizeof buf, "$param%d", i);
9145 38 : parameters->push_back(Typed_identifier(buf, p->type(),
9146 38 : p->location()));
9147 : }
9148 : }
9149 : }
9150 :
9151 598 : const Typed_identifier_list* method_results = method_type->results();
9152 598 : Typed_identifier_list* results;
9153 598 : if (method_results == NULL)
9154 : results = NULL;
9155 : else
9156 : {
9157 477 : results = new Typed_identifier_list();
9158 477 : for (Typed_identifier_list::const_iterator p = method_results->begin();
9159 1004 : p != method_results->end();
9160 527 : ++p)
9161 527 : results->push_back(*p);
9162 : }
9163 :
9164 598 : Function_type* fntype = Type::make_function_type(NULL, parameters, results,
9165 : location);
9166 598 : if (method_type->is_varargs())
9167 3 : fntype->set_is_varargs();
9168 :
9169 : // We generate methods which always takes a pointer to the receiver
9170 : // as their first argument. If this is for a pointer type, we can
9171 : // simply reuse the existing function. We use an internal hack to
9172 : // get the right type.
9173 : // FIXME: This optimization is disabled because it doesn't yet work
9174 : // with function descriptors when the method expression is not
9175 : // directly called.
9176 598 : if (method != NULL && is_pointer && false)
9177 : {
9178 : Named_object* mno = (method->needs_stub_method()
9179 : ? method->stub_object()
9180 : : method->named_object());
9181 : Expression* f = Expression::make_func_reference(mno, NULL, location);
9182 : f = Expression::make_cast(fntype, f, location);
9183 : Type_conversion_expression* tce =
9184 : static_cast<Type_conversion_expression*>(f);
9185 : tce->set_may_convert_function_types();
9186 : return f;
9187 : }
9188 :
9189 598 : Named_object* no = gogo->start_function(gogo->thunk_name(), fntype, false,
9190 : location);
9191 :
9192 598 : Named_object* vno = gogo->lookup(receiver_name, NULL);
9193 598 : go_assert(vno != NULL);
9194 598 : Expression* ve = Expression::make_var_reference(vno, location);
9195 598 : Expression* bm;
9196 598 : if (method != NULL)
9197 570 : bm = Type::bind_field_or_method(gogo, type, ve, name, location);
9198 : else
9199 28 : bm = Expression::make_interface_field_reference(ve, name, location);
9200 :
9201 : // Even though we found the method above, if it has an error type we
9202 : // may see an error here.
9203 598 : if (bm->is_error_expression())
9204 : {
9205 0 : gogo->finish_function(location);
9206 0 : return bm;
9207 : }
9208 :
9209 598 : Expression_list* args;
9210 598 : if (parameters->size() <= 1)
9211 : args = NULL;
9212 : else
9213 : {
9214 272 : args = new Expression_list();
9215 272 : Typed_identifier_list::const_iterator p = parameters->begin();
9216 272 : ++p;
9217 730 : for (; p != parameters->end(); ++p)
9218 : {
9219 458 : vno = gogo->lookup(p->name(), NULL);
9220 458 : go_assert(vno != NULL);
9221 458 : args->push_back(Expression::make_var_reference(vno, location));
9222 : }
9223 : }
9224 :
9225 598 : gogo->start_block(location);
9226 :
9227 598 : Call_expression* call = Expression::make_call(bm, args,
9228 598 : method_type->is_varargs(),
9229 : location);
9230 :
9231 598 : Statement* s = Statement::make_return_from_call(no, call, location);
9232 598 : s->determine_types(gogo);
9233 598 : gogo->add_statement(s);
9234 :
9235 598 : Block* b = gogo->finish_block(location);
9236 :
9237 598 : gogo->add_block(b, location);
9238 :
9239 598 : gogo->finish_function(location);
9240 :
9241 598 : return Expression::make_func_reference(no, NULL, location);
9242 : }
9243 :
9244 : // Dump the ast for a selector expression.
9245 :
9246 : void
9247 0 : Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
9248 : const
9249 : {
9250 0 : ast_dump_context->dump_expression(this->left_);
9251 0 : ast_dump_context->ostream() << ".";
9252 0 : ast_dump_context->ostream() << this->name_;
9253 0 : }
9254 :
9255 : // Make a selector expression.
9256 :
9257 : Expression*
9258 700127 : Expression::make_selector(Expression* left, const std::string& name,
9259 : Location location)
9260 : {
9261 700127 : return new Selector_expression(left, name, location);
9262 : }
9263 :
9264 : // Class Builtin_call_expression. This is used for a call to a
9265 : // builtin function.
9266 :
9267 240766 : Builtin_call_expression::Builtin_call_expression(Gogo* gogo,
9268 : Expression* fn,
9269 : Expression_list* args,
9270 : bool is_varargs,
9271 240766 : Location location)
9272 : : Call_expression(fn, args, is_varargs, location),
9273 240766 : gogo_(gogo), code_(BUILTIN_INVALID), seen_(false),
9274 240766 : recover_arg_is_set_(false)
9275 : {
9276 240766 : const Named_object* no;
9277 240766 : if (fn->is_error_expression())
9278 : {
9279 : this->code_ = BUILTIN_INVALID;
9280 : return;
9281 : }
9282 240766 : else if (fn->func_expression() != NULL)
9283 240766 : no = fn->func_expression()->named_object();
9284 0 : else if (fn->unknown_expression() != NULL)
9285 0 : no = fn->unknown_expression()->named_object();
9286 : else
9287 0 : go_unreachable();
9288 :
9289 240766 : const std::string& name(no->name());
9290 240766 : if (name == "append")
9291 15751 : this->code_ = BUILTIN_APPEND;
9292 225015 : else if (name == "cap")
9293 16623 : this->code_ = BUILTIN_CAP;
9294 208392 : else if (name == "close")
9295 1094 : this->code_ = BUILTIN_CLOSE;
9296 207298 : else if (name == "complex")
9297 13722 : this->code_ = BUILTIN_COMPLEX;
9298 193576 : else if (name == "copy")
9299 4493 : this->code_ = BUILTIN_COPY;
9300 189083 : else if (name == "delete")
9301 943 : this->code_ = BUILTIN_DELETE;
9302 188140 : else if (name == "imag")
9303 555 : this->code_ = BUILTIN_IMAG;
9304 187585 : else if (name == "len")
9305 116380 : this->code_ = BUILTIN_LEN;
9306 71205 : else if (name == "make")
9307 15137 : this->code_ = BUILTIN_MAKE;
9308 56068 : else if (name == "new")
9309 21304 : this->code_ = BUILTIN_NEW;
9310 34764 : else if (name == "panic")
9311 15153 : this->code_ = BUILTIN_PANIC;
9312 19611 : else if (name == "print")
9313 2727 : this->code_ = BUILTIN_PRINT;
9314 16884 : else if (name == "println")
9315 13459 : this->code_ = BUILTIN_PRINTLN;
9316 3425 : else if (name == "real")
9317 493 : this->code_ = BUILTIN_REAL;
9318 2932 : else if (name == "recover")
9319 857 : this->code_ = BUILTIN_RECOVER;
9320 2075 : else if (name == "Add")
9321 9 : this->code_ = BUILTIN_ADD;
9322 2066 : else if (name == "Alignof")
9323 17 : this->code_ = BUILTIN_ALIGNOF;
9324 2049 : else if (name == "Offsetof")
9325 1161 : this->code_ = BUILTIN_OFFSETOF;
9326 888 : else if (name == "Sizeof")
9327 879 : this->code_ = BUILTIN_SIZEOF;
9328 9 : else if (name == "Slice")
9329 9 : this->code_ = BUILTIN_SLICE;
9330 : else
9331 0 : go_unreachable();
9332 : }
9333 :
9334 : // Return whether this is a call to recover. This is a virtual
9335 : // function called from the parent class.
9336 :
9337 : bool
9338 1580 : Builtin_call_expression::do_is_recover_call() const
9339 : {
9340 1580 : if (this->classification() == EXPRESSION_ERROR)
9341 : return false;
9342 1580 : return this->code_ == BUILTIN_RECOVER;
9343 : }
9344 :
9345 : // Set the argument for a call to recover.
9346 :
9347 : void
9348 857 : Builtin_call_expression::do_set_recover_arg(Expression* arg)
9349 : {
9350 857 : const Expression_list* args = this->args();
9351 857 : go_assert(args == NULL || args->empty());
9352 857 : Expression_list* new_args = new Expression_list();
9353 857 : new_args->push_back(arg);
9354 857 : this->set_args(new_args);
9355 857 : this->recover_arg_is_set_ = true;
9356 857 : }
9357 :
9358 : // Lower a builtin call expression. This turns new and make into
9359 : // specific expressions. We also convert to a constant if we can.
9360 :
9361 : Expression*
9362 449703 : Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
9363 : Statement_inserter* inserter)
9364 : {
9365 449703 : if (this->is_error_expression())
9366 995 : return this;
9367 :
9368 448708 : Location loc = this->location();
9369 :
9370 448708 : if (this->code_ == BUILTIN_OFFSETOF)
9371 : {
9372 1154 : Expression* arg = this->one_arg();
9373 1154 : Field_reference_expression* farg = arg->field_reference_expression();
9374 2097 : while (farg != NULL)
9375 : {
9376 2097 : if (!farg->implicit())
9377 : break;
9378 : // When the selector refers to an embedded field,
9379 : // it must not be reached through pointer indirections.
9380 1841 : if (farg->expr()->deref() != farg->expr())
9381 : {
9382 898 : this->report_error(_("argument of Offsetof implies "
9383 : "indirection of an embedded field"));
9384 898 : return this;
9385 : }
9386 : // Go up until we reach the original base.
9387 3040 : farg = farg->expr()->field_reference_expression();
9388 : }
9389 : }
9390 :
9391 447810 : if (this->is_constant())
9392 : {
9393 15726 : Numeric_constant nc;
9394 15726 : if (this->numeric_constant_value(&nc))
9395 : {
9396 15726 : Expression* ret = nc.expression(loc);
9397 15726 : Type_context subcontext;
9398 15726 : if (this->type() != NULL)
9399 1526 : subcontext = Type_context(this->type(),
9400 1526 : this->type()->is_abstract());
9401 15726 : ret->determine_type(gogo, &subcontext);
9402 15726 : return ret;
9403 : }
9404 15726 : }
9405 :
9406 432084 : switch (this->code_)
9407 : {
9408 : default:
9409 : break;
9410 :
9411 23184 : case BUILTIN_NEW:
9412 23184 : return Expression::make_allocation(this->one_arg()->type(), loc);
9413 :
9414 15099 : case BUILTIN_MAKE:
9415 15099 : return this->lower_make(gogo, inserter);
9416 :
9417 874 : case BUILTIN_RECOVER:
9418 874 : if (function != NULL)
9419 874 : function->func_value()->set_calls_recover();
9420 : else
9421 : {
9422 : // Calling recover outside of a function always returns the
9423 : // nil empty interface.
9424 0 : Type* eface = Type::make_empty_interface_type(loc);
9425 0 : return Expression::make_cast(eface, Expression::make_nil(loc), loc);
9426 : }
9427 874 : break;
9428 :
9429 1559 : case BUILTIN_DELETE:
9430 1559 : {
9431 1559 : const Expression_list* args = this->args();
9432 1559 : Type* key_type =
9433 3118 : args->front()->type()->map_type()->key_type();
9434 1559 : Expression_list::iterator pa = this->args()->begin();
9435 1559 : pa++;
9436 1559 : Type* arg_type = (*pa)->type();
9437 1559 : if (!Type::are_identical(key_type, arg_type, 0, NULL))
9438 16 : *pa = Expression::make_cast(key_type, *pa, loc);
9439 : }
9440 : break;
9441 :
9442 17885 : case BUILTIN_PRINT:
9443 17885 : case BUILTIN_PRINTLN:
9444 : // Force all the arguments into temporary variables, so that we
9445 : // don't try to evaluate something while holding the print lock.
9446 17885 : if (this->args() == NULL)
9447 : break;
9448 61881 : for (Expression_list::iterator pa = this->args()->begin();
9449 61881 : pa != this->args()->end();
9450 44065 : ++pa)
9451 : {
9452 44065 : if (!(*pa)->is_multi_eval_safe())
9453 : {
9454 27576 : Temporary_statement* temp =
9455 27576 : Statement::make_temporary(NULL, *pa, loc);
9456 27576 : inserter->insert(temp);
9457 27576 : *pa = Expression::make_temporary_reference(temp, loc);
9458 : }
9459 : }
9460 : break;
9461 : }
9462 :
9463 : return this;
9464 : }
9465 :
9466 : // Flatten a builtin call expression. This turns the arguments of some
9467 : // builtin calls into temporary expressions. Also expand copy and append
9468 : // to runtime calls.
9469 :
9470 : Expression*
9471 210171 : Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function,
9472 : Statement_inserter* inserter)
9473 : {
9474 210171 : if (this->is_error_expression())
9475 : {
9476 978 : go_assert(saw_errors());
9477 978 : return this;
9478 : }
9479 :
9480 209193 : Location loc = this->location();
9481 :
9482 209193 : switch (this->code_)
9483 : {
9484 : default:
9485 : break;
9486 :
9487 2654 : case BUILTIN_APPEND:
9488 2654 : return this->flatten_append(gogo, function, inserter, NULL, NULL);
9489 :
9490 4478 : case BUILTIN_COPY:
9491 4478 : {
9492 4478 : Type* at = this->args()->front()->type();
9493 13434 : for (Expression_list::iterator pa = this->args()->begin();
9494 13434 : pa != this->args()->end();
9495 8956 : ++pa)
9496 : {
9497 8956 : if ((*pa)->is_error_expression())
9498 : {
9499 0 : go_assert(saw_errors());
9500 0 : return Expression::make_error(loc);
9501 : }
9502 8956 : if ((*pa)->is_nil_expression())
9503 : {
9504 0 : Expression* nil = Expression::make_nil(loc);
9505 0 : Expression* zero = Expression::make_integer_ul(0, NULL, loc);
9506 0 : *pa = Expression::make_slice_value(at, nil, zero, zero, loc);
9507 : }
9508 8956 : if (!(*pa)->is_multi_eval_safe())
9509 : {
9510 5001 : Temporary_statement* temp =
9511 5001 : Statement::make_temporary(NULL, *pa, loc);
9512 5001 : inserter->insert(temp);
9513 5001 : *pa = Expression::make_temporary_reference(temp, loc);
9514 : }
9515 : }
9516 :
9517 : // Lower to runtime call.
9518 4478 : const Expression_list* args = this->args();
9519 4478 : go_assert(args != NULL && args->size() == 2);
9520 4478 : Expression* arg1 = args->front();
9521 4478 : Expression* arg2 = args->back();
9522 4478 : go_assert(arg1->is_multi_eval_safe());
9523 4478 : go_assert(arg2->is_multi_eval_safe());
9524 4478 : bool arg2_is_string = arg2->type()->is_string_type();
9525 :
9526 4478 : Expression* ret;
9527 8956 : Type* et = at->array_type()->element_type();
9528 4478 : if (et->has_pointer())
9529 : {
9530 1649 : Expression* td = Expression::make_type_descriptor(et, loc);
9531 1649 : Expression* pd =
9532 1649 : Expression::make_slice_info(arg1, SLICE_INFO_VALUE_POINTER, loc);
9533 1649 : Expression* ld =
9534 1649 : Expression::make_slice_info(arg1, SLICE_INFO_LENGTH, loc);
9535 1649 : Expression* ps =
9536 1649 : Expression::make_slice_info(arg2, SLICE_INFO_VALUE_POINTER, loc);
9537 1649 : Expression* ls =
9538 1649 : Expression::make_slice_info(arg2, SLICE_INFO_LENGTH, loc);
9539 1649 : ret = Runtime::make_call(gogo, Runtime::TYPEDSLICECOPY, loc,
9540 : 5, td, pd, ld, ps, ls);
9541 : }
9542 : else
9543 : {
9544 2829 : Type* int_type = Type::lookup_integer_type("int");
9545 2829 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
9546 :
9547 : // l1 = len(arg1)
9548 2829 : Named_object* lenfn = gogo->lookup_global("len");
9549 2829 : Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
9550 2829 : Expression_list* len_args = new Expression_list();
9551 2829 : len_args->push_back(arg1->copy());
9552 2829 : Expression* len1 = Expression::make_call(lenref, len_args, false, loc);
9553 2829 : gogo->lower_expression(function, inserter, &len1);
9554 2829 : gogo->flatten_expression(function, inserter, &len1);
9555 2829 : Temporary_statement* l1tmp = Statement::make_temporary(int_type, len1, loc);
9556 2829 : l1tmp->determine_types(gogo);
9557 2829 : inserter->insert(l1tmp);
9558 :
9559 : // l2 = len(arg2)
9560 2829 : len_args = new Expression_list();
9561 2829 : len_args->push_back(arg2->copy());
9562 2829 : Expression* len2 = Expression::make_call(lenref, len_args, false, loc);
9563 2829 : gogo->lower_expression(function, inserter, &len2);
9564 2829 : gogo->flatten_expression(function, inserter, &len2);
9565 2829 : Temporary_statement* l2tmp = Statement::make_temporary(int_type, len2, loc);
9566 2829 : l2tmp->determine_types(gogo);
9567 2829 : inserter->insert(l2tmp);
9568 :
9569 : // n = (l1 < l2 ? l1 : l2)
9570 2829 : Expression* l1ref = Expression::make_temporary_reference(l1tmp, loc);
9571 2829 : Expression* l2ref = Expression::make_temporary_reference(l2tmp, loc);
9572 2829 : Expression* cond = Expression::make_binary(OPERATOR_LT, l1ref, l2ref, loc);
9573 2829 : Expression* n = Expression::make_conditional(cond,
9574 : l1ref->copy(),
9575 : l2ref->copy(),
9576 : loc);
9577 2829 : Temporary_statement* ntmp = Statement::make_temporary(NULL, n, loc);
9578 2829 : ntmp->determine_types(gogo);
9579 2829 : inserter->insert(ntmp);
9580 :
9581 : // sz = n * sizeof(elem_type)
9582 2829 : Expression* nref = Expression::make_temporary_reference(ntmp, loc);
9583 2829 : nref = Expression::make_cast(uintptr_type, nref, loc);
9584 2829 : Expression* sz = Expression::make_type_info(et, TYPE_INFO_SIZE);
9585 2829 : sz = Expression::make_binary(OPERATOR_MULT, sz, nref, loc);
9586 :
9587 : // memmove(arg1.ptr, arg2.ptr, sz)
9588 2829 : Expression* p1 = Expression::make_slice_info(arg1,
9589 : SLICE_INFO_VALUE_POINTER,
9590 : loc);
9591 2829 : Expression* p2 = (arg2_is_string
9592 2829 : ? Expression::make_string_info(arg2,
9593 : STRING_INFO_DATA,
9594 : loc)
9595 2452 : : Expression::make_slice_info(arg2,
9596 : SLICE_INFO_VALUE_POINTER,
9597 : loc));
9598 2829 : Expression* call = Runtime::make_call(gogo,
9599 : Runtime::BUILTIN_MEMMOVE,
9600 : loc, 3,
9601 : p1, p2, sz);
9602 :
9603 : // n is the return value of copy
9604 2829 : nref = Expression::make_temporary_reference(ntmp, loc);
9605 2829 : ret = Expression::make_compound(call, nref, loc);
9606 : }
9607 4478 : ret->determine_type_no_context(gogo);
9608 4478 : return ret;
9609 : }
9610 15370 : break;
9611 :
9612 15370 : case BUILTIN_PANIC:
9613 15370 : for (Expression_list::iterator pa = this->args()->begin();
9614 30740 : pa != this->args()->end();
9615 15370 : ++pa)
9616 : {
9617 15370 : if (!(*pa)->is_multi_eval_safe()
9618 30138 : && (*pa)->type()->interface_type() != NULL)
9619 : {
9620 14768 : Temporary_statement* temp =
9621 14768 : Statement::make_temporary(NULL, *pa, loc);
9622 14768 : inserter->insert(temp);
9623 14768 : *pa = Expression::make_temporary_reference(temp, loc);
9624 : }
9625 : }
9626 : break;
9627 :
9628 154386 : case BUILTIN_LEN:
9629 154386 : case BUILTIN_CAP:
9630 154386 : {
9631 154386 : Expression_list::iterator pa = this->args()->begin();
9632 154386 : if (!(*pa)->is_multi_eval_safe()
9633 154386 : && ((*pa)->type()->map_type() != NULL
9634 15197 : || (*pa)->type()->channel_type() != NULL))
9635 : {
9636 692 : Temporary_statement* temp =
9637 692 : Statement::make_temporary(NULL, *pa, loc);
9638 692 : inserter->insert(temp);
9639 692 : *pa = Expression::make_temporary_reference(temp, loc);
9640 : }
9641 : }
9642 : break;
9643 :
9644 867 : case BUILTIN_DELETE:
9645 867 : {
9646 : // Lower to a runtime function call.
9647 867 : const Expression_list* args = this->args();
9648 :
9649 : // Since this function returns no value it must appear in
9650 : // a statement by itself, so we don't have to worry about
9651 : // order of evaluation of values around it. Evaluate the
9652 : // map first to get order of evaluation right.
9653 867 : Map_type* mt = args->front()->type()->map_type();
9654 867 : Temporary_statement* map_temp =
9655 867 : Statement::make_temporary(mt, args->front(), loc);
9656 867 : inserter->insert(map_temp);
9657 :
9658 867 : Temporary_statement* key_temp =
9659 867 : Statement::make_temporary(mt->key_type(), args->back(), loc);
9660 867 : inserter->insert(key_temp);
9661 :
9662 867 : Expression* e1 = Expression::make_type_descriptor(mt, loc);
9663 867 : Expression* e2 = Expression::make_temporary_reference(map_temp,
9664 : loc);
9665 867 : Expression* e3 = Expression::make_temporary_reference(key_temp,
9666 : loc);
9667 :
9668 867 : Runtime::Function code;
9669 867 : switch (mt->algorithm(gogo))
9670 : {
9671 139 : case Map_type::MAP_ALG_FAST32:
9672 139 : case Map_type::MAP_ALG_FAST32PTR:
9673 139 : {
9674 139 : code = Runtime::MAPDELETE_FAST32;
9675 139 : Type* uint32_type = Type::lookup_integer_type("uint32");
9676 139 : Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
9677 139 : e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
9678 139 : e3 = Expression::make_unsafe_cast(uint32_ptr_type, e3,
9679 : loc);
9680 139 : e3 = Expression::make_dereference(e3,
9681 : Expression::NIL_CHECK_NOT_NEEDED,
9682 : loc);
9683 139 : break;
9684 : }
9685 211 : case Map_type::MAP_ALG_FAST64:
9686 211 : case Map_type::MAP_ALG_FAST64PTR:
9687 211 : {
9688 211 : code = Runtime::MAPDELETE_FAST64;
9689 211 : Type* uint64_type = Type::lookup_integer_type("uint64");
9690 211 : Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
9691 211 : e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
9692 211 : e3 = Expression::make_unsafe_cast(uint64_ptr_type, e3,
9693 : loc);
9694 211 : e3 = Expression::make_dereference(e3,
9695 : Expression::NIL_CHECK_NOT_NEEDED,
9696 : loc);
9697 211 : break;
9698 : }
9699 : case Map_type::MAP_ALG_FASTSTR:
9700 : code = Runtime::MAPDELETE_FASTSTR;
9701 : break;
9702 177 : default:
9703 177 : code = Runtime::MAPDELETE;
9704 :
9705 : // If the call to delete is deferred, and is in a loop,
9706 : // then the loop will only have a single instance of the
9707 : // temporary variable. Passing the address of the
9708 : // temporary variable here means that the deferred call
9709 : // will see the last value in the loop, not the current
9710 : // value. So for this unusual case copy the value into
9711 : // the heap.
9712 177 : if (!this->is_deferred())
9713 144 : e3 = Expression::make_unary(OPERATOR_AND, e3, loc);
9714 : else
9715 : {
9716 33 : Expression* a = Expression::make_allocation(mt->key_type(),
9717 : loc);
9718 33 : Temporary_statement* atemp =
9719 33 : Statement::make_temporary(NULL, a, loc);
9720 33 : atemp->determine_types(gogo);
9721 33 : inserter->insert(atemp);
9722 :
9723 33 : a = Expression::make_temporary_reference(atemp, loc);
9724 33 : a = Expression::make_dereference(a, NIL_CHECK_NOT_NEEDED, loc);
9725 33 : Statement* s = Statement::make_assignment(a, e3, loc);
9726 33 : s->determine_types(gogo);
9727 33 : inserter->insert(s);
9728 :
9729 33 : e3 = Expression::make_temporary_reference(atemp, loc);
9730 : }
9731 : }
9732 :
9733 867 : Expression* ret = Runtime::make_call(gogo, code, loc, 3, e1, e2, e3);
9734 867 : ret->determine_type_no_context(gogo);
9735 867 : return ret;
9736 : }
9737 :
9738 2 : case BUILTIN_ADD:
9739 2 : {
9740 2 : Expression* ptr = this->args()->front();
9741 2 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
9742 2 : ptr = Expression::make_cast(uintptr_type, ptr, loc);
9743 2 : Expression* len = this->args()->back();
9744 2 : len = Expression::make_cast(uintptr_type, len, loc);
9745 2 : Expression* add = Expression::make_binary(OPERATOR_PLUS, ptr, len,
9746 : loc);
9747 2 : Expression* ret = Expression::make_cast(this->args()->front()->type(),
9748 : add, loc);
9749 2 : ret->determine_type_no_context(gogo);
9750 2 : return ret;
9751 : }
9752 :
9753 9 : case BUILTIN_SLICE:
9754 9 : {
9755 9 : Expression* ptr = this->args()->front();
9756 9 : Temporary_statement* ptr_temp = NULL;
9757 9 : if (!ptr->is_multi_eval_safe())
9758 : {
9759 8 : ptr_temp = Statement::make_temporary(NULL, ptr, loc);
9760 8 : inserter->insert(ptr_temp);
9761 8 : ptr = Expression::make_temporary_reference(ptr_temp, loc);
9762 : }
9763 :
9764 9 : Expression* len = this->args()->back();
9765 9 : Temporary_statement* len_temp = NULL;
9766 9 : if (!len->is_multi_eval_safe())
9767 : {
9768 2 : len_temp = Statement::make_temporary(NULL, len, loc);
9769 2 : inserter->insert(len_temp);
9770 2 : len = Expression::make_temporary_reference(len_temp, loc);
9771 : }
9772 :
9773 9 : bool fits_in_int;
9774 9 : Numeric_constant nc;
9775 9 : if (this->args()->back()->numeric_constant_value(&nc))
9776 : {
9777 : // We gave an error for constants that don't fit in int in
9778 : // check_types.
9779 : fits_in_int = true;
9780 : }
9781 : else
9782 : {
9783 2 : Integer_type* itype = this->args()->back()->type()->integer_type();
9784 0 : go_assert(itype != NULL);
9785 2 : int ebits = itype->bits();
9786 2 : int intbits =
9787 4 : Type::lookup_integer_type("int")->integer_type()->bits();
9788 :
9789 : // We can treat ebits == intbits as small even for an
9790 : // unsigned integer type, because we will convert the
9791 : // value to int and then reject it in the runtime if it is
9792 : // negative.
9793 :
9794 2 : fits_in_int = ebits <= intbits;
9795 : }
9796 :
9797 11 : Runtime::Function code = (fits_in_int
9798 2 : ? Runtime::UNSAFESLICE
9799 : : Runtime::UNSAFESLICE64);
9800 9 : Expression* td =
9801 9 : Expression::make_type_descriptor(ptr->type()->points_to(), loc);
9802 9 : Expression* check = Runtime::make_call(gogo, code, loc, 3,
9803 : td, ptr, len);
9804 :
9805 9 : if (ptr_temp == NULL)
9806 1 : ptr = ptr->copy();
9807 : else
9808 8 : ptr = Expression::make_temporary_reference(ptr_temp, loc);
9809 9 : Expression* nil = Expression::make_nil(loc);
9810 9 : nil = Expression::make_cast(ptr->type(), nil, loc);
9811 9 : Expression* is_nil = Expression::make_binary(OPERATOR_EQEQ, ptr, nil,
9812 : loc);
9813 :
9814 9 : if (len_temp == NULL)
9815 7 : len = len->copy();
9816 : else
9817 2 : len = Expression::make_temporary_reference(len_temp, loc);
9818 9 : Expression* zero = Expression::make_integer_ul(0, len->type(), loc);
9819 9 : Expression* is_zero = Expression::make_binary(OPERATOR_EQEQ, len, zero,
9820 : loc);
9821 :
9822 9 : Expression* cond = Expression::make_binary(OPERATOR_ANDAND, is_nil,
9823 : is_zero, loc);
9824 :
9825 9 : Type* slice_type = Type::make_array_type(ptr->type()->points_to(),
9826 : NULL);
9827 9 : nil = Expression::make_nil(loc);
9828 9 : Expression* nil_slice = Expression::make_cast(slice_type, nil, loc);
9829 :
9830 9 : if (ptr_temp == NULL)
9831 1 : ptr = ptr->copy();
9832 : else
9833 8 : ptr = Expression::make_temporary_reference(ptr_temp, loc);
9834 :
9835 9 : if (len_temp == NULL)
9836 7 : len = len->copy();
9837 : else
9838 2 : len = Expression::make_temporary_reference(len_temp, loc);
9839 :
9840 9 : Expression* cap;
9841 9 : if (len_temp == NULL)
9842 7 : cap = len->copy();
9843 : else
9844 2 : cap = Expression::make_temporary_reference(len_temp, loc);
9845 :
9846 9 : Expression* slice = Expression::make_slice_value(slice_type, ptr,
9847 : len, cap, loc);
9848 :
9849 9 : slice = Expression::make_conditional(cond, nil_slice, slice, loc);
9850 :
9851 9 : Expression* ret = Expression::make_compound(check, slice, loc);
9852 9 : ret->determine_type_no_context(gogo);
9853 9 : return ret;
9854 9 : }
9855 : }
9856 :
9857 201183 : return this;
9858 : }
9859 :
9860 : // Lower a make expression.
9861 :
9862 : Expression*
9863 15099 : Builtin_call_expression::lower_make(Gogo* gogo, Statement_inserter* inserter)
9864 : {
9865 15099 : Location loc = this->location();
9866 :
9867 15099 : const Expression_list* args = this->args();
9868 :
9869 15099 : Expression_list::const_iterator parg = args->begin();
9870 :
9871 15099 : Expression* first_arg = *parg;
9872 15099 : go_assert(first_arg->is_type_expression());
9873 15099 : Type* type = first_arg->type();
9874 :
9875 15099 : bool is_slice = false;
9876 15099 : bool is_map = false;
9877 15099 : bool is_chan = false;
9878 15099 : if (type->is_slice_type())
9879 : is_slice = true;
9880 6609 : else if (type->map_type() != NULL)
9881 : is_map = true;
9882 17862 : else if (type->channel_type() != NULL)
9883 : is_chan = true;
9884 : else
9885 0 : go_unreachable();
9886 :
9887 15099 : ++parg;
9888 15099 : Expression* len_arg;
9889 15099 : bool len_small = false;
9890 15099 : if (parg == args->end())
9891 : {
9892 4933 : go_assert(!is_slice);
9893 4933 : len_arg = Expression::make_integer_ul(0, NULL, loc);
9894 4933 : len_small = true;
9895 : }
9896 : else
9897 : {
9898 10166 : len_arg = *parg;
9899 10166 : if (!this->check_int_value(len_arg, true, &len_small))
9900 8 : return Expression::make_error(this->location());
9901 10158 : ++parg;
9902 : }
9903 :
9904 15091 : Expression* cap_arg = NULL;
9905 15091 : bool cap_small = false;
9906 15091 : Numeric_constant nclen;
9907 15091 : Numeric_constant nccap;
9908 15091 : unsigned long vlen;
9909 15091 : unsigned long vcap;
9910 15091 : if (is_slice && parg != args->end())
9911 : {
9912 1715 : cap_arg = *parg;
9913 1715 : if (!this->check_int_value(cap_arg, false, &cap_small))
9914 2 : return Expression::make_error(this->location());
9915 :
9916 1713 : if (len_arg->numeric_constant_value(&nclen)
9917 1614 : && cap_arg->numeric_constant_value(&nccap)
9918 554 : && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
9919 554 : && nccap.to_unsigned_long(&vcap) == Numeric_constant::NC_UL_VALID
9920 2267 : && vlen > vcap)
9921 : {
9922 1 : this->report_error(_("len larger than cap"));
9923 1 : return Expression::make_error(this->location());
9924 : }
9925 :
9926 1712 : ++parg;
9927 : }
9928 :
9929 15088 : go_assert(parg == args->end());
9930 :
9931 15088 : Location type_loc = first_arg->location();
9932 :
9933 15088 : Expression* call;
9934 15088 : if (is_slice)
9935 : {
9936 8479 : Temporary_statement* len_temp = NULL;
9937 8479 : if (!len_arg->is_constant())
9938 : {
9939 4458 : len_temp = Statement::make_temporary(NULL, len_arg, loc);
9940 4458 : inserter->insert(len_temp);
9941 4458 : len_arg = Expression::make_temporary_reference(len_temp, loc);
9942 : }
9943 :
9944 8479 : if (cap_arg == NULL)
9945 : {
9946 6767 : cap_small = len_small;
9947 6767 : if (len_temp == NULL)
9948 2408 : cap_arg = len_arg->copy();
9949 : else
9950 4359 : cap_arg = Expression::make_temporary_reference(len_temp, loc);
9951 : }
9952 1712 : else if (!cap_arg->is_constant())
9953 : {
9954 1138 : Temporary_statement* cap_temp = Statement::make_temporary(NULL,
9955 : cap_arg,
9956 : loc);
9957 1138 : inserter->insert(cap_temp);
9958 1138 : cap_arg = Expression::make_temporary_reference(cap_temp, loc);
9959 : }
9960 :
9961 16958 : Type* et = type->array_type()->element_type();
9962 8479 : Expression* type_arg = Expression::make_type_descriptor(et, type_loc);
9963 8479 : Runtime::Function code = Runtime::MAKESLICE;
9964 8479 : if (!len_small || !cap_small)
9965 120 : code = Runtime::MAKESLICE64;
9966 8479 : Expression* mem = Runtime::make_call(gogo, code, loc, 3,
9967 : type_arg, len_arg, cap_arg);
9968 8479 : mem = Expression::make_unsafe_cast(Type::make_pointer_type(et), mem,
9969 : loc);
9970 8479 : Type* int_type = Type::lookup_integer_type("int");
9971 8479 : len_arg = Expression::make_cast(int_type, len_arg->copy(), loc);
9972 8479 : cap_arg = Expression::make_cast(int_type, cap_arg->copy(), loc);
9973 8479 : call = Expression::make_slice_value(type, mem, len_arg, cap_arg, loc);
9974 : }
9975 6609 : else if (is_map)
9976 : {
9977 3846 : Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
9978 3846 : if (!len_small)
9979 2 : call = Runtime::make_call(gogo, Runtime::MAKEMAP64, loc, 3, type_arg,
9980 : len_arg,
9981 : Expression::make_nil(loc));
9982 : else
9983 : {
9984 3844 : if (len_arg->numeric_constant_value(&nclen)
9985 3485 : && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
9986 7329 : && vlen <= Map_type::bucket_size)
9987 3434 : call = Runtime::make_call(gogo, Runtime::MAKEMAP_SMALL, loc, 0);
9988 : else
9989 410 : call = Runtime::make_call(gogo, Runtime::MAKEMAP, loc, 3, type_arg,
9990 : len_arg,
9991 : Expression::make_nil(loc));
9992 : }
9993 : }
9994 2763 : else if (is_chan)
9995 : {
9996 2763 : Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
9997 2763 : Runtime::Function code = Runtime::MAKECHAN;
9998 2763 : if (!len_small)
9999 0 : code = Runtime::MAKECHAN64;
10000 2763 : call = Runtime::make_call(gogo, code, loc, 2, type_arg, len_arg);
10001 : }
10002 : else
10003 0 : go_unreachable();
10004 :
10005 15088 : Expression* ret = Expression::make_unsafe_cast(type, call, loc);
10006 15088 : ret->determine_type_no_context(gogo);
10007 15088 : return ret;
10008 15091 : }
10009 :
10010 : // Flatten a call to the predeclared append function. We do this in
10011 : // the flatten phase, not the lowering phase, so that we run after
10012 : // type checking and after order_evaluations. If ASSIGN_LHS is not
10013 : // NULL, this append is the right-hand-side of an assignment and
10014 : // ASSIGN_LHS is the left-hand-side; in that case, set LHS directly
10015 : // rather than returning a slice. This lets us omit a write barrier
10016 : // in common cases like a = append(a, ...) when the slice does not
10017 : // need to grow. ENCLOSING is not NULL iff ASSIGN_LHS is not NULL.
10018 :
10019 : Expression*
10020 15676 : Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
10021 : Statement_inserter* inserter,
10022 : Expression* assign_lhs,
10023 : Block* enclosing)
10024 : {
10025 15676 : if (this->is_error_expression())
10026 0 : return this;
10027 :
10028 15676 : Location loc = this->location();
10029 :
10030 15676 : const Expression_list* args = this->args();
10031 15676 : go_assert(args != NULL && !args->empty());
10032 :
10033 15676 : Type* slice_type = args->front()->type();
10034 15676 : go_assert(slice_type->is_slice_type());
10035 31352 : Type* element_type = slice_type->array_type()->element_type();
10036 :
10037 15676 : if (args->size() == 1)
10038 : {
10039 : // append(s) evaluates to s.
10040 23 : if (assign_lhs != NULL)
10041 : return NULL;
10042 23 : return args->front();
10043 : }
10044 :
10045 15653 : Type* int_type = Type::lookup_integer_type("int");
10046 15653 : Type_context int_context(int_type, false);
10047 15653 : Type* uint_type = Type::lookup_integer_type("uint");
10048 :
10049 : // Implementing
10050 : // append(s1, s2...)
10051 : // or
10052 : // append(s1, a1, a2, a3, ...)
10053 :
10054 : // s1tmp := s1
10055 15653 : Temporary_statement* s1tmp = Statement::make_temporary(NULL, args->front(),
10056 : loc);
10057 15653 : inserter->insert(s1tmp);
10058 :
10059 : // l1tmp := len(s1tmp)
10060 15653 : Named_object* lenfn = gogo->lookup_global("len");
10061 15653 : Expression* lenref = Expression::make_func_reference(lenfn, NULL, loc);
10062 15653 : Expression_list* call_args = new Expression_list();
10063 15653 : call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
10064 15653 : Expression* len = Expression::make_call(lenref, call_args, false, loc);
10065 15653 : len->determine_type(gogo, &int_context);
10066 15653 : gogo->lower_expression(function, inserter, &len);
10067 15653 : gogo->flatten_expression(function, inserter, &len);
10068 15653 : Temporary_statement* l1tmp = Statement::make_temporary(int_type, len, loc);
10069 15653 : inserter->insert(l1tmp);
10070 :
10071 15653 : Temporary_statement* s2tmp = NULL;
10072 15653 : Temporary_statement* l2tmp = NULL;
10073 15653 : Expression_list* add = NULL;
10074 15653 : Expression* len2;
10075 15653 : Call_expression* makecall = NULL;
10076 15653 : if (this->is_varargs())
10077 : {
10078 3556 : go_assert(args->size() == 2);
10079 :
10080 3556 : std::pair<Call_expression*, Temporary_statement*> p =
10081 3556 : Expression::find_makeslice_call(args->back());
10082 3556 : makecall = p.first;
10083 3556 : if (makecall != NULL)
10084 : {
10085 : // We are handling
10086 : // append(s, make([]T, len[, cap])...))
10087 : // which has already been lowered to
10088 : // append(s, runtime.makeslice(T, len, cap)).
10089 : // We will optimize this to directly zeroing the tail,
10090 : // instead of allocating a new slice then copy.
10091 :
10092 : // Retrieve the length and capacity. Cannot reference s2 as
10093 : // we will remove the makeslice call.
10094 27 : Expression* len_arg = makecall->args()->at(1);
10095 27 : len_arg = Expression::make_cast(int_type, len_arg, loc);
10096 27 : l2tmp = Statement::make_temporary(int_type, len_arg, loc);
10097 27 : l2tmp->determine_types(gogo);
10098 27 : inserter->insert(l2tmp);
10099 :
10100 27 : Expression* cap_arg = makecall->args()->at(2);
10101 27 : cap_arg = Expression::make_cast(int_type, cap_arg, loc);
10102 27 : Temporary_statement* c2tmp =
10103 27 : Statement::make_temporary(int_type, cap_arg, loc);
10104 27 : c2tmp->determine_types(gogo);
10105 27 : inserter->insert(c2tmp);
10106 :
10107 : // Check bad len/cap here.
10108 : // checkmakeslice(type, len, cap)
10109 : // (Note that if len and cap are constants, we won't see a
10110 : // makeslice call here, as it will be rewritten to a stack
10111 : // allocated array by Mark_address_taken::expression.)
10112 27 : Expression* elem = Expression::make_type_descriptor(element_type,
10113 : loc);
10114 27 : len2 = Expression::make_temporary_reference(l2tmp, loc);
10115 27 : Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc);
10116 27 : Expression* check = Runtime::make_call(gogo,
10117 : Runtime::CHECK_MAKE_SLICE,
10118 27 : loc, 3, elem, len2, cap2);
10119 27 : check->determine_type_no_context(gogo);
10120 27 : gogo->lower_expression(function, inserter, &check);
10121 27 : gogo->flatten_expression(function, inserter, &check);
10122 27 : Statement* s = Statement::make_statement(check, false);
10123 27 : inserter->insert(s);
10124 :
10125 : // Remove the original makeslice call.
10126 27 : Temporary_statement* ts = p.second;
10127 27 : if (ts != NULL && ts->uses() == 1)
10128 27 : ts->set_init(Expression::make_nil(loc));
10129 : }
10130 : else
10131 : {
10132 : // s2tmp := s2
10133 3529 : s2tmp = Statement::make_temporary(NULL, args->back(), loc);
10134 3529 : inserter->insert(s2tmp);
10135 :
10136 : // l2tmp := len(s2tmp)
10137 3529 : lenref = Expression::make_func_reference(lenfn, NULL, loc);
10138 3529 : call_args = new Expression_list();
10139 3529 : call_args->push_back(Expression::make_temporary_reference(s2tmp, loc));
10140 3529 : len = Expression::make_call(lenref, call_args, false, loc);
10141 3529 : len->determine_type(gogo, &int_context);
10142 3529 : gogo->lower_expression(function, inserter, &len);
10143 3529 : gogo->flatten_expression(function, inserter, &len);
10144 3529 : l2tmp = Statement::make_temporary(int_type, len, loc);
10145 3529 : l2tmp->determine_types(gogo);
10146 3529 : inserter->insert(l2tmp);
10147 : }
10148 :
10149 : // len2 = l2tmp
10150 3556 : len2 = Expression::make_temporary_reference(l2tmp, loc);
10151 : }
10152 : else
10153 : {
10154 : // We have to ensure that all the arguments are in variables
10155 : // now, because otherwise if one of them is an index expression
10156 : // into the current slice we could overwrite it before we fetch
10157 : // it.
10158 12097 : add = new Expression_list();
10159 12097 : Expression_list::const_iterator pa = args->begin();
10160 26301 : for (++pa; pa != args->end(); ++pa)
10161 : {
10162 14204 : if ((*pa)->is_multi_eval_safe())
10163 7816 : add->push_back(*pa);
10164 : else
10165 : {
10166 6388 : Temporary_statement* tmp = Statement::make_temporary(NULL, *pa,
10167 : loc);
10168 6388 : inserter->insert(tmp);
10169 6388 : add->push_back(Expression::make_temporary_reference(tmp, loc));
10170 : }
10171 : }
10172 :
10173 : // len2 = len(add)
10174 12097 : len2 = Expression::make_integer_ul(add->size(), int_type, loc);
10175 : }
10176 :
10177 : // ntmp := l1tmp + len2
10178 15653 : Expression* ref = Expression::make_temporary_reference(l1tmp, loc);
10179 15653 : Expression* sum = Expression::make_binary(OPERATOR_PLUS, ref, len2, loc);
10180 15653 : sum->determine_type(gogo, &int_context);
10181 15653 : gogo->lower_expression(function, inserter, &sum);
10182 15653 : gogo->flatten_expression(function, inserter, &sum);
10183 15653 : Temporary_statement* ntmp = Statement::make_temporary(int_type, sum, loc);
10184 15653 : ntmp->determine_types(gogo);
10185 15653 : inserter->insert(ntmp);
10186 :
10187 : // s1tmp = uint(ntmp) > uint(cap(s1tmp)) ?
10188 : // growslice(type, s1tmp, ntmp) :
10189 : // s1tmp[:ntmp]
10190 : // Using uint here means that if the computation of ntmp overflowed,
10191 : // we will call growslice which will panic.
10192 :
10193 15653 : Named_object* capfn = gogo->lookup_global("cap");
10194 15653 : Expression* capref = Expression::make_func_reference(capfn, NULL, loc);
10195 15653 : call_args = new Expression_list();
10196 15653 : call_args->push_back(Expression::make_temporary_reference(s1tmp, loc));
10197 15653 : Expression* cap = Expression::make_call(capref, call_args, false, loc);
10198 15653 : cap->determine_type(gogo, &int_context);
10199 15653 : gogo->lower_expression(function, inserter, &cap);
10200 15653 : gogo->flatten_expression(function, inserter, &cap);
10201 15653 : Temporary_statement* c1tmp = Statement::make_temporary(int_type, cap, loc);
10202 15653 : c1tmp->determine_types(gogo);
10203 15653 : inserter->insert(c1tmp);
10204 :
10205 15653 : Expression* left = Expression::make_temporary_reference(ntmp, loc);
10206 15653 : left = Expression::make_cast(uint_type, left, loc);
10207 15653 : Expression* right = Expression::make_temporary_reference(c1tmp, loc);
10208 15653 : right = Expression::make_cast(uint_type, right, loc);
10209 :
10210 15653 : Expression* cond = Expression::make_binary(OPERATOR_GT, left, right, loc);
10211 :
10212 15653 : Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
10213 15653 : Expression* a1 = Expression::make_type_descriptor(element_type, loc);
10214 15653 : Expression* a2 = Expression::make_temporary_reference(s1tmp, loc);
10215 31306 : a2 = slice_type->array_type()->get_value_pointer(gogo, a2);
10216 15653 : a2 = Expression::make_cast(unsafe_ptr_type, a2, loc);
10217 15653 : Expression* a3 = Expression::make_temporary_reference(l1tmp, loc);
10218 15653 : Expression* a4 = Expression::make_temporary_reference(c1tmp, loc);
10219 15653 : Expression* a5 = Expression::make_temporary_reference(ntmp, loc);
10220 15653 : Expression* call = Runtime::make_call(gogo, Runtime::GROWSLICE, loc, 5,
10221 15653 : a1, a2, a3, a4, a5);
10222 15653 : call = Expression::make_unsafe_cast(slice_type, call, loc);
10223 :
10224 15653 : ref = Expression::make_temporary_reference(s1tmp, loc);
10225 15653 : Expression* zero = Expression::make_integer_ul(0, int_type, loc);
10226 15653 : Expression* ref2 = Expression::make_temporary_reference(ntmp, loc);
10227 15653 : ref = Expression::make_array_index(ref, zero, ref2, NULL, loc);
10228 15653 : ref->array_index_expression()->set_needs_bounds_check(false);
10229 :
10230 15653 : if (assign_lhs == NULL)
10231 : {
10232 2631 : Expression* rhs = Expression::make_conditional(cond, call, ref, loc);
10233 :
10234 2631 : rhs->determine_type_no_context(gogo);
10235 2631 : gogo->lower_expression(function, inserter, &rhs);
10236 2631 : gogo->flatten_expression(function, inserter, &rhs);
10237 :
10238 2631 : ref = Expression::make_temporary_reference(s1tmp, loc);
10239 2631 : Statement* assign = Statement::make_assignment(ref, rhs, loc);
10240 2631 : assign->determine_types(gogo);
10241 2631 : inserter->insert(assign);
10242 : }
10243 : else
10244 : {
10245 13022 : cond->determine_type_no_context(gogo);
10246 13022 : gogo->lower_expression(function, inserter, &cond);
10247 13022 : gogo->flatten_expression(function, inserter, &cond);
10248 13022 : call->determine_type_no_context(gogo);
10249 13022 : gogo->lower_expression(function, inserter, &call);
10250 13022 : gogo->flatten_expression(function, inserter, &call);
10251 13022 : ref->determine_type_no_context(gogo);
10252 13022 : gogo->lower_expression(function, inserter, &ref);
10253 13022 : gogo->flatten_expression(function, inserter, &ref);
10254 :
10255 13022 : Block* then_block = new Block(enclosing, loc);
10256 13022 : Assignment_statement* assign =
10257 13022 : Statement::make_assignment(assign_lhs, call, loc);
10258 13022 : assign->determine_types(gogo);
10259 13022 : then_block->add_statement(assign);
10260 :
10261 13022 : Block* else_block = new Block(enclosing, loc);
10262 13022 : assign = Statement::make_assignment(assign_lhs->copy(), ref, loc);
10263 : // This assignment will not change the pointer value, so it does
10264 : // not need a write barrier.
10265 13022 : assign->set_omit_write_barrier();
10266 13022 : assign->determine_types(gogo);
10267 13022 : else_block->add_statement(assign);
10268 :
10269 13022 : Statement* s = Statement::make_if_statement(cond, then_block,
10270 : else_block, loc);
10271 13022 : s->determine_types(gogo);
10272 13022 : inserter->insert(s);
10273 :
10274 13022 : ref = Expression::make_temporary_reference(s1tmp, loc);
10275 13022 : assign = Statement::make_assignment(ref, assign_lhs->copy(), loc);
10276 13022 : assign->determine_types(gogo);
10277 13022 : inserter->insert(assign);
10278 : }
10279 :
10280 15653 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
10281 :
10282 15653 : if (this->is_varargs())
10283 : {
10284 3556 : if (makecall != NULL)
10285 : {
10286 : // memclr(&s1tmp[l1tmp], l2tmp*sizeof(elem))
10287 27 : a1 = Expression::make_temporary_reference(s1tmp, loc);
10288 27 : ref = Expression::make_temporary_reference(l1tmp, loc);
10289 27 : a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
10290 27 : a1->array_index_expression()->set_needs_bounds_check(false);
10291 27 : a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
10292 :
10293 27 : ref = Expression::make_temporary_reference(l2tmp, loc);
10294 27 : ref = Expression::make_cast(uintptr_type, ref, loc);
10295 27 : a2 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
10296 27 : a2 = Expression::make_binary(OPERATOR_MULT, a2, ref, loc);
10297 :
10298 27 : if (element_type->has_pointer())
10299 7 : call = Runtime::make_call(gogo, Runtime::MEMCLRHASPTR, loc, 2,
10300 : a1, a2);
10301 : else
10302 : {
10303 20 : Type* int32_type = Type::lookup_integer_type("int32");
10304 20 : zero = Expression::make_integer_ul(0, int32_type, loc);
10305 20 : call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMSET, loc, 3,
10306 : a1, zero, a2);
10307 : }
10308 :
10309 27 : if (element_type->has_pointer())
10310 : {
10311 : // For a slice containing pointers, growslice already zeroed
10312 : // the memory. We only need to zero in non-growing case.
10313 : // Note: growslice does not zero the memory in non-pointer case.
10314 7 : ref = Expression::make_temporary_reference(ntmp, loc);
10315 7 : ref = Expression::make_cast(uint_type, ref, loc);
10316 7 : ref2 = Expression::make_temporary_reference(c1tmp, loc);
10317 7 : ref2 = Expression::make_cast(uint_type, ref2, loc);
10318 7 : cond = Expression::make_binary(OPERATOR_GT, ref, ref2, loc);
10319 7 : zero = Expression::make_integer_ul(0, int_type, loc);
10320 7 : call = Expression::make_conditional(cond, zero, call, loc);
10321 : }
10322 : }
10323 : else
10324 : {
10325 3529 : if (element_type->has_pointer())
10326 : {
10327 : // copy(s1tmp[l1tmp:], s2tmp)
10328 1251 : a1 = Expression::make_temporary_reference(s1tmp, loc);
10329 1251 : ref = Expression::make_temporary_reference(l1tmp, loc);
10330 1251 : Expression* nil = Expression::make_nil(loc);
10331 1251 : a1 = Expression::make_array_index(a1, ref, nil, NULL, loc);
10332 1251 : a1->array_index_expression()->set_needs_bounds_check(false);
10333 :
10334 1251 : a2 = Expression::make_temporary_reference(s2tmp, loc);
10335 :
10336 1251 : Named_object* copyfn = gogo->lookup_global("copy");
10337 1251 : Expression* copyref = Expression::make_func_reference(copyfn, NULL, loc);
10338 1251 : call_args = new Expression_list();
10339 1251 : call_args->push_back(a1);
10340 1251 : call_args->push_back(a2);
10341 1251 : call = Expression::make_call(copyref, call_args, false, loc);
10342 : }
10343 : else
10344 : {
10345 : // memmove(&s1tmp[l1tmp], s2tmp.ptr, l2tmp*sizeof(elem))
10346 2278 : a1 = Expression::make_temporary_reference(s1tmp, loc);
10347 2278 : ref = Expression::make_temporary_reference(l1tmp, loc);
10348 2278 : a1 = Expression::make_array_index(a1, ref, NULL, NULL, loc);
10349 2278 : a1->array_index_expression()->set_needs_bounds_check(false);
10350 2278 : a1 = Expression::make_unary(OPERATOR_AND, a1, loc);
10351 :
10352 2278 : a2 = Expression::make_temporary_reference(s2tmp, loc);
10353 2278 : a2 = (a2->type()->is_string_type()
10354 2278 : ? Expression::make_string_info(a2,
10355 : STRING_INFO_DATA,
10356 : loc)
10357 1314 : : Expression::make_slice_info(a2,
10358 : SLICE_INFO_VALUE_POINTER,
10359 : loc));
10360 :
10361 2278 : ref = Expression::make_temporary_reference(l2tmp, loc);
10362 2278 : ref = Expression::make_cast(uintptr_type, ref, loc);
10363 2278 : a3 = Expression::make_type_info(element_type, TYPE_INFO_SIZE);
10364 2278 : a3 = Expression::make_binary(OPERATOR_MULT, a3, ref, loc);
10365 :
10366 2278 : call = Runtime::make_call(gogo, Runtime::BUILTIN_MEMMOVE, loc, 3,
10367 : a1, a2, a3);
10368 : }
10369 : }
10370 3556 : call->determine_type_no_context(gogo);
10371 3556 : gogo->lower_expression(function, inserter, &call);
10372 3556 : gogo->flatten_expression(function, inserter, &call);
10373 3556 : inserter->insert(Statement::make_statement(call, false));
10374 : }
10375 : else
10376 : {
10377 : // For each argument:
10378 : // s1tmp[l1tmp+i] = a
10379 12097 : unsigned long i = 0;
10380 12097 : for (Expression_list::const_iterator pa = add->begin();
10381 26301 : pa != add->end();
10382 14204 : ++pa, ++i)
10383 : {
10384 14204 : ref = Expression::make_temporary_reference(s1tmp, loc);
10385 14204 : ref2 = Expression::make_temporary_reference(l1tmp, loc);
10386 14204 : Expression* off = Expression::make_integer_ul(i, int_type, loc);
10387 14204 : ref2 = Expression::make_binary(OPERATOR_PLUS, ref2, off, loc);
10388 14204 : Expression* lhs = Expression::make_array_index(ref, ref2, NULL,
10389 14204 : NULL, loc);
10390 14204 : lhs->array_index_expression()->set_needs_bounds_check(false);
10391 14204 : lhs->determine_type_no_context(gogo);
10392 14204 : gogo->lower_expression(function, inserter, &lhs);
10393 14204 : gogo->flatten_expression(function, inserter, &lhs);
10394 14204 : Expression* elem = *pa;
10395 14204 : if (!Type::are_identical(element_type, elem->type(), 0, NULL)
10396 14204 : && element_type->interface_type() != NULL)
10397 504 : elem = Expression::make_cast(element_type, elem, loc);
10398 : // The flatten pass runs after the write barrier pass, so we
10399 : // need to insert a write barrier here if necessary.
10400 : // However, if ASSIGN_LHS is not NULL, we have been called
10401 : // directly before the write barrier pass.
10402 14204 : Statement* assign;
10403 14204 : if (assign_lhs != NULL
10404 14204 : || !gogo->assign_needs_write_barrier(lhs, NULL))
10405 12988 : assign = Statement::make_assignment(lhs, elem, loc);
10406 : else
10407 : {
10408 1216 : Function* f = function == NULL ? NULL : function->func_value();
10409 1216 : assign = gogo->assign_with_write_barrier(f, NULL, inserter,
10410 : lhs, elem, loc);
10411 : }
10412 14204 : assign->determine_types(gogo);
10413 14204 : inserter->insert(assign);
10414 : }
10415 : }
10416 :
10417 15653 : if (assign_lhs != NULL)
10418 : return NULL;
10419 :
10420 2631 : return Expression::make_temporary_reference(s1tmp, loc);
10421 : }
10422 :
10423 : // Return whether an expression has an integer value. Report an error
10424 : // if not. This is used when handling calls to the predeclared make
10425 : // function. Set *SMALL if the value is known to fit in type "int".
10426 :
10427 : bool
10428 11881 : Builtin_call_expression::check_int_value(Expression* e, bool is_length,
10429 : bool *small)
10430 : {
10431 11881 : *small = false;
10432 :
10433 11881 : Numeric_constant nc;
10434 11881 : if (e->numeric_constant_value(&nc))
10435 : {
10436 5748 : unsigned long v;
10437 5748 : switch (nc.to_unsigned_long(&v))
10438 : {
10439 : case Numeric_constant::NC_UL_VALID:
10440 : break;
10441 1 : case Numeric_constant::NC_UL_NOTINT:
10442 1 : go_error_at(e->location(), "non-integer %s argument to make",
10443 : is_length ? "len" : "cap");
10444 1 : return false;
10445 2 : case Numeric_constant::NC_UL_NEGATIVE:
10446 2 : go_error_at(e->location(), "negative %s argument to make",
10447 : is_length ? "len" : "cap");
10448 2 : return false;
10449 : case Numeric_constant::NC_UL_BIG:
10450 : // We don't want to give a compile-time error for a 64-bit
10451 : // value on a 32-bit target.
10452 : break;
10453 : }
10454 :
10455 5745 : mpz_t val;
10456 5745 : if (!nc.to_int(&val))
10457 0 : go_unreachable();
10458 5745 : int bits = mpz_sizeinbase(val, 2);
10459 5745 : mpz_clear(val);
10460 5745 : Type* int_type = Type::lookup_integer_type("int");
10461 11490 : if (bits >= int_type->integer_type()->bits())
10462 : {
10463 1 : go_error_at(e->location(), "%s argument too large for make",
10464 : is_length ? "len" : "cap");
10465 1 : return false;
10466 : }
10467 :
10468 5744 : *small = true;
10469 5744 : return true;
10470 : }
10471 :
10472 6133 : if (e->type()->integer_type() != NULL)
10473 : {
10474 12254 : int ebits = e->type()->integer_type()->bits();
10475 12254 : int intbits = Type::lookup_integer_type("int")->integer_type()->bits();
10476 :
10477 : // We can treat ebits == intbits as small even for an unsigned
10478 : // integer type, because we will convert the value to int and
10479 : // then reject it in the runtime if it is negative.
10480 6127 : *small = ebits <= intbits;
10481 :
10482 6127 : return true;
10483 : }
10484 :
10485 6 : go_error_at(e->location(), "non-integer %s argument to make",
10486 : is_length ? "len" : "cap");
10487 6 : return false;
10488 11881 : }
10489 :
10490 : // Return the type of the real or imag functions, given the type of
10491 : // the argument. We need to map complex64 to float32 and complex128
10492 : // to float64, so it has to be done by name. This returns NULL if it
10493 : // can't figure out the type.
10494 :
10495 : Type*
10496 22174 : Builtin_call_expression::real_imag_type(Type* arg_type)
10497 : {
10498 22174 : if (arg_type == NULL || arg_type->is_abstract())
10499 95 : return NULL;
10500 22079 : Named_type* nt = arg_type->named_type();
10501 22079 : if (nt == NULL)
10502 : return NULL;
10503 22080 : while (nt->real_type()->named_type() != NULL)
10504 5 : nt = nt->real_type()->named_type();
10505 22075 : if (nt->name() == "complex64")
10506 153 : return Type::lookup_float_type("float32");
10507 21922 : else if (nt->name() == "complex128")
10508 21859 : return Type::lookup_float_type("float64");
10509 : else
10510 : return NULL;
10511 : }
10512 :
10513 : // Return the type of the complex function, given the type of one of the
10514 : // argments. Like real_imag_type, we have to map by name.
10515 :
10516 : Type*
10517 88910 : Builtin_call_expression::complex_type(Type* arg_type)
10518 : {
10519 88910 : if (arg_type == NULL || arg_type->is_abstract())
10520 305 : return NULL;
10521 88605 : Named_type* nt = arg_type->named_type();
10522 88605 : if (nt == NULL)
10523 : return NULL;
10524 88599 : while (nt->real_type()->named_type() != NULL)
10525 2 : nt = nt->real_type()->named_type();
10526 88597 : if (nt->name() == "float32")
10527 117 : return Type::lookup_complex_type("complex64");
10528 88480 : else if (nt->name() == "float64")
10529 88470 : return Type::lookup_complex_type("complex128");
10530 : else
10531 : return NULL;
10532 : }
10533 :
10534 : // Return a single argument, or NULL if there isn't one.
10535 :
10536 : Expression*
10537 593023 : Builtin_call_expression::one_arg() const
10538 : {
10539 593023 : const Expression_list* args = this->args();
10540 1186046 : if (args == NULL || args->size() != 1)
10541 : return NULL;
10542 593023 : return args->front();
10543 : }
10544 :
10545 : // A traversal class which looks for a call or receive expression.
10546 :
10547 22831 : class Find_call_expression : public Traverse
10548 : {
10549 : public:
10550 22831 : Find_call_expression()
10551 22831 : : Traverse(traverse_expressions),
10552 22831 : found_(false)
10553 : { }
10554 :
10555 : int
10556 : expression(Expression**);
10557 :
10558 : bool
10559 22831 : found()
10560 22831 : { return this->found_; }
10561 :
10562 : private:
10563 : bool found_;
10564 : };
10565 :
10566 : int
10567 27379 : Find_call_expression::expression(Expression** pexpr)
10568 : {
10569 27379 : Expression* expr = *pexpr;
10570 27379 : if (!expr->is_constant()
10571 54529 : && (expr->call_expression() != NULL
10572 52 : || expr->receive_expression() != NULL))
10573 : {
10574 52 : this->found_ = true;
10575 52 : return TRAVERSE_EXIT;
10576 : }
10577 : return TRAVERSE_CONTINUE;
10578 : }
10579 :
10580 : // Return whether calling len or cap on EXPR, of array type, is a
10581 : // constant. The language spec says "the expressions len(s) and
10582 : // cap(s) are constants if the type of s is an array or pointer to an
10583 : // array and the expression s does not contain channel receives or
10584 : // (non-constant) function calls."
10585 :
10586 : bool
10587 22831 : Builtin_call_expression::array_len_is_constant(Expression* expr)
10588 : {
10589 91324 : go_assert(expr->type()->deref()->array_type() != NULL
10590 : && !expr->type()->deref()->is_slice_type());
10591 22831 : if (expr->is_constant())
10592 : return true;
10593 22831 : Find_call_expression find_call;
10594 22831 : Expression::traverse(&expr, &find_call);
10595 22831 : return !find_call.found();
10596 22831 : }
10597 :
10598 : // Return whether this is constant: len of a string constant, or len
10599 : // or cap of an array, or unsafe.Sizeof, unsafe.Offsetof,
10600 : // unsafe.Alignof.
10601 :
10602 : bool
10603 508655 : Builtin_call_expression::do_is_constant() const
10604 : {
10605 508655 : if (this->is_error_expression())
10606 : return true;
10607 508655 : switch (this->code_)
10608 : {
10609 327550 : case BUILTIN_LEN:
10610 327550 : case BUILTIN_CAP:
10611 327550 : {
10612 327550 : if (this->seen_)
10613 : return false;
10614 :
10615 327550 : Expression* arg = this->one_arg();
10616 327550 : if (arg == NULL)
10617 : return false;
10618 :
10619 : // We may be called before the determine_types pass.
10620 327550 : arg->determine_type_no_context(this->gogo_);
10621 :
10622 327550 : Type* arg_type = arg->type();
10623 327550 : if (arg_type->is_error())
10624 : return true;
10625 :
10626 327547 : if (arg_type->points_to() != NULL
10627 9306 : && arg_type->points_to()->array_type() != NULL
10628 336847 : && !arg_type->points_to()->is_slice_type())
10629 9294 : arg_type = arg_type->points_to();
10630 :
10631 601776 : if (arg_type->array_type() != NULL
10632 274229 : && arg_type->array_type()->length() != NULL)
10633 : {
10634 13527 : this->seen_ = true;
10635 13527 : bool ret = Builtin_call_expression::array_len_is_constant(arg);
10636 13527 : this->seen_ = false;
10637 13527 : return ret;
10638 : }
10639 :
10640 594242 : if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
10641 : {
10642 50230 : this->seen_ = true;
10643 50230 : bool ret = arg->is_constant();
10644 50230 : this->seen_ = false;
10645 50230 : return ret;
10646 : }
10647 : }
10648 : break;
10649 :
10650 1625 : case BUILTIN_SIZEOF:
10651 1625 : case BUILTIN_ALIGNOF:
10652 1625 : return this->one_arg() != NULL;
10653 :
10654 1378 : case BUILTIN_OFFSETOF:
10655 1378 : {
10656 1378 : Expression* arg = this->one_arg();
10657 1378 : if (arg == NULL)
10658 : return false;
10659 1378 : return (arg->field_reference_expression() != NULL
10660 1122 : || arg->classification() == Expression::EXPRESSION_SELECTOR);
10661 : }
10662 :
10663 49388 : case BUILTIN_COMPLEX:
10664 49388 : {
10665 49388 : const Expression_list* args = this->args();
10666 98776 : if (args != NULL && args->size() == 2)
10667 49388 : return args->front()->is_constant() && args->back()->is_constant();
10668 : }
10669 : break;
10670 :
10671 2195 : case BUILTIN_REAL:
10672 2195 : case BUILTIN_IMAG:
10673 2195 : {
10674 2195 : Expression* arg = this->one_arg();
10675 4390 : return arg != NULL && arg->is_constant();
10676 : }
10677 :
10678 : default:
10679 : break;
10680 : }
10681 :
10682 : return false;
10683 : }
10684 :
10685 : // Return whether a builtin call is untyped. Most builtin functions
10686 : // have a known type, but complex, real, and imag can be untyped.
10687 :
10688 : bool
10689 56988 : Builtin_call_expression::do_is_untyped(Type** ptype) const
10690 : {
10691 56988 : if (this->is_error_expression())
10692 : return false;
10693 :
10694 56988 : switch (this->code_)
10695 : {
10696 : default:
10697 : return false;
10698 :
10699 13556 : case BUILTIN_COMPLEX:
10700 13556 : {
10701 13556 : const Expression_list* args = this->args();
10702 27112 : if (args == NULL || args->size() != 2)
10703 : return false;
10704 13556 : Type* dummy;
10705 13556 : if (!args->front()->is_untyped(&dummy)
10706 13556 : || !args->back()->is_untyped(&dummy))
10707 12065 : return false;
10708 1491 : *ptype = Type::make_abstract_complex_type();
10709 1491 : return true;
10710 : }
10711 :
10712 1197 : case BUILTIN_REAL:
10713 1197 : case BUILTIN_IMAG:
10714 1197 : {
10715 1197 : Expression* arg = this->one_arg();
10716 1197 : if (arg == NULL)
10717 : return false;
10718 1197 : if (!arg->is_untyped(ptype))
10719 : return false;
10720 32 : *ptype = Type::make_abstract_float_type();
10721 32 : return true;
10722 : }
10723 : }
10724 : }
10725 :
10726 : // Return a numeric constant if possible.
10727 :
10728 : bool
10729 148021 : Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc)
10730 : {
10731 148021 : if (this->code_ == BUILTIN_LEN
10732 148021 : || this->code_ == BUILTIN_CAP)
10733 : {
10734 142023 : Expression* arg = this->one_arg();
10735 142023 : if (arg == NULL)
10736 : return false;
10737 :
10738 : // We may be called before the determine_types pass.
10739 142023 : arg->determine_type_no_context(this->gogo_);
10740 :
10741 142023 : Type* arg_type = arg->type();
10742 142023 : if (arg_type->is_error())
10743 : return false;
10744 :
10745 282621 : if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
10746 : {
10747 33992 : std::string sval;
10748 33992 : if (arg->string_constant_value(&sval))
10749 : {
10750 2376 : nc->set_unsigned_long(Type::lookup_integer_type("int"),
10751 : sval.length());
10752 2376 : return true;
10753 : }
10754 33992 : }
10755 :
10756 139647 : if (arg_type->points_to() != NULL
10757 9189 : && arg_type->points_to()->array_type() != NULL
10758 148836 : && !arg_type->points_to()->is_slice_type())
10759 9189 : arg_type = arg_type->points_to();
10760 :
10761 244731 : if (arg_type->array_type() != NULL
10762 105084 : && arg_type->array_type()->length() != NULL)
10763 : {
10764 12302 : if (this->seen_)
10765 : return false;
10766 :
10767 12302 : if (!arg_type->is_error())
10768 : {
10769 24604 : Expression* e = arg_type->array_type()->length();
10770 12302 : this->seen_ = true;
10771 12302 : bool r = e->numeric_constant_value(nc);
10772 12302 : this->seen_ = false;
10773 12302 : if (r)
10774 : {
10775 12302 : if (!nc->set_type(Type::lookup_integer_type("int"), false,
10776 : this->location()))
10777 0 : r = false;
10778 : }
10779 12302 : return r;
10780 : }
10781 : }
10782 : }
10783 : else if (this->code_ == BUILTIN_SIZEOF
10784 : || this->code_ == BUILTIN_ALIGNOF)
10785 : {
10786 1870 : Expression* arg = this->one_arg();
10787 1870 : if (arg == NULL)
10788 : return false;
10789 :
10790 : // We may be called before the determine_types pass.
10791 1870 : arg->determine_type_no_context(this->gogo_);
10792 :
10793 1870 : Type* arg_type = arg->type();
10794 1870 : if (arg_type->is_error())
10795 : return false;
10796 1870 : if (arg_type->is_abstract())
10797 0 : arg_type = arg_type->make_non_abstract_type();
10798 1870 : if (this->seen_)
10799 : return false;
10800 :
10801 1870 : int64_t ret;
10802 1870 : if (this->code_ == BUILTIN_SIZEOF)
10803 : {
10804 1859 : this->seen_ = true;
10805 1859 : bool ok = arg_type->backend_type_size(this->gogo_, &ret);
10806 1859 : this->seen_ = false;
10807 1859 : if (!ok)
10808 : return false;
10809 : }
10810 11 : else if (this->code_ == BUILTIN_ALIGNOF)
10811 : {
10812 11 : bool ok;
10813 11 : this->seen_ = true;
10814 11 : if (arg->field_reference_expression() == NULL)
10815 5 : ok = arg_type->backend_type_align(this->gogo_, &ret);
10816 : else
10817 : {
10818 : // Calling unsafe.Alignof(s.f) returns the alignment of
10819 : // the type of f when it is used as a field in a struct.
10820 6 : ok = arg_type->backend_type_field_align(this->gogo_, &ret);
10821 : }
10822 11 : this->seen_ = false;
10823 11 : if (!ok)
10824 : return false;
10825 : }
10826 : else
10827 0 : go_unreachable();
10828 :
10829 1870 : mpz_t zval;
10830 1870 : set_mpz_from_int64(&zval, ret);
10831 1870 : nc->set_int(Type::lookup_integer_type("uintptr"), zval);
10832 1870 : mpz_clear(zval);
10833 1870 : return true;
10834 : }
10835 : else if (this->code_ == BUILTIN_OFFSETOF)
10836 : {
10837 804 : Expression* arg = this->one_arg();
10838 804 : if (arg == NULL)
10839 : return false;
10840 :
10841 : // We may be called before the determine_types pass.
10842 804 : arg->determine_type_no_context(this->gogo_);
10843 :
10844 804 : Field_reference_expression* farg = arg->field_reference_expression();
10845 256 : if (farg == NULL)
10846 : return false;
10847 256 : if (this->seen_)
10848 : return false;
10849 :
10850 : int64_t total_offset = 0;
10851 966 : while (true)
10852 : {
10853 611 : Expression* struct_expr = farg->expr();
10854 611 : Type* st = struct_expr->type();
10855 611 : if (st->struct_type() == NULL)
10856 0 : return false;
10857 611 : if (st->named_type() != NULL)
10858 584 : st->named_type()->convert(this->gogo_);
10859 611 : if (st->is_error_type())
10860 : {
10861 0 : go_assert(saw_errors());
10862 : return false;
10863 : }
10864 611 : int64_t offset;
10865 611 : this->seen_ = true;
10866 1222 : bool ok = st->struct_type()->backend_field_offset(this->gogo_,
10867 : farg->field_index(),
10868 : &offset);
10869 611 : this->seen_ = false;
10870 611 : if (!ok)
10871 : return false;
10872 611 : total_offset += offset;
10873 611 : if (farg->implicit() && struct_expr->field_reference_expression() != NULL)
10874 : {
10875 : // Go up until we reach the original base.
10876 355 : farg = struct_expr->field_reference_expression();
10877 355 : continue;
10878 : }
10879 256 : break;
10880 : }
10881 256 : mpz_t zval;
10882 256 : set_mpz_from_int64(&zval, total_offset);
10883 256 : nc->set_int(Type::lookup_integer_type("uintptr"), zval);
10884 256 : mpz_clear(zval);
10885 256 : return true;
10886 : }
10887 : else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG)
10888 : {
10889 636 : Expression* arg = this->one_arg();
10890 636 : if (arg == NULL)
10891 : return false;
10892 :
10893 636 : Numeric_constant argnc;
10894 636 : if (!arg->numeric_constant_value(&argnc))
10895 : return false;
10896 :
10897 42 : mpc_t val;
10898 42 : if (!argnc.to_complex(&val))
10899 : return false;
10900 :
10901 42 : Type* type = Builtin_call_expression::real_imag_type(argnc.type());
10902 42 : if (this->code_ == BUILTIN_REAL)
10903 22 : nc->set_float(type, mpc_realref(val));
10904 : else
10905 20 : nc->set_float(type, mpc_imagref(val));
10906 42 : mpc_clear(val);
10907 42 : return true;
10908 636 : }
10909 : else if (this->code_ == BUILTIN_COMPLEX)
10910 : {
10911 1528 : const Expression_list* args = this->args();
10912 3056 : if (args == NULL || args->size() != 2)
10913 : return false;
10914 :
10915 1528 : Numeric_constant rnc;
10916 1528 : if (!args->front()->numeric_constant_value(&rnc))
10917 : return false;
10918 1527 : Numeric_constant inc;
10919 1527 : if (!args->back()->numeric_constant_value(&inc))
10920 : return false;
10921 :
10922 1527 : if (rnc.type() != NULL
10923 1527 : && !rnc.type()->is_abstract()
10924 1506 : && inc.type() != NULL
10925 1506 : && !inc.type()->is_abstract()
10926 3033 : && !Type::are_identical(rnc.type(), inc.type(),
10927 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
10928 : NULL))
10929 : return false;
10930 :
10931 1527 : mpfr_t r;
10932 1527 : if (!rnc.to_float(&r))
10933 : return false;
10934 1527 : mpfr_t i;
10935 1527 : if (!inc.to_float(&i))
10936 : {
10937 0 : mpfr_clear(r);
10938 0 : return false;
10939 : }
10940 :
10941 1527 : Type* arg_type = rnc.type();
10942 1527 : if (arg_type == NULL || arg_type->is_abstract())
10943 21 : arg_type = inc.type();
10944 :
10945 1527 : mpc_t val;
10946 1527 : mpc_init2(val, mpc_precision);
10947 1527 : mpc_set_fr_fr(val, r, i, MPC_RNDNN);
10948 1527 : mpfr_clear(r);
10949 1527 : mpfr_clear(i);
10950 :
10951 1527 : Type* type = Builtin_call_expression::complex_type(arg_type);
10952 1527 : nc->set_complex(type, val);
10953 :
10954 1527 : mpc_clear(val);
10955 :
10956 1527 : return true;
10957 1528 : }
10958 :
10959 : return false;
10960 : }
10961 :
10962 : // Give an error if we are discarding the value of an expression which
10963 : // should not normally be discarded. We don't give an error for
10964 : // discarding the value of an ordinary function call, but we do for
10965 : // builtin functions, purely for consistency with the gc compiler.
10966 :
10967 : bool
10968 34613 : Builtin_call_expression::do_discarding_value()
10969 : {
10970 34613 : switch (this->code_)
10971 : {
10972 0 : case BUILTIN_INVALID:
10973 0 : default:
10974 0 : go_unreachable();
10975 :
10976 71 : case BUILTIN_APPEND:
10977 71 : case BUILTIN_CAP:
10978 71 : case BUILTIN_COMPLEX:
10979 71 : case BUILTIN_IMAG:
10980 71 : case BUILTIN_LEN:
10981 71 : case BUILTIN_MAKE:
10982 71 : case BUILTIN_NEW:
10983 71 : case BUILTIN_REAL:
10984 71 : case BUILTIN_ADD:
10985 71 : case BUILTIN_ALIGNOF:
10986 71 : case BUILTIN_OFFSETOF:
10987 71 : case BUILTIN_SIZEOF:
10988 71 : case BUILTIN_SLICE:
10989 71 : this->unused_value_error();
10990 71 : return false;
10991 :
10992 : case BUILTIN_CLOSE:
10993 : case BUILTIN_COPY:
10994 : case BUILTIN_DELETE:
10995 : case BUILTIN_PANIC:
10996 : case BUILTIN_PRINT:
10997 : case BUILTIN_PRINTLN:
10998 : case BUILTIN_RECOVER:
10999 : return true;
11000 : }
11001 : }
11002 :
11003 : // Return the type.
11004 :
11005 : Type*
11006 1451500 : Builtin_call_expression::do_type()
11007 : {
11008 1451500 : if (this->is_error_expression())
11009 1941 : return Type::make_error_type();
11010 :
11011 1449559 : Type* type = this->type();
11012 1449559 : if (type != NULL)
11013 : return type;
11014 :
11015 1448018 : switch (this->code_)
11016 : {
11017 0 : case BUILTIN_INVALID:
11018 0 : default:
11019 0 : return Type::make_error_type();
11020 :
11021 14123 : case BUILTIN_NEW:
11022 14123 : {
11023 14123 : const Expression_list* args = this->args();
11024 14123 : if (args == NULL || args->empty())
11025 0 : return Type::make_error_type();
11026 14123 : return Type::make_pointer_type(args->front()->type());
11027 : }
11028 :
11029 24732 : case BUILTIN_MAKE:
11030 24732 : {
11031 24732 : const Expression_list* args = this->args();
11032 24732 : if (args == NULL || args->empty())
11033 0 : return Type::make_error_type();
11034 24732 : return args->front()->type();
11035 : }
11036 :
11037 1142751 : case BUILTIN_CAP:
11038 1142751 : case BUILTIN_COPY:
11039 1142751 : case BUILTIN_LEN:
11040 1142751 : return Type::lookup_integer_type("int");
11041 :
11042 3750 : case BUILTIN_ALIGNOF:
11043 3750 : case BUILTIN_OFFSETOF:
11044 3750 : case BUILTIN_SIZEOF:
11045 3750 : return Type::lookup_integer_type("uintptr");
11046 :
11047 75676 : case BUILTIN_CLOSE:
11048 75676 : case BUILTIN_DELETE:
11049 75676 : case BUILTIN_PANIC:
11050 75676 : case BUILTIN_PRINT:
11051 75676 : case BUILTIN_PRINTLN:
11052 75676 : return Type::make_void_type();
11053 :
11054 6835 : case BUILTIN_RECOVER:
11055 6835 : return Type::make_empty_interface_type(Linemap::predeclared_location());
11056 :
11057 85298 : case BUILTIN_APPEND:
11058 85298 : {
11059 85298 : const Expression_list* args = this->args();
11060 85298 : if (args == NULL || args->empty())
11061 0 : return Type::make_error_type();
11062 85298 : Type *ret = args->front()->type();
11063 85298 : if (!ret->is_slice_type())
11064 2 : return Type::make_error_type();
11065 : return ret;
11066 : }
11067 :
11068 8427 : case BUILTIN_REAL:
11069 8427 : case BUILTIN_IMAG:
11070 8427 : {
11071 8427 : Expression* arg = this->one_arg();
11072 8427 : if (arg == NULL)
11073 0 : return Type::make_error_type();
11074 8427 : Type* t = arg->type();
11075 8427 : if (t->is_abstract())
11076 0 : t = t->make_non_abstract_type();
11077 8427 : t = Builtin_call_expression::real_imag_type(t);
11078 8427 : if (t == NULL)
11079 4 : t = Type::make_error_type();
11080 : return t;
11081 : }
11082 :
11083 86335 : case BUILTIN_COMPLEX:
11084 86335 : {
11085 86335 : const Expression_list* args = this->args();
11086 172670 : if (args == NULL || args->size() != 2)
11087 0 : return Type::make_error_type();
11088 86335 : Type* t = args->front()->type();
11089 86335 : if (t->is_abstract())
11090 : {
11091 0 : t = args->back()->type();
11092 0 : if (t->is_abstract())
11093 0 : t = t->make_non_abstract_type();
11094 : }
11095 86335 : t = Builtin_call_expression::complex_type(t);
11096 86335 : if (t == NULL)
11097 1 : t = Type::make_error_type();
11098 : return t;
11099 : }
11100 :
11101 41 : case BUILTIN_ADD:
11102 41 : return Type::make_pointer_type(Type::make_void_type());
11103 :
11104 50 : case BUILTIN_SLICE:
11105 50 : const Expression_list* args = this->args();
11106 100 : if (args == NULL || args->size() != 2)
11107 0 : return Type::make_error_type();
11108 50 : Type* pt = args->front()->type()->points_to();
11109 50 : if (pt == NULL)
11110 0 : return Type::make_error_type();
11111 50 : return Type::make_array_type(pt, NULL);
11112 : }
11113 : }
11114 :
11115 : // Determine the type.
11116 :
11117 : void
11118 295515 : Builtin_call_expression::do_determine_type(Gogo* gogo,
11119 : const Type_context* context)
11120 : {
11121 295515 : if (!this->determining_types())
11122 : return;
11123 :
11124 226650 : this->fn()->determine_type_no_context(gogo);
11125 :
11126 226650 : this->simplify_multiple_results(gogo);
11127 :
11128 226650 : const Expression_list* args = this->args();
11129 :
11130 226650 : bool is_print;
11131 226650 : Type* arg_type = NULL;
11132 226650 : Type* trailing_arg_types = NULL;
11133 226650 : switch (this->code_)
11134 : {
11135 15117 : case BUILTIN_MAKE:
11136 15117 : trailing_arg_types = Type::lookup_integer_type("int");
11137 15117 : is_print = false;
11138 15117 : break;
11139 :
11140 15153 : case BUILTIN_PANIC:
11141 15153 : arg_type =
11142 15153 : Type::make_empty_interface_type(Linemap::predeclared_location());
11143 15153 : is_print = false;
11144 15153 : break;
11145 :
11146 : case BUILTIN_PRINT:
11147 : case BUILTIN_PRINTLN:
11148 : // Do not force a large integer constant to "int".
11149 : is_print = true;
11150 : break;
11151 :
11152 1048 : case BUILTIN_REAL:
11153 1048 : case BUILTIN_IMAG:
11154 1048 : {
11155 : // We need the argument to determine the type, so check it now
11156 : // before any call to the do_type method.
11157 1048 : const Expression_list* args = this->args();
11158 2096 : if (args == NULL || args->size() < 1)
11159 : {
11160 0 : this->report_error(_("not enough arguments"));
11161 0 : return;
11162 : }
11163 1048 : else if (args->size() > 1)
11164 : {
11165 0 : this->report_error(_("too many arguments"));
11166 0 : return;
11167 : }
11168 :
11169 1048 : Type* dummy;
11170 1048 : if (context->type != NULL
11171 764 : && context->type->is_numeric_type()
11172 1803 : && this->is_untyped(&dummy))
11173 : {
11174 28 : Type* type = context->type;
11175 28 : if (type->is_abstract() && !context->may_be_abstract)
11176 0 : type = type->make_non_abstract_type();
11177 28 : this->set_type(type);
11178 : }
11179 1020 : else if (context->may_be_abstract && this->is_constant())
11180 5 : this->set_type(Type::make_abstract_float_type());
11181 :
11182 1048 : arg_type = Builtin_call_expression::complex_type(context->type);
11183 1048 : if (arg_type == NULL)
11184 : {
11185 301 : if (context->may_be_abstract)
11186 6 : arg_type = Type::make_abstract_complex_type();
11187 : else
11188 295 : arg_type = Type::lookup_complex_type("complex128");
11189 : }
11190 :
11191 1048 : if (!args->front()->is_untyped(&dummy))
11192 : {
11193 994 : Type_context subcontext(arg_type, context->may_be_abstract);
11194 994 : args->front()->determine_type(gogo, &subcontext);
11195 : }
11196 :
11197 1048 : is_print = false;
11198 : }
11199 1048 : break;
11200 :
11201 13710 : case BUILTIN_COMPLEX:
11202 13710 : {
11203 : // We need the arguments to determine the type, so check them
11204 : // now before any call to the do_type method.
11205 13710 : const Expression_list* args = this->args();
11206 27419 : if (args == NULL || args->size() < 2)
11207 : {
11208 4 : this->report_error(_("not enough arguments"));
11209 9 : return;
11210 : }
11211 13706 : else if (args->size() > 2)
11212 : {
11213 1 : this->report_error(_("too many arguments"));
11214 1 : return;
11215 : }
11216 :
11217 13705 : Type* dummy;
11218 13705 : if (context->type != NULL
11219 13615 : && context->type->is_numeric_type()
11220 27259 : && this->is_untyped(&dummy))
11221 : {
11222 1490 : Type* type = context->type;
11223 1490 : if (type->is_abstract() && !context->may_be_abstract)
11224 0 : type = type->make_non_abstract_type();
11225 1490 : this->set_type(type);
11226 : }
11227 12215 : else if (context->may_be_abstract && this->is_constant())
11228 6 : this->set_type(Type::make_abstract_complex_type());
11229 :
11230 : // For the complex function the type of one operand can
11231 : // determine the type of the other, as in a binary expression.
11232 13705 : arg_type = Builtin_call_expression::real_imag_type(context->type);
11233 13705 : if (arg_type == NULL)
11234 : {
11235 153 : if (context->may_be_abstract)
11236 6 : arg_type = Type::make_abstract_float_type();
11237 : else
11238 147 : arg_type = Type::lookup_float_type("float64");
11239 : }
11240 :
11241 13705 : Type_context subcontext(arg_type, context->may_be_abstract);
11242 13705 : if (!args->front()->is_untyped(&dummy))
11243 : {
11244 11127 : args->front()->determine_type(gogo, &subcontext);
11245 11127 : arg_type = args->front()->type();
11246 : }
11247 2578 : else if (!args->back()->is_untyped(&dummy))
11248 : {
11249 1054 : args->back()->determine_type(gogo, &subcontext);
11250 1054 : arg_type = args->back()->type();
11251 : }
11252 :
11253 13705 : is_print = false;
11254 : }
11255 13705 : break;
11256 :
11257 15743 : case BUILTIN_APPEND:
11258 15743 : if (!this->is_varargs()
11259 12154 : && args != NULL
11260 27897 : && !args->empty())
11261 : {
11262 12154 : args->front()->determine_type_no_context(gogo);
11263 12154 : if (args->front()->type()->is_slice_type())
11264 12152 : trailing_arg_types =
11265 24304 : args->front()->type()->array_type()->element_type();
11266 : }
11267 12152 : is_print = false;
11268 12152 : break;
11269 :
11270 18 : case BUILTIN_ADD:
11271 18 : case BUILTIN_SLICE:
11272 : // Both unsafe.Add and unsafe.Slice take two arguments, and the
11273 : // second arguments defaults to "int".
11274 36 : if (args != NULL && args->size() == 2)
11275 : {
11276 18 : if (this->code_ == BUILTIN_SLICE)
11277 9 : args->front()->determine_type_no_context(gogo);
11278 : else
11279 : {
11280 9 : Type* pointer = Type::make_pointer_type(Type::make_void_type());
11281 9 : Type_context subcontext(pointer, false);
11282 9 : args->front()->determine_type(gogo, &subcontext);
11283 : }
11284 18 : Type* int_type = Type::lookup_integer_type("int");
11285 18 : Type_context subcontext(int_type, false);
11286 18 : args->back()->determine_type(gogo, &subcontext);
11287 18 : return;
11288 : }
11289 : is_print = false;
11290 : break;
11291 :
11292 943 : case BUILTIN_DELETE:
11293 1885 : if (args != NULL && args->size() == 2)
11294 : {
11295 940 : args->front()->determine_type_no_context(gogo);
11296 940 : Map_type* mt = args->front()->type()->map_type();
11297 939 : if (mt != NULL)
11298 939 : trailing_arg_types = mt->key_type();
11299 : }
11300 : is_print = false;
11301 : break;
11302 :
11303 : default:
11304 152325 : is_print = false;
11305 : break;
11306 : }
11307 :
11308 226625 : if (args != NULL)
11309 : {
11310 522951 : for (Expression_list::const_iterator pa = args->begin();
11311 522951 : pa != args->end();
11312 297236 : ++pa)
11313 : {
11314 297236 : Type_context subcontext;
11315 297236 : subcontext.type = arg_type;
11316 :
11317 297236 : if (is_print && (*pa)->is_constant())
11318 : {
11319 : // We want to print large constants, we so can't just
11320 : // use the appropriate nonabstract type. Use uint64 for
11321 : // an integer if we know it is nonnegative, otherwise
11322 : // use int64 for a integer, otherwise use float64 for a
11323 : // float or complex128 for a complex.
11324 26478 : Type* atype;
11325 26478 : if ((*pa)->is_untyped(&atype))
11326 : {
11327 25189 : Type* want_type = NULL;
11328 25189 : if (atype->integer_type() != NULL)
11329 : {
11330 505 : Numeric_constant nc;
11331 505 : if (this->numeric_constant_value(&nc))
11332 : {
11333 0 : mpz_t val;
11334 0 : if (nc.to_int(&val))
11335 : {
11336 0 : if (mpz_sgn(val) >= 0)
11337 0 : want_type = Type::lookup_integer_type("uint64");
11338 0 : mpz_clear(val);
11339 : }
11340 : }
11341 0 : if (want_type == NULL)
11342 505 : want_type = Type::lookup_integer_type("int64");
11343 505 : }
11344 24684 : else if (atype->float_type() != NULL)
11345 56 : want_type = Type::lookup_float_type("float64");
11346 24628 : else if (atype->complex_type() != NULL)
11347 14 : want_type = Type::lookup_complex_type("complex128");
11348 24614 : else if (atype->is_abstract_string_type())
11349 24588 : want_type = Type::lookup_string_type();
11350 26 : else if (atype->is_abstract_boolean_type())
11351 26 : want_type = Type::lookup_bool_type();
11352 : else
11353 0 : go_unreachable();
11354 25189 : subcontext.type = want_type;
11355 : }
11356 : }
11357 :
11358 297236 : (*pa)->determine_type(gogo, &subcontext);
11359 :
11360 297236 : if (trailing_arg_types != NULL)
11361 : {
11362 28208 : arg_type = trailing_arg_types;
11363 28208 : trailing_arg_types = NULL;
11364 : }
11365 : }
11366 : }
11367 : }
11368 :
11369 : // If there is exactly one argument, return true. Otherwise give an
11370 : // error message and return false.
11371 :
11372 : bool
11373 80123 : Builtin_call_expression::check_one_arg()
11374 : {
11375 80123 : const Expression_list* args = this->args();
11376 160246 : if (args == NULL || args->size() < 1)
11377 : {
11378 0 : this->report_error(_("not enough arguments"));
11379 0 : return false;
11380 : }
11381 80123 : else if (args->size() > 1)
11382 : {
11383 0 : this->report_error(_("too many arguments"));
11384 0 : return false;
11385 : }
11386 80123 : if (args->front()->is_error_expression()
11387 80123 : || args->front()->type()->is_error())
11388 : {
11389 5 : this->set_is_error();
11390 5 : return false;
11391 : }
11392 : return true;
11393 : }
11394 :
11395 : // Check argument types for a builtin function.
11396 :
11397 : void
11398 145801 : Builtin_call_expression::do_check_types(Gogo* gogo)
11399 : {
11400 145801 : if (this->is_error_expression())
11401 : return;
11402 :
11403 145724 : if (this->is_varargs() && this->code_ != BUILTIN_APPEND)
11404 : {
11405 8 : go_error_at(this->location(),
11406 : "invalid use of %<...%> with built-in function");
11407 8 : this->set_is_error();
11408 8 : return;
11409 : }
11410 :
11411 145716 : switch (this->code_)
11412 : {
11413 : case BUILTIN_INVALID:
11414 : return;
11415 :
11416 7322 : case BUILTIN_NEW:
11417 7322 : if (this->check_one_arg())
11418 : {
11419 7322 : Expression* arg = this->one_arg();
11420 7322 : if (!arg->is_type_expression())
11421 : {
11422 0 : go_error_at(arg->location(), "expected type");
11423 0 : this->set_is_error();
11424 : }
11425 : }
11426 : break;
11427 :
11428 15106 : case BUILTIN_MAKE:
11429 15106 : {
11430 15106 : const Expression_list* args = this->args();
11431 30212 : if (args == NULL || args->size() < 1)
11432 : {
11433 0 : this->report_error(_("not enough arguments"));
11434 0 : return;
11435 : }
11436 :
11437 15106 : Expression* first_arg = args->front();
11438 15106 : if (!first_arg->is_type_expression())
11439 : {
11440 0 : go_error_at(first_arg->location(), "expected type");
11441 0 : this->set_is_error();
11442 0 : return;
11443 : }
11444 :
11445 15106 : Type* type = first_arg->type();
11446 15106 : if (!type->in_heap())
11447 0 : go_error_at(first_arg->location(),
11448 : "cannot make slice of go:notinheap type");
11449 :
11450 15106 : bool is_slice = type->is_slice_type();
11451 15106 : if (!is_slice
11452 2766 : && type->map_type() == NULL
11453 21721 : && type->channel_type() == NULL)
11454 : {
11455 0 : this->report_error(_("invalid type for make function"));
11456 0 : return;
11457 : }
11458 :
11459 15106 : Expression_list::const_iterator parg = args->begin();
11460 15106 : ++parg;
11461 15106 : if (parg == args->end())
11462 : {
11463 4935 : if (is_slice)
11464 : {
11465 0 : this->report_error(_("length required when "
11466 : "allocating a slice"));
11467 0 : return;
11468 : }
11469 : }
11470 : else
11471 : {
11472 10171 : if ((*parg)->type()->integer_type() == NULL)
11473 : {
11474 8 : go_error_at((*parg)->location(),
11475 : "non-integer len argument in make");
11476 8 : return;
11477 : }
11478 10163 : ++parg;
11479 :
11480 10163 : if (is_slice && parg != args->end())
11481 : {
11482 1716 : if ((*parg)->type()->integer_type() == NULL)
11483 : {
11484 5 : go_error_at((*parg)->location(),
11485 : "non-integer cap argument in make");
11486 5 : return;
11487 : }
11488 1711 : ++parg;
11489 : }
11490 : }
11491 :
11492 15093 : if (parg != args->end())
11493 : {
11494 1 : this->report_error(_("too many arguments to make"));
11495 1 : return;
11496 : }
11497 : }
11498 : break;
11499 :
11500 892 : case BUILTIN_DELETE:
11501 892 : {
11502 892 : const Expression_list* args = this->args();
11503 1783 : if (args == NULL || args->size() < 2)
11504 2 : this->report_error(_("not enough arguments"));
11505 890 : else if (args->size() > 2)
11506 1 : this->report_error(_("too many arguments"));
11507 889 : else if (args->front()->type()->map_type() == NULL)
11508 1 : this->report_error(_("argument 1 must be a map"));
11509 : else
11510 : {
11511 888 : Type* key_type =
11512 1776 : args->front()->type()->map_type()->key_type();
11513 888 : Expression_list::iterator pa = this->args()->begin();
11514 888 : pa++;
11515 888 : Type* arg_type = (*pa)->type();
11516 888 : std::string reason;
11517 888 : if (!Type::are_assignable(key_type, arg_type, &reason))
11518 : {
11519 0 : if (reason.empty())
11520 0 : go_error_at(this->location(),
11521 : "argument 2 has incompatible type");
11522 : else
11523 0 : go_error_at(this->location(),
11524 : "argument 2 has incompatible type (%s)",
11525 : reason.c_str());
11526 0 : this->set_is_error();
11527 : }
11528 888 : }
11529 : }
11530 : break;
11531 :
11532 54786 : case BUILTIN_LEN:
11533 54786 : case BUILTIN_CAP:
11534 54786 : {
11535 : // The single argument may be either a string or an array or a
11536 : // map or a channel, or a pointer to a closed array.
11537 54786 : if (this->check_one_arg())
11538 : {
11539 54783 : Type* arg_type = this->one_arg()->type();
11540 54783 : if (arg_type->points_to() != NULL
11541 204 : && arg_type->points_to()->array_type() != NULL
11542 54981 : && !arg_type->points_to()->is_slice_type())
11543 192 : arg_type = arg_type->points_to();
11544 54783 : if (this->code_ == BUILTIN_CAP)
11545 : {
11546 944 : if (!arg_type->is_error()
11547 54 : && arg_type->array_type() == NULL
11548 944 : && arg_type->channel_type() == NULL)
11549 3 : this->report_error(_("argument must be array or slice "
11550 : "or channel"));
11551 : }
11552 : else
11553 : {
11554 53839 : if (!arg_type->is_error()
11555 53839 : && !arg_type->is_string_type()
11556 1230 : && arg_type->array_type() == NULL
11557 42 : && arg_type->map_type() == NULL
11558 53839 : && arg_type->channel_type() == NULL)
11559 9 : this->report_error(_("argument must be string or "
11560 : "array or slice or map or channel"));
11561 : }
11562 : }
11563 : }
11564 : break;
11565 :
11566 16165 : case BUILTIN_PRINT:
11567 16165 : case BUILTIN_PRINTLN:
11568 16165 : {
11569 16165 : const Expression_list* args = this->args();
11570 16165 : if (args != NULL)
11571 : {
11572 16111 : for (Expression_list::const_iterator p = args->begin();
11573 54836 : p != args->end();
11574 38725 : ++p)
11575 : {
11576 38725 : Type* type = (*p)->type();
11577 38725 : if (type->is_error()
11578 38712 : || type->is_string_type()
11579 39671 : || type->integer_type() != NULL
11580 39442 : || type->float_type() != NULL
11581 39366 : || type->complex_type() != NULL
11582 641 : || type->is_boolean_type()
11583 482 : || type->points_to() != NULL
11584 38752 : || type->interface_type() != NULL
11585 38750 : || type->channel_type() != NULL
11586 38747 : || type->map_type() != NULL
11587 38725 : || type->function_type() != NULL
11588 38745 : || type->is_slice_type())
11589 : ;
11590 1 : else if ((*p)->is_type_expression())
11591 : {
11592 : // If this is a type expression it's going to give
11593 : // an error anyhow, so we don't need one here.
11594 : }
11595 : else
11596 : {
11597 : // Report errors in the expression first.
11598 1 : (*p)->check_types(gogo);
11599 1 : if (!(*p)->is_error_expression())
11600 0 : this->report_error(_("unsupported argument type to "
11601 : "builtin function"));
11602 : }
11603 : }
11604 : }
11605 : }
11606 : break;
11607 :
11608 863 : case BUILTIN_CLOSE:
11609 863 : if (this->check_one_arg())
11610 : {
11611 863 : if (this->one_arg()->type()->channel_type() == NULL)
11612 1 : this->report_error(_("argument must be channel"));
11613 1724 : else if (!this->one_arg()->type()->channel_type()->may_send())
11614 1 : this->report_error(_("cannot close receive-only channel"));
11615 : }
11616 : break;
11617 :
11618 14972 : case BUILTIN_PANIC:
11619 14972 : case BUILTIN_SIZEOF:
11620 14972 : case BUILTIN_ALIGNOF:
11621 14972 : if (this->check_one_arg())
11622 : {
11623 14972 : Expression* arg = this->one_arg();
11624 14972 : if (arg->type()->is_void_type())
11625 0 : this->report_error(_("argument to builtin has void type"));
11626 : }
11627 : break;
11628 :
11629 848 : case BUILTIN_RECOVER:
11630 848 : if (this->args() != NULL
11631 1 : && !this->args()->empty()
11632 849 : && !this->recover_arg_is_set_)
11633 0 : this->report_error(_("too many arguments"));
11634 : break;
11635 :
11636 1156 : case BUILTIN_OFFSETOF:
11637 1156 : if (this->check_one_arg())
11638 : {
11639 1156 : Expression* arg = this->one_arg();
11640 1156 : if (arg->classification() == Expression::EXPRESSION_SELECTOR)
11641 : {
11642 1156 : Selector_expression* se = static_cast<Selector_expression*>(arg);
11643 1156 : Expression* resolved = se->resolved();
11644 1156 : if (resolved != NULL)
11645 1156 : arg = resolved;
11646 : }
11647 1156 : if (arg->is_error_expression())
11648 : ;
11649 1156 : else if (arg->bound_method_expression() != NULL
11650 2 : || arg->interface_field_reference_expression() != NULL)
11651 2 : this->report_error(_("invalid use of method value as "
11652 : "argument of Offsetof"));
11653 1154 : else if (arg->field_reference_expression() == NULL)
11654 0 : this->report_error(_("argument must be a field reference"));
11655 : }
11656 : break;
11657 :
11658 3229 : case BUILTIN_COPY:
11659 3229 : {
11660 3229 : const Expression_list* args = this->args();
11661 6458 : if (args == NULL || args->size() < 2)
11662 : {
11663 0 : this->report_error(_("not enough arguments"));
11664 0 : break;
11665 : }
11666 3229 : else if (args->size() > 2)
11667 : {
11668 0 : this->report_error(_("too many arguments"));
11669 0 : break;
11670 : }
11671 3229 : Type* arg1_type = args->front()->type();
11672 3229 : Type* arg2_type = args->back()->type();
11673 3229 : if (arg1_type->is_error() || arg2_type->is_error())
11674 : {
11675 0 : this->set_is_error();
11676 0 : break;
11677 : }
11678 :
11679 3229 : Type* e1;
11680 3229 : if (arg1_type->is_slice_type())
11681 6456 : e1 = arg1_type->array_type()->element_type();
11682 : else
11683 : {
11684 1 : this->report_error(_("left argument must be a slice"));
11685 1 : break;
11686 : }
11687 :
11688 3228 : if (arg2_type->is_slice_type())
11689 : {
11690 5700 : Type* e2 = arg2_type->array_type()->element_type();
11691 2850 : if (!Type::are_identical(e1, e2, Type::COMPARE_TAGS, NULL))
11692 0 : this->report_error(_("element types must be the same"));
11693 : }
11694 378 : else if (arg2_type->is_string_type())
11695 : {
11696 1131 : if (e1->integer_type() == NULL || !e1->integer_type()->is_byte())
11697 0 : this->report_error(_("first argument must be []byte"));
11698 : }
11699 : else
11700 1 : this->report_error(_("second argument must be slice or string"));
11701 : }
11702 : break;
11703 :
11704 15645 : case BUILTIN_APPEND:
11705 15645 : {
11706 15645 : const Expression_list* args = this->args();
11707 15645 : if (args == NULL || args->empty())
11708 : {
11709 0 : this->report_error(_("not enough arguments"));
11710 0 : break;
11711 : }
11712 :
11713 15645 : Type* slice_type = args->front()->type();
11714 15645 : if (!slice_type->is_slice_type())
11715 : {
11716 2 : if (slice_type->is_error_type())
11717 : break;
11718 2 : if (slice_type->is_nil_type())
11719 1 : go_error_at(args->front()->location(), "use of untyped nil");
11720 : else
11721 1 : go_error_at(args->front()->location(),
11722 : "argument 1 must be a slice");
11723 2 : this->set_is_error();
11724 2 : break;
11725 : }
11726 :
11727 31286 : Type* element_type = slice_type->array_type()->element_type();
11728 15643 : if (!element_type->in_heap())
11729 0 : go_error_at(args->front()->location(),
11730 : "cannot append to slice of go:notinheap type");
11731 15643 : if (this->is_varargs())
11732 : {
11733 3553 : if (!args->back()->type()->is_slice_type()
11734 3553 : && !args->back()->type()->is_string_type())
11735 : {
11736 0 : go_error_at(args->back()->location(),
11737 : "invalid use of %<...%> with non-slice/non-string");
11738 0 : this->set_is_error();
11739 0 : break;
11740 : }
11741 :
11742 3553 : if (args->size() < 2)
11743 : {
11744 0 : this->report_error(_("not enough arguments"));
11745 0 : break;
11746 : }
11747 3553 : if (args->size() > 2)
11748 : {
11749 0 : this->report_error(_("too many arguments"));
11750 0 : break;
11751 : }
11752 :
11753 3553 : if (args->back()->type()->is_string_type()
11754 942 : && element_type->integer_type() != NULL
11755 4495 : && element_type->integer_type()->is_byte())
11756 : {
11757 : // Permit append(s1, s2...) when s1 is a slice of
11758 : // bytes and s2 is a string type.
11759 : }
11760 : else
11761 : {
11762 : // We have to test for assignment compatibility to a
11763 : // slice of the element type, which is not necessarily
11764 : // the same as the type of the first argument: the
11765 : // first argument might have a named type.
11766 2611 : Type* check_type = Type::make_array_type(element_type, NULL);
11767 2611 : std::string reason;
11768 2611 : if (!Type::are_assignable(check_type, args->back()->type(),
11769 : &reason))
11770 : {
11771 0 : if (reason.empty())
11772 0 : go_error_at(args->back()->location(),
11773 : "argument 2 has invalid type");
11774 : else
11775 0 : go_error_at(args->back()->location(),
11776 : "argument 2 has invalid type (%s)",
11777 : reason.c_str());
11778 0 : this->set_is_error();
11779 0 : break;
11780 : }
11781 2611 : }
11782 : }
11783 : else
11784 : {
11785 12090 : Expression_list::const_iterator pa = args->begin();
11786 12090 : int i = 2;
11787 26264 : for (++pa; pa != args->end(); ++pa, ++i)
11788 : {
11789 14174 : std::string reason;
11790 14174 : if (!Type::are_assignable(element_type, (*pa)->type(),
11791 : &reason))
11792 : {
11793 2 : if (reason.empty())
11794 0 : go_error_at((*pa)->location(),
11795 : "argument %d has incompatible type", i);
11796 : else
11797 2 : go_error_at((*pa)->location(),
11798 : "argument %d has incompatible type (%s)",
11799 : i, reason.c_str());
11800 2 : this->set_is_error();
11801 : }
11802 14174 : }
11803 : }
11804 : }
11805 : break;
11806 :
11807 1024 : case BUILTIN_REAL:
11808 1024 : case BUILTIN_IMAG:
11809 1024 : if (this->check_one_arg())
11810 : {
11811 1022 : if (this->one_arg()->type()->complex_type() == NULL)
11812 2 : this->report_error(_("argument must have complex type"));
11813 : }
11814 : break;
11815 :
11816 13690 : case BUILTIN_COMPLEX:
11817 13690 : {
11818 13690 : const Expression_list* args = this->args();
11819 27380 : go_assert(args != NULL && args->size() == 2);
11820 13690 : if (args->front()->is_error_expression()
11821 13683 : || args->front()->type()->is_error()
11822 13683 : || args->back()->is_error_expression()
11823 27371 : || args->back()->type()->is_error())
11824 9 : this->set_is_error();
11825 13681 : else if (!Type::are_identical(args->front()->type(),
11826 13681 : args->back()->type(),
11827 : Type::COMPARE_TAGS, NULL))
11828 6 : this->report_error(_("complex arguments must have identical types"));
11829 13675 : else if (args->front()->type()->float_type() == NULL)
11830 1 : this->report_error(_("complex arguments must have "
11831 : "floating-point type"));
11832 : }
11833 : break;
11834 :
11835 18 : case BUILTIN_ADD:
11836 18 : case BUILTIN_SLICE:
11837 18 : {
11838 18 : Numeric_constant nc;
11839 18 : unsigned long v;
11840 18 : const Expression_list* args = this->args();
11841 36 : if (args == NULL || args->size() < 2)
11842 0 : this->report_error(_("not enough arguments"));
11843 18 : else if (args->size() > 2)
11844 0 : this->report_error(_("too many arguments"));
11845 18 : else if (args->front()->is_error_expression()
11846 18 : || args->front()->type()->is_error()
11847 18 : || args->back()->is_error_expression()
11848 36 : || args->back()->type()->is_error())
11849 0 : this->set_is_error();
11850 18 : else if (args->back()->type()->integer_type() == NULL
11851 0 : && (!args->back()->type()->is_abstract()
11852 0 : || !args->back()->numeric_constant_value(&nc)
11853 0 : || (nc.to_unsigned_long(&v)
11854 : == Numeric_constant::NC_UL_NOTINT)))
11855 : {
11856 0 : if (this->code_ == BUILTIN_ADD)
11857 0 : go_error_at(args->back()->location(), "non-integer offset");
11858 : else
11859 0 : go_error_at(args->back()->location(), "non-integer size");
11860 : }
11861 18 : else if (this->code_ == BUILTIN_ADD)
11862 : {
11863 9 : Type* pointer_type =
11864 9 : Type::make_pointer_type(Type::make_void_type());
11865 9 : std::string reason;
11866 9 : if (!Type::are_assignable(pointer_type, args->front()->type(),
11867 : &reason))
11868 : {
11869 0 : if (reason.empty())
11870 0 : go_error_at(args->front()->location(),
11871 : "argument 1 has incompatible type");
11872 : else
11873 0 : go_error_at(args->front()->location(),
11874 : "argument 1 has incompatible type (%s)",
11875 : reason.c_str());
11876 0 : this->set_is_error();
11877 : }
11878 9 : }
11879 : else
11880 : {
11881 9 : if (args->front()->type()->points_to() == NULL)
11882 : {
11883 0 : go_error_at(args->front()->location(),
11884 : "argument 1 must be a pointer");
11885 0 : this->set_is_error();
11886 : }
11887 :
11888 9 : unsigned int int_bits =
11889 18 : Type::lookup_integer_type("int")->integer_type()->bits();
11890 :
11891 9 : mpz_t ival;
11892 9 : if (args->back()->numeric_constant_value(&nc) && nc.to_int(&ival))
11893 : {
11894 7 : if (mpz_sgn(ival) < 0
11895 7 : || mpz_sizeinbase(ival, 2) >= int_bits)
11896 : {
11897 0 : go_error_at(args->back()->location(),
11898 : "slice length out of range");
11899 0 : this->set_is_error();
11900 : }
11901 7 : mpz_clear(ival);
11902 : }
11903 : }
11904 18 : }
11905 18 : break;
11906 :
11907 0 : default:
11908 0 : go_unreachable();
11909 : }
11910 : }
11911 :
11912 : Expression*
11913 0 : Builtin_call_expression::do_copy()
11914 : {
11915 0 : Call_expression* bce =
11916 : new Builtin_call_expression(this->gogo_, this->fn()->copy(),
11917 0 : (this->args() == NULL
11918 : ? NULL
11919 0 : : this->args()->copy()),
11920 0 : this->is_varargs(),
11921 0 : this->location());
11922 :
11923 0 : if (this->varargs_are_lowered())
11924 0 : bce->set_varargs_are_lowered();
11925 0 : if (this->is_deferred())
11926 0 : bce->set_is_deferred();
11927 0 : if (this->is_concurrent())
11928 0 : bce->set_is_concurrent();
11929 0 : return bce;
11930 : }
11931 :
11932 : // Return the backend representation for a builtin function.
11933 :
11934 : Bexpression*
11935 164888 : Builtin_call_expression::do_get_backend(Translate_context* context)
11936 : {
11937 164888 : Gogo* gogo = context->gogo();
11938 164888 : Location location = this->location();
11939 :
11940 164888 : if (this->is_erroneous_call())
11941 : {
11942 29 : go_assert(saw_errors());
11943 29 : return gogo->backend()->error_expression();
11944 : }
11945 :
11946 164859 : switch (this->code_)
11947 : {
11948 0 : case BUILTIN_INVALID:
11949 0 : case BUILTIN_NEW:
11950 0 : case BUILTIN_MAKE:
11951 0 : case BUILTIN_ADD:
11952 0 : case BUILTIN_SLICE:
11953 0 : go_unreachable();
11954 :
11955 119501 : case BUILTIN_LEN:
11956 119501 : case BUILTIN_CAP:
11957 119501 : {
11958 119501 : const Expression_list* args = this->args();
11959 239002 : go_assert(args != NULL && args->size() == 1);
11960 119501 : Expression* arg = args->front();
11961 119501 : Type* arg_type = arg->type();
11962 :
11963 119501 : if (this->seen_)
11964 : {
11965 0 : go_assert(saw_errors());
11966 0 : return context->backend()->error_expression();
11967 : }
11968 119501 : this->seen_ = true;
11969 119501 : this->seen_ = false;
11970 119501 : if (arg_type->points_to() != NULL)
11971 : {
11972 6 : arg_type = arg_type->points_to();
11973 12 : go_assert(arg_type->array_type() != NULL
11974 : && !arg_type->is_slice_type());
11975 6 : arg = Expression::make_dereference(arg, NIL_CHECK_DEFAULT,
11976 : location);
11977 : }
11978 :
11979 119501 : Type* int_type = Type::lookup_integer_type("int");
11980 119501 : Expression* val;
11981 119501 : if (this->code_ == BUILTIN_LEN)
11982 : {
11983 102918 : if (arg_type->is_string_type())
11984 16417 : val = Expression::make_string_info(arg, STRING_INFO_LENGTH,
11985 : location);
11986 86501 : else if (arg_type->array_type() != NULL)
11987 : {
11988 85290 : if (this->seen_)
11989 : {
11990 0 : go_assert(saw_errors());
11991 0 : return context->backend()->error_expression();
11992 : }
11993 85290 : this->seen_ = true;
11994 170580 : val = arg_type->array_type()->get_length(gogo, arg);
11995 85290 : this->seen_ = false;
11996 : }
11997 1244 : else if (arg_type->map_type() != NULL
11998 1211 : || arg_type->channel_type() != NULL)
11999 : {
12000 : // The first field is the length. If the pointer is
12001 : // nil, the length is zero.
12002 1211 : Type* pint_type = Type::make_pointer_type(int_type);
12003 1211 : arg = Expression::make_unsafe_cast(pint_type, arg, location);
12004 1211 : Expression* nil = Expression::make_nil(location);
12005 1211 : nil = Expression::make_cast(pint_type, nil, location);
12006 1211 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
12007 : arg, nil, location);
12008 1211 : Expression* zero = Expression::make_integer_ul(0, int_type,
12009 : location);
12010 1211 : Expression* indir =
12011 1211 : Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED,
12012 : location);
12013 1211 : val = Expression::make_conditional(cmp, zero, indir, location);
12014 : }
12015 : else
12016 0 : go_unreachable();
12017 : }
12018 : else
12019 : {
12020 16583 : if (arg_type->array_type() != NULL)
12021 : {
12022 16532 : if (this->seen_)
12023 : {
12024 0 : go_assert(saw_errors());
12025 0 : return context->backend()->error_expression();
12026 : }
12027 16532 : this->seen_ = true;
12028 33064 : val = arg_type->array_type()->get_capacity(gogo, arg);
12029 16532 : this->seen_ = false;
12030 : }
12031 51 : else if (arg_type->channel_type() != NULL)
12032 : {
12033 : // The second field is the capacity. If the pointer
12034 : // is nil, the capacity is zero.
12035 51 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
12036 51 : Type* pint_type = Type::make_pointer_type(int_type);
12037 51 : Expression* parg = Expression::make_unsafe_cast(uintptr_type,
12038 : arg,
12039 : location);
12040 102 : int off = int_type->integer_type()->bits() / 8;
12041 51 : Expression* eoff = Expression::make_integer_ul(off,
12042 : uintptr_type,
12043 : location);
12044 51 : parg = Expression::make_binary(OPERATOR_PLUS, parg, eoff,
12045 : location);
12046 51 : parg = Expression::make_unsafe_cast(pint_type, parg, location);
12047 51 : Expression* nil = Expression::make_nil(location);
12048 51 : nil = Expression::make_cast(pint_type, nil, location);
12049 51 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ,
12050 : arg, nil, location);
12051 51 : Expression* zero = Expression::make_integer_ul(0, int_type,
12052 : location);
12053 51 : Expression* indir =
12054 51 : Expression::make_dereference(parg, NIL_CHECK_NOT_NEEDED,
12055 : location);
12056 51 : val = Expression::make_conditional(cmp, zero, indir, location);
12057 : }
12058 : else
12059 0 : go_unreachable();
12060 : }
12061 :
12062 119501 : Expression* e = Expression::make_cast(int_type, val, location);
12063 119501 : e->determine_type_no_context(gogo);
12064 119501 : return e->get_backend(context);
12065 : }
12066 :
12067 15643 : case BUILTIN_PRINT:
12068 15643 : case BUILTIN_PRINTLN:
12069 15643 : {
12070 15643 : const bool is_ln = this->code_ == BUILTIN_PRINTLN;
12071 :
12072 15643 : Expression* print_stmts = Runtime::make_call(gogo, Runtime::PRINTLOCK,
12073 : location, 0);
12074 :
12075 15643 : const Expression_list* call_args = this->args();
12076 15643 : if (call_args != NULL)
12077 : {
12078 15596 : for (Expression_list::const_iterator p = call_args->begin();
12079 52179 : p != call_args->end();
12080 36583 : ++p)
12081 : {
12082 36583 : if (is_ln && p != call_args->begin())
12083 : {
12084 15284 : Expression* print_space =
12085 15284 : Runtime::make_call(gogo, Runtime::PRINTSP, location, 0);
12086 :
12087 15284 : print_stmts =
12088 15284 : Expression::make_compound(print_stmts, print_space,
12089 : location);
12090 : }
12091 :
12092 36583 : Expression* arg = *p;
12093 36583 : Type* type = arg->type();
12094 36583 : Runtime::Function code;
12095 36583 : if (type->is_string_type())
12096 : code = Runtime::PRINTSTRING;
12097 19704 : else if (type->integer_type() != NULL
12098 9466 : && type->integer_type()->is_unsigned())
12099 : {
12100 4454 : Type* itype = Type::lookup_integer_type("uint64");
12101 4454 : arg = Expression::make_cast(itype, arg, location);
12102 8908 : if (gogo->compiling_runtime()
12103 1686 : && type->named_type() != NULL
12104 10594 : && gogo->unpack_hidden_name(type->named_type()->name())
12105 1686 : == "hex")
12106 : code = Runtime::PRINTHEX;
12107 : else
12108 3964 : code = Runtime::PRINTUINT;
12109 : }
12110 5784 : else if (type->integer_type() != NULL)
12111 : {
12112 5012 : Type* itype = Type::lookup_integer_type("int64");
12113 5012 : arg = Expression::make_cast(itype, arg, location);
12114 5012 : code = Runtime::PRINTINT;
12115 : }
12116 772 : else if (type->float_type() != NULL)
12117 : {
12118 220 : Type* dtype = Type::lookup_float_type("float64");
12119 220 : arg = Expression::make_cast(dtype, arg, location);
12120 220 : code = Runtime::PRINTFLOAT;
12121 : }
12122 552 : else if (type->complex_type() != NULL)
12123 : {
12124 76 : Type* ctype = Type::lookup_complex_type("complex128");
12125 76 : arg = Expression::make_cast(ctype, arg, location);
12126 76 : code = Runtime::PRINTCOMPLEX;
12127 : }
12128 476 : else if (type->is_boolean_type())
12129 : code = Runtime::PRINTBOOL;
12130 349 : else if (type->points_to() != NULL
12131 54 : || type->channel_type() != NULL
12132 351 : || type->map_type() != NULL
12133 356 : || type->function_type() != NULL)
12134 : {
12135 300 : arg = Expression::make_cast(type, arg, location);
12136 300 : code = Runtime::PRINTPOINTER;
12137 : }
12138 49 : else if (type->interface_type() != NULL)
12139 : {
12140 60 : if (type->interface_type()->is_empty())
12141 : code = Runtime::PRINTEFACE;
12142 : else
12143 4 : code = Runtime::PRINTIFACE;
12144 : }
12145 19 : else if (type->is_slice_type())
12146 : code = Runtime::PRINTSLICE;
12147 : else
12148 : {
12149 0 : go_assert(saw_errors());
12150 0 : return context->backend()->error_expression();
12151 : }
12152 :
12153 36583 : Expression* call = Runtime::make_call(gogo, code, location, 1,
12154 : arg);
12155 36583 : print_stmts = Expression::make_compound(print_stmts, call,
12156 : location);
12157 : }
12158 : }
12159 :
12160 15643 : if (is_ln)
12161 : {
12162 13300 : Expression* print_nl =
12163 13300 : Runtime::make_call(gogo, Runtime::PRINTNL, location, 0);
12164 13300 : print_stmts = Expression::make_compound(print_stmts, print_nl,
12165 : location);
12166 : }
12167 :
12168 15643 : Expression* unlock = Runtime::make_call(gogo, Runtime::PRINTUNLOCK,
12169 : location, 0);
12170 15643 : print_stmts = Expression::make_compound(print_stmts, unlock, location);
12171 :
12172 15643 : print_stmts->determine_type_no_context(gogo);
12173 :
12174 15643 : return print_stmts->get_backend(context);
12175 : }
12176 :
12177 14856 : case BUILTIN_PANIC:
12178 14856 : {
12179 14856 : const Expression_list* args = this->args();
12180 29712 : go_assert(args != NULL && args->size() == 1);
12181 14856 : Expression* arg = args->front();
12182 14856 : Type *empty =
12183 14856 : Type::make_empty_interface_type(Linemap::predeclared_location());
12184 14856 : arg = Expression::convert_for_assignment(gogo, empty, arg, location);
12185 :
12186 14856 : Expression* panic =
12187 14856 : Runtime::make_call(gogo, Runtime::GOPANIC, location, 1, arg);
12188 14856 : panic->determine_type_no_context(gogo);
12189 14856 : return panic->get_backend(context);
12190 : }
12191 :
12192 847 : case BUILTIN_RECOVER:
12193 847 : {
12194 : // The argument is set when building recover thunks. It's a
12195 : // boolean value which is true if we can recover a value now.
12196 847 : const Expression_list* args = this->args();
12197 1694 : go_assert(args != NULL && args->size() == 1);
12198 847 : Expression* arg = args->front();
12199 847 : Type *empty =
12200 847 : Type::make_empty_interface_type(Linemap::predeclared_location());
12201 :
12202 847 : Expression* nil = Expression::make_nil(location);
12203 847 : nil = Expression::make_interface_value(empty, nil, nil, location);
12204 :
12205 : // We need to handle a deferred call to recover specially,
12206 : // because it changes whether it can recover a panic or not.
12207 : // See test7 in test/recover1.go.
12208 847 : Expression* recover = Runtime::make_call(gogo,
12209 847 : (this->is_deferred()
12210 : ? Runtime::DEFERREDRECOVER
12211 : : Runtime::GORECOVER),
12212 : location, 0);
12213 847 : Expression* cond =
12214 847 : Expression::make_conditional(arg, recover, nil, location);
12215 847 : cond->determine_type_no_context(gogo);
12216 847 : return cond->get_backend(context);
12217 : }
12218 :
12219 861 : case BUILTIN_CLOSE:
12220 861 : {
12221 861 : const Expression_list* args = this->args();
12222 1722 : go_assert(args != NULL && args->size() == 1);
12223 861 : Expression* arg = args->front();
12224 861 : Expression* close = Runtime::make_call(gogo, Runtime::CLOSE, location,
12225 : 1, arg);
12226 861 : close->determine_type_no_context(gogo);
12227 861 : return close->get_backend(context);
12228 : }
12229 :
12230 0 : case BUILTIN_SIZEOF:
12231 0 : case BUILTIN_OFFSETOF:
12232 0 : case BUILTIN_ALIGNOF:
12233 0 : {
12234 0 : Numeric_constant nc;
12235 0 : unsigned long val;
12236 0 : if (!this->numeric_constant_value(&nc)
12237 0 : || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
12238 : {
12239 0 : go_assert(saw_errors());
12240 0 : return context->backend()->error_expression();
12241 : }
12242 0 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
12243 0 : mpz_t ival;
12244 0 : nc.get_int(&ival);
12245 0 : Expression* int_cst =
12246 0 : Expression::make_integer_z(&ival, uintptr_type, location);
12247 0 : mpz_clear(ival);
12248 0 : return int_cst->get_backend(context);
12249 0 : }
12250 :
12251 0 : case BUILTIN_COPY:
12252 : // Handled in Builtin_call_expression::do_flatten.
12253 0 : go_unreachable();
12254 :
12255 0 : case BUILTIN_APPEND:
12256 : // Handled in Builtin_call_expression::flatten_append.
12257 0 : go_unreachable();
12258 :
12259 986 : case BUILTIN_REAL:
12260 986 : case BUILTIN_IMAG:
12261 986 : {
12262 986 : const Expression_list* args = this->args();
12263 1972 : go_assert(args != NULL && args->size() == 1);
12264 :
12265 986 : Bexpression* ret;
12266 986 : Bexpression* bcomplex = args->front()->get_backend(context);
12267 986 : if (this->code_ == BUILTIN_REAL)
12268 460 : ret = gogo->backend()->real_part_expression(bcomplex, location);
12269 : else
12270 526 : ret = gogo->backend()->imag_part_expression(bcomplex, location);
12271 : return ret;
12272 : }
12273 :
12274 12165 : case BUILTIN_COMPLEX:
12275 12165 : {
12276 12165 : const Expression_list* args = this->args();
12277 24330 : go_assert(args != NULL && args->size() == 2);
12278 12165 : Bexpression* breal = args->front()->get_backend(context);
12279 12165 : Bexpression* bimag = args->back()->get_backend(context);
12280 12165 : return gogo->backend()->complex_expression(breal, bimag, location);
12281 : }
12282 :
12283 0 : default:
12284 0 : go_unreachable();
12285 : }
12286 : }
12287 :
12288 : // We have to support exporting a builtin call expression, because
12289 : // code can set a constant to the result of a builtin expression.
12290 :
12291 : void
12292 4252 : Builtin_call_expression::do_export(Export_function_body* efb) const
12293 : {
12294 4252 : if (this->code_ == BUILTIN_ADD || this->code_ == BUILTIN_SLICE)
12295 : {
12296 0 : char buf[50];
12297 0 : snprintf(buf, sizeof buf, "<p%d>%s", efb->unsafe_package_index(),
12298 : (this->code_ == BUILTIN_ADD ? "Add" : "Slice"));
12299 0 : efb->write_c_string(buf);
12300 0 : this->export_arguments(efb);
12301 : }
12302 : else
12303 : {
12304 4252 : const char *s = NULL;
12305 4252 : switch (this->code_)
12306 : {
12307 0 : default:
12308 0 : go_unreachable();
12309 : case BUILTIN_APPEND:
12310 : s = "append";
12311 : break;
12312 54 : case BUILTIN_COPY:
12313 54 : s = "copy";
12314 54 : break;
12315 3177 : case BUILTIN_LEN:
12316 3177 : s = "len";
12317 3177 : break;
12318 14 : case BUILTIN_CAP:
12319 14 : s = "cap";
12320 14 : break;
12321 24 : case BUILTIN_DELETE:
12322 24 : s = "delete";
12323 24 : break;
12324 13 : case BUILTIN_PRINT:
12325 13 : s = "print";
12326 13 : break;
12327 17 : case BUILTIN_PRINTLN:
12328 17 : s = "println";
12329 17 : break;
12330 519 : case BUILTIN_PANIC:
12331 519 : s = "panic";
12332 519 : break;
12333 13 : case BUILTIN_RECOVER:
12334 13 : s = "recover";
12335 13 : break;
12336 9 : case BUILTIN_CLOSE:
12337 9 : s = "close";
12338 9 : break;
12339 64 : case BUILTIN_REAL:
12340 64 : s = "real";
12341 64 : break;
12342 76 : case BUILTIN_IMAG:
12343 76 : s = "imag";
12344 76 : break;
12345 66 : case BUILTIN_COMPLEX:
12346 66 : s = "complex";
12347 66 : break;
12348 : }
12349 4252 : efb->write_c_string(s);
12350 4252 : this->export_arguments(efb);
12351 : }
12352 4252 : }
12353 :
12354 : // Class Call_expression.
12355 :
12356 : // A Go function can be viewed in a couple of different ways. The
12357 : // code of a Go function becomes a backend function with parameters
12358 : // whose types are simply the backend representation of the Go types.
12359 : // If there are multiple results, they are returned as a backend
12360 : // struct.
12361 :
12362 : // However, when Go code refers to a function other than simply
12363 : // calling it, the backend type of that function is actually a struct.
12364 : // The first field of the struct points to the Go function code
12365 : // (sometimes a wrapper as described below). The remaining fields
12366 : // hold addresses of closed-over variables. This struct is called a
12367 : // closure.
12368 :
12369 : // There are a few cases to consider.
12370 :
12371 : // A direct function call of a known function in package scope. In
12372 : // this case there are no closed-over variables, and we know the name
12373 : // of the function code. We can simply produce a backend call to the
12374 : // function directly, and not worry about the closure.
12375 :
12376 : // A direct function call of a known function literal. In this case
12377 : // we know the function code and we know the closure. We generate the
12378 : // function code such that it expects an additional final argument of
12379 : // the closure type. We pass the closure as the last argument, after
12380 : // the other arguments.
12381 :
12382 : // An indirect function call. In this case we have a closure. We
12383 : // load the pointer to the function code from the first field of the
12384 : // closure. We pass the address of the closure as the last argument.
12385 :
12386 : // A call to a method of an interface. Type methods are always at
12387 : // package scope, so we call the function directly, and don't worry
12388 : // about the closure.
12389 :
12390 : // This means that for a function at package scope we have two cases.
12391 : // One is the direct call, which has no closure. The other is the
12392 : // indirect call, which does have a closure. We can't simply ignore
12393 : // the closure, even though it is the last argument, because that will
12394 : // fail on targets where the function pops its arguments. So when
12395 : // generating a closure for a package-scope function we set the
12396 : // function code pointer in the closure to point to a wrapper
12397 : // function. This wrapper function accepts a final argument that
12398 : // points to the closure, ignores it, and calls the real function as a
12399 : // direct function call. This wrapper will normally be efficient, and
12400 : // can often simply be a tail call to the real function.
12401 :
12402 : // We don't use GCC's static chain pointer because 1) we don't need
12403 : // it; 2) GCC only permits using a static chain to call a known
12404 : // function, so we can't use it for an indirect call anyhow. Since we
12405 : // can't use it for an indirect call, we may as well not worry about
12406 : // using it for a direct call either.
12407 :
12408 : // We pass the closure last rather than first because it means that
12409 : // the function wrapper we put into a closure for a package-scope
12410 : // function can normally just be a tail call to the real function.
12411 :
12412 : // For method expressions we generate a wrapper that loads the
12413 : // receiver from the closure and then calls the method. This
12414 : // unfortunately forces reshuffling the arguments, since there is a
12415 : // new first argument, but we can't avoid reshuffling either for
12416 : // method expressions or for indirect calls of package-scope
12417 : // functions, and since the latter are more common we reshuffle for
12418 : // method expressions.
12419 :
12420 : // Note that the Go code retains the Go types. The extra final
12421 : // argument only appears when we convert to the backend
12422 : // representation.
12423 :
12424 : // Traversal.
12425 :
12426 : int
12427 17229502 : Call_expression::do_traverse(Traverse* traverse)
12428 : {
12429 17229502 : if (this->lowered_ != NULL)
12430 347105 : return Expression::traverse(&this->lowered_, traverse);
12431 :
12432 : // If we are calling a function in a different package that returns
12433 : // an unnamed type, this may be the only chance we get to traverse
12434 : // that type. We don't traverse this->type_ because it may be a
12435 : // Call_multiple_result_type that will just lead back here.
12436 16882397 : if (this->type_ != NULL && !this->type_->is_error_type())
12437 : {
12438 12523828 : Function_type *fntype = this->get_function_type();
12439 12523828 : if (fntype != NULL && Type::traverse(fntype, traverse) == TRAVERSE_EXIT)
12440 : return TRAVERSE_EXIT;
12441 : }
12442 16880257 : if (Expression::traverse(&this->fn_, traverse) == TRAVERSE_EXIT)
12443 : return TRAVERSE_EXIT;
12444 16281475 : if (this->args_ != NULL)
12445 : {
12446 14759903 : if (this->args_->traverse(traverse) == TRAVERSE_EXIT)
12447 : return TRAVERSE_EXIT;
12448 : }
12449 : return TRAVERSE_CONTINUE;
12450 : }
12451 :
12452 : // Lower a Call_expression to a Builtin_call_expression. This happens
12453 : // early on, before determine_types.
12454 :
12455 : Expression*
12456 3894877 : Call_expression::lower_builtin(Gogo* gogo)
12457 : {
12458 : // This is called before determine_types, so we can't call
12459 : // this->fn_->type(). Fortunately builtin calls require a direct
12460 : // reference to the builtin.
12461 3894877 : Expression* fn = this->fn_;
12462 3894877 : Named_object* no;
12463 3894877 : if (fn->func_expression() != NULL)
12464 2459852 : no = fn->func_expression()->named_object();
12465 1435025 : else if (fn->unknown_expression() != NULL)
12466 : {
12467 446148 : no = fn->unknown_expression()->named_object();
12468 446148 : if (no->is_unknown())
12469 : {
12470 446148 : no = no->unknown_value()->real_named_object();
12471 446148 : if (no == NULL)
12472 10 : return this;
12473 : }
12474 : }
12475 : else
12476 988877 : return this;
12477 :
12478 2905990 : if (!no->is_function_declaration())
12479 854597 : return this;
12480 2051393 : if (!no->func_declaration_value()->type()->is_builtin())
12481 1810627 : return this;
12482 :
12483 240766 : if (fn->unknown_expression() != NULL)
12484 143737 : fn = Expression::make_func_reference(no, NULL, fn->location());
12485 :
12486 240766 : Builtin_call_expression* bce = new Builtin_call_expression(gogo, fn,
12487 : this->args_,
12488 240766 : this->is_varargs_,
12489 240766 : this->location());
12490 240766 : if (this->is_deferred_)
12491 344 : bce->set_is_deferred();
12492 240766 : if (this->is_concurrent_)
12493 27 : bce->set_is_concurrent();
12494 : return bce;
12495 : }
12496 :
12497 : // A type conversion can be a constant.
12498 :
12499 : bool
12500 177932 : Call_expression::do_is_constant() const
12501 : {
12502 177932 : if (this->lowered_ != NULL)
12503 635 : return this->lowered_->is_constant();
12504 177297 : if (this->fn_->is_type_expression()
12505 40307 : && this->args_ != NULL
12506 217604 : && this->args_->size() == 1)
12507 40307 : return this->args_->front()->is_constant();
12508 : return false;
12509 : }
12510 :
12511 : bool
12512 172549 : Call_expression::do_is_untyped(Type** ptype) const
12513 : {
12514 172549 : if (this->lowered_ != NULL)
12515 2 : return this->lowered_->is_untyped(ptype);
12516 : return false;
12517 : }
12518 :
12519 : bool
12520 132233 : Call_expression::do_numeric_constant_value(Numeric_constant* nc)
12521 : {
12522 132233 : if (this->lowered_ != NULL)
12523 10307 : return this->lowered_->numeric_constant_value(nc);
12524 121926 : if (this->fn_->is_type_expression()
12525 34 : && this->args_ != NULL
12526 121960 : && this->args_->size() == 1)
12527 : {
12528 : // If we get here, it's before the determine_types pass, so we
12529 : // have to pull apart the type carefully. This is a hack that
12530 : // is needed because the finalize_methods needs to be able to
12531 : // determine whether the length of an array is 1.
12532 :
12533 34 : Type* type;
12534 34 : if (this->fn_->classification() == EXPRESSION_TYPE)
12535 0 : type = this->fn_->type();
12536 121927 : else if (this->fn_->unknown_expression() != NULL)
12537 : {
12538 34 : Named_object* no = this->fn_->unknown_expression()->named_object();
12539 34 : if (no->is_unknown())
12540 : {
12541 34 : no = no->unknown_value()->real_named_object();
12542 34 : go_assert(no != NULL);
12543 : }
12544 34 : type = no->type_value();
12545 : }
12546 : else
12547 : return false;
12548 :
12549 34 : if (!type->is_numeric_type())
12550 : return false;
12551 34 : if (!this->args_->front()->numeric_constant_value(nc))
12552 : return false;
12553 33 : return nc->set_type(type, false, this->location());
12554 : }
12555 : return false;
12556 : }
12557 :
12558 : bool
12559 243404 : Call_expression::do_discarding_value()
12560 : {
12561 243404 : if (this->fn_->is_type_expression())
12562 : {
12563 4 : this->unused_value_error();
12564 4 : return false;
12565 : }
12566 : return true;
12567 : }
12568 :
12569 : // Lower a call statement.
12570 :
12571 : Expression*
12572 1493644 : Call_expression::do_lower(Gogo* gogo, Named_object*,
12573 : Statement_inserter* inserter)
12574 : {
12575 1493644 : if (this->lowered_ != NULL)
12576 : return this->lowered_;
12577 :
12578 1328393 : Location loc = this->location();
12579 :
12580 1328393 : if (this->is_error_expression())
12581 96 : return Expression::make_error(loc);
12582 :
12583 : // Although we've already lowered calls to builtin functions, we may
12584 : // still see calls generated to builtins elsewhere in the lowering
12585 : // pass. It's simpler to handle them here.
12586 1328297 : Expression* builtin = this->lower_builtin(gogo);
12587 1328297 : if (builtin != this)
12588 : return builtin;
12589 :
12590 : // If this call returns multiple results, create a temporary
12591 : // variable to hold them.
12592 1308691 : if (this->result_count() > 1 && this->call_temp_ == NULL)
12593 : {
12594 93382 : Struct_field_list* sfl = new Struct_field_list();
12595 93382 : const Typed_identifier_list* results =
12596 93382 : this->get_function_type()->results();
12597 :
12598 93382 : int i = 0;
12599 93382 : char buf[20];
12600 93382 : for (Typed_identifier_list::const_iterator p = results->begin();
12601 290003 : p != results->end();
12602 196621 : ++p, ++i)
12603 : {
12604 196621 : snprintf(buf, sizeof buf, "res%d", i);
12605 393242 : sfl->push_back(Struct_field(Typed_identifier(buf, p->type(), loc)));
12606 : }
12607 :
12608 93382 : Struct_type* st = Type::make_struct_type(sfl, loc);
12609 93382 : st->set_is_struct_incomparable();
12610 93382 : st->set_is_results_struct();
12611 93382 : this->call_temp_ = Statement::make_temporary(st, NULL, loc);
12612 93382 : inserter->insert(this->call_temp_);
12613 : }
12614 :
12615 : // If this is call to a method, call the method directly passing the
12616 : // object as the first parameter.
12617 1308691 : Bound_method_expression* bme = this->fn_->bound_method_expression();
12618 264234 : if (bme != NULL && !this->is_deferred_ && !this->is_concurrent_)
12619 : {
12620 258280 : Named_object* methodfn = bme->function();
12621 258280 : Function_type* mft = (methodfn->is_function()
12622 258280 : ? methodfn->func_value()->type()
12623 123936 : : methodfn->func_declaration_value()->type());
12624 258280 : Expression* first_arg = bme->first_argument();
12625 :
12626 : // We always pass a pointer when calling a method, except for
12627 : // direct interface types when calling a value method.
12628 258280 : if (!first_arg->type()->is_error()
12629 258279 : && first_arg->type()->points_to() == NULL
12630 298190 : && !first_arg->type()->is_direct_iface_type())
12631 : {
12632 35412 : first_arg = Expression::make_unary(OPERATOR_AND, first_arg, loc);
12633 : // We may need to create a temporary variable so that we can
12634 : // take the address. We can't do that here because it will
12635 : // mess up the order of evaluation.
12636 35412 : Unary_expression* ue = static_cast<Unary_expression*>(first_arg);
12637 35412 : ue->set_create_temp();
12638 : }
12639 222868 : else if (mft->receiver()->type()->points_to() == NULL
12640 6612 : && first_arg->type()->points_to() != NULL
12641 224981 : && first_arg->type()->points_to()->is_direct_iface_type())
12642 45 : first_arg = Expression::make_dereference(first_arg,
12643 : Expression::NIL_CHECK_DEFAULT,
12644 : loc);
12645 :
12646 : // If we are calling a method which was inherited from an
12647 : // embedded struct, and the method did not get a stub, then the
12648 : // first type may be wrong.
12649 258280 : Type* fatype = bme->first_argument_type();
12650 258280 : if (fatype != NULL)
12651 : {
12652 0 : if (fatype->points_to() == NULL)
12653 0 : fatype = Type::make_pointer_type(fatype);
12654 0 : first_arg = Expression::make_unsafe_cast(fatype, first_arg, loc);
12655 : }
12656 :
12657 258280 : first_arg->determine_type_no_context(gogo);
12658 258280 : first_arg->check_types(gogo);
12659 :
12660 258280 : Expression_list* new_args = new Expression_list();
12661 258280 : new_args->push_back(first_arg);
12662 258280 : if (this->args_ != NULL)
12663 : {
12664 156432 : for (Expression_list::const_iterator p = this->args_->begin();
12665 405779 : p != this->args_->end();
12666 249347 : ++p)
12667 249347 : new_args->push_back(*p);
12668 : }
12669 :
12670 : // We have to change in place because this structure may be
12671 : // referenced by Call_result_expressions. We can't delete the
12672 : // old arguments, because we may be traversing them up in some
12673 : // caller. FIXME.
12674 258280 : this->args_ = new_args;
12675 258280 : this->fn_ = Expression::make_func_reference(methodfn, NULL,
12676 : bme->location());
12677 : }
12678 :
12679 : // If this is a call to an imported function for which we have an
12680 : // inlinable function body, add it to the list of functions to give
12681 : // to the backend as inlining opportunities.
12682 1308691 : Func_expression* fe = this->fn_->func_expression();
12683 1200143 : if (fe != NULL
12684 1200143 : && fe->named_object()->is_function_declaration()
12685 719437 : && fe->named_object()->func_declaration_value()->has_imported_body())
12686 82289 : gogo->add_imported_inlinable_function(fe->named_object());
12687 :
12688 : return this;
12689 : }
12690 :
12691 : // Flatten a call with multiple results into a temporary.
12692 :
12693 : Expression*
12694 1039120 : Call_expression::do_flatten(Gogo* gogo, Named_object*,
12695 : Statement_inserter* inserter)
12696 : {
12697 1039120 : if (this->is_erroneous_call())
12698 : {
12699 3209 : go_assert(saw_errors());
12700 3209 : return Expression::make_error(this->location());
12701 : }
12702 :
12703 1035911 : if (this->is_flattened_)
12704 153795 : return this;
12705 882116 : this->is_flattened_ = true;
12706 :
12707 : // Add temporary variables for all arguments that require type
12708 : // conversion.
12709 882116 : Function_type* fntype = this->get_function_type();
12710 882116 : if (fntype == NULL)
12711 : {
12712 0 : go_assert(saw_errors());
12713 0 : return this;
12714 : }
12715 829367 : if (this->args_ != NULL && !this->args_->empty()
12716 1703276 : && fntype->parameters() != NULL && !fntype->parameters()->empty())
12717 : {
12718 719811 : bool is_interface_method =
12719 719811 : this->fn_->interface_field_reference_expression() != NULL;
12720 :
12721 719811 : Expression_list *args = new Expression_list();
12722 719811 : Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
12723 719811 : Expression_list::const_iterator pa = this->args_->begin();
12724 719811 : if (!is_interface_method && fntype->is_method())
12725 : {
12726 : // The receiver argument.
12727 155666 : args->push_back(*pa);
12728 155666 : ++pa;
12729 : }
12730 2248040 : for (; pa != this->args_->end(); ++pa, ++pp)
12731 : {
12732 1528229 : go_assert(pp != fntype->parameters()->end());
12733 1528229 : if (Type::are_identical(pp->type(), (*pa)->type(),
12734 : Type::COMPARE_TAGS, NULL))
12735 1512105 : args->push_back(*pa);
12736 : else
12737 : {
12738 16124 : Location loc = (*pa)->location();
12739 16124 : Expression* arg = *pa;
12740 16124 : if (!arg->is_multi_eval_safe())
12741 : {
12742 14979 : Temporary_statement *temp =
12743 14979 : Statement::make_temporary(NULL, arg, loc);
12744 14979 : inserter->insert(temp);
12745 14979 : arg = Expression::make_temporary_reference(temp, loc);
12746 : }
12747 16124 : arg = Expression::convert_for_assignment(gogo, pp->type(), arg,
12748 : loc);
12749 16124 : args->push_back(arg);
12750 : }
12751 : }
12752 719811 : delete this->args_;
12753 719811 : this->args_ = args;
12754 : }
12755 :
12756 : // Lower to compiler intrinsic if possible.
12757 882116 : Func_expression* fe = this->fn_->func_expression();
12758 879619 : if (!this->is_concurrent_ && !this->is_deferred_
12759 871094 : && fe != NULL
12760 1702719 : && (fe->named_object()->is_function_declaration()
12761 345636 : || fe->named_object()->is_function()))
12762 : {
12763 820603 : Expression* ret = this->intrinsify(gogo, inserter);
12764 820603 : if (ret != NULL)
12765 : {
12766 6161 : ret->determine_type_no_context(gogo);
12767 6161 : return ret;
12768 : }
12769 : }
12770 :
12771 : // Add an implicit conversion to a boolean type, if needed. See the
12772 : // comment in Binary_expression::lower_array_comparison.
12773 875955 : if (this->is_equal_function_
12774 961 : && this->type_ != NULL
12775 876916 : && this->type_ != Type::lookup_bool_type())
12776 0 : return Expression::make_cast(this->type_, this, this->location());
12777 :
12778 875955 : return this;
12779 : }
12780 :
12781 : // Lower a call to a compiler intrinsic if possible.
12782 : // Returns NULL if it is not an intrinsic.
12783 :
12784 : Expression*
12785 820603 : Call_expression::intrinsify(Gogo* gogo,
12786 : Statement_inserter* inserter)
12787 : {
12788 820603 : Func_expression* fe = this->fn_->func_expression();
12789 820603 : Named_object* no = fe->named_object();
12790 820603 : std::string name = Gogo::unpack_hidden_name(no->name());
12791 820603 : std::string package = (no->package() != NULL
12792 264826 : ? no->package()->pkgpath()
12793 820603 : : gogo->pkgpath());
12794 820603 : bool is_method = ((no->is_function() && no->func_value()->is_method())
12795 1031135 : || (no->is_function_declaration()
12796 474967 : && no->func_declaration_value()->is_method()));
12797 820603 : Location loc = this->location();
12798 :
12799 820603 : Type* int_type = Type::lookup_integer_type("int");
12800 820603 : Type* int32_type = Type::lookup_integer_type("int32");
12801 820603 : Type* int64_type = Type::lookup_integer_type("int64");
12802 820603 : Type* uint_type = Type::lookup_integer_type("uint");
12803 820603 : Type* uint8_type = Type::lookup_integer_type("uint8");
12804 820603 : Type* uint32_type = Type::lookup_integer_type("uint32");
12805 820603 : Type* uint64_type = Type::lookup_integer_type("uint64");
12806 820603 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
12807 820603 : Type* pointer_type = Type::make_pointer_type(Type::make_void_type());
12808 :
12809 1641206 : int int_size = int_type->named_type()->real_type()->integer_type()->bits() / 8;
12810 1641206 : int ptr_size = uintptr_type->named_type()->real_type()->integer_type()->bits() / 8;
12811 :
12812 820603 : if (package == "sync/atomic")
12813 : {
12814 2095 : if (is_method)
12815 : return NULL;
12816 :
12817 : // sync/atomic functions and runtime/internal/atomic functions
12818 : // are very similar. In order not to duplicate code, we just
12819 : // redirect to the latter and let the code below to handle them.
12820 : // Note: no StorePointer, SwapPointer, and CompareAndSwapPointer,
12821 : // as they need write barriers.
12822 1717 : if (name == "LoadInt32")
12823 201 : name = "Loadint32";
12824 1516 : else if (name == "LoadInt64")
12825 39 : name = "Loadint64";
12826 1477 : else if (name == "LoadUint32")
12827 147 : name = "Load";
12828 1330 : else if (name == "LoadUint64")
12829 104 : name = "Load64";
12830 1226 : else if (name == "LoadUintptr")
12831 16 : name = "Loaduintptr";
12832 1210 : else if (name == "LoadPointer")
12833 102 : name = "Loadp";
12834 1108 : else if (name == "StoreInt32")
12835 125 : name = "Storeint32";
12836 983 : else if (name == "StoreInt64")
12837 20 : name = "Storeint64";
12838 963 : else if (name == "StoreUint32")
12839 111 : name = "Store";
12840 852 : else if (name == "StoreUint64")
12841 25 : name = "Store64";
12842 827 : else if (name == "StoreUintptr")
12843 12 : name = "Storeuintptr";
12844 815 : else if (name == "AddInt32")
12845 161 : name = "Xaddint32";
12846 654 : else if (name == "AddInt64")
12847 40 : name = "Xaddint64";
12848 614 : else if (name == "AddUint32")
12849 52 : name = "Xadd";
12850 562 : else if (name == "AddUint64")
12851 57 : name = "Xadd64";
12852 505 : else if (name == "AddUintptr")
12853 14 : name = "Xadduintptr";
12854 491 : else if (name == "SwapInt32")
12855 6 : name = "Xchgint32";
12856 485 : else if (name == "SwapInt64")
12857 6 : name = "Xchgint64";
12858 479 : else if (name == "SwapUint32")
12859 7 : name = "Xchg";
12860 472 : else if (name == "SwapUint64")
12861 6 : name = "Xchg64";
12862 466 : else if (name == "SwapUintptr")
12863 7 : name = "Xchguintptr";
12864 459 : else if (name == "CompareAndSwapInt32")
12865 101 : name = "Casint32";
12866 358 : else if (name == "CompareAndSwapInt64")
12867 8 : name = "Casint64";
12868 350 : else if (name == "CompareAndSwapUint32")
12869 21 : name = "Cas";
12870 329 : else if (name == "CompareAndSwapUint64")
12871 60 : name = "Cas64";
12872 269 : else if (name == "CompareAndSwapUintptr")
12873 16 : name = "Casuintptr";
12874 : else
12875 : return NULL;
12876 :
12877 1464 : package = "runtime/internal/atomic";
12878 : }
12879 :
12880 819972 : if (package == "runtime/internal/sys")
12881 : {
12882 308 : if (is_method)
12883 : return NULL;
12884 :
12885 : // runtime/internal/sys functions and math/bits functions
12886 : // are very similar. In order not to duplicate code, we just
12887 : // redirect to the latter and let the code below to handle them.
12888 308 : if (name == "Bswap32")
12889 2 : name = "ReverseBytes32";
12890 306 : else if (name == "Bswap64")
12891 2 : name = "ReverseBytes64";
12892 304 : else if (name == "Ctz32")
12893 5 : name = "TrailingZeros32";
12894 299 : else if (name == "Ctz64")
12895 27 : name = "TrailingZeros64";
12896 : else
12897 : return NULL;
12898 :
12899 36 : package = "math/bits";
12900 : }
12901 :
12902 819700 : if (package == "runtime")
12903 : {
12904 73025 : if (is_method)
12905 : return NULL;
12906 :
12907 : // Handle a couple of special runtime functions. In the runtime
12908 : // package, getcallerpc returns the PC of the caller, and
12909 : // getcallersp returns the frame pointer of the caller. Implement
12910 : // these by turning them into calls to GCC builtin functions. We
12911 : // could implement them in normal code, but then we would have to
12912 : // explicitly unwind the stack. These functions are intended to be
12913 : // efficient. Note that this technique obviously only works for
12914 : // direct calls, but that is the only way they are used.
12915 50939 : if (name == "getcallerpc"
12916 50939 : && (this->args_ == NULL || this->args_->size() == 0))
12917 : {
12918 216 : Expression* arg = Expression::make_integer_ul(0, uint32_type, loc);
12919 216 : Expression* call =
12920 216 : Runtime::make_call(gogo, Runtime::BUILTIN_RETURN_ADDRESS, loc,
12921 : 1, arg);
12922 : // The builtin functions return void*, but the Go functions return uintptr.
12923 216 : return Expression::make_cast(uintptr_type, call, loc);
12924 : }
12925 50723 : else if (name == "getcallersp"
12926 50723 : && (this->args_ == NULL || this->args_->size() == 0))
12927 :
12928 : {
12929 28 : Expression* call =
12930 28 : Runtime::make_call(gogo, Runtime::BUILTIN_DWARF_CFA, loc, 0);
12931 : // The builtin functions return void*, but the Go functions return uintptr.
12932 28 : return Expression::make_cast(uintptr_type, call, loc);
12933 : }
12934 : }
12935 746675 : else if (package == "math/bits")
12936 : {
12937 12928 : if (is_method)
12938 : return NULL;
12939 :
12940 12922 : if ((name == "ReverseBytes16" || name == "ReverseBytes32"
12941 12902 : || name == "ReverseBytes64" || name == "ReverseBytes")
12942 12988 : && this->args_ != NULL && this->args_->size() == 1)
12943 : {
12944 66 : Runtime::Function code;
12945 66 : if (name == "ReverseBytes16")
12946 : code = Runtime::BUILTIN_BSWAP16;
12947 60 : else if (name == "ReverseBytes32")
12948 : code = Runtime::BUILTIN_BSWAP32;
12949 40 : else if (name == "ReverseBytes64")
12950 : code = Runtime::BUILTIN_BSWAP64;
12951 4 : else if (name == "ReverseBytes")
12952 24 : code = (int_size == 8 ? Runtime::BUILTIN_BSWAP64 : Runtime::BUILTIN_BSWAP32);
12953 : else
12954 0 : go_unreachable();
12955 66 : Expression* arg = this->args_->front();
12956 66 : Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
12957 66 : if (name == "ReverseBytes")
12958 4 : return Expression::make_cast(uint_type, call, loc);
12959 : return call;
12960 : }
12961 12856 : else if ((name == "TrailingZeros8" || name == "TrailingZeros16")
12962 12868 : && this->args_ != NULL && this->args_->size() == 1)
12963 : {
12964 : // GCC does not have a ctz8 or ctz16 intrinsic. We do
12965 : // ctz32(0x100 | arg) or ctz32(0x10000 | arg).
12966 12 : Expression* arg = this->args_->front();
12967 12 : arg = Expression::make_cast(uint32_type, arg, loc);
12968 12 : unsigned long mask = (name == "TrailingZeros8" ? 0x100 : 0x10000);
12969 12 : Expression* c = Expression::make_integer_ul(mask, uint32_type, loc);
12970 12 : arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
12971 12 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
12972 : loc, 1, arg);
12973 12 : return Expression::make_cast(int_type, call, loc);
12974 : }
12975 12850 : else if ((name == "TrailingZeros32"
12976 12823 : || (name == "TrailingZeros" && int_size == 4))
12977 12861 : && this->args_ != NULL && this->args_->size() == 1)
12978 : {
12979 38 : Expression* arg = this->args_->front();
12980 38 : if (!arg->is_multi_eval_safe())
12981 : {
12982 28 : Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
12983 28 : inserter->insert(ts);
12984 28 : arg = Expression::make_temporary_reference(ts, loc);
12985 : }
12986 : // arg == 0 ? 32 : __builtin_ctz(arg)
12987 38 : Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
12988 38 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
12989 38 : Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
12990 38 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZ,
12991 : loc, 1, arg->copy());
12992 38 : call = Expression::make_cast(int_type, call, loc);
12993 38 : return Expression::make_conditional(cmp, c32, call, loc);
12994 : }
12995 12812 : else if ((name == "TrailingZeros64"
12996 12747 : || (name == "TrailingZeros" && int_size == 8))
12997 12823 : && this->args_ != NULL && this->args_->size() == 1)
12998 : {
12999 76 : Expression* arg = this->args_->front();
13000 76 : if (!arg->is_multi_eval_safe())
13001 : {
13002 52 : Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
13003 52 : inserter->insert(ts);
13004 52 : arg = Expression::make_temporary_reference(ts, loc);
13005 : }
13006 : // arg == 0 ? 64 : __builtin_ctzll(arg)
13007 76 : Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
13008 76 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
13009 76 : Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
13010 76 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CTZLL,
13011 : loc, 1, arg->copy());
13012 76 : call = Expression::make_cast(int_type, call, loc);
13013 76 : return Expression::make_conditional(cmp, c64, call, loc);
13014 : }
13015 12730 : else if ((name == "LeadingZeros8" || name == "LeadingZeros16"
13016 12724 : || name == "Len8" || name == "Len16")
13017 12766 : && this->args_ != NULL && this->args_->size() == 1)
13018 : {
13019 : // GCC does not have a clz8 ir clz16 intrinsic. We do
13020 : // clz32(arg<<24 | 0xffffff) or clz32(arg<<16 | 0xffff).
13021 36 : Expression* arg = this->args_->front();
13022 36 : arg = Expression::make_cast(uint32_type, arg, loc);
13023 36 : unsigned long shift =
13024 36 : ((name == "LeadingZeros8" || name == "Len8") ? 24 : 16);
13025 36 : Expression* c = Expression::make_integer_ul(shift, uint32_type, loc);
13026 36 : arg = Expression::make_binary(OPERATOR_LSHIFT, arg, c, loc);
13027 36 : unsigned long mask =
13028 36 : ((name == "LeadingZeros8" || name == "Len8") ? 0xffffff : 0xffff);
13029 36 : c = Expression::make_integer_ul(mask, uint32_type, loc);
13030 36 : arg = Expression::make_binary(OPERATOR_OR, arg, c, loc);
13031 36 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
13032 : loc, 1, arg);
13033 36 : call = Expression::make_cast(int_type, call, loc);
13034 : // len = width - clz
13035 36 : if (name == "Len8")
13036 : {
13037 12 : c = Expression::make_integer_ul(8, int_type, loc);
13038 12 : return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
13039 : }
13040 24 : else if (name == "Len16")
13041 : {
13042 12 : c = Expression::make_integer_ul(16, int_type, loc);
13043 12 : return Expression::make_binary(OPERATOR_MINUS, c, call, loc);
13044 : }
13045 : return call;
13046 : }
13047 12694 : else if ((name == "LeadingZeros32" || name == "Len32"
13048 12669 : || ((name == "LeadingZeros" || name == "Len") && int_size == 4))
13049 12745 : && this->args_ != NULL && this->args_->size() == 1)
13050 : {
13051 51 : Expression* arg = this->args_->front();
13052 51 : if (!arg->is_multi_eval_safe())
13053 : {
13054 26 : Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc);
13055 26 : inserter->insert(ts);
13056 26 : arg = Expression::make_temporary_reference(ts, loc);
13057 : }
13058 : // arg == 0 ? 32 : __builtin_clz(arg)
13059 51 : Expression* zero = Expression::make_integer_ul(0, uint32_type, loc);
13060 51 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
13061 51 : Expression* c32 = Expression::make_integer_ul(32, int_type, loc);
13062 51 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZ,
13063 : loc, 1, arg->copy());
13064 51 : call = Expression::make_cast(int_type, call, loc);
13065 51 : Expression* cond = Expression::make_conditional(cmp, c32, call, loc);
13066 : // len = 32 - clz
13067 51 : if (name == "Len32" || name == "Len")
13068 40 : return Expression::make_binary(OPERATOR_MINUS, c32->copy(), cond, loc);
13069 : return cond;
13070 : }
13071 12569 : else if ((name == "LeadingZeros64" || name == "Len64"
13072 12485 : || ((name == "LeadingZeros" || name == "Len") && int_size == 8))
13073 12753 : && this->args_ != NULL && this->args_->size() == 1)
13074 : {
13075 184 : Expression* arg = this->args_->front();
13076 184 : if (!arg->is_multi_eval_safe())
13077 : {
13078 51 : Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc);
13079 51 : inserter->insert(ts);
13080 51 : arg = Expression::make_temporary_reference(ts, loc);
13081 : }
13082 : // arg == 0 ? 64 : __builtin_clzll(arg)
13083 184 : Expression* zero = Expression::make_integer_ul(0, uint64_type, loc);
13084 184 : Expression* cmp = Expression::make_binary(OPERATOR_EQEQ, arg, zero, loc);
13085 184 : Expression* c64 = Expression::make_integer_ul(64, int_type, loc);
13086 184 : Expression* call = Runtime::make_call(gogo, Runtime::BUILTIN_CLZLL,
13087 : loc, 1, arg->copy());
13088 184 : call = Expression::make_cast(int_type, call, loc);
13089 184 : Expression* cond = Expression::make_conditional(cmp, c64, call, loc);
13090 : // len = 64 - clz
13091 184 : if (name == "Len64" || name == "Len")
13092 99 : return Expression::make_binary(OPERATOR_MINUS, c64->copy(), cond, loc);
13093 : return cond;
13094 : }
13095 12441 : else if ((name == "OnesCount8" || name == "OnesCount16"
13096 12435 : || name == "OnesCount32" || name == "OnesCount64"
13097 12411 : || name == "OnesCount")
13098 12501 : && this->args_ != NULL && this->args_->size() == 1)
13099 : {
13100 60 : Runtime::Function code;
13101 60 : if (name == "OnesCount64")
13102 : code = Runtime::BUILTIN_POPCOUNTLL;
13103 46 : else if (name == "OnesCount")
13104 6 : code = (int_size == 8 ? Runtime::BUILTIN_POPCOUNTLL : Runtime::BUILTIN_POPCOUNT);
13105 : else
13106 : code = Runtime::BUILTIN_POPCOUNT;
13107 60 : Expression* arg = this->args_->front();
13108 60 : Expression* call = Runtime::make_call(gogo, code, loc, 1, arg);
13109 60 : return Expression::make_cast(int_type, call, loc);
13110 : }
13111 : }
13112 733747 : else if (package == "runtime/internal/atomic")
13113 : {
13114 6502 : int memorder = __ATOMIC_SEQ_CST;
13115 :
13116 6502 : if (is_method)
13117 : {
13118 580 : Function_type* ftype = (no->is_function()
13119 580 : ? no->func_value()->type()
13120 568 : : no->func_declaration_value()->type());
13121 580 : Type* rtype = ftype->receiver()->type()->deref();
13122 580 : go_assert(rtype->named_type() != NULL);
13123 580 : const std::string& rname(rtype->named_type()->name());
13124 580 : if (rname == "Int32")
13125 : {
13126 42 : if (name == "Load")
13127 35 : name = "LoadInt32";
13128 7 : else if (name == "Store")
13129 7 : name = "Storeint32";
13130 0 : else if (name == "CompareAndSwap")
13131 0 : name = "Casint32";
13132 0 : else if (name == "Swap")
13133 0 : name = "Xchgint32";
13134 0 : else if (name == "Add")
13135 0 : name = "Xaddint32";
13136 : else
13137 0 : go_unreachable();
13138 : }
13139 538 : else if (rname == "Int64")
13140 : {
13141 100 : if (name == "Load")
13142 42 : name = "LoadInt64";
13143 58 : else if (name == "Store")
13144 21 : name = "Storeint64";
13145 37 : else if (name == "CompareAndSwap")
13146 0 : name = "Casint64";
13147 37 : else if (name == "Swap")
13148 0 : name = "Xchgint64";
13149 37 : else if (name == "Add")
13150 37 : name = "Xaddint64";
13151 : else
13152 0 : go_unreachable();
13153 : }
13154 438 : else if (rname == "Uint8")
13155 : {
13156 0 : if (name == "Load")
13157 0 : name = "Load8";
13158 0 : else if (name == "Store")
13159 0 : name = "Store8";
13160 0 : else if (name == "And")
13161 0 : name = "And8";
13162 0 : else if (name == "Or")
13163 0 : name = "Or8";
13164 : else
13165 0 : go_unreachable();
13166 : }
13167 438 : else if (rname == "Uint32")
13168 : {
13169 119 : if (name == "Load")
13170 70 : name = "Load";
13171 49 : else if (name == "LoadAcquire")
13172 0 : name = "LoadAcq";
13173 49 : else if (name == "Store")
13174 14 : name = "Store";
13175 35 : else if (name == "CompareAndSwap")
13176 35 : name = "Cas";
13177 0 : else if (name == "CompareAndSwapRelease")
13178 0 : name = "CasRel";
13179 0 : else if (name == "Swap")
13180 0 : name = "Xchg";
13181 0 : else if (name == "And")
13182 0 : name = "And";
13183 0 : else if (name == "Or")
13184 0 : name = "Or";
13185 0 : else if (name == "Add")
13186 0 : name = "Xadd";
13187 : else
13188 0 : go_unreachable();
13189 : }
13190 319 : else if (rname == "Uint64")
13191 : {
13192 120 : if (name == "Load")
13193 58 : name = "Load64";
13194 62 : else if (name == "Store")
13195 34 : name = "Store64";
13196 28 : else if (name == "CompareAndSwap")
13197 0 : name = "Cas64";
13198 28 : else if (name == "Swap")
13199 0 : name = "Xchgt64";
13200 28 : else if (name == "Add")
13201 28 : name = "Xadd64";
13202 : else
13203 0 : go_unreachable();
13204 : }
13205 199 : else if (rname == "Uintptr")
13206 : {
13207 133 : if (name == "Load")
13208 49 : name = "Loaduintptr";
13209 84 : else if (name == "LoadAcquire")
13210 0 : name = "Loadacquintptr";
13211 84 : else if (name == "Store")
13212 35 : name = "Storeuintptr";
13213 49 : else if (name == "StoreRelease")
13214 0 : name = "StoreReluintptr";
13215 49 : else if (name == "CompareAndSwap")
13216 28 : name = "Casuintptr";
13217 21 : else if (name == "Swap")
13218 7 : name = "Xchguintptr";
13219 14 : else if (name == "Add")
13220 14 : name = "Xadduintptr";
13221 : else
13222 0 : go_unreachable();
13223 : }
13224 66 : else if (rname == "Float64")
13225 : {
13226 : // Needs unsafe type conversion. Don't intrinsify for now.
13227 : return NULL;
13228 : }
13229 0 : else if (rname == "UnsafePointer")
13230 : {
13231 0 : if (name == "Load")
13232 0 : name = "Loadp";
13233 0 : else if (name == "StoreNoWB")
13234 0 : name = "StorepoWB";
13235 0 : else if (name == "CompareAndSwapNoWB")
13236 0 : name = "Casp1";
13237 : else
13238 0 : go_unreachable();
13239 : }
13240 : else
13241 0 : go_unreachable();
13242 : }
13243 :
13244 5460 : if ((name == "Load" || name == "Load64" || name == "Loadint64" || name == "Loadp"
13245 4594 : || name == "Loaduint" || name == "Loaduintptr" || name == "LoadAcq"
13246 4321 : || name == "Loadint32" || name == "Load8")
13247 7827 : && this->args_ != NULL && this->args_->size() == 1)
13248 : {
13249 2367 : if (int_size < 8 && (name == "Load64" || name == "Loadint64"))
13250 : // On 32-bit architectures we need to check alignment.
13251 : // Not intrinsify for now.
13252 : return NULL;
13253 :
13254 2075 : Runtime::Function code;
13255 2075 : Type* res_type;
13256 2075 : if (name == "Load")
13257 : {
13258 : code = Runtime::ATOMIC_LOAD_4;
13259 : res_type = uint32_type;
13260 : }
13261 1099 : else if (name == "Load64")
13262 : {
13263 : code = Runtime::ATOMIC_LOAD_8;
13264 : res_type = uint64_type;
13265 : }
13266 768 : else if (name == "Loadint32")
13267 : {
13268 : code = Runtime::ATOMIC_LOAD_4;
13269 : res_type = int32_type;
13270 : }
13271 561 : else if (name == "Loadint64")
13272 : {
13273 : code = Runtime::ATOMIC_LOAD_8;
13274 : res_type = int64_type;
13275 : }
13276 524 : else if (name == "Loaduint")
13277 : {
13278 3 : code = (int_size == 8
13279 7 : ? Runtime::ATOMIC_LOAD_8
13280 : : Runtime::ATOMIC_LOAD_4);
13281 : res_type = uint_type;
13282 : }
13283 517 : else if (name == "Loaduintptr")
13284 : {
13285 92 : code = (ptr_size == 8
13286 211 : ? Runtime::ATOMIC_LOAD_8
13287 : : Runtime::ATOMIC_LOAD_4);
13288 : res_type = uintptr_type;
13289 : }
13290 306 : else if (name == "Loadp")
13291 : {
13292 96 : code = (ptr_size == 8
13293 206 : ? Runtime::ATOMIC_LOAD_8
13294 : : Runtime::ATOMIC_LOAD_4);
13295 : res_type = pointer_type;
13296 : }
13297 100 : else if (name == "LoadAcq")
13298 : {
13299 : code = Runtime::ATOMIC_LOAD_4;
13300 : res_type = uint32_type;
13301 : memorder = __ATOMIC_ACQUIRE;
13302 : }
13303 45 : else if (name == "Load8")
13304 : {
13305 : code = Runtime::ATOMIC_LOAD_1;
13306 : res_type = uint8_type;
13307 : }
13308 : else
13309 0 : go_unreachable();
13310 2075 : Expression* a1 = this->args_->front();
13311 2075 : Expression* a2 = Expression::make_integer_ul(memorder, int32_type, loc);
13312 2075 : Expression* call = Runtime::make_call(gogo, code, loc, 2, a1, a2);
13313 2075 : return Expression::make_unsafe_cast(res_type, call, loc);
13314 : }
13315 :
13316 3586 : if ((name == "Store" || name == "Store64" || name == "StorepNoWB"
13317 3226 : || name == "Storeuintptr" || name == "StoreRel"
13318 3097 : || name == "Storeint32" || name == "Storeint64")
13319 4743 : && this->args_ != NULL && this->args_->size() == 2)
13320 : {
13321 1157 : if (int_size < 8 && (name == "Store64" || name == "Storeint64"))
13322 : return NULL;
13323 :
13324 1019 : Runtime::Function code;
13325 1019 : Expression* a1 = this->args_->at(0);
13326 1019 : Expression* a2 = this->args_->at(1);
13327 1019 : if (name == "Store")
13328 : code = Runtime::ATOMIC_STORE_4;
13329 536 : else if (name == "Store64")
13330 : code = Runtime::ATOMIC_STORE_8;
13331 391 : else if (name == "Storeint32")
13332 : code = Runtime::ATOMIC_STORE_4;
13333 253 : else if (name == "Storeint64")
13334 : code = Runtime::ATOMIC_STORE_8;
13335 228 : else if (name == "Storeuintptr")
13336 102 : code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
13337 126 : else if (name == "StorepNoWB")
13338 : {
13339 99 : code = (ptr_size == 8 ? Runtime::ATOMIC_STORE_8 : Runtime::ATOMIC_STORE_4);
13340 99 : a2 = Expression::make_unsafe_cast(uintptr_type, a2, loc);
13341 99 : a2 = Expression::make_cast(uint64_type, a2, loc);
13342 : }
13343 27 : else if (name == "StoreRel")
13344 : {
13345 : code = Runtime::ATOMIC_STORE_4;
13346 : memorder = __ATOMIC_RELEASE;
13347 : }
13348 0 : else if (name == "Store8")
13349 : code = Runtime::ATOMIC_STORE_1;
13350 : else
13351 0 : go_unreachable();
13352 1019 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13353 1019 : return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13354 : }
13355 :
13356 2848 : if ((name == "Xchg" || name == "Xchg64" || name == "Xchguintptr"
13357 2798 : || name == "Xchgint32" || name == "Xchgint64")
13358 2986 : && this->args_ != NULL && this->args_->size() == 2)
13359 : {
13360 138 : if (int_size < 8 && (name == "Xchg64" || name == "Xchgint64"))
13361 : return NULL;
13362 :
13363 118 : Runtime::Function code;
13364 118 : Type* res_type;
13365 118 : if (name == "Xchg")
13366 : {
13367 : code = Runtime::ATOMIC_EXCHANGE_4;
13368 : res_type = uint32_type;
13369 : }
13370 54 : else if (name == "Xchg64")
13371 : {
13372 : code = Runtime::ATOMIC_EXCHANGE_8;
13373 : res_type = uint64_type;
13374 : }
13375 38 : else if (name == "Xchgint32")
13376 : {
13377 : code = Runtime::ATOMIC_EXCHANGE_4;
13378 : res_type = int32_type;
13379 : }
13380 26 : else if (name == "Xchgint64")
13381 : {
13382 : code = Runtime::ATOMIC_EXCHANGE_8;
13383 : res_type = int64_type;
13384 : }
13385 20 : else if (name == "Xchguintptr")
13386 : {
13387 9 : code = (ptr_size == 8
13388 20 : ? Runtime::ATOMIC_EXCHANGE_8
13389 : : Runtime::ATOMIC_EXCHANGE_4);
13390 : res_type = uintptr_type;
13391 : }
13392 : else
13393 0 : go_unreachable();
13394 118 : Expression* a1 = this->args_->at(0);
13395 118 : Expression* a2 = this->args_->at(1);
13396 118 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13397 118 : Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13398 118 : return Expression::make_cast(res_type, call, loc);
13399 : }
13400 :
13401 2197 : if ((name == "Cas" || name == "Cas64" || name == "Casuintptr"
13402 1963 : || name == "Casp1" || name == "CasRel"
13403 1923 : || name == "Casint32" || name == "Casint64")
13404 3176 : && this->args_ != NULL && this->args_->size() == 3)
13405 : {
13406 979 : if (int_size < 8 && (name == "Cas64" || name == "Casint64"))
13407 : return NULL;
13408 :
13409 903 : Runtime::Function code;
13410 903 : Expression* a1 = this->args_->at(0);
13411 :
13412 : // Builtin cas takes a pointer to the old value.
13413 : // Store it in a temporary and take the address.
13414 903 : Expression* a2 = this->args_->at(1);
13415 903 : Temporary_statement* ts = Statement::make_temporary(NULL, a2, loc);
13416 903 : inserter->insert(ts);
13417 903 : a2 = Expression::make_temporary_reference(ts, loc);
13418 903 : a2 = Expression::make_unary(OPERATOR_AND, a2, loc);
13419 :
13420 903 : Expression* a3 = this->args_->at(2);
13421 903 : if (name == "Cas")
13422 : code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
13423 326 : else if (name == "Cas64")
13424 : code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
13425 250 : else if (name == "Casint32")
13426 : code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
13427 143 : else if (name == "Casint64")
13428 : code = Runtime::ATOMIC_COMPARE_EXCHANGE_8;
13429 132 : else if (name == "Casuintptr")
13430 41 : code = (ptr_size == 8
13431 92 : ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
13432 : : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
13433 40 : else if (name == "Casp1")
13434 : {
13435 3 : code = (ptr_size == 8
13436 6 : ? Runtime::ATOMIC_COMPARE_EXCHANGE_8
13437 : : Runtime::ATOMIC_COMPARE_EXCHANGE_4);
13438 6 : a3 = Expression::make_unsafe_cast(uintptr_type, a3, loc);
13439 6 : a3 = Expression::make_cast(uint64_type, a3, loc);
13440 : }
13441 34 : else if (name == "CasRel")
13442 : {
13443 : code = Runtime::ATOMIC_COMPARE_EXCHANGE_4;
13444 : memorder = __ATOMIC_RELEASE;
13445 : }
13446 : else
13447 0 : go_unreachable();
13448 903 : Expression* a4 = Expression::make_boolean(false, loc);
13449 903 : Expression* a5 = Expression::make_integer_ul(memorder, int32_type, loc);
13450 903 : Expression* a6 = Expression::make_integer_ul(__ATOMIC_RELAXED, int32_type, loc);
13451 903 : return Runtime::make_call(gogo, code, loc, 6, a1, a2, a3, a4, a5, a6);
13452 : }
13453 :
13454 1287 : if ((name == "Xadd" || name == "Xadd64" || name == "Xaddint64"
13455 787 : || name == "Xadduintptr" || name == "Xaddint32")
13456 2581 : && this->args_ != NULL && this->args_->size() == 2)
13457 : {
13458 1294 : if (int_size < 8 && (name == "Xadd64" || name == "Xaddint64"))
13459 : return NULL;
13460 :
13461 1079 : Runtime::Function code;
13462 1079 : Type* res_type;
13463 1079 : if (name == "Xadd")
13464 : {
13465 : code = Runtime::ATOMIC_ADD_FETCH_4;
13466 : res_type = uint32_type;
13467 : }
13468 571 : else if (name == "Xadd64")
13469 : {
13470 : code = Runtime::ATOMIC_ADD_FETCH_8;
13471 : res_type = uint64_type;
13472 : }
13473 432 : else if (name == "Xaddint32")
13474 : {
13475 : code = Runtime::ATOMIC_ADD_FETCH_4;
13476 : res_type = int32_type;
13477 : }
13478 265 : else if (name == "Xaddint64")
13479 : {
13480 : code = Runtime::ATOMIC_ADD_FETCH_8;
13481 : res_type = int64_type;
13482 : }
13483 119 : else if (name == "Xadduintptr")
13484 : {
13485 53 : code = (ptr_size == 8
13486 119 : ? Runtime::ATOMIC_ADD_FETCH_8
13487 : : Runtime::ATOMIC_ADD_FETCH_4);
13488 : res_type = uintptr_type;
13489 : }
13490 : else
13491 0 : go_unreachable();
13492 1079 : Expression* a1 = this->args_->at(0);
13493 1079 : Expression* a2 = this->args_->at(1);
13494 1079 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13495 1079 : Expression* call = Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13496 1079 : return Expression::make_cast(res_type, call, loc);
13497 : }
13498 :
13499 457 : if ((name == "And8" || name == "Or8")
13500 580 : && this->args_ != NULL && this->args_->size() == 2)
13501 : {
13502 123 : Runtime::Function code;
13503 123 : if (name == "And8")
13504 : code = Runtime::ATOMIC_AND_FETCH_1;
13505 79 : else if (name == "Or8")
13506 : code = Runtime::ATOMIC_OR_FETCH_1;
13507 : else
13508 0 : go_unreachable();
13509 123 : Expression* a1 = this->args_->at(0);
13510 123 : Expression* a2 = this->args_->at(1);
13511 123 : Expression* a3 = Expression::make_integer_ul(memorder, int32_type, loc);
13512 123 : return Runtime::make_call(gogo, code, loc, 3, a1, a2, a3);
13513 : }
13514 : }
13515 727245 : else if (package == "internal/abi"
13516 727245 : || package == "bootstrap/internal/abi") // for bootstrapping gc
13517 : {
13518 77 : if (is_method)
13519 : return NULL;
13520 :
13521 71 : if ((name == "FuncPCABI0" || name == "FuncPCABIInternal")
13522 77 : && this->args_ != NULL
13523 154 : && this->args_->size() == 1)
13524 : {
13525 : // We expect to see a conversion from the expression to "any".
13526 77 : Expression* expr = this->args_->front();
13527 77 : Type_conversion_expression* tce = expr->conversion_expression();
13528 75 : if (tce != NULL)
13529 75 : expr = tce->expr();
13530 77 : Func_expression* fe = expr->func_expression();
13531 77 : Interface_field_reference_expression* interface_method =
13532 77 : expr->interface_field_reference_expression();
13533 77 : if (fe != NULL)
13534 : {
13535 75 : Named_object* no = fe->named_object();
13536 75 : Expression* ref = Expression::make_func_code_reference(no, loc);
13537 75 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
13538 75 : return Expression::make_cast(uintptr_type, ref, loc);
13539 : }
13540 2 : else if (interface_method != NULL)
13541 0 : return interface_method->get_function();
13542 : else
13543 : {
13544 2 : expr = this->args_->front();
13545 6 : go_assert(expr->type()->interface_type() != NULL
13546 : && expr->type()->interface_type()->is_empty());
13547 2 : expr = Expression::make_interface_info(expr,
13548 : INTERFACE_INFO_OBJECT,
13549 : loc);
13550 : // Trust that this is a function type, which means that
13551 : // it is a direct iface type and we can use EXPR
13552 : // directly. The backend representation of this
13553 : // function is a pointer to a struct whose first field
13554 : // is the actual function to call.
13555 2 : Type* pvoid = Type::make_pointer_type(Type::make_void_type());
13556 2 : Type* pfntype = Type::make_pointer_type(pvoid);
13557 2 : Expression* ref = make_unsafe_cast(pfntype, expr, loc);
13558 2 : return Expression::make_dereference(ref, NIL_CHECK_NOT_NEEDED,
13559 2 : loc);
13560 : }
13561 : }
13562 : }
13563 :
13564 : return NULL;
13565 820603 : }
13566 :
13567 : // Make implicit type conversions explicit.
13568 :
13569 : void
13570 834516 : Call_expression::do_add_conversions()
13571 : {
13572 : // Skip call that requires a thunk. We generate conversions inside the thunk.
13573 834516 : if (this->is_concurrent_ || this->is_deferred_)
13574 304608 : return;
13575 :
13576 820773 : if (this->args_ == NULL || this->args_->empty())
13577 : return;
13578 :
13579 760824 : Function_type* fntype = this->get_function_type();
13580 760824 : if (fntype == NULL)
13581 : {
13582 0 : go_assert(saw_errors());
13583 : return;
13584 : }
13585 760824 : if (fntype->parameters() == NULL || fntype->parameters()->empty())
13586 : return;
13587 :
13588 529908 : Location loc = this->location();
13589 529908 : Expression_list::iterator pa = this->args_->begin();
13590 529908 : Typed_identifier_list::const_iterator pp = fntype->parameters()->begin();
13591 529908 : bool is_interface_method =
13592 529908 : this->fn_->interface_field_reference_expression() != NULL;
13593 529908 : size_t argcount = this->args_->size();
13594 529908 : if (!is_interface_method && fntype->is_method())
13595 : {
13596 : // Skip the receiver argument, which cannot be interface.
13597 155666 : pa++;
13598 155666 : argcount--;
13599 : }
13600 529908 : if (argcount != fntype->parameters()->size())
13601 : {
13602 0 : go_assert(saw_errors());
13603 : return;
13604 : }
13605 1522980 : for (; pa != this->args_->end(); ++pa, ++pp)
13606 : {
13607 993072 : Type* pt = pp->type();
13608 993072 : if (!Type::are_identical(pt, (*pa)->type(), 0, NULL)
13609 1068791 : && pt->interface_type() != NULL)
13610 59595 : *pa = Expression::make_cast(pt, *pa, loc);
13611 : }
13612 : }
13613 :
13614 : // Get the function type. This can return NULL in error cases.
13615 :
13616 : Function_type*
13617 24775571 : Call_expression::get_function_type() const
13618 : {
13619 24775571 : return this->fn_->type()->function_type();
13620 : }
13621 :
13622 : // Return the number of values which this call will return.
13623 :
13624 : size_t
13625 2920417 : Call_expression::result_count() const
13626 : {
13627 2920417 : const Function_type* fntype = this->get_function_type();
13628 2920417 : if (fntype == NULL)
13629 : return 0;
13630 2908353 : if (fntype->results() == NULL)
13631 : return 0;
13632 2331939 : return fntype->results()->size();
13633 : }
13634 :
13635 : // Return the temporary that holds the result for a call with multiple
13636 : // results.
13637 :
13638 : Temporary_statement*
13639 167662 : Call_expression::results() const
13640 : {
13641 167662 : if (this->call_temp_ == NULL)
13642 : {
13643 0 : go_assert(saw_errors());
13644 : return NULL;
13645 : }
13646 : return this->call_temp_;
13647 : }
13648 :
13649 : // Set the number of results expected from a call expression.
13650 :
13651 : void
13652 64962 : Call_expression::set_expected_result_count(size_t count)
13653 : {
13654 64962 : go_assert(this->expected_result_count_ == 0);
13655 64962 : go_assert(!this->types_are_determined_);
13656 64962 : this->expected_result_count_ = count;
13657 64962 : }
13658 :
13659 : // Return whether this is a call to the predeclared function recover.
13660 :
13661 : bool
13662 16490 : Call_expression::is_recover_call() const
13663 : {
13664 16490 : return this->do_is_recover_call();
13665 : }
13666 :
13667 : // Set the argument to the recover function.
13668 :
13669 : void
13670 857 : Call_expression::set_recover_arg(Expression* arg)
13671 : {
13672 857 : this->do_set_recover_arg(arg);
13673 857 : }
13674 :
13675 : // Virtual functions also implemented by Builtin_call_expression.
13676 :
13677 : bool
13678 14910 : Call_expression::do_is_recover_call() const
13679 : {
13680 14910 : return false;
13681 : }
13682 :
13683 : void
13684 0 : Call_expression::do_set_recover_arg(Expression*)
13685 : {
13686 0 : go_unreachable();
13687 : }
13688 :
13689 : // We have found an error with this call expression; return true if
13690 : // we should report it.
13691 :
13692 : bool
13693 9 : Call_expression::issue_error()
13694 : {
13695 9 : if (this->issued_error_)
13696 : return false;
13697 : else
13698 : {
13699 5 : this->issued_error_ = true;
13700 5 : return true;
13701 : }
13702 : }
13703 :
13704 : // Whether or not this call contains errors, either in the call or the
13705 : // arguments to the call.
13706 :
13707 : bool
13708 1204008 : Call_expression::is_erroneous_call()
13709 : {
13710 1204008 : if (this->is_error_expression() || this->fn()->is_error_expression())
13711 : return true;
13712 :
13713 1204007 : if (this->args() == NULL)
13714 : return false;
13715 3457485 : for (Expression_list::iterator pa = this->args()->begin();
13716 3457485 : pa != this->args()->end();
13717 2315560 : ++pa)
13718 : {
13719 2318797 : if ((*pa)->type()->is_error_type() || (*pa)->is_error_expression())
13720 3238 : return true;
13721 : }
13722 : return false;
13723 : }
13724 :
13725 : // Get the type.
13726 :
13727 : Type*
13728 6213156 : Call_expression::do_type()
13729 : {
13730 6213156 : if (this->is_error_expression())
13731 36 : return Type::make_error_type();
13732 6213120 : if (this->lowered_ != NULL)
13733 140189 : return this->lowered_->type();
13734 6072931 : go_assert(this->type_ != NULL);
13735 : return this->type_;
13736 : }
13737 :
13738 : // Determine types for a call expression. We can use the function
13739 : // parameter types to set the types of the arguments. We simplify
13740 : // some of the call cases here, storing the result in the lowered_
13741 : // field.
13742 :
13743 : void
13744 2243966 : Call_expression::do_determine_type(Gogo* gogo, const Type_context* context)
13745 : {
13746 2243966 : if (!this->determining_types())
13747 2243966 : return;
13748 :
13749 1730105 : if (this->lowered_== NULL)
13750 : {
13751 1730105 : Expression* builtin = this->lower_builtin(gogo);
13752 1730105 : if (builtin != this)
13753 75182 : this->lowered_ = builtin;
13754 : }
13755 :
13756 1730105 : if (this->lowered_ != NULL)
13757 : {
13758 75182 : this->lowered_->determine_type(gogo, context);
13759 75182 : return;
13760 : }
13761 :
13762 1654923 : this->fn_->determine_type_no_context(gogo);
13763 :
13764 : // Simplify a type conversion.
13765 :
13766 1654923 : if (this->fn_->is_type_expression()
13767 89712 : && this->args_ != NULL
13768 89712 : && this->args_->size() == 1
13769 1744635 : && (this->expected_result_count_ == 0
13770 : || this->expected_result_count_ == 1))
13771 : {
13772 89712 : this->lowered_ = Expression::make_cast(this->fn_->type(),
13773 89712 : this->args_->front(),
13774 : this->location());
13775 89712 : this->lowered_->determine_type(gogo, context);
13776 89712 : return;
13777 : }
13778 :
13779 : // Get the type of the function we are calling.
13780 :
13781 1565211 : Function_type* fntype = this->get_function_type();
13782 1565211 : if (fntype == NULL)
13783 : {
13784 : // We report the error here so that we can reasonably return an
13785 : // error type in do_type.
13786 56 : if (!this->fn_->type()->is_error())
13787 5 : this->report_error(_("expected function"));
13788 : else
13789 51 : this->set_is_error();
13790 56 : if (this->args_ != NULL)
13791 : {
13792 34 : for (Expression_list::iterator p = this->args_->begin();
13793 34 : p != this->args_->end();
13794 18 : ++p)
13795 18 : (*p)->determine_type_no_context(gogo);
13796 : }
13797 56 : return;
13798 : }
13799 :
13800 : // Simplify f(g()) where g() returns multiple results.
13801 :
13802 1565155 : this->simplify_multiple_results(gogo);
13803 :
13804 : // Set the type of this expression.
13805 :
13806 1565155 : go_assert(this->type_ == NULL);
13807 1565155 : const Typed_identifier_list* results = fntype->results();
13808 1565155 : if (results == NULL || results->empty())
13809 889677 : this->type_ = Type::make_void_type();
13810 675478 : else if (results->size() == 1)
13811 : {
13812 : // If this is a call to a generated equality function, we
13813 : // determine the type based on the context. See the comment in
13814 : // Binary_expression::lower_array_comparison.
13815 582084 : if (this->is_equal_function_
13816 961 : && !context->may_be_abstract
13817 961 : && context->type != NULL
13818 582084 : && context->type->is_boolean_type())
13819 0 : this->type_ = context->type;
13820 : else
13821 582084 : this->type_ = results->begin()->type();
13822 : }
13823 : else
13824 93394 : this->type_ = Type::make_call_multiple_result_type();
13825 :
13826 : // Determine the types of the arguments.
13827 :
13828 1565155 : if (this->args_ == NULL)
13829 : {
13830 165646 : if (fntype->is_varargs())
13831 : {
13832 193 : if (!this->rewrite_varargs())
13833 0 : this->set_is_error();
13834 : }
13835 165646 : return;
13836 : }
13837 :
13838 1399509 : const Typed_identifier_list* parameters = fntype->parameters();
13839 1399509 : Typed_identifier_list::const_iterator pt;
13840 1399509 : if (parameters != NULL)
13841 1236667 : pt = parameters->begin();
13842 1399509 : bool first = true;
13843 4174810 : for (Expression_list::const_iterator pa = this->args_->begin();
13844 4174810 : pa != this->args_->end();
13845 2775301 : ++pa)
13846 : {
13847 2775301 : if (first)
13848 : {
13849 1236667 : first = false;
13850 : // If this is a method, the first argument is the
13851 : // receiver.
13852 1236667 : if (fntype != NULL && fntype->is_method())
13853 : {
13854 0 : Type* rtype = fntype->receiver()->type();
13855 : // The receiver is always passed as a pointer.
13856 0 : if (rtype->points_to() == NULL)
13857 0 : rtype = Type::make_pointer_type(rtype);
13858 0 : Type_context subcontext(rtype, false);
13859 0 : (*pa)->determine_type(gogo, &subcontext);
13860 0 : continue;
13861 0 : }
13862 : }
13863 :
13864 2770686 : if ((this->is_varargs_ || this->varargs_are_lowered_)
13865 27434 : && fntype->is_varargs()
13866 4632 : && pa + 1 == this->args_->end()
13867 2308 : && parameters != NULL
13868 2777609 : && pt + 1 == parameters->end())
13869 : {
13870 2308 : Type_context subcontext(pt->type(), false);
13871 2308 : (*pa)->determine_type(gogo, &subcontext);
13872 2308 : continue;
13873 2308 : }
13874 :
13875 2772993 : if (!this->is_varargs_
13876 2770670 : && fntype->is_varargs()
13877 177215 : && parameters != NULL
13878 2950208 : && pt + 1 == parameters->end())
13879 : {
13880 114906 : go_assert(pt->type()->is_slice_type());
13881 114906 : Type_context subcontext(pt->type()->array_type()->element_type(),
13882 229812 : false);
13883 114906 : (*pa)->determine_type(gogo, &subcontext);
13884 114906 : continue;
13885 114906 : }
13886 :
13887 2658087 : if (parameters != NULL && pt != parameters->end())
13888 : {
13889 2658085 : Type_context subcontext(pt->type(), false);
13890 2658085 : (*pa)->determine_type(gogo, &subcontext);
13891 2658085 : if (!fntype->is_varargs() || pt + 1 != parameters->end())
13892 2658082 : ++pt;
13893 : }
13894 : else
13895 2 : (*pa)->determine_type_no_context(gogo);
13896 : }
13897 :
13898 1399509 : if (fntype->is_varargs())
13899 : {
13900 72617 : if (!this->rewrite_varargs())
13901 6 : this->set_is_error();
13902 : }
13903 : }
13904 :
13905 : // Called when determining types for a Call_expression. Return true
13906 : // if we should go ahead, false if they have already been determined.
13907 :
13908 : bool
13909 2539481 : Call_expression::determining_types()
13910 : {
13911 2539481 : if (this->types_are_determined_)
13912 : return false;
13913 : else
13914 : {
13915 1956755 : this->types_are_determined_ = true;
13916 1956755 : return true;
13917 : }
13918 : }
13919 :
13920 : // Simplify f(g()) where g() returns multiple results. Called by
13921 : // do_determine_types of both Call_expression and
13922 : // Builtin_call_expression.
13923 :
13924 : void
13925 1791805 : Call_expression::simplify_multiple_results(Gogo* gogo)
13926 : {
13927 1791805 : if (this->args_ == NULL || this->args_->size() != 1)
13928 : return;
13929 :
13930 489705 : Call_expression* call = this->args_->front()->call_expression();
13931 23895 : if (call == NULL || call->is_builtin())
13932 467170 : return;
13933 :
13934 22535 : call->determine_type_no_context(gogo);
13935 22535 : size_t rc = call->result_count();
13936 22535 : Function_type* fntype = this->get_function_type();
13937 22535 : if (rc > 1
13938 22535 : && ((fntype->parameters() != NULL
13939 288 : && (fntype->parameters()->size() == rc
13940 16 : || (fntype->is_varargs()
13941 16 : && fntype->parameters()->size() - 1 <= rc)))
13942 12 : || fntype->is_builtin()))
13943 : {
13944 300 : if (this->is_varargs_)
13945 : {
13946 2 : go_error_at(call->location(),
13947 : "multiple-value argument in single-value context");
13948 2 : this->set_is_error();
13949 : }
13950 :
13951 300 : call->set_is_multi_value_arg();
13952 300 : Expression_list* args = new Expression_list;
13953 987 : for (size_t i = 0; i < rc; ++i)
13954 687 : args->push_back(Expression::make_call_result(call, i));
13955 : // We can't create a new Call_expression here because this
13956 : // one may be referred to by Call_result expressions.
13957 300 : this->args_ = args;
13958 : }
13959 : }
13960 :
13961 : // Lower a call to a varargs function by rewriting the value(s) passed
13962 : // to the varargs argument into a slice. Called during the
13963 : // determine_types pass.
13964 :
13965 : bool
13966 72810 : Call_expression::rewrite_varargs()
13967 : {
13968 72810 : if (this->varargs_are_lowered_)
13969 : return true;
13970 72491 : this->varargs_are_lowered_ = true;
13971 :
13972 72491 : Function_type* fntype = this->get_function_type();
13973 :
13974 72491 : const Typed_identifier_list* parameters = fntype->parameters();
13975 72491 : go_assert(parameters != NULL && !parameters->empty());
13976 72491 : size_t param_count = parameters->size();
13977 :
13978 72491 : Type* varargs_type = parameters->back().type();
13979 72491 : go_assert(varargs_type->is_slice_type());
13980 :
13981 72491 : size_t arg_count = this->args_ == NULL ? 0 : this->args_->size();
13982 72491 : if (arg_count < param_count - 1)
13983 : {
13984 0 : if (!this->is_error_expression())
13985 0 : this->report_error(_("not enough arguments"));
13986 0 : return false;
13987 : }
13988 :
13989 72491 : bool ret = true;
13990 72491 : Expression_list* old_args = this->args_;
13991 72491 : Expression_list* new_args = new Expression_list();
13992 72491 : bool push_empty_arg = false;
13993 72491 : if (old_args == NULL || old_args->empty())
13994 : {
13995 193 : go_assert(param_count == 1);
13996 : push_empty_arg = true;
13997 : }
13998 : else
13999 : {
14000 : Expression_list::const_iterator pa;
14001 : size_t i = 1;
14002 136625 : for (pa = old_args->begin(); pa != old_args->end(); ++pa, ++i)
14003 : {
14004 130282 : if (i == param_count)
14005 : break;
14006 64327 : new_args->push_back(*pa);
14007 : }
14008 :
14009 : // We have reached the varargs parameter.
14010 :
14011 72298 : if (pa == old_args->end())
14012 : push_empty_arg = true;
14013 65955 : else if (pa + 1 == old_args->end() && this->is_varargs_)
14014 1987 : new_args->push_back(*pa);
14015 63968 : else if (this->is_varargs_)
14016 : {
14017 2 : if (!this->is_error_expression())
14018 : {
14019 1 : if ((*pa)->type()->is_slice_type())
14020 1 : this->report_error(_("too many arguments"));
14021 : else
14022 : {
14023 0 : go_error_at(this->location(),
14024 : "invalid use of %<...%> with non-slice");
14025 0 : this->set_is_error();
14026 : }
14027 : }
14028 2 : return false;
14029 : }
14030 : else
14031 : {
14032 127932 : Type* element_type = varargs_type->array_type()->element_type();
14033 63966 : Expression_list* vals = new Expression_list;
14034 178872 : for (; pa != old_args->end(); ++pa, ++i)
14035 : {
14036 114906 : Type* patype = (*pa)->type();
14037 114906 : Location paloc = (*pa)->location();
14038 114906 : if (!this->check_argument_type(i, element_type, patype, paloc))
14039 : {
14040 4 : ret = false;
14041 4 : continue;
14042 : }
14043 114902 : vals->push_back(*pa);
14044 : }
14045 63966 : Expression* val =
14046 63966 : Expression::make_slice_composite_literal(varargs_type, vals,
14047 : this->location());
14048 63966 : new_args->push_back(val);
14049 : }
14050 : }
14051 :
14052 65953 : if (push_empty_arg)
14053 6536 : new_args->push_back(Expression::make_nil(this->location()));
14054 :
14055 : // We can't create a new Call_expression here because this
14056 : // one may be referred to by Call_result expressions.
14057 72489 : this->args_ = new_args;
14058 :
14059 72489 : return ret;
14060 : }
14061 :
14062 : // Check types for parameter I.
14063 :
14064 : bool
14065 975026 : Call_expression::check_argument_type(int i, const Type* parameter_type,
14066 : const Type* argument_type,
14067 : Location argument_location)
14068 : {
14069 975026 : std::string reason;
14070 975026 : if (!Type::are_assignable(parameter_type, argument_type, &reason))
14071 : {
14072 27 : if (reason.empty())
14073 0 : go_error_at(argument_location, "argument %d has incompatible type", i);
14074 : else
14075 27 : go_error_at(argument_location,
14076 : "argument %d has incompatible type (%s)",
14077 : i, reason.c_str());
14078 27 : this->set_is_error();
14079 27 : return false;
14080 : }
14081 : return true;
14082 975026 : }
14083 :
14084 : // Check types.
14085 :
14086 : void
14087 723626 : Call_expression::do_check_types(Gogo*)
14088 : {
14089 723626 : if (this->is_error_expression()
14090 723561 : || this->fn_->is_error_expression()
14091 1447187 : || this->fn_->type()->is_error())
14092 66 : return;
14093 723560 : if (this->lowered_ != NULL)
14094 : return;
14095 :
14096 633878 : Function_type* fntype = this->get_function_type();
14097 633878 : go_assert(fntype != NULL);
14098 :
14099 633878 : if (this->expected_result_count_ != 0
14100 633878 : && this->expected_result_count_ != this->result_count())
14101 : {
14102 5 : if (this->issue_error())
14103 3 : this->report_error(_("function result count mismatch"));
14104 5 : this->set_is_error();
14105 5 : return;
14106 : }
14107 :
14108 633873 : if (this->is_varargs_ && !fntype->is_varargs())
14109 : {
14110 1 : go_error_at(this->location(),
14111 : "invalid use of %<...%> calling non-variadic function");
14112 1 : this->set_is_error();
14113 1 : return;
14114 : }
14115 :
14116 633872 : bool is_method = fntype->is_method();
14117 633872 : if (is_method)
14118 : {
14119 1987 : go_assert(this->args_ != NULL && !this->args_->empty());
14120 1987 : Type* rtype = fntype->receiver()->type();
14121 1987 : Expression* first_arg = this->args_->front();
14122 : // We dereference the values since receivers are always passed
14123 : // as pointers.
14124 1987 : std::string reason;
14125 5961 : if (!Type::are_assignable(rtype->deref(), first_arg->type()->deref(),
14126 : &reason))
14127 : {
14128 0 : if (reason.empty())
14129 0 : this->report_error(_("incompatible type for receiver"));
14130 : else
14131 : {
14132 0 : go_error_at(this->location(),
14133 : "incompatible type for receiver (%s)",
14134 : reason.c_str());
14135 0 : this->set_is_error();
14136 : }
14137 : }
14138 1987 : }
14139 :
14140 633872 : const Typed_identifier_list* parameters = fntype->parameters();
14141 633872 : if (this->args_ == NULL || this->args_->empty())
14142 : {
14143 158039 : if (parameters != NULL && !parameters->empty())
14144 9 : this->report_error(_("not enough arguments"));
14145 : }
14146 475833 : else if (parameters == NULL)
14147 : {
14148 1170 : if (!is_method || this->args_->size() > 1)
14149 0 : this->report_error(_("too many arguments"));
14150 : }
14151 474663 : else if (this->args_->size() == 1
14152 243598 : && this->args_->front()->call_expression() != NULL
14153 494584 : && this->args_->front()->call_expression()->result_count() > 1)
14154 : {
14155 : // This is F(G()) when G returns more than one result. If the
14156 : // results can be matched to parameters, it would have been
14157 : // rewritten in determine_types. If we get here we know there
14158 : // is a mismatch.
14159 0 : if (this->args_->front()->call_expression()->result_count()
14160 0 : < parameters->size())
14161 0 : this->report_error(_("not enough arguments"));
14162 : else
14163 0 : this->report_error(_("too many arguments"));
14164 : }
14165 : else
14166 : {
14167 474663 : int i = 0;
14168 474663 : Expression_list::const_iterator pa = this->args_->begin();
14169 474663 : if (is_method)
14170 817 : ++pa;
14171 474663 : for (Typed_identifier_list::const_iterator pt = parameters->begin();
14172 1334783 : pt != parameters->end();
14173 860120 : ++pt, ++pa, ++i)
14174 : {
14175 860121 : if (pa == this->args_->end())
14176 : {
14177 1 : this->report_error(_("not enough arguments"));
14178 1 : return;
14179 : }
14180 860120 : this->check_argument_type(i + 1, pt->type(), (*pa)->type(),
14181 860120 : (*pa)->location());
14182 : }
14183 474662 : if (pa != this->args_->end())
14184 2 : this->report_error(_("too many arguments"));
14185 : }
14186 : }
14187 :
14188 : Expression*
14189 11 : Call_expression::do_copy()
14190 : {
14191 11 : Call_expression* call =
14192 22 : Expression::make_call(this->fn_->copy(),
14193 11 : (this->args_ == NULL
14194 : ? NULL
14195 11 : : this->args_->copy()),
14196 11 : this->is_varargs_, this->location());
14197 :
14198 11 : if (this->varargs_are_lowered_)
14199 0 : call->set_varargs_are_lowered();
14200 11 : if (this->is_deferred_)
14201 0 : call->set_is_deferred();
14202 11 : if (this->is_concurrent_)
14203 0 : call->set_is_concurrent();
14204 11 : return call;
14205 : }
14206 :
14207 : // Return whether we have to use a temporary variable to ensure that
14208 : // we evaluate this call expression in order. If the call returns no
14209 : // results then it will inevitably be executed last.
14210 :
14211 : bool
14212 974114 : Call_expression::do_must_eval_in_order() const
14213 : {
14214 974114 : return this->result_count() > 0;
14215 : }
14216 :
14217 : // Get the function and the first argument to use when calling an
14218 : // interface method.
14219 :
14220 : Expression*
14221 31774 : Call_expression::interface_method_function(
14222 : Interface_field_reference_expression* interface_method,
14223 : Expression** first_arg_ptr,
14224 : Location location)
14225 : {
14226 31774 : Expression* object = interface_method->get_underlying_object();
14227 31774 : Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
14228 63548 : *first_arg_ptr =
14229 31774 : Expression::make_unsafe_cast(unsafe_ptr_type, object, location);
14230 31774 : return interface_method->get_function();
14231 : }
14232 :
14233 : // Build the call expression.
14234 :
14235 : Bexpression*
14236 1754598 : Call_expression::do_get_backend(Translate_context* context)
14237 : {
14238 1754598 : Location location = this->location();
14239 :
14240 1754598 : if (this->call_ != NULL)
14241 : {
14242 : // If the call returns multiple results, make a new reference to
14243 : // the temporary.
14244 95 : if (this->call_temp_ != NULL)
14245 : {
14246 95 : Expression* ref =
14247 95 : Expression::make_temporary_reference(this->call_temp_, location);
14248 95 : return ref->get_backend(context);
14249 : }
14250 :
14251 : return this->call_;
14252 : }
14253 :
14254 1754503 : Function_type* fntype = this->get_function_type();
14255 1754503 : if (fntype == NULL)
14256 0 : return context->backend()->error_expression();
14257 :
14258 1754503 : if (this->fn_->is_error_expression())
14259 0 : return context->backend()->error_expression();
14260 :
14261 1754503 : Gogo* gogo = context->gogo();
14262 :
14263 1754503 : Func_expression* func = this->fn_->func_expression();
14264 1754503 : Interface_field_reference_expression* interface_method =
14265 1754503 : this->fn_->interface_field_reference_expression();
14266 1754503 : const bool has_closure = func != NULL && func->closure() != NULL;
14267 3454044 : const bool is_interface_method = interface_method != NULL;
14268 :
14269 1753810 : bool has_closure_arg;
14270 1753810 : if (has_closure)
14271 : has_closure_arg = true;
14272 1753810 : else if (func != NULL)
14273 : has_closure_arg = false;
14274 54269 : else if (is_interface_method)
14275 : has_closure_arg = false;
14276 : else
14277 : has_closure_arg = true;
14278 :
14279 1722729 : Expression* first_arg = NULL;
14280 1722729 : if (!is_interface_method && fntype->is_method())
14281 : {
14282 256652 : first_arg = this->args_->front();
14283 256652 : if (first_arg->type()->points_to() == NULL
14284 261195 : && first_arg->type()->is_direct_iface_type())
14285 4543 : first_arg = Expression::unpack_direct_iface(first_arg,
14286 : first_arg->location());
14287 : }
14288 :
14289 1754503 : int nargs;
14290 1754503 : std::vector<Bexpression*> fn_args;
14291 1754503 : if (this->args_ == NULL || this->args_->empty())
14292 : {
14293 215243 : nargs = is_interface_method ? 1 : 0;
14294 19932 : if (nargs > 0)
14295 19932 : fn_args.resize(1);
14296 : }
14297 1539260 : else if (fntype->parameters() == NULL || fntype->parameters()->empty())
14298 : {
14299 : // Passing a receiver parameter.
14300 101195 : go_assert(!is_interface_method
14301 : && fntype->is_method()
14302 : && this->args_->size() == 1);
14303 101195 : nargs = 1;
14304 101195 : fn_args.resize(1);
14305 101195 : fn_args[0] = first_arg->get_backend(context);
14306 : }
14307 : else
14308 : {
14309 1438065 : const Typed_identifier_list* params = fntype->parameters();
14310 :
14311 1438065 : nargs = this->args_->size();
14312 1438065 : int i = is_interface_method ? 1 : 0;
14313 1438065 : nargs += i;
14314 1438065 : fn_args.resize(nargs);
14315 :
14316 1438065 : Typed_identifier_list::const_iterator pp = params->begin();
14317 1438065 : Expression_list::const_iterator pe = this->args_->begin();
14318 1438065 : if (!is_interface_method && fntype->is_method())
14319 : {
14320 155457 : fn_args[i] = first_arg->get_backend(context);
14321 155457 : ++pe;
14322 155457 : ++i;
14323 : }
14324 4360716 : for (; pe != this->args_->end(); ++pe, ++pp, ++i)
14325 : {
14326 2922651 : go_assert(pp != params->end());
14327 2922651 : Expression* arg =
14328 2922651 : Expression::convert_for_assignment(gogo, pp->type(), *pe,
14329 : location);
14330 2922651 : fn_args[i] = arg->get_backend(context);
14331 : }
14332 1438065 : go_assert(pp == params->end());
14333 1438065 : go_assert(i == nargs);
14334 : }
14335 :
14336 1754503 : Expression* fn;
14337 1754503 : Expression* closure = NULL;
14338 1754503 : if (func != NULL)
14339 : {
14340 1700234 : Named_object* no = func->named_object();
14341 1700234 : fn = Expression::make_func_code_reference(no, location);
14342 1700234 : if (has_closure)
14343 693 : closure = func->closure();
14344 : }
14345 54269 : else if (!is_interface_method)
14346 : {
14347 22495 : closure = this->fn_;
14348 :
14349 : // The backend representation of this function type is a pointer
14350 : // to a struct whose first field is the actual function to call.
14351 22495 : Type* pfntype =
14352 22495 : Type::make_pointer_type(
14353 22495 : Type::make_pointer_type(Type::make_void_type()));
14354 22495 : fn = Expression::make_unsafe_cast(pfntype, this->fn_, location);
14355 22495 : fn = Expression::make_dereference(fn, NIL_CHECK_NOT_NEEDED, location);
14356 : }
14357 : else
14358 : {
14359 31774 : Expression* arg0;
14360 31774 : fn = this->interface_method_function(interface_method, &arg0,
14361 : location);
14362 31774 : fn_args[0] = arg0->get_backend(context);
14363 : }
14364 :
14365 1754503 : Bexpression* bclosure = NULL;
14366 1754503 : if (has_closure_arg)
14367 23188 : bclosure = closure->get_backend(context);
14368 : else
14369 1731315 : go_assert(closure == NULL);
14370 :
14371 1754503 : Bexpression* bfn = fn->get_backend(context);
14372 :
14373 : // When not calling a named function directly, use a type conversion
14374 : // in case the type of the function is a recursive type which refers
14375 : // to itself. We don't do this for an interface method because 1)
14376 : // an interface method never refers to itself, so we always have a
14377 : // function type here; 2) we pass an extra first argument to an
14378 : // interface method, so fntype is not correct.
14379 1754503 : if (func == NULL && !is_interface_method)
14380 : {
14381 22495 : Btype* bft = fntype->get_backend_fntype(gogo);
14382 22495 : bfn = gogo->backend()->convert_expression(bft, bfn, location);
14383 : }
14384 :
14385 1754503 : Bfunction* bfunction = NULL;
14386 1754503 : if (context->function())
14387 1750503 : bfunction = context->function()->func_value()->get_decl();
14388 1754503 : Bexpression* call = gogo->backend()->call_expression(bfunction, bfn,
14389 : fn_args, bclosure,
14390 : location);
14391 :
14392 1754503 : if (this->call_temp_ != NULL)
14393 : {
14394 : // This case occurs when the call returns multiple results.
14395 :
14396 92971 : Expression* ref = Expression::make_temporary_reference(this->call_temp_,
14397 : location);
14398 92971 : Bexpression* bref = ref->get_backend(context);
14399 92971 : Bstatement* bassn = gogo->backend()->assignment_statement(bfunction,
14400 : bref, call,
14401 : location);
14402 :
14403 92971 : ref = Expression::make_temporary_reference(this->call_temp_, location);
14404 92971 : this->call_ = ref->get_backend(context);
14405 :
14406 92971 : return gogo->backend()->compound_expression(bassn, this->call_,
14407 92971 : location);
14408 : }
14409 :
14410 1661532 : this->call_ = call;
14411 1661532 : return this->call_;
14412 1754503 : }
14413 :
14414 : // The cost of inlining a call expression.
14415 :
14416 : int
14417 915929 : Call_expression::do_inlining_cost() const
14418 : {
14419 915929 : Func_expression* fn = this->fn_->func_expression();
14420 :
14421 : // FIXME: We don't yet support all kinds of calls.
14422 889802 : if (fn != NULL && fn->closure() != NULL)
14423 : return 0x100000;
14424 1495716 : if (this->fn_->interface_field_reference_expression())
14425 : return 0x100000;
14426 896176 : if (this->get_function_type()->is_method())
14427 : return 0x100000;
14428 :
14429 : return 5;
14430 : }
14431 :
14432 : // Export a call expression.
14433 :
14434 : void
14435 10850 : Call_expression::do_export(Export_function_body* efb) const
14436 : {
14437 10850 : bool simple_call = (this->fn_->func_expression() != NULL);
14438 194 : if (!simple_call)
14439 194 : efb->write_c_string("(");
14440 10850 : this->fn_->export_expression(efb);
14441 10850 : if (!simple_call)
14442 194 : efb->write_c_string(")");
14443 10850 : this->export_arguments(efb);
14444 10850 : }
14445 :
14446 : // Export call expression arguments.
14447 :
14448 : void
14449 15102 : Call_expression::export_arguments(Export_function_body* efb) const
14450 : {
14451 15102 : efb->write_c_string("(");
14452 15102 : if (this->args_ != NULL && !this->args_->empty())
14453 : {
14454 12676 : Expression_list::const_iterator pa = this->args_->begin();
14455 12676 : (*pa)->export_expression(efb);
14456 22352 : for (pa++; pa != this->args_->end(); pa++)
14457 : {
14458 9676 : efb->write_c_string(", ");
14459 9676 : (*pa)->export_expression(efb);
14460 : }
14461 12676 : if (this->is_varargs_)
14462 199 : efb->write_c_string("...");
14463 : }
14464 15102 : efb->write_c_string(")");
14465 15102 : }
14466 :
14467 : // Dump ast representation for a call expression.
14468 :
14469 : void
14470 0 : Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
14471 : {
14472 0 : this->fn_->dump_expression(ast_dump_context);
14473 0 : ast_dump_context->ostream() << "(";
14474 0 : if (args_ != NULL)
14475 0 : ast_dump_context->dump_expression_list(this->args_);
14476 :
14477 0 : ast_dump_context->ostream() << ") ";
14478 0 : }
14479 :
14480 : // Make a call expression.
14481 :
14482 : Call_expression*
14483 2128957 : Expression::make_call(Expression* fn, Expression_list* args, bool is_varargs,
14484 : Location location)
14485 : {
14486 2128957 : return new Call_expression(fn, args, is_varargs, location);
14487 : }
14488 :
14489 : // Class Call_result_expression.
14490 :
14491 : // Traverse a call result.
14492 :
14493 : int
14494 3067286 : Call_result_expression::do_traverse(Traverse* traverse)
14495 : {
14496 3067286 : if (traverse->remember_expression(this->call_))
14497 : {
14498 : // We have already traversed the call expression.
14499 : return TRAVERSE_CONTINUE;
14500 : }
14501 1669260 : return Expression::traverse(&this->call_, traverse);
14502 : }
14503 :
14504 : // Get the type.
14505 :
14506 : Type*
14507 1990403 : Call_result_expression::do_type()
14508 : {
14509 1990403 : if (this->classification() == EXPRESSION_ERROR)
14510 30 : return Type::make_error_type();
14511 :
14512 : // THIS->CALL_ can be replaced with a temporary reference due to
14513 : // Call_expression::do_must_eval_in_order when there is an error.
14514 1990373 : Call_expression* ce = this->call_->call_expression();
14515 1990373 : if (ce == NULL)
14516 : {
14517 12 : this->set_is_error();
14518 12 : return Type::make_error_type();
14519 : }
14520 1990361 : Function_type* fntype = ce->get_function_type();
14521 1990361 : if (fntype == NULL)
14522 : {
14523 0 : if (ce->issue_error())
14524 : {
14525 0 : if (!ce->fn()->type()->is_error())
14526 0 : this->report_error(_("expected function"));
14527 : }
14528 0 : this->set_is_error();
14529 0 : return Type::make_error_type();
14530 : }
14531 1990361 : const Typed_identifier_list* results = fntype->results();
14532 3980722 : if (results == NULL || results->size() < 2)
14533 : {
14534 4 : if (ce->issue_error())
14535 2 : this->report_error(_("number of results does not match "
14536 : "number of values"));
14537 4 : return Type::make_error_type();
14538 : }
14539 : Typed_identifier_list::const_iterator pr = results->begin();
14540 3206421 : for (unsigned int i = 0; i < this->index_; ++i)
14541 : {
14542 1216064 : if (pr == results->end())
14543 : break;
14544 1216064 : ++pr;
14545 : }
14546 1990357 : if (pr == results->end())
14547 : {
14548 0 : if (ce->issue_error())
14549 0 : this->report_error(_("number of results does not match "
14550 : "number of values"));
14551 0 : return Type::make_error_type();
14552 : }
14553 1990357 : return pr->type();
14554 : }
14555 :
14556 : // Check the type. Just make sure that we trigger the warning in
14557 : // do_type.
14558 :
14559 : void
14560 146270 : Call_result_expression::do_check_types(Gogo*)
14561 : {
14562 146270 : this->type();
14563 146270 : }
14564 :
14565 : // Determine the type. We have nothing to do here, but the 0 result
14566 : // needs to pass down to the caller.
14567 :
14568 : void
14569 193148 : Call_result_expression::do_determine_type(Gogo* gogo, const Type_context*)
14570 : {
14571 193148 : this->call_->determine_type_no_context(gogo);
14572 193148 : }
14573 :
14574 : // Return the backend representation. We just refer to the temporary set by the
14575 : // call expression. We don't do this at lowering time because it makes it
14576 : // hard to evaluate the call at the right time.
14577 :
14578 : Bexpression*
14579 167662 : Call_result_expression::do_get_backend(Translate_context* context)
14580 : {
14581 167662 : Call_expression* ce = this->call_->call_expression();
14582 167662 : if (ce == NULL)
14583 : {
14584 0 : go_assert(this->call_->is_error_expression());
14585 0 : return context->backend()->error_expression();
14586 : }
14587 167662 : Temporary_statement* ts = ce->results();
14588 167662 : if (ts == NULL)
14589 : {
14590 0 : go_assert(saw_errors());
14591 0 : return context->backend()->error_expression();
14592 : }
14593 167662 : Expression* ref = Expression::make_temporary_reference(ts, this->location());
14594 167662 : ref = Expression::make_field_reference(ref, this->index_, this->location());
14595 167662 : return ref->get_backend(context);
14596 : }
14597 :
14598 : // Dump ast representation for a call result expression.
14599 :
14600 : void
14601 0 : Call_result_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
14602 : const
14603 : {
14604 : // FIXME: Wouldn't it be better if the call is assigned to a temporary
14605 : // (struct) and the fields are referenced instead.
14606 0 : ast_dump_context->ostream() << this->index_ << "@(";
14607 0 : ast_dump_context->dump_expression(this->call_);
14608 0 : ast_dump_context->ostream() << ")";
14609 0 : }
14610 :
14611 : // Make a reference to a single result of a call which returns
14612 : // multiple results.
14613 :
14614 : Expression*
14615 168017 : Expression::make_call_result(Call_expression* call, unsigned int index)
14616 : {
14617 168017 : return new Call_result_expression(call, index);
14618 : }
14619 :
14620 : // Class Index_expression.
14621 :
14622 : // Report whether EXPR is a map index expression. This is called when
14623 : // types are determined but before lowering.
14624 :
14625 : bool
14626 34763 : Index_expression::is_map_index(Expression* expr)
14627 : {
14628 34763 : if (expr->map_index_expression() != NULL)
14629 : return true;
14630 34763 : if (expr->index_expression() != NULL)
14631 14232 : return expr->index_expression()->left_->type()->map_type() != NULL;
14632 : return false;
14633 : }
14634 :
14635 : // Traversal.
14636 :
14637 : int
14638 823151 : Index_expression::do_traverse(Traverse* traverse)
14639 : {
14640 823151 : if (Expression::traverse(&this->left_, traverse) == TRAVERSE_EXIT
14641 823151 : || Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT
14642 823150 : || (this->end_ != NULL
14643 238856 : && Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
14644 1646301 : || (this->cap_ != NULL
14645 19045 : && Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT))
14646 1 : return TRAVERSE_EXIT;
14647 : return TRAVERSE_CONTINUE;
14648 : }
14649 :
14650 : void
14651 213061 : Index_expression::do_determine_type(Gogo* gogo, const Type_context*)
14652 : {
14653 213061 : this->left_->determine_type_no_context(gogo);
14654 :
14655 213061 : Type_context end_context;
14656 213061 : Type* type = this->left_->type();
14657 213061 : if (type->array_type() != NULL
14658 51651 : || (type->points_to() != NULL
14659 51652 : && type->points_to()->array_type() != NULL
14660 15822 : && !type->points_to()->is_slice_type())
14661 35829 : || type->is_string_type())
14662 : {
14663 196990 : Type_context index_context(Type::lookup_integer_type("int"), false);
14664 196990 : this->start_->determine_type(gogo, &index_context);
14665 196990 : end_context = index_context;
14666 : }
14667 16071 : else if (type->map_type() != NULL)
14668 : {
14669 32128 : Type_context key_context(type->map_type()->key_type(), false);
14670 16064 : this->start_->determine_type(gogo, &key_context);
14671 : }
14672 7 : else if (type->is_error())
14673 1 : this->set_is_error();
14674 : else
14675 : {
14676 6 : if (this->cap_ != NULL)
14677 0 : this->report_error(_("invalid 3-index slice of object "
14678 : "that is not a slice"));
14679 6 : else if (this->end_ != NULL)
14680 5 : this->report_error(_("attempt to slice object that is not "
14681 : "array, slice, or string"));
14682 : else
14683 1 : this->report_error(_("attempt to index object that is not "
14684 : "array, slice, string, or map"));
14685 :
14686 6 : this->start_->determine_type_no_context(gogo);
14687 : }
14688 :
14689 213061 : if (this->end_ != NULL)
14690 50072 : this->end_->determine_type(gogo, &end_context);
14691 213061 : if (this->cap_ != NULL)
14692 3824 : this->cap_->determine_type(gogo, &end_context);
14693 213061 : }
14694 :
14695 : Type*
14696 364616 : Index_expression::do_type()
14697 : {
14698 364616 : if (this->is_error_expression())
14699 10 : return Type::make_error_type();
14700 :
14701 364606 : Type* type = this->left_->type();
14702 364606 : if (this->end_ != NULL)
14703 : {
14704 : // A slice of an array is a slice type. A slice of a slice or
14705 : // string type is that same type.
14706 112050 : Array_type* at = type->deref()->array_type();
14707 43426 : if (at != NULL && !at->is_slice_type())
14708 16257 : return Type::make_array_type(at->element_type(), NULL);
14709 39768 : return type;
14710 : }
14711 617162 : if (type->deref()->array_type() != NULL)
14712 816789 : return type->deref()->array_type()->element_type();
14713 36318 : else if (type->is_string_type())
14714 14018 : return Type::lookup_integer_type("byte");
14715 22300 : else if (type->map_type() != NULL)
14716 44600 : return type->map_type()->val_type();
14717 : else
14718 0 : return Type::make_error_type();
14719 : }
14720 :
14721 : void
14722 157136 : Index_expression::do_check_types(Gogo*)
14723 : {
14724 157136 : if (this->is_error_expression())
14725 : return;
14726 :
14727 157129 : Type* ltype = this->left_->type();
14728 157129 : if (ltype->is_error())
14729 : {
14730 0 : go_assert(saw_errors());
14731 : return;
14732 : }
14733 :
14734 157129 : if (this->left_->is_type_expression())
14735 : {
14736 0 : this->report_error(_("attempt to index type expression"));
14737 0 : return;
14738 : }
14739 :
14740 157129 : if (ltype->array_type() != NULL)
14741 : {
14742 110274 : if (!Array_index_expression::check_indexes(this->left_, this->start_,
14743 : this->end_, this->cap_,
14744 : this->location()))
14745 1535 : this->set_is_error();
14746 : }
14747 46855 : else if (ltype->points_to() != NULL
14748 15637 : && ltype->points_to()->array_type() != NULL
14749 62492 : && !ltype->points_to()->is_slice_type())
14750 : {
14751 15637 : Expression* deref = Expression::make_dereference(this->left_,
14752 : NIL_CHECK_DEFAULT,
14753 : this->location());
14754 15637 : if (!Array_index_expression::check_indexes(deref, this->start_,
14755 : this->end_, this->cap_,
14756 : this->location()))
14757 979 : this->set_is_error();
14758 15637 : delete deref;
14759 : }
14760 31218 : else if (ltype->is_string_type())
14761 : {
14762 17514 : if (this->cap_ != NULL)
14763 8 : this->report_error(_("invalid 3-index slice of string"));
14764 : else
14765 : {
14766 17506 : if (!String_index_expression::check_indexes(this->left_,
14767 : this->start_,
14768 : this->end_,
14769 : this->location()))
14770 15 : this->set_is_error();
14771 : }
14772 : }
14773 13704 : else if (ltype->map_type() != NULL)
14774 : {
14775 13704 : if (this->end_ != NULL || this->cap_ != NULL)
14776 0 : this->report_error(_("invalid slice of map"));
14777 : else
14778 : {
14779 13704 : Map_type* mt = ltype->map_type();
14780 13704 : std::string reason;
14781 13704 : if (!Type::are_assignable(mt->key_type(), this->start_->type(),
14782 : &reason))
14783 : {
14784 1 : if (reason.empty())
14785 0 : this->report_error(_("incompatible type for map index"));
14786 : else
14787 : {
14788 1 : go_error_at(this->location(),
14789 : "incompatible type for map index (%s)",
14790 : reason.c_str());
14791 1 : this->set_is_error();
14792 : }
14793 : }
14794 13704 : }
14795 : }
14796 : else
14797 0 : go_unreachable();
14798 : }
14799 :
14800 : bool
14801 40649 : Index_expression::do_is_addressable() const
14802 : {
14803 40649 : if (this->is_error_expression())
14804 : return true;
14805 :
14806 40649 : Type* type = this->left_->type();
14807 40649 : if (type->is_error())
14808 : return true;
14809 :
14810 : // A slice index is addressable, and an index of an addressable
14811 : // array is addressable.
14812 :
14813 40649 : bool is_pointer = false;
14814 40649 : if (type->points_to() != NULL
14815 3647 : && type->points_to()->array_type() != NULL
14816 44296 : && !type->points_to()->is_slice_type())
14817 : {
14818 3647 : type = type->points_to();
14819 3647 : is_pointer = true;
14820 : }
14821 :
14822 46452 : if (type->array_type() == NULL)
14823 : return false;
14824 :
14825 34904 : if (this->end_ != NULL)
14826 : return false;
14827 34850 : if (type->is_slice_type())
14828 : return true;
14829 13523 : return is_pointer || this->left_->is_addressable();
14830 : }
14831 :
14832 : // We need to do a nil check of any pointer dereference.
14833 :
14834 : void
14835 4655 : Index_expression::do_issue_nil_check()
14836 : {
14837 4655 : this->left_->issue_nil_check();
14838 4655 : this->needs_nil_check_ = true;
14839 4655 : }
14840 :
14841 : // Lower an index expression. This converts the generic index
14842 : // expression into an array index, a string index, or a map index.
14843 :
14844 : Expression*
14845 189160 : Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*)
14846 : {
14847 189160 : if (this->is_error_expression())
14848 2543 : return Expression::make_error(this->location());
14849 :
14850 186617 : Location location = this->location();
14851 186617 : Expression* left = this->left_;
14852 186617 : Expression* start = this->start_;
14853 186617 : Expression* end = this->end_;
14854 186617 : Expression* cap = this->cap_;
14855 :
14856 186617 : Type* type = left->type();
14857 186617 : if (type->is_error())
14858 : {
14859 1 : go_assert(saw_errors());
14860 1 : return Expression::make_error(location);
14861 : }
14862 186616 : else if (type->array_type() != NULL)
14863 138128 : return Expression::make_array_index(left, start, end, cap, location);
14864 48488 : else if (type->points_to() != NULL
14865 14748 : && type->points_to()->array_type() != NULL
14866 63236 : && !type->points_to()->is_slice_type())
14867 : {
14868 14748 : Expression* deref =
14869 14748 : Expression::make_dereference(left, NIL_CHECK_DEFAULT, location);
14870 :
14871 : // For an ordinary index into the array, the pointer will be
14872 : // dereferenced. For a slice it will not--the resulting slice
14873 : // will simply reuse the pointer, which is incorrect if that
14874 : // pointer is nil. We may also be in a context that requires a
14875 : // nil check.
14876 14748 : if (end != NULL || cap != NULL || this->needs_nil_check_)
14877 3964 : deref->issue_nil_check();
14878 :
14879 14748 : return Expression::make_array_index(deref, start, end, cap, location);
14880 : }
14881 33740 : else if (type->is_string_type())
14882 : {
14883 19681 : go_assert(cap == NULL);
14884 19681 : return Expression::make_string_index(left, start, end, location);
14885 : }
14886 14059 : else if (type->map_type() != NULL)
14887 : {
14888 14059 : go_assert(end == NULL && cap == NULL);
14889 14059 : return Expression::make_map_index(left, start, location);
14890 : }
14891 : else
14892 0 : go_unreachable();
14893 : }
14894 :
14895 : // Write an indexed expression
14896 : // (expr[expr:expr:expr], expr[expr:expr] or expr[expr]) to a dump context.
14897 :
14898 : void
14899 0 : Index_expression::dump_index_expression(Ast_dump_context* ast_dump_context,
14900 : const Expression* expr,
14901 : const Expression* start,
14902 : const Expression* end,
14903 : const Expression* cap)
14904 : {
14905 0 : expr->dump_expression(ast_dump_context);
14906 0 : ast_dump_context->ostream() << "[";
14907 0 : start->dump_expression(ast_dump_context);
14908 0 : if (end != NULL)
14909 : {
14910 0 : ast_dump_context->ostream() << ":";
14911 0 : end->dump_expression(ast_dump_context);
14912 : }
14913 0 : if (cap != NULL)
14914 : {
14915 0 : ast_dump_context->ostream() << ":";
14916 0 : cap->dump_expression(ast_dump_context);
14917 : }
14918 0 : ast_dump_context->ostream() << "]";
14919 0 : }
14920 :
14921 : // Dump ast representation for an index expression.
14922 :
14923 : void
14924 0 : Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
14925 : const
14926 : {
14927 0 : Index_expression::dump_index_expression(ast_dump_context, this->left_,
14928 0 : this->start_, this->end_, this->cap_);
14929 0 : }
14930 :
14931 : // Make an index expression.
14932 :
14933 : Expression*
14934 181155 : Expression::make_index(Expression* left, Expression* start, Expression* end,
14935 : Expression* cap, Location location)
14936 : {
14937 181155 : return new Index_expression(left, start, end, cap, location);
14938 : }
14939 :
14940 : // Class Array_index_expression.
14941 :
14942 : // Array index traversal.
14943 :
14944 : int
14945 2785745 : Array_index_expression::do_traverse(Traverse* traverse)
14946 : {
14947 2785745 : if (Expression::traverse(&this->array_, traverse) == TRAVERSE_EXIT)
14948 : return TRAVERSE_EXIT;
14949 2759773 : if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
14950 : return TRAVERSE_EXIT;
14951 2756656 : if (this->end_ != NULL)
14952 : {
14953 629217 : if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
14954 : return TRAVERSE_EXIT;
14955 : }
14956 2756562 : if (this->cap_ != NULL)
14957 : {
14958 58788 : if (Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
14959 : return TRAVERSE_EXIT;
14960 : }
14961 : return TRAVERSE_CONTINUE;
14962 : }
14963 :
14964 : // Return the type of an array index.
14965 :
14966 : Type*
14967 2601412 : Array_index_expression::do_type()
14968 : {
14969 2601412 : if (this->type_ == NULL)
14970 : {
14971 218694 : Array_type* type = this->array_->type()->array_type();
14972 218694 : if (type == NULL)
14973 0 : this->type_ = Type::make_error_type();
14974 218694 : else if (this->end_ == NULL)
14975 166047 : this->type_ = type->element_type();
14976 52647 : else if (type->is_slice_type())
14977 : {
14978 : // A slice of a slice has the same type as the original
14979 : // slice.
14980 79858 : this->type_ = this->array_->type()->deref();
14981 : }
14982 : else
14983 : {
14984 : // A slice of an array is a slice.
14985 12718 : this->type_ = Type::make_array_type(type->element_type(), NULL);
14986 : }
14987 : }
14988 2601412 : return this->type_;
14989 : }
14990 :
14991 : // Set the type of an array index.
14992 :
14993 : void
14994 183534 : Array_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
14995 : {
14996 183534 : this->array_->determine_type_no_context(gogo);
14997 :
14998 183534 : Type_context index_context(Type::lookup_integer_type("int"), false);
14999 183534 : this->start_->determine_type(gogo, &index_context);
15000 183534 : if (this->end_ != NULL)
15001 56850 : this->end_->determine_type(gogo, &index_context);
15002 183534 : if (this->cap_ != NULL)
15003 3342 : this->cap_->determine_type(gogo, &index_context);
15004 183534 : }
15005 :
15006 : // Check types of an array index.
15007 :
15008 : void
15009 551 : Array_index_expression::do_check_types(Gogo*)
15010 : {
15011 551 : if (!Array_index_expression::check_indexes(this->array_, this->start_,
15012 : this->end_, this->cap_,
15013 : this->location()))
15014 0 : this->set_is_error();
15015 551 : }
15016 :
15017 : // A static function to check array index types. This is also called
15018 : // by Index_expression::do_check_types. It reports whether type
15019 : // checking succeeded.
15020 :
15021 : bool
15022 126462 : Array_index_expression::check_indexes(Expression* array, Expression* start,
15023 : Expression* end, Expression* cap,
15024 : Location loc)
15025 : {
15026 126462 : bool ret = true;
15027 :
15028 126462 : Numeric_constant nc;
15029 126462 : unsigned long v;
15030 126467 : if (start->type()->integer_type() == NULL
15031 5 : && !start->type()->is_error()
15032 5 : && (!start->type()->is_abstract()
15033 0 : || !start->numeric_constant_value(&nc)
15034 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15035 : {
15036 5 : go_error_at(loc, "index must be integer");
15037 5 : ret = false;
15038 : }
15039 :
15040 126462 : if (end != NULL
15041 53125 : && end->type()->integer_type() == NULL
15042 15763 : && !end->type()->is_error()
15043 15754 : && !end->is_nil_expression()
15044 0 : && !end->is_error_expression()
15045 126462 : && (!end->type()->is_abstract()
15046 0 : || !end->numeric_constant_value(&nc)
15047 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15048 : {
15049 0 : go_error_at(loc, "slice end must be integer");
15050 0 : ret = false;
15051 : }
15052 :
15053 126462 : if (cap != NULL
15054 3809 : && cap->type()->integer_type() == NULL
15055 8 : && !cap->type()->is_error()
15056 0 : && !cap->is_nil_expression()
15057 0 : && !cap->is_error_expression()
15058 126462 : && (!cap->type()->is_abstract()
15059 0 : || !cap->numeric_constant_value(&nc)
15060 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15061 : {
15062 0 : go_error_at(loc, "slice capacity must be integer");
15063 0 : ret = false;
15064 : }
15065 :
15066 126462 : Array_type* array_type = array->type()->array_type();
15067 126462 : if (array_type == NULL)
15068 : {
15069 0 : go_assert(array->type()->is_error());
15070 : return false;
15071 : }
15072 :
15073 126462 : unsigned int int_bits =
15074 252924 : Type::lookup_integer_type("int")->integer_type()->bits();
15075 :
15076 126462 : Numeric_constant lvalnc;
15077 126462 : mpz_t lval;
15078 126462 : bool lval_valid = (array_type->length() != NULL
15079 51618 : && array_type->length()->numeric_constant_value(&lvalnc)
15080 178080 : && lvalnc.to_int(&lval));
15081 126462 : Numeric_constant inc;
15082 126462 : mpz_t ival;
15083 126462 : bool ival_valid = false;
15084 126462 : if (start->numeric_constant_value(&inc) && inc.to_int(&ival))
15085 : {
15086 71376 : ival_valid = true;
15087 106799 : if (mpz_sgn(ival) < 0
15088 70400 : || mpz_sizeinbase(ival, 2) >= int_bits
15089 70398 : || (lval_valid
15090 24171 : && (end == NULL
15091 24171 : ? mpz_cmp(ival, lval) >= 0
15092 11252 : : mpz_cmp(ival, lval) > 0)))
15093 : {
15094 1491 : go_error_at(start->location(), "array index out of bounds");
15095 1491 : ret = false;
15096 : }
15097 : }
15098 :
15099 126462 : if (end != NULL && !end->is_nil_expression())
15100 : {
15101 21608 : Numeric_constant enc;
15102 21608 : mpz_t eval;
15103 21608 : bool eval_valid = false;
15104 21608 : if (end->numeric_constant_value(&enc) && enc.to_int(&eval))
15105 : {
15106 7697 : eval_valid = true;
15107 7697 : if (mpz_sgn(eval) < 0
15108 6723 : || mpz_sizeinbase(eval, 2) >= int_bits
15109 6721 : || (lval_valid && mpz_cmp(eval, lval) > 0))
15110 : {
15111 1489 : go_error_at(end->location(), "array index out of bounds");
15112 1489 : ret = false;
15113 : }
15114 6208 : else if (ival_valid && mpz_cmp(ival, eval) > 0)
15115 : {
15116 14 : go_error_at(loc, "inverted slice range");
15117 14 : ret = false;
15118 : }
15119 : }
15120 :
15121 21608 : Numeric_constant cnc;
15122 21608 : mpz_t cval;
15123 21608 : if (cap != NULL
15124 25409 : && cap->numeric_constant_value(&cnc) && cnc.to_int(&cval))
15125 : {
15126 1201 : if (mpz_sgn(cval) < 0
15127 1201 : || mpz_sizeinbase(cval, 2) >= int_bits
15128 1201 : || (lval_valid && mpz_cmp(cval, lval) > 0))
15129 : {
15130 3 : go_error_at(cap->location(), "array index out of bounds");
15131 3 : ret = false;
15132 : }
15133 1198 : else if (ival_valid && mpz_cmp(ival, cval) > 0)
15134 : {
15135 10 : go_error_at(cap->location(),
15136 : "invalid slice index: capacity less than start");
15137 10 : ret = false;
15138 : }
15139 1188 : else if (eval_valid && mpz_cmp(eval, cval) > 0)
15140 : {
15141 6 : go_error_at(cap->location(),
15142 : "invalid slice index: capacity less than length");
15143 6 : ret = false;
15144 : }
15145 1201 : mpz_clear(cval);
15146 : }
15147 :
15148 21608 : if (eval_valid)
15149 7697 : mpz_clear(eval);
15150 21608 : }
15151 126462 : if (ival_valid)
15152 71376 : mpz_clear(ival);
15153 126462 : if (lval_valid)
15154 51618 : mpz_clear(lval);
15155 :
15156 : // A slice of an array requires an addressable array. A slice of a
15157 : // slice is always possible.
15158 126462 : if (end != NULL && !array_type->is_slice_type())
15159 : {
15160 14285 : if (!array->is_addressable())
15161 : {
15162 4 : go_error_at(loc, "slice of unaddressable value");
15163 4 : ret = false;
15164 : }
15165 : else
15166 : {
15167 : // Set the array address taken but not escape. The escape
15168 : // analysis will make it escape to heap when needed.
15169 14281 : array->address_taken(false);
15170 : }
15171 : }
15172 :
15173 126462 : return ret;
15174 126462 : }
15175 :
15176 : // The subexpressions of an array index must be evaluated in order.
15177 : // If this is indexing into an array, rather than a slice, then only
15178 : // the index should be evaluated. Since this is called for values on
15179 : // the left hand side of an assigment, evaluating the array, meaning
15180 : // copying the array, will cause a different array to be modified.
15181 :
15182 : bool
15183 4166 : Array_index_expression::do_must_eval_subexpressions_in_order(
15184 : int* skip) const
15185 : {
15186 4166 : *skip = this->array_->type()->is_slice_type() ? 0 : 1;
15187 4166 : return true;
15188 : }
15189 :
15190 : // Flatten array indexing: add temporary variables and bounds checks.
15191 :
15192 : Expression*
15193 249462 : Array_index_expression::do_flatten(Gogo* gogo, Named_object*,
15194 : Statement_inserter* inserter)
15195 : {
15196 249462 : if (this->is_flattened_)
15197 40350 : return this;
15198 209112 : this->is_flattened_ = true;
15199 :
15200 209112 : Location loc = this->location();
15201 :
15202 209112 : if (this->is_error_expression())
15203 0 : return Expression::make_error(loc);
15204 :
15205 209112 : Expression* array = this->array_;
15206 209112 : Expression* start = this->start_;
15207 209112 : Expression* end = this->end_;
15208 209112 : Expression* cap = this->cap_;
15209 209112 : if (array->is_error_expression()
15210 209112 : || array->type()->is_error_type()
15211 209112 : || start->is_error_expression()
15212 208675 : || start->type()->is_error_type()
15213 208675 : || (end != NULL
15214 104236 : && (end->is_error_expression() || end->type()->is_error_type()))
15215 417491 : || (cap != NULL
15216 7536 : && (cap->is_error_expression() || cap->type()->is_error_type())))
15217 : {
15218 737 : go_assert(saw_errors());
15219 737 : return Expression::make_error(loc);
15220 : }
15221 :
15222 208375 : Array_type* array_type = this->array_->type()->array_type();
15223 208375 : if (array_type == NULL)
15224 : {
15225 0 : go_assert(saw_errors());
15226 0 : return Expression::make_error(loc);
15227 : }
15228 :
15229 208375 : Temporary_statement* temp;
15230 208375 : if (array_type->is_slice_type() && !array->is_multi_eval_safe())
15231 : {
15232 18925 : temp = Statement::make_temporary(NULL, array, loc);
15233 18925 : inserter->insert(temp);
15234 18925 : this->array_ = Expression::make_temporary_reference(temp, loc);
15235 18925 : array = this->array_;
15236 : }
15237 208375 : if (!start->is_multi_eval_safe())
15238 : {
15239 28762 : temp = Statement::make_temporary(NULL, start, loc);
15240 28762 : inserter->insert(temp);
15241 28762 : this->start_ = Expression::make_temporary_reference(temp, loc);
15242 28762 : start = this->start_;
15243 : }
15244 208375 : if (end != NULL
15245 51966 : && !end->is_nil_expression()
15246 243893 : && !end->is_multi_eval_safe())
15247 : {
15248 3946 : temp = Statement::make_temporary(NULL, end, loc);
15249 3946 : inserter->insert(temp);
15250 3946 : this->end_ = Expression::make_temporary_reference(temp, loc);
15251 3946 : end = this->end_;
15252 : }
15253 208375 : if (cap != NULL && !cap->is_multi_eval_safe())
15254 : {
15255 328 : temp = Statement::make_temporary(NULL, cap, loc);
15256 328 : inserter->insert(temp);
15257 328 : this->cap_ = Expression::make_temporary_reference(temp, loc);
15258 328 : cap = this->cap_;
15259 : }
15260 :
15261 208375 : if (!this->needs_bounds_check_)
15262 33694 : return this;
15263 :
15264 174681 : Expression* len;
15265 174681 : if (!array_type->is_slice_type())
15266 : {
15267 80221 : len = array_type->get_length(gogo, this->array_);
15268 80221 : go_assert(len->is_constant());
15269 : }
15270 : else
15271 : {
15272 94460 : len = array_type->get_length(gogo, this->array_->copy());
15273 94460 : temp = Statement::make_temporary(NULL, len, loc);
15274 94460 : temp->determine_types(gogo);
15275 94460 : inserter->insert(temp);
15276 94460 : len = Expression::make_temporary_reference(temp, loc);
15277 : }
15278 :
15279 174681 : Expression* scap = NULL;
15280 174681 : if (array_type->is_slice_type())
15281 : {
15282 94460 : scap = array_type->get_capacity(gogo, this->array_->copy());
15283 94460 : temp = Statement::make_temporary(NULL, scap, loc);
15284 94460 : temp->determine_types(gogo);
15285 94460 : inserter->insert(temp);
15286 94460 : scap = Expression::make_temporary_reference(temp, loc);
15287 : }
15288 :
15289 : // The order of bounds checks here matches the order used by the gc
15290 : // compiler, as tested by issue30116[u].go.
15291 :
15292 174681 : if (cap != NULL)
15293 : {
15294 3766 : if (array_type->is_slice_type())
15295 2260 : Expression::check_bounds(gogo, cap, OPERATOR_LE, scap,
15296 : Runtime::PANIC_SLICE3_ACAP,
15297 : Runtime::PANIC_SLICE3_ACAP_U,
15298 : Runtime::PANIC_EXTEND_SLICE3_ACAP,
15299 : Runtime::PANIC_EXTEND_SLICE3_ACAP_U,
15300 : inserter, loc);
15301 : else
15302 1506 : Expression::check_bounds(gogo, cap, OPERATOR_LE, len,
15303 : Runtime::PANIC_SLICE3_ALEN,
15304 : Runtime::PANIC_SLICE3_ALEN_U,
15305 : Runtime::PANIC_EXTEND_SLICE3_ALEN,
15306 : Runtime::PANIC_EXTEND_SLICE3_ALEN_U,
15307 : inserter, loc);
15308 :
15309 3766 : Expression* start_bound = cap;
15310 3766 : if (end != NULL && !end->is_nil_expression())
15311 : {
15312 3766 : Expression::check_bounds(gogo, end, OPERATOR_LE, cap,
15313 : Runtime::PANIC_SLICE3_B,
15314 : Runtime::PANIC_SLICE3_B_U,
15315 : Runtime::PANIC_EXTEND_SLICE3_B,
15316 : Runtime::PANIC_EXTEND_SLICE3_B_U,
15317 : inserter, loc);
15318 3766 : start_bound = end;
15319 : }
15320 :
15321 3766 : Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
15322 : Runtime::PANIC_SLICE3_C,
15323 : Runtime::PANIC_SLICE3_C_U,
15324 : Runtime::PANIC_EXTEND_SLICE3_C,
15325 : Runtime::PANIC_EXTEND_SLICE3_C_U,
15326 : inserter, loc);
15327 : }
15328 170915 : else if (end != NULL && !end->is_nil_expression())
15329 : {
15330 16099 : if (array_type->is_slice_type())
15331 11950 : Expression::check_bounds(gogo, end, OPERATOR_LE, scap,
15332 : Runtime::PANIC_SLICE_ACAP,
15333 : Runtime::PANIC_SLICE_ACAP_U,
15334 : Runtime::PANIC_EXTEND_SLICE_ACAP,
15335 : Runtime::PANIC_EXTEND_SLICE_ACAP_U,
15336 : inserter, loc);
15337 : else
15338 4149 : Expression::check_bounds(gogo, end, OPERATOR_LE, len,
15339 : Runtime::PANIC_SLICE_ALEN,
15340 : Runtime::PANIC_SLICE_ALEN_U,
15341 : Runtime::PANIC_EXTEND_SLICE_ALEN,
15342 : Runtime::PANIC_EXTEND_SLICE_ALEN_U,
15343 : inserter, loc);
15344 :
15345 16099 : Expression::check_bounds(gogo, start, OPERATOR_LE, end,
15346 : Runtime::PANIC_SLICE_B,
15347 : Runtime::PANIC_SLICE_B_U,
15348 : Runtime::PANIC_EXTEND_SLICE_B,
15349 : Runtime::PANIC_EXTEND_SLICE_B_U,
15350 : inserter, loc);
15351 : }
15352 154816 : else if (end != NULL)
15353 : {
15354 15197 : Expression* start_bound;
15355 15197 : if (array_type->is_slice_type())
15356 : start_bound = scap;
15357 : else
15358 6666 : start_bound = len;
15359 15197 : Expression::check_bounds(gogo, start, OPERATOR_LE, start_bound,
15360 : Runtime::PANIC_SLICE_B,
15361 : Runtime::PANIC_SLICE_B_U,
15362 : Runtime::PANIC_EXTEND_SLICE_B,
15363 : Runtime::PANIC_EXTEND_SLICE_B_U,
15364 : inserter, loc);
15365 : }
15366 : else
15367 139619 : Expression::check_bounds(gogo, start, OPERATOR_LT, len,
15368 : Runtime::PANIC_INDEX,
15369 : Runtime::PANIC_INDEX_U,
15370 : Runtime::PANIC_EXTEND_INDEX,
15371 : Runtime::PANIC_EXTEND_INDEX_U,
15372 : inserter, loc);
15373 :
15374 174681 : return this;
15375 : }
15376 :
15377 : // Return whether this expression is addressable.
15378 :
15379 : bool
15380 1158 : Array_index_expression::do_is_addressable() const
15381 : {
15382 : // A slice expression is not addressable.
15383 1158 : if (this->end_ != NULL)
15384 : return false;
15385 :
15386 : // An index into a slice is addressable.
15387 1104 : if (this->array_->type()->is_slice_type())
15388 : return true;
15389 :
15390 : // An index into an array is addressable if the array is
15391 : // addressable.
15392 432 : return this->array_->is_addressable();
15393 : }
15394 :
15395 : void
15396 13984 : Array_index_expression::do_address_taken(bool escapes)
15397 : {
15398 : // In &x[0], if x is a slice, then x's address is not taken.
15399 13984 : if (!this->array_->type()->is_slice_type())
15400 4590 : this->array_->address_taken(escapes);
15401 13984 : }
15402 :
15403 : // Get the backend representation for an array index.
15404 :
15405 : Bexpression*
15406 207326 : Array_index_expression::do_get_backend(Translate_context* context)
15407 : {
15408 207326 : Array_type* array_type = this->array_->type()->array_type();
15409 207326 : if (array_type == NULL)
15410 : {
15411 0 : go_assert(this->array_->type()->is_error());
15412 0 : return context->backend()->error_expression();
15413 : }
15414 207326 : go_assert(!array_type->is_slice_type()
15415 : || this->array_->is_multi_eval_safe());
15416 :
15417 207326 : Location loc = this->location();
15418 207326 : Gogo* gogo = context->gogo();
15419 :
15420 207326 : Type* int_type = Type::lookup_integer_type("int");
15421 207326 : Btype* int_btype = int_type->get_backend(gogo);
15422 :
15423 : // Convert the length and capacity to "int". FIXME: Do we need to
15424 : // do this?
15425 207326 : Bexpression* length = NULL;
15426 207326 : if (this->end_ == NULL || this->end_->is_nil_expression())
15427 : {
15428 171814 : Expression* len = array_type->get_length(gogo, this->array_);
15429 171814 : length = len->get_backend(context);
15430 171814 : length = gogo->backend()->convert_expression(int_btype, length, loc);
15431 : }
15432 :
15433 207326 : Bexpression* capacity = NULL;
15434 207326 : if (this->end_ != NULL)
15435 : {
15436 51960 : Expression* cap = array_type->get_capacity(gogo, this->array_);
15437 51960 : capacity = cap->get_backend(context);
15438 51960 : capacity = gogo->backend()->convert_expression(int_btype, capacity, loc);
15439 : }
15440 :
15441 207326 : Bexpression* cap_arg = capacity;
15442 207326 : if (this->cap_ != NULL)
15443 : {
15444 3766 : cap_arg = this->cap_->get_backend(context);
15445 3766 : cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
15446 : }
15447 :
15448 207326 : if (length == NULL)
15449 35512 : length = cap_arg;
15450 :
15451 207326 : if (this->start_->type()->integer_type() == NULL
15452 0 : && !Type::are_convertible(int_type, this->start_->type(), NULL))
15453 : {
15454 0 : go_assert(saw_errors());
15455 0 : return context->backend()->error_expression();
15456 : }
15457 :
15458 207326 : Bexpression* start = this->start_->get_backend(context);
15459 207326 : start = gogo->backend()->convert_expression(int_btype, start, loc);
15460 :
15461 207326 : Bfunction* bfn = context->function()->func_value()->get_decl();
15462 207326 : if (this->end_ == NULL)
15463 : {
15464 : // Simple array indexing.
15465 155366 : Bexpression* ret;
15466 155366 : if (!array_type->is_slice_type())
15467 : {
15468 66928 : Bexpression* array = this->array_->get_backend(context);
15469 66928 : ret = gogo->backend()->array_index_expression(array, start, loc);
15470 : }
15471 : else
15472 : {
15473 88438 : Expression* valptr = array_type->get_value_pointer(gogo,
15474 : this->array_);
15475 88438 : Bexpression* ptr = valptr->get_backend(context);
15476 88438 : ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc);
15477 :
15478 176876 : Type* ele_type = this->array_->type()->array_type()->element_type();
15479 88438 : Btype* ele_btype = ele_type->get_backend(gogo);
15480 88438 : ret = gogo->backend()->indirect_expression(ele_btype, ptr, false,
15481 : loc);
15482 : }
15483 155366 : return ret;
15484 : }
15485 :
15486 : // Slice expression.
15487 :
15488 51960 : Bexpression* end;
15489 51960 : if (this->end_->is_nil_expression())
15490 : end = length;
15491 : else
15492 : {
15493 35512 : end = this->end_->get_backend(context);
15494 35512 : end = gogo->backend()->convert_expression(int_btype, end, loc);
15495 : }
15496 :
15497 51960 : Bexpression* result_length =
15498 51960 : gogo->backend()->binary_expression(OPERATOR_MINUS, end, start, loc);
15499 :
15500 51960 : Bexpression* result_capacity =
15501 51960 : gogo->backend()->binary_expression(OPERATOR_MINUS, cap_arg, start, loc);
15502 :
15503 : // If the new capacity is zero, don't change val. Otherwise we can
15504 : // get a pointer to the next object in memory, keeping it live
15505 : // unnecessarily. When the capacity is zero, the actual pointer
15506 : // value doesn't matter.
15507 51960 : Bexpression* zero =
15508 51960 : Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
15509 51960 : Bexpression* cond =
15510 51960 : gogo->backend()->binary_expression(OPERATOR_EQEQ, result_capacity, zero,
15511 : loc);
15512 51960 : Bexpression* offset = gogo->backend()->conditional_expression(bfn, int_btype,
15513 : cond, zero,
15514 : start, loc);
15515 51960 : Expression* valptr = array_type->get_value_pointer(gogo, this->array_);
15516 51960 : Bexpression* val = valptr->get_backend(context);
15517 51960 : val = gogo->backend()->pointer_offset_expression(val, offset, loc);
15518 :
15519 51960 : Btype* struct_btype = this->type()->get_backend(gogo);
15520 51960 : std::vector<Bexpression*> init;
15521 51960 : init.push_back(val);
15522 51960 : init.push_back(result_length);
15523 51960 : init.push_back(result_capacity);
15524 :
15525 51960 : return gogo->backend()->constructor_expression(struct_btype, init, loc);
15526 51960 : }
15527 :
15528 : // Export an array index expression.
15529 :
15530 : void
15531 3549 : Array_index_expression::do_export(Export_function_body* efb) const
15532 : {
15533 3549 : efb->write_c_string("(");
15534 3549 : this->array_->export_expression(efb);
15535 3549 : efb->write_c_string(")[");
15536 :
15537 3549 : Type* old_context = efb->type_context();
15538 3549 : efb->set_type_context(Type::lookup_integer_type("int"));
15539 :
15540 3549 : this->start_->export_expression(efb);
15541 3549 : if (this->end_ == NULL)
15542 2760 : go_assert(this->cap_ == NULL);
15543 : else
15544 : {
15545 789 : efb->write_c_string(":");
15546 789 : if (!this->end_->is_nil_expression())
15547 427 : this->end_->export_expression(efb);
15548 789 : if (this->cap_ != NULL)
15549 : {
15550 0 : efb->write_c_string(":");
15551 0 : this->cap_->export_expression(efb);
15552 : }
15553 : }
15554 :
15555 3549 : efb->set_type_context(old_context);
15556 :
15557 3549 : efb->write_c_string("]");
15558 3549 : }
15559 :
15560 : // Dump ast representation for an array index expression.
15561 :
15562 : void
15563 0 : Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
15564 : const
15565 : {
15566 0 : Index_expression::dump_index_expression(ast_dump_context, this->array_,
15567 0 : this->start_, this->end_, this->cap_);
15568 0 : }
15569 :
15570 : // Make an array index expression. END and CAP may be NULL.
15571 :
15572 : Expression*
15573 218694 : Expression::make_array_index(Expression* array, Expression* start,
15574 : Expression* end, Expression* cap,
15575 : Location location)
15576 : {
15577 218694 : return new Array_index_expression(array, start, end, cap, location);
15578 : }
15579 :
15580 : // Class String_index_expression.
15581 :
15582 : // String index traversal.
15583 :
15584 : int
15585 314914 : String_index_expression::do_traverse(Traverse* traverse)
15586 : {
15587 314914 : if (Expression::traverse(&this->string_, traverse) == TRAVERSE_EXIT)
15588 : return TRAVERSE_EXIT;
15589 314671 : if (Expression::traverse(&this->start_, traverse) == TRAVERSE_EXIT)
15590 : return TRAVERSE_EXIT;
15591 314622 : if (this->end_ != NULL)
15592 : {
15593 179740 : if (Expression::traverse(&this->end_, traverse) == TRAVERSE_EXIT)
15594 : return TRAVERSE_EXIT;
15595 : }
15596 : return TRAVERSE_CONTINUE;
15597 : }
15598 :
15599 : Expression*
15600 21435 : String_index_expression::do_flatten(Gogo* gogo, Named_object*,
15601 : Statement_inserter* inserter)
15602 : {
15603 21435 : if (this->is_flattened_)
15604 1203 : return this;
15605 20232 : this->is_flattened_ = true;
15606 :
15607 20232 : Location loc = this->location();
15608 :
15609 20232 : if (this->is_error_expression())
15610 0 : return Expression::make_error(loc);
15611 :
15612 20232 : Expression* string = this->string_;
15613 20232 : Expression* start = this->start_;
15614 20232 : Expression* end = this->end_;
15615 20232 : if (string->is_error_expression()
15616 20232 : || string->type()->is_error_type()
15617 20232 : || start->is_error_expression()
15618 20229 : || start->type()->is_error_type()
15619 40461 : || (end != NULL
15620 22840 : && (end->is_error_expression() || end->type()->is_error_type())))
15621 : {
15622 3 : go_assert(saw_errors());
15623 3 : return Expression::make_error(loc);
15624 : }
15625 :
15626 20229 : Temporary_statement* temp;
15627 20229 : if (!string->is_multi_eval_safe())
15628 : {
15629 3072 : temp = Statement::make_temporary(NULL, string, loc);
15630 3072 : inserter->insert(temp);
15631 3072 : this->string_ = Expression::make_temporary_reference(temp, loc);
15632 3072 : string = this->string_;
15633 : }
15634 20229 : if (!start->is_multi_eval_safe())
15635 : {
15636 4291 : temp = Statement::make_temporary(NULL, start, loc);
15637 4291 : inserter->insert(temp);
15638 4291 : this->start_ = Expression::make_temporary_reference(temp, loc);
15639 4291 : start = this->start_;
15640 : }
15641 20229 : if (end != NULL
15642 11420 : && !end->is_nil_expression()
15643 26163 : && !end->is_multi_eval_safe())
15644 : {
15645 1800 : temp = Statement::make_temporary(NULL, end, loc);
15646 1800 : inserter->insert(temp);
15647 1800 : this->end_ = Expression::make_temporary_reference(temp, loc);
15648 1800 : end = this->end_;
15649 : }
15650 :
15651 20229 : Expression* len = Expression::make_string_info(string->copy(),
15652 : STRING_INFO_LENGTH, loc);
15653 20229 : temp = Statement::make_temporary(NULL, len, loc);
15654 20229 : temp->determine_types(gogo);
15655 20229 : inserter->insert(temp);
15656 20229 : len = Expression::make_temporary_reference(temp, loc);
15657 :
15658 : // The order of bounds checks here matches the order used by the gc
15659 : // compiler, as tested by issue30116[u].go.
15660 :
15661 20229 : if (end != NULL && !end->is_nil_expression())
15662 : {
15663 5934 : Expression::check_bounds(gogo, end, OPERATOR_LE, len,
15664 : Runtime::PANIC_SLICE_ALEN,
15665 : Runtime::PANIC_SLICE_ALEN_U,
15666 : Runtime::PANIC_EXTEND_SLICE_ALEN,
15667 : Runtime::PANIC_EXTEND_SLICE_ALEN_U,
15668 : inserter, loc);
15669 5934 : Expression::check_bounds(gogo, start, OPERATOR_LE, end,
15670 : Runtime::PANIC_SLICE_B,
15671 : Runtime::PANIC_SLICE_B_U,
15672 : Runtime::PANIC_EXTEND_SLICE_B,
15673 : Runtime::PANIC_EXTEND_SLICE_B_U,
15674 : inserter, loc);
15675 : }
15676 14295 : else if (end != NULL)
15677 5486 : Expression::check_bounds(gogo, start, OPERATOR_LE, len,
15678 : Runtime::PANIC_SLICE_B,
15679 : Runtime::PANIC_SLICE_B_U,
15680 : Runtime::PANIC_EXTEND_SLICE_B,
15681 : Runtime::PANIC_EXTEND_SLICE_B_U,
15682 : inserter, loc);
15683 : else
15684 8809 : Expression::check_bounds(gogo, start, OPERATOR_LT, len,
15685 : Runtime::PANIC_INDEX,
15686 : Runtime::PANIC_INDEX_U,
15687 : Runtime::PANIC_EXTEND_INDEX,
15688 : Runtime::PANIC_EXTEND_INDEX_U,
15689 : inserter, loc);
15690 :
15691 20229 : return this;
15692 : }
15693 :
15694 : // Return the type of a string index.
15695 :
15696 : Type*
15697 256128 : String_index_expression::do_type()
15698 : {
15699 256128 : if (this->end_ == NULL)
15700 120127 : return Type::lookup_integer_type("byte");
15701 : else
15702 136001 : return this->string_->type();
15703 : }
15704 :
15705 : // Determine the type of a string index.
15706 :
15707 : void
15708 10575 : String_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
15709 : {
15710 10575 : this->string_->determine_type_no_context(gogo);
15711 :
15712 10575 : Type_context index_context(Type::lookup_integer_type("int"), false);
15713 10575 : this->start_->determine_type(gogo, &index_context);
15714 10575 : if (this->end_ != NULL)
15715 4547 : this->end_->determine_type(gogo, &index_context);
15716 10575 : }
15717 :
15718 : // Check types of a string index.
15719 :
15720 : void
15721 0 : String_index_expression::do_check_types(Gogo*)
15722 : {
15723 0 : if (!String_index_expression::check_indexes(this->string_, this->start_,
15724 : this->end_, this->location()))
15725 0 : this->set_is_error();
15726 0 : }
15727 :
15728 : // A static function to check string index types. This is also called
15729 : // by Index_expression::do_check_types. It reports whether type
15730 : // checking succeeded.
15731 :
15732 : bool
15733 17506 : String_index_expression::check_indexes(Expression* string, Expression* start,
15734 : Expression* end, Location loc)
15735 : {
15736 17506 : bool ret = true;
15737 :
15738 17506 : Numeric_constant nc;
15739 17506 : unsigned long v;
15740 17509 : if (start->type()->integer_type() == NULL
15741 3 : && !start->type()->is_error()
15742 3 : && (!start->type()->is_abstract()
15743 0 : || !start->numeric_constant_value(&nc)
15744 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15745 : {
15746 3 : go_error_at(loc, "index must be integer");
15747 3 : ret = false;
15748 : }
15749 :
15750 17506 : if (end != NULL
15751 14387 : && end->type()->integer_type() == NULL
15752 4709 : && !end->type()->is_error()
15753 4709 : && !end->is_nil_expression()
15754 0 : && !end->is_error_expression()
15755 17506 : && (!end->type()->is_abstract()
15756 0 : || !end->numeric_constant_value(&nc)
15757 0 : || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
15758 : {
15759 0 : go_error_at(loc, "slice end must be integer");
15760 0 : ret = false;
15761 : }
15762 :
15763 17506 : std::string sval;
15764 17506 : bool sval_valid = string->string_constant_value(&sval);
15765 :
15766 17506 : Numeric_constant inc;
15767 17506 : mpz_t ival;
15768 17506 : bool ival_valid = false;
15769 17506 : if (start->numeric_constant_value(&inc) && inc.to_int(&ival))
15770 : {
15771 9360 : ival_valid = true;
15772 9360 : if (mpz_sgn(ival) < 0
15773 9360 : || (sval_valid
15774 21 : && (end == NULL
15775 21 : ? mpz_cmp_ui(ival, sval.length()) >= 0
15776 811 : : mpz_cmp_ui(ival, sval.length()) > 0)))
15777 : {
15778 7 : go_error_at(start->location(), "string index out of bounds");
15779 7 : ret = false;
15780 : }
15781 : }
15782 :
15783 17506 : if (end != NULL && !end->is_nil_expression())
15784 : {
15785 4969 : Numeric_constant enc;
15786 4969 : mpz_t eval;
15787 4969 : if (end->numeric_constant_value(&enc) && enc.to_int(&eval))
15788 : {
15789 1334 : if (mpz_sgn(eval) < 0
15790 2107 : || (sval_valid && mpz_cmp_ui(eval, sval.length()) > 0))
15791 : {
15792 5 : go_error_at(end->location(), "string index out of bounds");
15793 5 : ret = false;
15794 : }
15795 1329 : else if (ival_valid && mpz_cmp(ival, eval) > 0)
15796 : {
15797 2 : go_error_at(loc, "inverted slice range");
15798 2 : ret = false;
15799 : }
15800 1334 : mpz_clear(eval);
15801 : }
15802 4969 : }
15803 17506 : if (ival_valid)
15804 9360 : mpz_clear(ival);
15805 :
15806 35012 : return ret;
15807 17506 : }
15808 :
15809 : // Get the backend representation for a string index.
15810 :
15811 : Bexpression*
15812 20228 : String_index_expression::do_get_backend(Translate_context* context)
15813 : {
15814 20228 : Location loc = this->location();
15815 20228 : Gogo* gogo = context->gogo();
15816 :
15817 20228 : Type* int_type = Type::lookup_integer_type("int");
15818 :
15819 : // It is possible that an error occurred earlier because the start index
15820 : // cannot be represented as an integer type. In this case, we shouldn't
15821 : // try casting the starting index into an integer since
15822 : // Type_conversion_expression will fail to get the backend representation.
15823 : // FIXME.
15824 20228 : if (this->start_->type()->integer_type() == NULL
15825 0 : && !Type::are_convertible(int_type, this->start_->type(), NULL))
15826 : {
15827 0 : go_assert(saw_errors());
15828 0 : return context->backend()->error_expression();
15829 : }
15830 :
15831 20228 : go_assert(this->string_->is_multi_eval_safe());
15832 20228 : go_assert(this->start_->is_multi_eval_safe());
15833 :
15834 20228 : Expression* start = Expression::make_cast(int_type, this->start_, loc);
15835 20228 : Bfunction* bfn = context->function()->func_value()->get_decl();
15836 :
15837 20228 : Expression* length =
15838 20228 : Expression::make_string_info(this->string_, STRING_INFO_LENGTH, loc);
15839 20228 : Expression* bytes =
15840 20228 : Expression::make_string_info(this->string_, STRING_INFO_DATA, loc);
15841 :
15842 20228 : Bexpression* bstart = start->get_backend(context);
15843 20228 : Bexpression* ptr = bytes->get_backend(context);
15844 :
15845 20228 : if (this->end_ == NULL)
15846 : {
15847 8808 : ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc);
15848 8808 : Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
15849 8808 : return gogo->backend()->indirect_expression(ubtype, ptr, false, loc);
15850 : }
15851 :
15852 11420 : Expression* end = NULL;
15853 11420 : if (this->end_->is_nil_expression())
15854 : end = length;
15855 : else
15856 : {
15857 5934 : go_assert(this->end_->is_multi_eval_safe());
15858 5934 : end = Expression::make_cast(int_type, this->end_, loc);
15859 : }
15860 :
15861 11420 : end = end->copy();
15862 11420 : Bexpression* bend = end->get_backend(context);
15863 11420 : Bexpression* new_length =
15864 11420 : gogo->backend()->binary_expression(OPERATOR_MINUS, bend, bstart, loc);
15865 :
15866 : // If the new length is zero, don't change pointer. Otherwise we can
15867 : // get a pointer to the next object in memory, keeping it live
15868 : // unnecessarily. When the length is zero, the actual pointer
15869 : // value doesn't matter.
15870 11420 : Btype* int_btype = int_type->get_backend(gogo);
15871 11420 : Bexpression* zero =
15872 11420 : Expression::make_integer_ul(0, int_type, loc)->get_backend(context);
15873 11420 : Bexpression* cond =
15874 11420 : gogo->backend()->binary_expression(OPERATOR_EQEQ, new_length, zero,
15875 : loc);
15876 11420 : Bexpression* offset =
15877 11420 : gogo->backend()->conditional_expression(bfn, int_btype, cond, zero,
15878 : bstart, loc);
15879 :
15880 11420 : ptr = gogo->backend()->pointer_offset_expression(ptr, offset, loc);
15881 :
15882 11420 : Btype* str_btype = this->type()->get_backend(gogo);
15883 11420 : std::vector<Bexpression*> init;
15884 11420 : init.push_back(ptr);
15885 11420 : init.push_back(new_length);
15886 11420 : return gogo->backend()->constructor_expression(str_btype, init, loc);
15887 11420 : }
15888 :
15889 : // Export a string index expression.
15890 :
15891 : void
15892 944 : String_index_expression::do_export(Export_function_body* efb) const
15893 : {
15894 944 : efb->write_c_string("(");
15895 944 : this->string_->export_expression(efb);
15896 944 : efb->write_c_string(")[");
15897 :
15898 944 : Type* old_context = efb->type_context();
15899 944 : efb->set_type_context(Type::lookup_integer_type("int"));
15900 :
15901 944 : this->start_->export_expression(efb);
15902 944 : if (this->end_ != NULL)
15903 : {
15904 550 : efb->write_c_string(":");
15905 550 : if (!this->end_->is_nil_expression())
15906 340 : this->end_->export_expression(efb);
15907 : }
15908 :
15909 944 : efb->set_type_context(old_context);
15910 :
15911 944 : efb->write_c_string("]");
15912 944 : }
15913 :
15914 : // Dump ast representation for a string index expression.
15915 :
15916 : void
15917 0 : String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
15918 : const
15919 : {
15920 0 : Index_expression::dump_index_expression(ast_dump_context, this->string_,
15921 0 : this->start_, this->end_, NULL);
15922 0 : }
15923 :
15924 : // Make a string index expression. END may be NULL.
15925 :
15926 : Expression*
15927 20293 : Expression::make_string_index(Expression* string, Expression* start,
15928 : Expression* end, Location location)
15929 : {
15930 20293 : return new String_index_expression(string, start, end, location);
15931 : }
15932 :
15933 : // Class Map_index.
15934 :
15935 : // Get the type of the map.
15936 :
15937 : Map_type*
15938 107930 : Map_index_expression::get_map_type() const
15939 : {
15940 107930 : Map_type* mt = this->map_->type()->map_type();
15941 0 : if (mt == NULL)
15942 0 : go_assert(saw_errors());
15943 107930 : return mt;
15944 : }
15945 :
15946 : // Map index traversal.
15947 :
15948 : int
15949 115905 : Map_index_expression::do_traverse(Traverse* traverse)
15950 : {
15951 115905 : if (Expression::traverse(&this->map_, traverse) == TRAVERSE_EXIT)
15952 : return TRAVERSE_EXIT;
15953 105985 : return Expression::traverse(&this->index_, traverse);
15954 : }
15955 :
15956 : void
15957 2555 : Map_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
15958 : {
15959 2555 : this->map_->determine_type_no_context(gogo);
15960 2555 : Map_type* mt = this->map_->type()->map_type();
15961 0 : go_assert(mt != NULL);
15962 2555 : Type_context index_context(mt->key_type(), false);
15963 2555 : this->index_->determine_type(gogo, &index_context);
15964 2555 : if (this->value_pointer_ != NULL)
15965 686 : this->value_pointer_->determine_type_no_context(gogo);
15966 2555 : }
15967 :
15968 : void
15969 15 : Map_index_expression::do_check_types(Gogo*)
15970 : {
15971 : // Types should have been checked before this was created, so this
15972 : // will probably never be called. Check it anyhow to be sure.
15973 15 : Map_type* mt = this->map_->type()->map_type();
15974 0 : go_assert(mt != NULL);
15975 15 : if (!Type::are_assignable(mt->key_type(), this->index_->type(), NULL))
15976 0 : this->report_error(_("incompatible type for map index"));
15977 15 : }
15978 :
15979 : // We need to pass in a pointer to the key, so flatten the index into a
15980 : // temporary variable if it isn't already. The value pointer will be
15981 : // dereferenced and checked for nil, so flatten into a temporary to avoid
15982 : // recomputation.
15983 :
15984 : Expression*
15985 6260 : Map_index_expression::do_flatten(Gogo* gogo, Named_object*,
15986 : Statement_inserter* inserter)
15987 : {
15988 6260 : Location loc = this->location();
15989 6260 : Map_type* mt = this->get_map_type();
15990 6260 : if (this->index()->is_error_expression()
15991 6260 : || this->index()->type()->is_error_type()
15992 12520 : || mt->is_error_type())
15993 : {
15994 0 : go_assert(saw_errors());
15995 0 : return Expression::make_error(loc);
15996 : }
15997 :
15998 : // Avoid copy for string([]byte) conversions used in map keys.
15999 : // mapaccess doesn't keep the reference, so this is safe.
16000 6260 : Type_conversion_expression* ce = this->index_->conversion_expression();
16001 209 : if (ce != NULL && ce->type()->is_string_type()
16002 68 : && ce->expr()->type()->is_slice_type())
16003 52 : ce->set_no_copy(true);
16004 :
16005 6260 : if (!Type::are_identical(mt->key_type(), this->index_->type(),
16006 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
16007 : NULL))
16008 : {
16009 6 : if (this->index_->type()->interface_type() != NULL
16010 0 : && !this->index_->is_multi_eval_safe())
16011 : {
16012 0 : Temporary_statement* temp =
16013 0 : Statement::make_temporary(NULL, this->index_, loc);
16014 0 : inserter->insert(temp);
16015 0 : this->index_ = Expression::make_temporary_reference(temp, loc);
16016 : }
16017 6 : this->index_ = Expression::convert_for_assignment(gogo, mt->key_type(),
16018 : this->index_, loc);
16019 : }
16020 :
16021 6260 : if (!this->index_->is_multi_eval_safe())
16022 : {
16023 2178 : Temporary_statement* temp = Statement::make_temporary(NULL, this->index_,
16024 : loc);
16025 2178 : inserter->insert(temp);
16026 2178 : this->index_ = Expression::make_temporary_reference(temp, loc);
16027 : }
16028 :
16029 6260 : if (this->value_pointer_ == NULL)
16030 5862 : this->get_value_pointer(gogo);
16031 6260 : if (this->value_pointer_->is_error_expression()
16032 6260 : || this->value_pointer_->type()->is_error_type())
16033 0 : return Expression::make_error(loc);
16034 6260 : if (!this->value_pointer_->is_multi_eval_safe())
16035 : {
16036 5862 : Temporary_statement* temp =
16037 5862 : Statement::make_temporary(NULL, this->value_pointer_, loc);
16038 5862 : inserter->insert(temp);
16039 5862 : this->value_pointer_ = Expression::make_temporary_reference(temp, loc);
16040 : }
16041 :
16042 6260 : return this;
16043 : }
16044 :
16045 : // Return the type of a map index.
16046 :
16047 : Type*
16048 81619 : Map_index_expression::do_type()
16049 : {
16050 81619 : Map_type* mt = this->get_map_type();
16051 81619 : if (mt == NULL)
16052 0 : return Type::make_error_type();
16053 81619 : return mt->val_type();
16054 : }
16055 :
16056 : // Add explicit type conversions.
16057 :
16058 : void
16059 5862 : Map_index_expression::do_add_conversions()
16060 : {
16061 5862 : Map_type* mt = this->get_map_type();
16062 5862 : if (mt == NULL)
16063 : return;
16064 5862 : Type* lt = mt->key_type();
16065 5862 : Type* rt = this->index_->type();
16066 5862 : if (!Type::are_identical(lt, rt, 0, NULL)
16067 5862 : && lt->interface_type() != NULL)
16068 123 : this->index_ = Expression::make_cast(lt, this->index_, this->location());
16069 : }
16070 :
16071 : // Get the backend representation for a map index.
16072 :
16073 : Bexpression*
16074 5866 : Map_index_expression::do_get_backend(Translate_context* context)
16075 : {
16076 5866 : Map_type* type = this->get_map_type();
16077 5866 : if (type == NULL)
16078 : {
16079 0 : go_assert(saw_errors());
16080 0 : return context->backend()->error_expression();
16081 : }
16082 :
16083 5866 : go_assert(this->value_pointer_ != NULL
16084 : && this->value_pointer_->is_multi_eval_safe());
16085 :
16086 5866 : Expression* val = Expression::make_dereference(this->value_pointer_,
16087 : NIL_CHECK_NOT_NEEDED,
16088 : this->location());
16089 5866 : return val->get_backend(context);
16090 : }
16091 :
16092 : // Get an expression for the map index. This returns an expression
16093 : // that evaluates to a pointer to a value. If the key is not in the
16094 : // map, the pointer will point to a zero value.
16095 :
16096 : Expression*
16097 5862 : Map_index_expression::get_value_pointer(Gogo* gogo)
16098 : {
16099 5862 : if (this->value_pointer_ == NULL)
16100 : {
16101 5862 : Map_type* type = this->get_map_type();
16102 5862 : if (type == NULL)
16103 : {
16104 0 : go_assert(saw_errors());
16105 0 : return Expression::make_error(this->location());
16106 : }
16107 :
16108 5862 : Location loc = this->location();
16109 5862 : Expression* map_ref = this->map_;
16110 :
16111 5862 : Expression* index_ptr = Expression::make_unary(OPERATOR_AND,
16112 : this->index_,
16113 : loc);
16114 :
16115 5862 : Expression* type_expr = Expression::make_type_descriptor(type, loc);
16116 5862 : Expression* zero = type->fat_zero_value(gogo);
16117 5862 : Expression* map_index;
16118 5862 : if (zero == NULL)
16119 : {
16120 5859 : Runtime::Function code;
16121 5859 : Expression* key;
16122 5859 : switch (type->algorithm(gogo))
16123 : {
16124 614 : case Map_type::MAP_ALG_FAST32:
16125 614 : case Map_type::MAP_ALG_FAST32PTR:
16126 614 : {
16127 614 : Type* uint32_type = Type::lookup_integer_type("uint32");
16128 614 : Type* uint32_ptr_type = Type::make_pointer_type(uint32_type);
16129 614 : key = Expression::make_unsafe_cast(uint32_ptr_type, index_ptr,
16130 : loc);
16131 614 : key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
16132 : loc);
16133 614 : code = Runtime::MAPACCESS1_FAST32;
16134 614 : break;
16135 : }
16136 1169 : case Map_type::MAP_ALG_FAST64:
16137 1169 : case Map_type::MAP_ALG_FAST64PTR:
16138 1169 : {
16139 1169 : Type* uint64_type = Type::lookup_integer_type("uint64");
16140 1169 : Type* uint64_ptr_type = Type::make_pointer_type(uint64_type);
16141 1169 : key = Expression::make_unsafe_cast(uint64_ptr_type, index_ptr,
16142 : loc);
16143 1169 : key = Expression::make_dereference(key, NIL_CHECK_NOT_NEEDED,
16144 : loc);
16145 1169 : code = Runtime::MAPACCESS1_FAST64;
16146 1169 : break;
16147 : }
16148 2897 : case Map_type::MAP_ALG_FASTSTR:
16149 2897 : key = this->index_;
16150 2897 : code = Runtime::MAPACCESS1_FASTSTR;
16151 2897 : break;
16152 : default:
16153 : key = index_ptr;
16154 : code = Runtime::MAPACCESS1;
16155 : break;
16156 : }
16157 5859 : map_index = Runtime::make_call(gogo, code, loc, 3,
16158 : type_expr, map_ref, key);
16159 : }
16160 : else
16161 3 : map_index = Runtime::make_call(gogo, Runtime::MAPACCESS1_FAT, loc, 4,
16162 : type_expr, map_ref, index_ptr, zero);
16163 :
16164 5862 : Type* val_type = type->val_type();
16165 11724 : this->value_pointer_ =
16166 5862 : Expression::make_unsafe_cast(Type::make_pointer_type(val_type),
16167 : map_index, this->location());
16168 5862 : this->value_pointer_->determine_type_no_context(gogo);
16169 : }
16170 :
16171 5862 : return this->value_pointer_;
16172 : }
16173 :
16174 : // Export a map index expression.
16175 :
16176 : void
16177 96 : Map_index_expression::do_export(Export_function_body* efb) const
16178 : {
16179 96 : efb->write_c_string("(");
16180 96 : this->map_->export_expression(efb);
16181 96 : efb->write_c_string(")[");
16182 :
16183 96 : Type* old_context = efb->type_context();
16184 96 : efb->set_type_context(this->get_map_type()->key_type());
16185 :
16186 96 : this->index_->export_expression(efb);
16187 :
16188 96 : efb->set_type_context(old_context);
16189 :
16190 96 : efb->write_c_string("]");
16191 96 : }
16192 :
16193 : // Dump ast representation for a map index expression
16194 :
16195 : void
16196 0 : Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
16197 : const
16198 : {
16199 0 : Index_expression::dump_index_expression(ast_dump_context, this->map_,
16200 0 : this->index_, NULL, NULL);
16201 0 : }
16202 :
16203 : // Make a map index expression.
16204 :
16205 : Map_index_expression*
16206 14200 : Expression::make_map_index(Expression* map, Expression* index,
16207 : Location location)
16208 : {
16209 14200 : return new Map_index_expression(map, index, location);
16210 : }
16211 :
16212 : // Class Field_reference_expression.
16213 :
16214 : // Lower a field reference expression. There is nothing to lower, but
16215 : // this is where we generate the tracking information for fields with
16216 : // the magic go:"track" tag.
16217 :
16218 : Expression*
16219 1328845 : Field_reference_expression::do_lower(Gogo* gogo, Named_object* function,
16220 : Statement_inserter* inserter)
16221 : {
16222 1328845 : Struct_type* struct_type = this->expr_->type()->struct_type();
16223 1328845 : if (struct_type == NULL)
16224 : {
16225 : // Error will be reported elsewhere.
16226 2 : return this;
16227 : }
16228 1328843 : const Struct_field* field = struct_type->field(this->field_index_);
16229 1328843 : if (field == NULL)
16230 0 : return this;
16231 1328843 : if (!field->has_tag())
16232 1309887 : return this;
16233 18956 : if (field->tag().find("go:\"track\"") == std::string::npos)
16234 18956 : return this;
16235 :
16236 : // References from functions generated by the compiler don't count.
16237 0 : if (function != NULL && function->func_value()->is_type_specific_function())
16238 0 : return this;
16239 :
16240 : // We have found a reference to a tracked field. Build a call to
16241 : // the runtime function __go_fieldtrack with a string that describes
16242 : // the field. FIXME: We should only call this once per referenced
16243 : // field per function, not once for each reference to the field.
16244 :
16245 0 : if (this->called_fieldtrack_)
16246 0 : return this;
16247 0 : this->called_fieldtrack_ = true;
16248 :
16249 0 : Location loc = this->location();
16250 :
16251 0 : std::string s = "fieldtrack \"";
16252 0 : Named_type* nt = this->expr_->type()->unalias()->named_type();
16253 0 : if (nt == NULL || nt->named_object()->package() == NULL)
16254 0 : s.append(gogo->pkgpath());
16255 : else
16256 0 : s.append(nt->named_object()->package()->pkgpath());
16257 0 : s.push_back('.');
16258 0 : if (nt != NULL)
16259 0 : s.append(Gogo::unpack_hidden_name(nt->name()));
16260 0 : s.push_back('.');
16261 0 : s.append(Gogo::unpack_hidden_name(field->field_name()));
16262 0 : s.push_back('"');
16263 :
16264 : // We can't use a string here, because internally a string holds a
16265 : // pointer to the actual bytes; when the linker garbage collects the
16266 : // string, it won't garbage collect the bytes. So we use a
16267 : // [...]byte.
16268 :
16269 0 : Expression* length_expr = Expression::make_integer_ul(s.length(), NULL, loc);
16270 :
16271 0 : Type* byte_type = Type::lookup_integer_type("byte");
16272 0 : Array_type* array_type = Type::make_array_type(byte_type, length_expr);
16273 0 : array_type->set_is_array_incomparable();
16274 :
16275 0 : Expression_list* bytes = new Expression_list();
16276 0 : for (std::string::const_iterator p = s.begin(); p != s.end(); p++)
16277 : {
16278 0 : unsigned char c = static_cast<unsigned char>(*p);
16279 0 : bytes->push_back(Expression::make_integer_ul(c, NULL, loc));
16280 : }
16281 :
16282 0 : Expression* e = Expression::make_composite_literal(array_type, 0, false,
16283 : bytes, false, loc);
16284 :
16285 0 : Variable* var = new Variable(array_type, e, true, false, false, loc);
16286 :
16287 0 : static int count;
16288 0 : char buf[50];
16289 0 : snprintf(buf, sizeof buf, "fieldtrack.%d", count);
16290 0 : ++count;
16291 :
16292 0 : Named_object* no = gogo->add_variable(buf, var);
16293 0 : e = Expression::make_var_reference(no, loc);
16294 0 : e = Expression::make_unary(OPERATOR_AND, e, loc);
16295 :
16296 0 : Expression* call = Runtime::make_call(gogo, Runtime::FIELDTRACK, loc, 1, e);
16297 0 : call->determine_type_no_context(gogo);
16298 0 : gogo->lower_expression(function, inserter, &call);
16299 0 : inserter->insert(Statement::make_statement(call, false));
16300 :
16301 : // Put this function, and the global variable we just created, into
16302 : // unique sections. This will permit the linker to garbage collect
16303 : // them if they are not referenced. The effect is that the only
16304 : // strings, indicating field references, that will wind up in the
16305 : // executable will be those for functions that are actually needed.
16306 0 : if (function != NULL)
16307 0 : function->func_value()->set_in_unique_section();
16308 0 : var->set_in_unique_section();
16309 :
16310 0 : return this;
16311 0 : }
16312 :
16313 : // Return the type of a field reference.
16314 :
16315 : Type*
16316 12705023 : Field_reference_expression::do_type()
16317 : {
16318 12705023 : Type* type = this->expr_->type();
16319 12705023 : if (type->is_error())
16320 : return type;
16321 12705003 : Struct_type* struct_type = type->struct_type();
16322 0 : go_assert(struct_type != NULL);
16323 12705003 : return struct_type->field(this->field_index_)->type();
16324 : }
16325 :
16326 : // Check the types for a field reference.
16327 :
16328 : void
16329 43952 : Field_reference_expression::do_check_types(Gogo*)
16330 : {
16331 43952 : Type* type = this->expr_->type();
16332 43952 : if (type->is_error())
16333 : return;
16334 43951 : Struct_type* struct_type = type->struct_type();
16335 0 : go_assert(struct_type != NULL);
16336 43951 : go_assert(struct_type->field(this->field_index_) != NULL);
16337 : }
16338 :
16339 : // Get the backend representation for a field reference.
16340 :
16341 : Bexpression*
16342 981990 : Field_reference_expression::do_get_backend(Translate_context* context)
16343 : {
16344 981990 : Bexpression* bstruct = this->expr_->get_backend(context);
16345 981990 : return context->gogo()->backend()->struct_field_expression(bstruct,
16346 981990 : this->field_index_,
16347 981990 : this->location());
16348 : }
16349 :
16350 : // Dump ast representation for a field reference expression.
16351 :
16352 : void
16353 0 : Field_reference_expression::do_dump_expression(
16354 : Ast_dump_context* ast_dump_context) const
16355 : {
16356 0 : this->expr_->dump_expression(ast_dump_context);
16357 0 : ast_dump_context->ostream() << "." << this->field_index_;
16358 0 : }
16359 :
16360 : // Make a reference to a qualified identifier in an expression.
16361 :
16362 : Field_reference_expression*
16363 987040 : Expression::make_field_reference(Expression* expr, unsigned int field_index,
16364 : Location location)
16365 : {
16366 987040 : return new Field_reference_expression(expr, field_index, location);
16367 : }
16368 :
16369 : // Class Interface_field_reference_expression.
16370 :
16371 : // Return an expression for the pointer to the function to call.
16372 :
16373 : Expression*
16374 31774 : Interface_field_reference_expression::get_function()
16375 : {
16376 31774 : Expression* ref = this->expr_;
16377 31774 : Location loc = this->location();
16378 31774 : if (ref->type()->points_to() != NULL)
16379 1160 : ref = Expression::make_dereference(ref, NIL_CHECK_DEFAULT, loc);
16380 :
16381 31774 : Expression* mtable =
16382 31774 : Expression::make_interface_info(ref, INTERFACE_INFO_METHODS, loc);
16383 31774 : Struct_type* mtable_type = mtable->type()->points_to()->struct_type();
16384 :
16385 31774 : std::string name = Gogo::unpack_hidden_name(this->name_);
16386 31774 : unsigned int index;
16387 31774 : const Struct_field* field = mtable_type->find_local_field(name, &index);
16388 31774 : go_assert(field != NULL);
16389 :
16390 31774 : mtable = Expression::make_dereference(mtable, NIL_CHECK_NOT_NEEDED, loc);
16391 31774 : return Expression::make_field_reference(mtable, index, loc);
16392 31774 : }
16393 :
16394 : // Return an expression for the first argument to pass to the interface
16395 : // function.
16396 :
16397 : Expression*
16398 31774 : Interface_field_reference_expression::get_underlying_object()
16399 : {
16400 31774 : Expression* expr = this->expr_;
16401 31774 : if (expr->type()->points_to() != NULL)
16402 1160 : expr = Expression::make_dereference(expr, NIL_CHECK_DEFAULT,
16403 : this->location());
16404 31774 : return Expression::make_interface_info(expr, INTERFACE_INFO_OBJECT,
16405 31774 : this->location());
16406 : }
16407 :
16408 : // Traversal.
16409 :
16410 : int
16411 495980 : Interface_field_reference_expression::do_traverse(Traverse* traverse)
16412 : {
16413 495980 : return Expression::traverse(&this->expr_, traverse);
16414 : }
16415 :
16416 : // Lower the expression. If this expression is not called, we need to
16417 : // evaluate the expression twice when converting to the backend
16418 : // interface. So introduce a temporary variable if necessary.
16419 :
16420 : Expression*
16421 39774 : Interface_field_reference_expression::do_flatten(Gogo*, Named_object*,
16422 : Statement_inserter* inserter)
16423 : {
16424 39774 : if (this->expr_->is_error_expression()
16425 39774 : || this->expr_->type()->is_error_type())
16426 : {
16427 1 : go_assert(saw_errors());
16428 1 : return Expression::make_error(this->location());
16429 : }
16430 :
16431 39773 : if (!this->expr_->is_multi_eval_safe())
16432 : {
16433 10225 : Temporary_statement* temp =
16434 10225 : Statement::make_temporary(NULL, this->expr_, this->location());
16435 10225 : inserter->insert(temp);
16436 10225 : this->expr_ = Expression::make_temporary_reference(temp, this->location());
16437 : }
16438 39773 : return this;
16439 : }
16440 :
16441 : // Return the type of an interface field reference.
16442 :
16443 : Type*
16444 1455651 : Interface_field_reference_expression::do_type()
16445 : {
16446 1455651 : Type* expr_type = this->expr_->type();
16447 :
16448 1455651 : Type* points_to = expr_type->points_to();
16449 1455651 : if (points_to != NULL)
16450 66180 : expr_type = points_to;
16451 :
16452 1455651 : Interface_type* interface_type = expr_type->interface_type();
16453 1455651 : if (interface_type == NULL)
16454 16 : return Type::make_error_type();
16455 :
16456 1455635 : const Typed_identifier* method = interface_type->find_method(this->name_);
16457 1455635 : if (method == NULL)
16458 0 : return Type::make_error_type();
16459 :
16460 1455635 : return method->type();
16461 : }
16462 :
16463 : // Determine types.
16464 :
16465 : void
16466 33019 : Interface_field_reference_expression::do_determine_type(Gogo* gogo,
16467 : const Type_context*)
16468 : {
16469 33019 : this->expr_->determine_type_no_context(gogo);
16470 33019 : }
16471 :
16472 : // Check the types for an interface field reference.
16473 :
16474 : void
16475 1292 : Interface_field_reference_expression::do_check_types(Gogo*)
16476 : {
16477 1292 : Type* type = this->expr_->type();
16478 :
16479 1292 : Type* points_to = type->points_to();
16480 1292 : if (points_to != NULL)
16481 1160 : type = points_to;
16482 :
16483 1292 : Interface_type* interface_type = type->interface_type();
16484 1292 : if (interface_type == NULL)
16485 : {
16486 1 : if (!type->is_error_type())
16487 0 : this->report_error(_("expected interface or pointer to interface"));
16488 : }
16489 : else
16490 : {
16491 1291 : const Typed_identifier* method =
16492 1291 : interface_type->find_method(this->name_);
16493 1291 : if (method == NULL)
16494 : {
16495 0 : go_error_at(this->location(), "method %qs not in interface",
16496 0 : Gogo::message_name(this->name_).c_str());
16497 0 : this->set_is_error();
16498 : }
16499 : }
16500 1292 : }
16501 :
16502 : // If an interface field reference is not simply called, then it is
16503 : // represented as a closure. The closure will hold a single variable,
16504 : // the value of the interface on which the method should be called.
16505 : // The function will be a simple thunk that pulls the value from the
16506 : // closure and calls the method with the remaining arguments.
16507 :
16508 : // Because method values are not common, we don't build all thunks for
16509 : // all possible interface methods, but instead only build them as we
16510 : // need them. In particular, we even build them on demand for
16511 : // interface methods defined in other packages.
16512 :
16513 : Interface_field_reference_expression::Interface_method_thunks
16514 : Interface_field_reference_expression::interface_method_thunks;
16515 :
16516 : // Find or create the thunk to call method NAME on TYPE.
16517 :
16518 : Named_object*
16519 105 : Interface_field_reference_expression::create_thunk(Gogo* gogo,
16520 : Interface_type* type,
16521 : const std::string& name)
16522 : {
16523 105 : std::pair<Interface_type*, Method_thunks*> val(type, NULL);
16524 105 : std::pair<Interface_method_thunks::iterator, bool> ins =
16525 105 : Interface_field_reference_expression::interface_method_thunks.insert(val);
16526 105 : if (ins.second)
16527 : {
16528 : // This is the first time we have seen this interface.
16529 52 : ins.first->second = new Method_thunks();
16530 : }
16531 :
16532 114 : for (Method_thunks::const_iterator p = ins.first->second->begin();
16533 114 : p != ins.first->second->end();
16534 9 : p++)
16535 53 : if (p->first == name)
16536 44 : return p->second;
16537 :
16538 61 : Location loc = type->location();
16539 :
16540 61 : const Typed_identifier* method_id = type->find_method(name);
16541 61 : if (method_id == NULL)
16542 0 : return Named_object::make_erroneous_name(gogo->thunk_name());
16543 :
16544 61 : Function_type* orig_fntype = method_id->type()->function_type();
16545 61 : if (orig_fntype == NULL)
16546 0 : return Named_object::make_erroneous_name(gogo->thunk_name());
16547 :
16548 61 : Struct_field_list* sfl = new Struct_field_list();
16549 : // The type here is wrong--it should be the C function type. But it
16550 : // doesn't really matter.
16551 61 : Type* vt = Type::make_pointer_type(Type::make_void_type());
16552 122 : sfl->push_back(Struct_field(Typed_identifier("fn", vt, loc)));
16553 122 : sfl->push_back(Struct_field(Typed_identifier("val", type, loc)));
16554 61 : Struct_type* st = Type::make_struct_type(sfl, loc);
16555 61 : st->set_is_struct_incomparable();
16556 61 : Type* closure_type = Type::make_pointer_type(st);
16557 :
16558 61 : Function_type* new_fntype = orig_fntype->copy_with_names();
16559 :
16560 61 : std::string thunk_name = gogo->thunk_name();
16561 61 : Named_object* new_no = gogo->start_function(thunk_name, new_fntype,
16562 61 : false, loc);
16563 :
16564 61 : Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
16565 61 : cvar->set_is_used();
16566 61 : cvar->set_is_closure();
16567 61 : Named_object* cp = Named_object::make_variable("$closure" + thunk_name,
16568 : NULL, cvar);
16569 61 : new_no->func_value()->set_closure_var(cp);
16570 :
16571 61 : gogo->start_block(loc);
16572 :
16573 : // Field 0 of the closure is the function code pointer, field 1 is
16574 : // the value on which to invoke the method.
16575 61 : Expression* arg = Expression::make_var_reference(cp, loc);
16576 61 : arg = Expression::make_dereference(arg, NIL_CHECK_NOT_NEEDED, loc);
16577 61 : arg = Expression::make_field_reference(arg, 1, loc);
16578 :
16579 61 : Expression *ifre = Expression::make_interface_field_reference(arg, name,
16580 : loc);
16581 :
16582 61 : const Typed_identifier_list* orig_params = orig_fntype->parameters();
16583 61 : Expression_list* args;
16584 61 : if (orig_params == NULL || orig_params->empty())
16585 : args = NULL;
16586 : else
16587 : {
16588 38 : const Typed_identifier_list* new_params = new_fntype->parameters();
16589 38 : args = new Expression_list();
16590 38 : for (Typed_identifier_list::const_iterator p = new_params->begin();
16591 92 : p != new_params->end();
16592 54 : ++p)
16593 : {
16594 54 : Named_object* p_no = gogo->lookup(p->name(), NULL);
16595 54 : go_assert(p_no != NULL
16596 : && p_no->is_variable()
16597 : && p_no->var_value()->is_parameter());
16598 54 : args->push_back(Expression::make_var_reference(p_no, loc));
16599 : }
16600 : }
16601 :
16602 61 : Call_expression* call = Expression::make_call(ifre, args,
16603 61 : orig_fntype->is_varargs(),
16604 : loc);
16605 61 : call->set_varargs_are_lowered();
16606 :
16607 61 : Statement* s = Statement::make_return_from_call(new_no, call, loc);
16608 61 : s->determine_types(gogo);
16609 61 : gogo->add_statement(s);
16610 61 : Block* b = gogo->finish_block(loc);
16611 61 : gogo->add_block(b, loc);
16612 :
16613 : // This is called after lowering.
16614 61 : gogo->lower_block(new_no, b);
16615 :
16616 61 : gogo->finish_function(loc);
16617 :
16618 122 : ins.first->second->push_back(std::make_pair(name, new_no));
16619 61 : return new_no;
16620 61 : }
16621 :
16622 : // Lookup a thunk to call method NAME on TYPE.
16623 :
16624 : Named_object*
16625 105 : Interface_field_reference_expression::lookup_thunk(Interface_type* type,
16626 : const std::string& name)
16627 : {
16628 105 : Interface_method_thunks::const_iterator p =
16629 105 : Interface_field_reference_expression::interface_method_thunks.find(type);
16630 105 : if (p == Interface_field_reference_expression::interface_method_thunks.end())
16631 : return NULL;
16632 114 : for (Method_thunks::const_iterator pm = p->second->begin();
16633 114 : pm != p->second->end();
16634 9 : ++pm)
16635 114 : if (pm->first == name)
16636 105 : return pm->second;
16637 : return NULL;
16638 : }
16639 :
16640 : // Get the backend representation for a method value.
16641 :
16642 : Bexpression*
16643 105 : Interface_field_reference_expression::do_get_backend(Translate_context* context)
16644 : {
16645 105 : Interface_type* type = this->expr_->type()->interface_type();
16646 105 : if (type == NULL)
16647 : {
16648 0 : go_assert(saw_errors());
16649 0 : return context->backend()->error_expression();
16650 : }
16651 :
16652 105 : Named_object* thunk =
16653 105 : Interface_field_reference_expression::lookup_thunk(type, this->name_);
16654 :
16655 : // The thunk should have been created during the
16656 : // create_function_descriptors pass.
16657 105 : if (thunk == NULL || thunk->is_erroneous())
16658 : {
16659 0 : go_assert(saw_errors());
16660 0 : return context->backend()->error_expression();
16661 : }
16662 :
16663 : // FIXME: We should lower this earlier, but we can't it lower it in
16664 : // the lowering pass because at that point we don't know whether we
16665 : // need to create the thunk or not. If the expression is called, we
16666 : // don't need the thunk.
16667 :
16668 105 : Location loc = this->location();
16669 :
16670 105 : Struct_field_list* fields = new Struct_field_list();
16671 210 : fields->push_back(Struct_field(Typed_identifier("fn",
16672 105 : thunk->func_value()->type(),
16673 105 : loc)));
16674 210 : fields->push_back(Struct_field(Typed_identifier("val",
16675 105 : this->expr_->type(),
16676 210 : loc)));
16677 105 : Struct_type* st = Type::make_struct_type(fields, loc);
16678 105 : st->set_is_struct_incomparable();
16679 :
16680 105 : Expression_list* vals = new Expression_list();
16681 105 : vals->push_back(Expression::make_func_code_reference(thunk, loc));
16682 105 : vals->push_back(this->expr_);
16683 :
16684 105 : Expression* expr = Expression::make_struct_composite_literal(st, vals, loc);
16685 105 : Bexpression* bclosure =
16686 105 : Expression::make_heap_expression(expr, loc)->get_backend(context);
16687 :
16688 105 : Gogo* gogo = context->gogo();
16689 105 : Btype* btype = this->type()->get_backend(gogo);
16690 105 : bclosure = gogo->backend()->convert_expression(btype, bclosure, loc);
16691 :
16692 105 : Expression* nil_check =
16693 105 : Expression::make_binary(OPERATOR_EQEQ, this->expr_,
16694 : Expression::make_nil(loc), loc);
16695 105 : Bexpression* bnil_check = nil_check->get_backend(context);
16696 :
16697 105 : Expression* crash = Runtime::make_call(gogo, Runtime::PANIC_MEM, loc, 0);
16698 105 : crash->determine_type_no_context(gogo);
16699 105 : Bexpression* bcrash = crash->get_backend(context);
16700 :
16701 105 : Bfunction* bfn = context->function()->func_value()->get_decl();
16702 105 : Bexpression* bcond =
16703 105 : gogo->backend()->conditional_expression(bfn, NULL,
16704 : bnil_check, bcrash, NULL, loc);
16705 105 : Bfunction* bfunction = context->function()->func_value()->get_decl();
16706 105 : Bstatement* cond_statement =
16707 105 : gogo->backend()->expression_statement(bfunction, bcond);
16708 105 : return gogo->backend()->compound_expression(cond_statement, bclosure, loc);
16709 : }
16710 :
16711 : // Dump ast representation for an interface field reference.
16712 :
16713 : void
16714 0 : Interface_field_reference_expression::do_dump_expression(
16715 : Ast_dump_context* ast_dump_context) const
16716 : {
16717 0 : this->expr_->dump_expression(ast_dump_context);
16718 0 : ast_dump_context->ostream() << "." << this->name_;
16719 0 : }
16720 :
16721 : // Make a reference to a field in an interface.
16722 :
16723 : Expression*
16724 32971 : Expression::make_interface_field_reference(Expression* expr,
16725 : const std::string& field,
16726 : Location location)
16727 : {
16728 32971 : return new Interface_field_reference_expression(expr, field, location);
16729 : }
16730 :
16731 : // Class Allocation_expression.
16732 :
16733 : int
16734 132210 : Allocation_expression::do_traverse(Traverse* traverse)
16735 : {
16736 132210 : return Type::traverse(this->type_, traverse);
16737 : }
16738 :
16739 : Type*
16740 150444 : Allocation_expression::do_type()
16741 : {
16742 150444 : return Type::make_pointer_type(this->type_);
16743 : }
16744 :
16745 : void
16746 1911 : Allocation_expression::do_check_types(Gogo*)
16747 : {
16748 1911 : if (!this->type_->in_heap())
16749 0 : go_error_at(this->location(), "cannot heap allocate go:notinheap type");
16750 1911 : }
16751 :
16752 : // Make a copy of an allocation expression.
16753 :
16754 : Expression*
16755 0 : Allocation_expression::do_copy()
16756 : {
16757 0 : Allocation_expression* alloc =
16758 0 : new Allocation_expression(this->type_->copy_expressions(),
16759 0 : this->location());
16760 0 : if (this->allocate_on_stack_)
16761 0 : alloc->set_allocate_on_stack();
16762 0 : if (this->no_zero_)
16763 0 : alloc->set_no_zero();
16764 0 : return alloc;
16765 : }
16766 :
16767 : // Return the backend representation for an allocation expression.
16768 :
16769 : Bexpression*
16770 239412 : Allocation_expression::do_get_backend(Translate_context* context)
16771 : {
16772 239412 : Gogo* gogo = context->gogo();
16773 239412 : Location loc = this->location();
16774 239412 : Btype* btype = this->type_->get_backend(gogo);
16775 :
16776 239412 : if (this->allocate_on_stack_)
16777 : {
16778 35031 : int64_t size;
16779 35031 : bool ok = this->type_->backend_type_size(gogo, &size);
16780 35031 : if (!ok)
16781 : {
16782 0 : go_assert(saw_errors());
16783 0 : return gogo->backend()->error_expression();
16784 : }
16785 35031 : Bstatement* decl;
16786 35031 : Named_object* fn = context->function();
16787 35031 : go_assert(fn != NULL);
16788 35031 : Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
16789 35031 : Bexpression* init = (this->no_zero_
16790 35031 : ? NULL
16791 21813 : : gogo->backend()->zero_expression(btype));
16792 35031 : Bvariable* temp =
16793 35031 : gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
16794 : init,
16795 : Backend::variable_address_is_taken,
16796 : loc, &decl);
16797 35031 : Bexpression* ret = gogo->backend()->var_expression(temp, loc);
16798 35031 : ret = gogo->backend()->address_expression(ret, loc);
16799 35031 : ret = gogo->backend()->compound_expression(decl, ret, loc);
16800 35031 : return ret;
16801 : }
16802 :
16803 204381 : Bexpression* space =
16804 204381 : gogo->allocate_memory(this->type_, loc)->get_backend(context);
16805 204381 : Btype* pbtype = gogo->backend()->pointer_type(btype);
16806 204381 : return gogo->backend()->convert_expression(pbtype, space, loc);
16807 : }
16808 :
16809 : // Dump ast representation for an allocation expression.
16810 :
16811 : void
16812 0 : Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
16813 : const
16814 : {
16815 0 : ast_dump_context->ostream() << "new(";
16816 0 : ast_dump_context->dump_type(this->type_);
16817 0 : ast_dump_context->ostream() << ")";
16818 0 : }
16819 :
16820 : // Make an allocation expression.
16821 :
16822 : Expression*
16823 241329 : Expression::make_allocation(Type* type, Location location)
16824 : {
16825 241329 : return new Allocation_expression(type, location);
16826 : }
16827 :
16828 : // Class Ordered_value_list.
16829 :
16830 : int
16831 5308929 : Ordered_value_list::traverse_vals(Traverse* traverse)
16832 : {
16833 5308929 : if (this->vals_ != NULL)
16834 : {
16835 5125530 : if (this->traverse_order_ == NULL)
16836 : {
16837 4272759 : if (this->vals_->traverse(traverse) == TRAVERSE_EXIT)
16838 : return TRAVERSE_EXIT;
16839 : }
16840 : else
16841 : {
16842 2357312 : for (std::vector<unsigned long>::const_iterator p =
16843 852771 : this->traverse_order_->begin();
16844 3210083 : p != this->traverse_order_->end();
16845 2357312 : ++p)
16846 : {
16847 2365211 : if (Expression::traverse(&this->vals_->at(*p), traverse)
16848 : == TRAVERSE_EXIT)
16849 38154 : return TRAVERSE_EXIT;
16850 : }
16851 : }
16852 : }
16853 : return TRAVERSE_CONTINUE;
16854 : }
16855 :
16856 : // Class Struct_construction_expression.
16857 :
16858 : // Traversal.
16859 :
16860 : int
16861 3301508 : Struct_construction_expression::do_traverse(Traverse* traverse)
16862 : {
16863 3301508 : if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
16864 : return TRAVERSE_EXIT;
16865 3283870 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
16866 : return TRAVERSE_EXIT;
16867 : return TRAVERSE_CONTINUE;
16868 : }
16869 :
16870 : // Return whether this is a constant initializer.
16871 :
16872 : bool
16873 0 : Struct_construction_expression::is_constant_struct() const
16874 : {
16875 0 : if (this->vals() == NULL)
16876 : return true;
16877 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
16878 0 : pv != this->vals()->end();
16879 0 : ++pv)
16880 : {
16881 0 : if (*pv != NULL
16882 0 : && !(*pv)->is_constant()
16883 0 : && (!(*pv)->is_composite_literal()
16884 0 : || (*pv)->is_nonconstant_composite_literal()))
16885 0 : return false;
16886 : }
16887 :
16888 0 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16889 0 : for (Struct_field_list::const_iterator pf = fields->begin();
16890 0 : pf != fields->end();
16891 0 : ++pf)
16892 : {
16893 : // There are no constant constructors for interfaces.
16894 0 : if (pf->type()->interface_type() != NULL)
16895 0 : return false;
16896 : }
16897 :
16898 : return true;
16899 : }
16900 :
16901 : // Return whether this is a zero value.
16902 :
16903 : bool
16904 36 : Struct_construction_expression::do_is_zero_value() const
16905 : {
16906 36 : if (this->vals() == NULL)
16907 : return true;
16908 9 : for (Expression_list::const_iterator pv = this->vals()->begin();
16909 9 : pv != this->vals()->end();
16910 0 : ++pv)
16911 9 : if (*pv != NULL && !(*pv)->is_zero_value())
16912 9 : return false;
16913 :
16914 0 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16915 0 : for (Struct_field_list::const_iterator pf = fields->begin();
16916 0 : pf != fields->end();
16917 0 : ++pf)
16918 : {
16919 : // Interface conversion may cause a zero value being converted
16920 : // to a non-zero value, like interface{}(0). Be conservative.
16921 0 : if (pf->type()->interface_type() != NULL)
16922 9 : return false;
16923 : }
16924 :
16925 : return true;
16926 : }
16927 :
16928 : // Return whether this struct can be used as a constant initializer.
16929 :
16930 : bool
16931 867757 : Struct_construction_expression::do_is_static_initializer() const
16932 : {
16933 867757 : if (this->vals() == NULL)
16934 : return true;
16935 4571484 : for (Expression_list::const_iterator pv = this->vals()->begin();
16936 4571484 : pv != this->vals()->end();
16937 3704306 : ++pv)
16938 : {
16939 3708608 : if (*pv != NULL && !(*pv)->is_static_initializer())
16940 4374 : return false;
16941 : }
16942 :
16943 1725752 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16944 862876 : for (Struct_field_list::const_iterator pf = fields->begin();
16945 4562353 : pf != fields->end();
16946 3699477 : ++pf)
16947 : {
16948 : // There are no constant constructors for interfaces.
16949 7399026 : if (pf->type()->interface_type() != NULL)
16950 4374 : return false;
16951 : }
16952 :
16953 : return true;
16954 : }
16955 :
16956 : // Final type determination.
16957 :
16958 : void
16959 1801044 : Struct_construction_expression::do_determine_type(Gogo* gogo,
16960 : const Type_context*)
16961 : {
16962 1801044 : if (this->vals() == NULL)
16963 : return;
16964 3586930 : const Struct_field_list* fields = this->type_->struct_type()->fields();
16965 1793465 : Expression_list::const_iterator pv = this->vals()->begin();
16966 1793465 : for (Struct_field_list::const_iterator pf = fields->begin();
16967 11669636 : pf != fields->end();
16968 9876171 : ++pf, ++pv)
16969 : {
16970 9876171 : if (pv == this->vals()->end())
16971 1801044 : return;
16972 9876171 : if (*pv != NULL)
16973 : {
16974 9828704 : Type_context subcontext(pf->type(), false);
16975 9828704 : (*pv)->determine_type(gogo, &subcontext);
16976 : }
16977 : }
16978 : // Extra values are an error we will report elsewhere; we still want
16979 : // to determine the type to avoid knockon errors.
16980 1832107 : for (; pv != this->vals()->end(); ++pv)
16981 38642 : (*pv)->determine_type_no_context(gogo);
16982 : }
16983 :
16984 : // Check types.
16985 :
16986 : void
16987 29829 : Struct_construction_expression::do_check_types(Gogo* gogo)
16988 : {
16989 29829 : Struct_construction_expression::check_value_types(gogo, this->type_,
16990 : this->vals(),
16991 : this->location());
16992 29829 : }
16993 :
16994 : // Check types. This static function is also called by
16995 : // Composite_literal_expression::do_check_types. Reports whether type
16996 : // checking succeeded.
16997 :
16998 : bool
16999 203788 : Struct_construction_expression::check_value_types(Gogo* gogo,
17000 : Type* type,
17001 : Expression_list* vals,
17002 : Location loc)
17003 : {
17004 203788 : if (vals == NULL || vals->empty())
17005 : return true;
17006 :
17007 194860 : Struct_type* st = type->struct_type();
17008 194860 : if (vals->size() > st->field_count())
17009 : {
17010 4 : go_error_at(loc, "too many expressions for struct");
17011 4 : return false;
17012 : }
17013 :
17014 194856 : bool imported_type =
17015 194856 : (type->named_type() != NULL
17016 194856 : && type->named_type()->named_object()->package() != NULL);
17017 :
17018 194856 : bool ret = true;
17019 194856 : const Struct_field_list* fields = st->fields();
17020 194856 : Expression_list::const_iterator pv = vals->begin();
17021 194856 : int i = 0;
17022 194856 : for (Struct_field_list::const_iterator pf = fields->begin();
17023 819924 : pf != fields->end();
17024 625068 : ++pf, ++pv, ++i)
17025 : {
17026 625071 : if (pv == vals->end())
17027 : {
17028 3 : go_error_at(loc, "too few expressions for struct");
17029 3 : return false;
17030 : }
17031 :
17032 625068 : if (*pv == NULL)
17033 95925 : continue;
17034 :
17035 529143 : if (imported_type
17036 529143 : && (Gogo::is_hidden_name(pf->field_name())
17037 60732 : || pf->is_embedded_builtin(gogo)))
17038 : {
17039 2 : go_error_at(loc,
17040 : "assignment of unexported field %qs in %qs literal",
17041 4 : Gogo::message_name(pf->field_name()).c_str(),
17042 2 : type->named_type()->message_name().c_str());
17043 2 : ret = false;
17044 : }
17045 :
17046 529143 : std::string reason;
17047 529143 : if (!Type::are_assignable(pf->type(), (*pv)->type(), &reason))
17048 : {
17049 4 : if (reason.empty())
17050 0 : go_error_at((*pv)->location(),
17051 : "incompatible type for field %d in struct construction",
17052 : i + 1);
17053 : else
17054 4 : go_error_at((*pv)->location(),
17055 : ("incompatible type for field %d in "
17056 : "struct construction (%s)"),
17057 : i + 1, reason.c_str());
17058 : ret = false;
17059 : }
17060 529143 : }
17061 194853 : go_assert(pv == vals->end());
17062 : return ret;
17063 : }
17064 :
17065 : // Copy.
17066 :
17067 : Expression*
17068 0 : Struct_construction_expression::do_copy()
17069 : {
17070 0 : Struct_construction_expression* ret =
17071 0 : new Struct_construction_expression(this->type_->copy_expressions(),
17072 0 : (this->vals() == NULL
17073 : ? NULL
17074 0 : : this->vals()->copy()),
17075 0 : this->location());
17076 0 : if (this->traverse_order() != NULL)
17077 0 : ret->set_traverse_order(this->traverse_order());
17078 0 : return ret;
17079 : }
17080 :
17081 : // Make implicit type conversions explicit.
17082 :
17083 : void
17084 186522 : Struct_construction_expression::do_add_conversions()
17085 : {
17086 186522 : if (this->vals() == NULL)
17087 7698 : return;
17088 :
17089 178824 : Location loc = this->location();
17090 357648 : const Struct_field_list* fields = this->type_->struct_type()->fields();
17091 178824 : Expression_list::iterator pv = this->vals()->begin();
17092 178824 : for (Struct_field_list::const_iterator pf = fields->begin();
17093 778677 : pf != fields->end();
17094 599853 : ++pf, ++pv)
17095 : {
17096 599853 : if (pv == this->vals()->end())
17097 : break;
17098 599853 : if (*pv != NULL)
17099 : {
17100 503885 : Type* ft = pf->type();
17101 503885 : if (!Type::are_identical(ft, (*pv)->type(), 0, NULL)
17102 618116 : && ft->interface_type() != NULL)
17103 15177 : *pv = Expression::make_cast(ft, *pv, loc);
17104 : }
17105 : }
17106 : }
17107 :
17108 : // Return the backend representation for constructing a struct.
17109 :
17110 : Bexpression*
17111 1134830 : Struct_construction_expression::do_get_backend(Translate_context* context)
17112 : {
17113 1134830 : Gogo* gogo = context->gogo();
17114 :
17115 1134830 : Btype* btype = this->type_->get_backend(gogo);
17116 1134830 : if (this->vals() == NULL)
17117 7690 : return gogo->backend()->zero_expression(btype);
17118 :
17119 2254280 : const Struct_field_list* fields = this->type_->struct_type()->fields();
17120 1127140 : Expression_list::const_iterator pv = this->vals()->begin();
17121 1127140 : std::vector<Bexpression*> init;
17122 6882990 : for (Struct_field_list::const_iterator pf = fields->begin();
17123 6882990 : pf != fields->end();
17124 5755850 : ++pf)
17125 : {
17126 5755850 : Btype* fbtype = pf->type()->get_backend(gogo);
17127 5755850 : if (pv == this->vals()->end())
17128 0 : init.push_back(gogo->backend()->zero_expression(fbtype));
17129 5755850 : else if (*pv == NULL)
17130 : {
17131 95942 : init.push_back(gogo->backend()->zero_expression(fbtype));
17132 95942 : ++pv;
17133 : }
17134 : else
17135 : {
17136 5659908 : Expression* val =
17137 5659908 : Expression::convert_for_assignment(gogo, pf->type(),
17138 5659908 : *pv, this->location());
17139 5659908 : init.push_back(val->get_backend(context));
17140 5659908 : ++pv;
17141 : }
17142 : }
17143 2254280 : if (this->type_->struct_type()->has_padding())
17144 : {
17145 : // Feed an extra value if there is a padding field.
17146 250 : Btype *fbtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
17147 250 : init.push_back(gogo->backend()->zero_expression(fbtype));
17148 : }
17149 1127140 : return gogo->backend()->constructor_expression(btype, init, this->location());
17150 1127140 : }
17151 :
17152 : // Export a struct construction.
17153 :
17154 : void
17155 0 : Struct_construction_expression::do_export(Export_function_body* efb) const
17156 : {
17157 0 : efb->write_c_string("$convert(");
17158 0 : efb->write_type(this->type_);
17159 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
17160 0 : pv != this->vals()->end();
17161 0 : ++pv)
17162 : {
17163 0 : efb->write_c_string(", ");
17164 0 : if (*pv != NULL)
17165 0 : (*pv)->export_expression(efb);
17166 : }
17167 0 : efb->write_c_string(")");
17168 0 : }
17169 :
17170 : // Dump ast representation of a struct construction expression.
17171 :
17172 : void
17173 0 : Struct_construction_expression::do_dump_expression(
17174 : Ast_dump_context* ast_dump_context) const
17175 : {
17176 0 : ast_dump_context->dump_type(this->type_);
17177 0 : ast_dump_context->ostream() << "{";
17178 0 : ast_dump_context->dump_expression_list(this->vals());
17179 0 : ast_dump_context->ostream() << "}";
17180 0 : }
17181 :
17182 : // Make a struct composite literal. This used by the thunk code.
17183 :
17184 : Expression*
17185 1370917 : Expression::make_struct_composite_literal(Type* type, Expression_list* vals,
17186 : Location location)
17187 : {
17188 1370917 : go_assert(type->struct_type() != NULL);
17189 1370917 : return new Struct_construction_expression(type, vals, location);
17190 : }
17191 :
17192 : // Class Array_construction_expression.
17193 :
17194 : // Traversal.
17195 :
17196 : int
17197 2007421 : Array_construction_expression::do_traverse(Traverse* traverse)
17198 : {
17199 2007421 : if (this->traverse_vals(traverse) == TRAVERSE_EXIT)
17200 : return TRAVERSE_EXIT;
17201 1986905 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
17202 : return TRAVERSE_EXIT;
17203 : return TRAVERSE_CONTINUE;
17204 : }
17205 :
17206 : // Return whether this is a constant initializer.
17207 :
17208 : bool
17209 0 : Array_construction_expression::is_constant_array() const
17210 : {
17211 0 : if (this->vals() == NULL)
17212 : return true;
17213 :
17214 : // There are no constant constructors for interfaces.
17215 0 : if (this->type_->array_type()->element_type()->interface_type() != NULL)
17216 : return false;
17217 :
17218 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
17219 0 : pv != this->vals()->end();
17220 0 : ++pv)
17221 : {
17222 0 : if (*pv != NULL
17223 0 : && !(*pv)->is_constant()
17224 0 : && (!(*pv)->is_composite_literal()
17225 0 : || (*pv)->is_nonconstant_composite_literal()))
17226 0 : return false;
17227 : }
17228 : return true;
17229 : }
17230 :
17231 : // Return whether this is a zero value.
17232 :
17233 : bool
17234 10 : Array_construction_expression::do_is_zero_value() const
17235 : {
17236 10 : if (this->vals() == NULL)
17237 : return true;
17238 :
17239 : // Interface conversion may cause a zero value being converted
17240 : // to a non-zero value, like interface{}(0). Be conservative.
17241 12 : if (this->type_->array_type()->element_type()->interface_type() != NULL)
17242 : return false;
17243 :
17244 4 : for (Expression_list::const_iterator pv = this->vals()->begin();
17245 4 : pv != this->vals()->end();
17246 0 : ++pv)
17247 4 : if (*pv != NULL && !(*pv)->is_zero_value())
17248 4 : return false;
17249 :
17250 : return true;
17251 : }
17252 :
17253 : // Return whether this can be used a constant initializer.
17254 :
17255 : bool
17256 860940 : Array_construction_expression::do_is_static_initializer() const
17257 : {
17258 860940 : if (this->vals() == NULL)
17259 : return true;
17260 :
17261 : // There are no constant constructors for interfaces.
17262 1384561 : if (this->type_->array_type()->element_type()->interface_type() != NULL)
17263 : return false;
17264 :
17265 2774895 : for (Expression_list::const_iterator pv = this->vals()->begin();
17266 2774895 : pv != this->vals()->end();
17267 2194040 : ++pv)
17268 : {
17269 2237101 : if (*pv != NULL && !(*pv)->is_static_initializer())
17270 102991 : return false;
17271 : }
17272 : return true;
17273 : }
17274 :
17275 : // Final type determination.
17276 :
17277 : void
17278 494472 : Array_construction_expression::do_determine_type(Gogo* gogo,
17279 : const Type_context*)
17280 : {
17281 494472 : if (this->is_error_expression())
17282 : {
17283 0 : go_assert(saw_errors());
17284 148833 : return;
17285 : }
17286 :
17287 494472 : if (this->vals() == NULL)
17288 : return;
17289 345639 : Array_type* at = this->type_->array_type();
17290 345639 : if (at == NULL || at->is_error() || at->element_type()->is_error())
17291 : {
17292 0 : go_assert(saw_errors());
17293 0 : this->set_is_error();
17294 0 : return;
17295 : }
17296 345639 : Type_context subcontext(at->element_type(), false);
17297 1556007 : for (Expression_list::const_iterator pv = this->vals()->begin();
17298 1556007 : pv != this->vals()->end();
17299 1210368 : ++pv)
17300 : {
17301 1210368 : if (*pv != NULL)
17302 1210368 : (*pv)->determine_type(gogo, &subcontext);
17303 : }
17304 : }
17305 :
17306 : // Check types.
17307 :
17308 : void
17309 64037 : Array_construction_expression::do_check_types(Gogo*)
17310 : {
17311 64037 : if (this->is_error_expression())
17312 : {
17313 0 : go_assert(saw_errors());
17314 : return;
17315 : }
17316 :
17317 64037 : if (this->vals() == NULL)
17318 : return;
17319 :
17320 64028 : Array_type* at = this->type_->array_type();
17321 64028 : if (at == NULL || at->is_error() || at->element_type()->is_error())
17322 : {
17323 0 : go_assert(saw_errors());
17324 0 : this->set_is_error();
17325 0 : return;
17326 : }
17327 64028 : int i = 0;
17328 64028 : Type* element_type = at->element_type();
17329 64028 : for (Expression_list::const_iterator pv = this->vals()->begin();
17330 179313 : pv != this->vals()->end();
17331 115285 : ++pv, ++i)
17332 : {
17333 115285 : if (*pv != NULL
17334 115285 : && !Type::are_assignable(element_type, (*pv)->type(), NULL))
17335 : {
17336 0 : go_error_at((*pv)->location(),
17337 : "incompatible type for element %d in composite literal",
17338 : i + 1);
17339 0 : this->set_is_error();
17340 : }
17341 : }
17342 : }
17343 :
17344 : // Make implicit type conversions explicit.
17345 :
17346 : void
17347 117250 : Array_construction_expression::do_add_conversions()
17348 : {
17349 117250 : if (this->is_error_expression())
17350 : {
17351 0 : go_assert(saw_errors());
17352 57385 : return;
17353 : }
17354 :
17355 117250 : if (this->vals() == NULL)
17356 : return;
17357 :
17358 226692 : Type* et = this->type_->array_type()->element_type();
17359 170731 : if (et->interface_type() == NULL)
17360 : return;
17361 :
17362 59865 : Location loc = this->location();
17363 169313 : for (Expression_list::iterator pv = this->vals()->begin();
17364 169313 : pv != this->vals()->end();
17365 109448 : ++pv)
17366 109448 : if (!Type::are_identical(et, (*pv)->type(), 0, NULL))
17367 107390 : *pv = Expression::make_cast(et, *pv, loc);
17368 : }
17369 :
17370 : // Get a constructor expression for the array values.
17371 :
17372 : Bexpression*
17373 434395 : Array_construction_expression::get_constructor(Translate_context* context,
17374 : Btype* array_btype)
17375 : {
17376 868790 : Type* element_type = this->type_->array_type()->element_type();
17377 :
17378 434395 : std::vector<unsigned long> indexes;
17379 434395 : std::vector<Bexpression*> vals;
17380 434395 : Gogo* gogo = context->gogo();
17381 434395 : if (this->vals() != NULL)
17382 : {
17383 362808 : size_t i = 0;
17384 362808 : std::vector<unsigned long>::const_iterator pi;
17385 362808 : if (this->indexes_ != NULL)
17386 448 : pi = this->indexes_->begin();
17387 362808 : for (Expression_list::const_iterator pv = this->vals()->begin();
17388 2054176 : pv != this->vals()->end();
17389 1691368 : ++pv, ++i)
17390 : {
17391 1691368 : if (this->indexes_ != NULL)
17392 110395 : go_assert(pi != this->indexes_->end());
17393 :
17394 1691368 : if (this->indexes_ == NULL)
17395 1580973 : indexes.push_back(i);
17396 : else
17397 110395 : indexes.push_back(*pi);
17398 1691368 : if (*pv == NULL)
17399 : {
17400 0 : Btype* ebtype = element_type->get_backend(gogo);
17401 0 : Bexpression *zv = gogo->backend()->zero_expression(ebtype);
17402 0 : vals.push_back(zv);
17403 : }
17404 : else
17405 : {
17406 1691368 : Expression* val_expr =
17407 1691368 : Expression::convert_for_assignment(gogo, element_type, *pv,
17408 : this->location());
17409 1691368 : vals.push_back(val_expr->get_backend(context));
17410 : }
17411 1691368 : if (this->indexes_ != NULL)
17412 110395 : ++pi;
17413 : }
17414 362808 : if (this->indexes_ != NULL)
17415 448 : go_assert(pi == this->indexes_->end());
17416 : }
17417 434395 : return gogo->backend()->array_constructor_expression(array_btype, indexes,
17418 434395 : vals, this->location());
17419 434395 : }
17420 :
17421 : // Export an array construction.
17422 :
17423 : void
17424 0 : Array_construction_expression::do_export(Export_function_body* efb) const
17425 : {
17426 0 : efb->write_c_string("$convert(");
17427 0 : efb->write_type(this->type_);
17428 0 : if (this->vals() != NULL)
17429 : {
17430 0 : std::vector<unsigned long>::const_iterator pi;
17431 0 : if (this->indexes_ != NULL)
17432 0 : pi = this->indexes_->begin();
17433 0 : for (Expression_list::const_iterator pv = this->vals()->begin();
17434 0 : pv != this->vals()->end();
17435 0 : ++pv)
17436 : {
17437 0 : efb->write_c_string(", ");
17438 :
17439 0 : if (this->indexes_ != NULL)
17440 : {
17441 0 : char buf[100];
17442 0 : snprintf(buf, sizeof buf, "%lu", *pi);
17443 0 : efb->write_c_string(buf);
17444 0 : efb->write_c_string(":");
17445 : }
17446 :
17447 0 : if (*pv != NULL)
17448 0 : (*pv)->export_expression(efb);
17449 :
17450 0 : if (this->indexes_ != NULL)
17451 0 : ++pi;
17452 : }
17453 : }
17454 0 : efb->write_c_string(")");
17455 0 : }
17456 :
17457 : // Dump ast representation of an array construction expression.
17458 :
17459 : void
17460 0 : Array_construction_expression::do_dump_expression(
17461 : Ast_dump_context* ast_dump_context) const
17462 : {
17463 0 : Expression* length = this->type_->array_type()->length();
17464 :
17465 0 : ast_dump_context->ostream() << "[" ;
17466 0 : if (length != NULL)
17467 : {
17468 0 : ast_dump_context->dump_expression(length);
17469 : }
17470 0 : ast_dump_context->ostream() << "]" ;
17471 0 : ast_dump_context->dump_type(this->type_);
17472 0 : this->dump_slice_storage_expression(ast_dump_context);
17473 0 : ast_dump_context->ostream() << "{" ;
17474 0 : if (this->indexes_ == NULL)
17475 0 : ast_dump_context->dump_expression_list(this->vals());
17476 : else
17477 : {
17478 0 : Expression_list::const_iterator pv = this->vals()->begin();
17479 0 : for (std::vector<unsigned long>::const_iterator pi =
17480 0 : this->indexes_->begin();
17481 0 : pi != this->indexes_->end();
17482 0 : ++pi, ++pv)
17483 : {
17484 0 : if (pi != this->indexes_->begin())
17485 0 : ast_dump_context->ostream() << ", ";
17486 0 : ast_dump_context->ostream() << *pi << ':';
17487 0 : ast_dump_context->dump_expression(*pv);
17488 : }
17489 : }
17490 0 : ast_dump_context->ostream() << "}" ;
17491 :
17492 0 : }
17493 :
17494 : // Class Fixed_array_construction_expression.
17495 :
17496 434435 : Fixed_array_construction_expression::Fixed_array_construction_expression(
17497 : Type* type, const std::vector<unsigned long>* indexes,
17498 434435 : Expression_list* vals, Location location)
17499 : : Array_construction_expression(EXPRESSION_FIXED_ARRAY_CONSTRUCTION,
17500 434435 : type, indexes, vals, location)
17501 868870 : { go_assert(type->array_type() != NULL && !type->is_slice_type()); }
17502 :
17503 :
17504 : // Copy.
17505 :
17506 : Expression*
17507 0 : Fixed_array_construction_expression::do_copy()
17508 : {
17509 0 : Type* t = this->type()->copy_expressions();
17510 0 : return new Fixed_array_construction_expression(t, this->indexes(),
17511 0 : (this->vals() == NULL
17512 : ? NULL
17513 0 : : this->vals()->copy()),
17514 0 : this->location());
17515 : }
17516 :
17517 : // Return the backend representation for constructing a fixed array.
17518 :
17519 : Bexpression*
17520 434395 : Fixed_array_construction_expression::do_get_backend(Translate_context* context)
17521 : {
17522 434395 : Type* type = this->type();
17523 434395 : Btype* btype = type->get_backend(context->gogo());
17524 434395 : return this->get_constructor(context, btype);
17525 : }
17526 :
17527 : Expression*
17528 36248 : Expression::make_array_composite_literal(Type* type, Expression_list* vals,
17529 : Location location)
17530 : {
17531 72496 : go_assert(type->array_type() != NULL && !type->is_slice_type());
17532 36248 : return new Fixed_array_construction_expression(type, NULL, vals, location);
17533 : }
17534 :
17535 : // Class Slice_construction_expression.
17536 :
17537 434136 : Slice_construction_expression::Slice_construction_expression(
17538 : Type* type, const std::vector<unsigned long>* indexes,
17539 434136 : Expression_list* vals, Location location)
17540 : : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
17541 : type, indexes, vals, location),
17542 434136 : valtype_(NULL), array_val_(NULL), slice_storage_(NULL),
17543 434136 : storage_escapes_(true)
17544 : {
17545 434136 : go_assert(type->is_slice_type());
17546 :
17547 434136 : unsigned long lenval;
17548 434136 : Expression* length;
17549 434136 : if (vals == NULL || vals->empty())
17550 : lenval = 0;
17551 : else
17552 : {
17553 345107 : if (this->indexes() == NULL)
17554 344977 : lenval = vals->size();
17555 : else
17556 130 : lenval = indexes->back() + 1;
17557 : }
17558 434136 : Type* int_type = Type::lookup_integer_type("int");
17559 434136 : length = Expression::make_integer_ul(lenval, int_type, location);
17560 868272 : Type* element_type = type->array_type()->element_type();
17561 434136 : Array_type* array_type = Type::make_array_type(element_type, length);
17562 434136 : array_type->set_is_array_incomparable();
17563 434136 : this->valtype_ = array_type;
17564 434136 : }
17565 :
17566 : // Traversal.
17567 :
17568 : int
17569 1644060 : Slice_construction_expression::do_traverse(Traverse* traverse)
17570 : {
17571 1644060 : if (this->Array_construction_expression::do_traverse(traverse)
17572 : == TRAVERSE_EXIT)
17573 : return TRAVERSE_EXIT;
17574 1626367 : if (Type::traverse(this->valtype_, traverse) == TRAVERSE_EXIT)
17575 : return TRAVERSE_EXIT;
17576 1624835 : if (this->array_val_ != NULL
17577 1624835 : && Expression::traverse(&this->array_val_, traverse) == TRAVERSE_EXIT)
17578 : return TRAVERSE_EXIT;
17579 1624835 : if (this->slice_storage_ != NULL
17580 1624835 : && Expression::traverse(&this->slice_storage_, traverse) == TRAVERSE_EXIT)
17581 : return TRAVERSE_EXIT;
17582 : return TRAVERSE_CONTINUE;
17583 : }
17584 :
17585 : // Helper routine to create fixed array value underlying the slice literal.
17586 : // May be called during flattening, or later during do_get_backend().
17587 :
17588 : Expression*
17589 377512 : Slice_construction_expression::create_array_val()
17590 : {
17591 377512 : Array_type* array_type = this->type()->array_type();
17592 377512 : if (array_type == NULL)
17593 : {
17594 0 : go_assert(this->type()->is_error());
17595 : return NULL;
17596 : }
17597 :
17598 377512 : Location loc = this->location();
17599 377512 : go_assert(this->valtype_ != NULL);
17600 :
17601 377512 : Expression_list* vals = this->vals();
17602 377512 : return new Fixed_array_construction_expression(
17603 377512 : this->valtype_, this->indexes(), vals, loc);
17604 : }
17605 :
17606 : // If we're previous established that the slice storage does not
17607 : // escape, then create a separate array temp val here for it. We
17608 : // need to do this as part of flattening so as to be able to insert
17609 : // the new temp statement.
17610 :
17611 : Expression*
17612 113370 : Slice_construction_expression::do_flatten(Gogo*, Named_object*,
17613 : Statement_inserter* inserter)
17614 : {
17615 113370 : if (this->type()->array_type() == NULL)
17616 : {
17617 0 : go_assert(saw_errors());
17618 0 : return Expression::make_error(this->location());
17619 : }
17620 :
17621 : // Create a stack-allocated storage temp if storage won't escape
17622 113370 : if (!this->storage_escapes_
17623 35047 : && this->slice_storage_ == NULL
17624 179126 : && this->element_count() > 0)
17625 : {
17626 32759 : Location loc = this->location();
17627 32759 : this->array_val_ = this->create_array_val();
17628 32759 : go_assert(this->array_val_ != NULL);
17629 32759 : Temporary_statement* temp =
17630 32759 : Statement::make_temporary(this->valtype_, this->array_val_, loc);
17631 32759 : inserter->insert(temp);
17632 32759 : this->slice_storage_ = Expression::make_temporary_reference(temp, loc);
17633 : }
17634 : return this;
17635 : }
17636 :
17637 : // When dumping a slice construction expression that has an explicit
17638 : // storeage temp, emit the temp here (if we don't do this the storage
17639 : // temp appears unused in the AST dump).
17640 :
17641 : void
17642 0 : Slice_construction_expression::
17643 : dump_slice_storage_expression(Ast_dump_context* ast_dump_context) const
17644 : {
17645 0 : if (this->slice_storage_ == NULL)
17646 : return;
17647 0 : ast_dump_context->ostream() << "storage=" ;
17648 0 : ast_dump_context->dump_expression(this->slice_storage_);
17649 : }
17650 :
17651 : // Copy.
17652 :
17653 : Expression*
17654 0 : Slice_construction_expression::do_copy()
17655 : {
17656 0 : return new Slice_construction_expression(this->type()->copy_expressions(),
17657 : this->indexes(),
17658 0 : (this->vals() == NULL
17659 : ? NULL
17660 0 : : this->vals()->copy()),
17661 0 : this->location());
17662 : }
17663 :
17664 : // Return the backend representation for constructing a slice.
17665 :
17666 : Bexpression*
17667 377508 : Slice_construction_expression::do_get_backend(Translate_context* context)
17668 : {
17669 377508 : if (this->array_val_ == NULL)
17670 344753 : this->array_val_ = this->create_array_val();
17671 377508 : if (this->array_val_ == NULL)
17672 : {
17673 0 : go_assert(this->type()->is_error());
17674 0 : return context->backend()->error_expression();
17675 : }
17676 :
17677 377508 : Location loc = this->location();
17678 :
17679 377508 : bool is_static_initializer = this->array_val_->is_static_initializer();
17680 :
17681 : // We have to copy the initial values into heap memory if we are in
17682 : // a function or if the values are not constants.
17683 377508 : bool copy_to_heap = context->function() != NULL || !is_static_initializer;
17684 :
17685 377508 : Expression* space;
17686 :
17687 377508 : if (this->slice_storage_ != NULL)
17688 : {
17689 32755 : go_assert(!this->storage_escapes_);
17690 32755 : space = Expression::make_unary(OPERATOR_AND, this->slice_storage_, loc);
17691 : }
17692 344753 : else if (!copy_to_heap)
17693 : {
17694 : // The initializer will only run once.
17695 287144 : space = Expression::make_unary(OPERATOR_AND, this->array_val_, loc);
17696 287144 : space->unary_expression()->set_is_slice_init();
17697 : }
17698 : else
17699 : {
17700 57639 : go_assert(this->storage_escapes_ || this->element_count() == 0);
17701 57609 : space = Expression::make_heap_expression(this->array_val_, loc);
17702 : }
17703 377508 : Array_type* at = this->valtype_->array_type();
17704 377508 : Type* et = at->element_type();
17705 377508 : space = Expression::make_unsafe_cast(Type::make_pointer_type(et),
17706 : space, loc);
17707 :
17708 : // Build a constructor for the slice.
17709 377508 : Expression* len = at->length();
17710 377508 : Expression* slice_val =
17711 377508 : Expression::make_slice_value(this->type(), space, len, len, loc);
17712 377508 : return slice_val->get_backend(context);
17713 : }
17714 :
17715 : // Make a slice composite literal. This is used by the type
17716 : // descriptor code.
17717 :
17718 : Slice_construction_expression*
17719 402841 : Expression::make_slice_composite_literal(Type* type, Expression_list* vals,
17720 : Location location)
17721 : {
17722 402841 : go_assert(type->is_slice_type());
17723 402841 : return new Slice_construction_expression(type, NULL, vals, location);
17724 : }
17725 :
17726 : // Class Map_construction_expression.
17727 :
17728 : // Traversal.
17729 :
17730 : int
17731 53169 : Map_construction_expression::do_traverse(Traverse* traverse)
17732 : {
17733 53169 : if (this->vals_ != NULL
17734 53169 : && this->vals_->traverse(traverse) == TRAVERSE_EXIT)
17735 : return TRAVERSE_EXIT;
17736 52785 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
17737 : return TRAVERSE_EXIT;
17738 : return TRAVERSE_CONTINUE;
17739 : }
17740 :
17741 : void
17742 2433 : Map_construction_expression::do_determine_type(Gogo* gogo, const Type_context*)
17743 : {
17744 2433 : Map_type* mt = this->type_->map_type();
17745 0 : go_assert(mt != NULL);
17746 2433 : Type_context key_context(mt->key_type(), false);
17747 2433 : Type_context val_context(mt->val_type(), false);
17748 2433 : if (this->vals_ != NULL)
17749 : {
17750 29823 : for (Expression_list::const_iterator pv = this->vals_->begin();
17751 29823 : pv != this->vals_->end();
17752 27748 : ++pv)
17753 : {
17754 27748 : (*pv)->determine_type(gogo, &key_context);
17755 27748 : ++pv;
17756 27748 : (*pv)->determine_type(gogo, &val_context);
17757 : }
17758 : }
17759 2433 : }
17760 :
17761 : void
17762 0 : Map_construction_expression::do_check_types(Gogo*)
17763 : {
17764 : // Types should have been checked before this was created, so this
17765 : // will probably never be called. Check it anyhow to be sure.
17766 :
17767 0 : if (this->vals_ == NULL)
17768 : return;
17769 :
17770 0 : Map_type* mt = this->type_->map_type();
17771 0 : go_assert(mt != NULL);
17772 0 : Type* key_type = mt->key_type();
17773 0 : Type* val_type = mt->val_type();
17774 0 : for (Expression_list::const_iterator pv = this->vals_->begin();
17775 0 : pv != this->vals_->end();
17776 0 : ++pv)
17777 : {
17778 0 : if (!Type::are_assignable(key_type, (*pv)->type(), NULL))
17779 : {
17780 0 : go_error_at((*pv)->location(),
17781 : "incompatible type for key in map composite literal");
17782 0 : this->set_is_error();
17783 : }
17784 0 : ++pv;
17785 0 : if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
17786 : {
17787 0 : go_error_at((*pv)->location(),
17788 : "incompatible type for value in map composite literal");
17789 0 : this->set_is_error();
17790 : }
17791 : }
17792 : }
17793 :
17794 : // Flatten constructor initializer into a temporary variable since
17795 : // we need to take its address for __go_construct_map.
17796 :
17797 : Expression*
17798 3534 : Map_construction_expression::do_flatten(Gogo* gogo, Named_object*,
17799 : Statement_inserter* inserter)
17800 : {
17801 3534 : if (!this->is_error_expression()
17802 3534 : && this->vals_ != NULL
17803 2672 : && !this->vals_->empty()
17804 6206 : && this->constructor_temp_ == NULL)
17805 : {
17806 2638 : Map_type* mt = this->type_->map_type();
17807 2638 : Type* key_type = mt->key_type();
17808 2638 : Type* val_type = mt->val_type();
17809 2638 : this->element_type_ = Type::make_builtin_struct_type(2,
17810 : "__key", key_type,
17811 : "__val", val_type);
17812 :
17813 2638 : Expression_list* value_pairs = new Expression_list();
17814 2638 : Location loc = this->location();
17815 :
17816 2638 : size_t i = 0;
17817 2638 : for (Expression_list::const_iterator pv = this->vals_->begin();
17818 32491 : pv != this->vals_->end();
17819 29853 : ++pv, ++i)
17820 : {
17821 29853 : Expression_list* key_value_pair = new Expression_list();
17822 29853 : Expression* key = *pv;
17823 59706 : if (key->is_error_expression() || key->type()->is_error_type())
17824 : {
17825 0 : go_assert(saw_errors());
17826 0 : return Expression::make_error(loc);
17827 : }
17828 29853 : if (key->type()->interface_type() != NULL
17829 148 : && !key->is_multi_eval_safe())
17830 : {
17831 44 : Temporary_statement* temp =
17832 44 : Statement::make_temporary(NULL, key, loc);
17833 44 : inserter->insert(temp);
17834 44 : key = Expression::make_temporary_reference(temp, loc);
17835 : }
17836 29853 : key = Expression::convert_for_assignment(gogo, key_type, key, loc);
17837 :
17838 29853 : ++pv;
17839 29853 : Expression* val = *pv;
17840 59706 : if (val->is_error_expression() || val->type()->is_error_type())
17841 : {
17842 0 : go_assert(saw_errors());
17843 0 : return Expression::make_error(loc);
17844 : }
17845 29853 : if (val->type()->interface_type() != NULL
17846 501 : && !val->is_multi_eval_safe())
17847 : {
17848 497 : Temporary_statement* temp =
17849 497 : Statement::make_temporary(NULL, val, loc);
17850 497 : inserter->insert(temp);
17851 497 : val = Expression::make_temporary_reference(temp, loc);
17852 : }
17853 29853 : val = Expression::convert_for_assignment(gogo, val_type, val, loc);
17854 :
17855 29853 : key_value_pair->push_back(key);
17856 29853 : key_value_pair->push_back(val);
17857 29853 : value_pairs->push_back(
17858 29853 : Expression::make_struct_composite_literal(this->element_type_,
17859 : key_value_pair, loc));
17860 : }
17861 :
17862 2638 : Expression* element_count = Expression::make_integer_ul(i, NULL, loc);
17863 2638 : Array_type* ctor_type =
17864 2638 : Type::make_array_type(this->element_type_, element_count);
17865 2638 : ctor_type->set_is_array_incomparable();
17866 2638 : Expression* constructor =
17867 : new Fixed_array_construction_expression(ctor_type, NULL,
17868 2638 : value_pairs, loc);
17869 :
17870 5276 : this->constructor_temp_ =
17871 2638 : Statement::make_temporary(NULL, constructor, loc);
17872 2638 : constructor->issue_nil_check();
17873 2638 : this->constructor_temp_->set_is_address_taken();
17874 2638 : this->constructor_temp_->determine_types(gogo);
17875 2638 : inserter->insert(this->constructor_temp_);
17876 : }
17877 :
17878 3534 : return this;
17879 : }
17880 :
17881 : // Copy.
17882 :
17883 : Expression*
17884 0 : Map_construction_expression::do_copy()
17885 : {
17886 0 : return new Map_construction_expression(this->type_->copy_expressions(),
17887 0 : (this->vals_ == NULL
17888 : ? NULL
17889 0 : : this->vals_->copy()),
17890 0 : this->location());
17891 : }
17892 :
17893 : // Make implicit type conversions explicit.
17894 :
17895 : void
17896 3481 : Map_construction_expression::do_add_conversions()
17897 : {
17898 3481 : if (this->vals_ == NULL || this->vals_->empty())
17899 3336 : return;
17900 :
17901 2638 : Map_type* mt = this->type_->map_type();
17902 2638 : Type* kt = mt->key_type();
17903 2638 : Type* vt = mt->val_type();
17904 2638 : bool key_is_interface = (kt->interface_type() != NULL);
17905 2638 : bool val_is_interface = (vt->interface_type() != NULL);
17906 2638 : if (!key_is_interface && !val_is_interface)
17907 : return;
17908 :
17909 145 : Location loc = this->location();
17910 790 : for (Expression_list::iterator pv = this->vals_->begin();
17911 790 : pv != this->vals_->end();
17912 645 : ++pv)
17913 : {
17914 793 : if (key_is_interface &&
17915 148 : !Type::are_identical(kt, (*pv)->type(), 0, NULL))
17916 44 : *pv = Expression::make_cast(kt, *pv, loc);
17917 645 : ++pv;
17918 1146 : if (val_is_interface &&
17919 501 : !Type::are_identical(vt, (*pv)->type(), 0, NULL))
17920 493 : *pv = Expression::make_cast(vt, *pv, loc);
17921 : }
17922 : }
17923 :
17924 : // Return the backend representation for constructing a map.
17925 :
17926 : Bexpression*
17927 3481 : Map_construction_expression::do_get_backend(Translate_context* context)
17928 : {
17929 3481 : if (this->is_error_expression())
17930 0 : return context->backend()->error_expression();
17931 3481 : Location loc = this->location();
17932 :
17933 3481 : size_t i = 0;
17934 3481 : Expression* ventries;
17935 3481 : if (this->vals_ == NULL || this->vals_->empty())
17936 843 : ventries = Expression::make_nil(loc);
17937 : else
17938 : {
17939 2638 : go_assert(this->constructor_temp_ != NULL);
17940 2638 : i = this->vals_->size() / 2;
17941 :
17942 2638 : Expression* ctor_ref =
17943 2638 : Expression::make_temporary_reference(this->constructor_temp_, loc);
17944 2638 : ventries = Expression::make_unary(OPERATOR_AND, ctor_ref, loc);
17945 : }
17946 :
17947 3481 : Map_type* mt = this->type_->map_type();
17948 3481 : if (this->element_type_ == NULL)
17949 843 : this->element_type_ =
17950 843 : Type::make_builtin_struct_type(2,
17951 : "__key", mt->key_type(),
17952 : "__val", mt->val_type());
17953 3481 : Expression* descriptor = Expression::make_type_descriptor(mt, loc);
17954 :
17955 3481 : Type* uintptr_t = Type::lookup_integer_type("uintptr");
17956 3481 : Expression* count = Expression::make_integer_ul(i, uintptr_t, loc);
17957 :
17958 3481 : Expression* entry_size =
17959 3481 : Expression::make_type_info(this->element_type_, TYPE_INFO_SIZE);
17960 :
17961 3481 : unsigned int field_index;
17962 3481 : const Struct_field* valfield =
17963 3481 : this->element_type_->find_local_field("__val", &field_index);
17964 3481 : Expression* val_offset =
17965 3481 : Expression::make_struct_field_offset(this->element_type_, valfield);
17966 :
17967 3481 : Gogo* gogo = context->gogo();
17968 3481 : Expression* map_ctor =
17969 3481 : Runtime::make_call(gogo, Runtime::CONSTRUCT_MAP, loc, 5,
17970 : descriptor, count, entry_size, val_offset, ventries);
17971 3481 : map_ctor->determine_type_no_context(gogo);
17972 3481 : return map_ctor->get_backend(context);
17973 : }
17974 :
17975 : // Export an array construction.
17976 :
17977 : void
17978 0 : Map_construction_expression::do_export(Export_function_body* efb) const
17979 : {
17980 0 : efb->write_c_string("$convert(");
17981 0 : efb->write_type(this->type_);
17982 0 : for (Expression_list::const_iterator pv = this->vals_->begin();
17983 0 : pv != this->vals_->end();
17984 0 : ++pv)
17985 : {
17986 0 : efb->write_c_string(", ");
17987 0 : (*pv)->export_expression(efb);
17988 : }
17989 0 : efb->write_c_string(")");
17990 0 : }
17991 :
17992 : // Dump ast representation for a map construction expression.
17993 :
17994 : void
17995 0 : Map_construction_expression::do_dump_expression(
17996 : Ast_dump_context* ast_dump_context) const
17997 : {
17998 0 : ast_dump_context->ostream() << "{" ;
17999 0 : ast_dump_context->dump_expression_list(this->vals_, true);
18000 0 : ast_dump_context->ostream() << "}";
18001 0 : }
18002 :
18003 : // A composite literal key. This is seen during parsing, but is not
18004 : // resolved to a named_object in case this is a composite literal of
18005 : // struct type.
18006 :
18007 : class Composite_literal_key_expression : public Parser_expression
18008 : {
18009 : public:
18010 115537 : Composite_literal_key_expression(const std::string& name, Location location)
18011 115537 : : Parser_expression(EXPRESSION_COMPOSITE_LITERAL_KEY, location),
18012 115537 : name_(name), expr_(NULL)
18013 115537 : { }
18014 :
18015 : const std::string&
18016 114998 : name() const
18017 114998 : { return this->name_; }
18018 :
18019 : protected:
18020 : Type*
18021 : do_type();
18022 :
18023 : void
18024 : do_determine_type(Gogo*, const Type_context*);
18025 :
18026 : Expression*
18027 : do_lower(Gogo*, Named_object*, Statement_inserter*);
18028 :
18029 : Expression*
18030 0 : do_copy()
18031 : {
18032 0 : return new Composite_literal_key_expression(this->name_, this->location());
18033 : }
18034 :
18035 : void
18036 : do_dump_expression(Ast_dump_context*) const;
18037 :
18038 : private:
18039 : // The name.
18040 : std::string name_;
18041 : // After we look up the name, a corresponding expression.
18042 : Expression* expr_;
18043 : };
18044 :
18045 : // Determine the type of a composite literal key. We will never get
18046 : // here for keys in composite literals of struct types, because they
18047 : // will be handled by Composite_literal_expression::do_determine_type.
18048 : // So if we get here, this must be a regular name reference after all.
18049 :
18050 : void
18051 529 : Composite_literal_key_expression::do_determine_type(
18052 : Gogo* gogo,
18053 : const Type_context* context)
18054 : {
18055 529 : if (this->expr_ != NULL)
18056 : {
18057 : // Already resolved.
18058 : return;
18059 : }
18060 :
18061 529 : Named_object* no = gogo->lookup(this->name_, NULL);
18062 529 : if (no == NULL)
18063 : {
18064 : // Gogo::lookup doesn't look in the global namespace, and names
18065 : // used in composite literal keys aren't seen by
18066 : // Gogo::define_global_names, so we have to look in the global
18067 : // namespace ourselves.
18068 9 : no = gogo->lookup_global(Gogo::unpack_hidden_name(this->name_).c_str());
18069 9 : if (no == NULL)
18070 : {
18071 1 : go_error_at(this->location(), "reference to undefined name %qs",
18072 1 : Gogo::message_name(this->name_).c_str());
18073 1 : this->set_is_error();
18074 1 : return;
18075 : }
18076 : }
18077 :
18078 528 : this->expr_ = Expression::make_unknown_reference(no, this->location());
18079 528 : this->expr_->determine_type(gogo, context);
18080 : }
18081 :
18082 : Type*
18083 369 : Composite_literal_key_expression::do_type()
18084 : {
18085 369 : if (this->is_error_expression())
18086 0 : return Type::make_error_type();
18087 369 : go_assert(this->expr_ != NULL);
18088 369 : return this->expr_->type();
18089 : }
18090 :
18091 : Expression*
18092 529 : Composite_literal_key_expression::do_lower(Gogo*, Named_object*,
18093 : Statement_inserter*)
18094 : {
18095 529 : if (this->is_error_expression())
18096 1 : return Expression::make_error(this->location());
18097 528 : go_assert(this->expr_ != NULL);
18098 : return this->expr_;
18099 : }
18100 :
18101 : // Dump a composite literal key.
18102 :
18103 : void
18104 0 : Composite_literal_key_expression::do_dump_expression(
18105 : Ast_dump_context* ast_dump_context) const
18106 : {
18107 0 : ast_dump_context->ostream() << "_UnknownName_(" << this->name_ << ")";
18108 0 : }
18109 :
18110 : // Make a composite literal key.
18111 :
18112 : Expression*
18113 115537 : Expression::make_composite_literal_key(const std::string& name,
18114 : Location location)
18115 : {
18116 115537 : return new Composite_literal_key_expression(name, location);
18117 : }
18118 :
18119 : // Class Composite_literal_expression.
18120 :
18121 : // Traversal.
18122 :
18123 : int
18124 1146569 : Composite_literal_expression::do_traverse(Traverse* traverse)
18125 : {
18126 1146569 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
18127 : return TRAVERSE_EXIT;
18128 :
18129 : // If this is a struct composite literal with keys, then the keys
18130 : // are field names, not expressions. We don't want to traverse them
18131 : // in that case. If we do, we can give an erroneous error "variable
18132 : // initializer refers to itself." See bug482.go in the testsuite.
18133 1146569 : if (this->has_keys_ && this->vals_ != NULL)
18134 : {
18135 : // The type may not be resolvable at this point.
18136 108128 : Type* type = this->type_;
18137 :
18138 158074 : for (int depth = 0; depth < this->depth_; ++depth)
18139 : {
18140 49951 : type = type->deref();
18141 49951 : if (type->array_type() != NULL)
18142 96928 : type = type->array_type()->element_type();
18143 159689 : else if (type->map_type() != NULL)
18144 : {
18145 1482 : if (this->key_path_[depth])
18146 12 : type = type->map_type()->key_type();
18147 : else
18148 2952 : type = type->map_type()->val_type();
18149 : }
18150 : else
18151 : {
18152 : // This error will be reported during lowering.
18153 : return TRAVERSE_CONTINUE;
18154 : }
18155 : }
18156 108123 : type = type->deref();
18157 :
18158 239712 : while (true)
18159 : {
18160 239712 : if (type->classification() == Type::TYPE_NAMED)
18161 86409 : type = type->named_type()->real_type();
18162 153303 : else if (type->classification() == Type::TYPE_FORWARD)
18163 : {
18164 45180 : Type* t = type->forwarded();
18165 45180 : if (t == type)
18166 : break;
18167 : type = t;
18168 : }
18169 : else
18170 : break;
18171 : }
18172 :
18173 108123 : if (type->classification() == Type::TYPE_STRUCT)
18174 : {
18175 92452 : Expression_list::iterator p = this->vals_->begin();
18176 346970 : while (p != this->vals_->end())
18177 : {
18178 : // Skip key.
18179 254518 : ++p;
18180 254518 : go_assert(p != this->vals_->end());
18181 254518 : if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
18182 : return TRAVERSE_EXIT;
18183 254518 : ++p;
18184 : }
18185 : return TRAVERSE_CONTINUE;
18186 : }
18187 : }
18188 :
18189 1054112 : if (this->vals_ != NULL)
18190 988367 : return this->vals_->traverse(traverse);
18191 :
18192 : return TRAVERSE_CONTINUE;
18193 : }
18194 :
18195 : void
18196 233460 : Composite_literal_expression::do_determine_type(Gogo* gogo,
18197 : const Type_context*)
18198 : {
18199 : // Resolve the type if this composite literal is within another
18200 : // composite literal and has omitted the type. The DEPTH_ field
18201 : // tells us how deeply this one is embedded.
18202 233460 : Type* type = this->type_;
18203 412341 : for (int depth = 0; depth < this->depth_; ++depth)
18204 : {
18205 178885 : type = type->deref();
18206 178885 : if (type->array_type() != NULL)
18207 349558 : type = type->array_type()->element_type();
18208 4106 : else if (type->map_type() != NULL)
18209 : {
18210 4102 : if (this->key_path_[depth])
18211 70 : type = type->map_type()->key_type();
18212 : else
18213 8134 : type = type->map_type()->val_type();
18214 : }
18215 : else
18216 : {
18217 4 : if (!type->is_error())
18218 4 : this->report_error(_("may only omit types within composite "
18219 : "literals of slice, array, or map type"));
18220 : else
18221 : {
18222 0 : go_assert(saw_errors());
18223 0 : this->set_is_error();
18224 : }
18225 4 : return;
18226 : }
18227 : }
18228 :
18229 233456 : this->type_ = type;
18230 233456 : this->depth_ = 0;
18231 :
18232 233456 : type = type->deref();
18233 :
18234 233456 : if (this->vals_ == NULL || this->vals_->empty())
18235 : {
18236 : // No value types to determine.
18237 17677 : if (type->array_type() != NULL
18238 4059 : && type->array_type()->length() != NULL
18239 577 : && type->array_type()->length()->is_nil_expression())
18240 2 : this->resolve_array_length(type);
18241 13618 : return;
18242 : }
18243 :
18244 390165 : if (type->struct_type() != NULL && this->has_keys_)
18245 : {
18246 : // Rewrite the value list by removing the struct field keys. We
18247 : // do this now rather than during lowering because handling
18248 : // struct keys is painful. We don't need to do this for
18249 : // slice/array/map literals, because it's easy to determine
18250 : // their types with or without the keys.
18251 45900 : if (!this->resolve_struct_keys(gogo, type))
18252 : {
18253 19 : this->set_is_error();
18254 38 : delete this->vals_;
18255 19 : this->vals_ = NULL;
18256 19 : this->has_keys_ = false;
18257 19 : return;
18258 : }
18259 : }
18260 :
18261 219819 : if (type->struct_type() != NULL)
18262 : {
18263 340616 : const Struct_field_list* fields = type->struct_type()->fields();
18264 170308 : Expression_list::const_iterator pv = this->vals_->begin();
18265 170308 : for (Struct_field_list::const_iterator pf = fields->begin();
18266 747385 : pf != fields->end();
18267 577077 : ++pf, ++pv)
18268 : {
18269 577080 : if (pv == this->vals_->end())
18270 233460 : return;
18271 577077 : if (*pv != NULL)
18272 : {
18273 480410 : Type_context subcontext(pf->type(), false);
18274 480410 : (*pv)->determine_type(gogo, &subcontext);
18275 : }
18276 : }
18277 : // Extra values are an error we will report in the check_types
18278 : // pass; we still want to determine the type to avoid knockon
18279 : // errors.
18280 170313 : for (; pv != this->vals_->end(); ++pv)
18281 8 : (*pv)->determine_type_no_context(gogo);
18282 : }
18283 49511 : else if (type->array_type() != NULL)
18284 : {
18285 46824 : Array_type* at = type->array_type();
18286 46824 : Type_context intcontext(Type::lookup_integer_type("int"), false);
18287 46824 : Type_context subcontext(at->element_type(), false);
18288 652101 : for (Expression_list::const_iterator pv = this->vals_->begin();
18289 652101 : pv != this->vals_->end();
18290 605277 : ++pv)
18291 : {
18292 605277 : if (this->has_keys_)
18293 : {
18294 110423 : if (*pv != NULL)
18295 110400 : (*pv)->determine_type(gogo, &intcontext);
18296 110423 : ++pv;
18297 110423 : if (pv == this->vals_->end())
18298 : break;
18299 : }
18300 :
18301 605277 : if (*pv != NULL)
18302 605277 : (*pv)->determine_type(gogo, &subcontext);
18303 : }
18304 :
18305 46824 : if (at->length() != NULL && at->length()->is_nil_expression())
18306 867 : this->resolve_array_length(type);
18307 : }
18308 2687 : else if (type->map_type() != NULL)
18309 : {
18310 2685 : if (!this->has_keys_)
18311 : {
18312 0 : this->report_error(_("map composite literal must have keys"));
18313 0 : return;
18314 : }
18315 :
18316 2685 : Map_type* mt = type->map_type();
18317 2685 : Type_context key_context(mt->key_type(), false);
18318 2685 : Type_context val_context(mt->val_type(), false);
18319 32763 : for (Expression_list::const_iterator pv = this->vals_->begin();
18320 32763 : pv != this->vals_->end();
18321 30078 : ++pv)
18322 : {
18323 30078 : if (*pv != NULL)
18324 30076 : (*pv)->determine_type(gogo, &key_context);
18325 30078 : ++pv;
18326 30078 : if (*pv != NULL)
18327 30078 : (*pv)->determine_type(gogo, &val_context);
18328 : }
18329 : }
18330 : else
18331 : {
18332 : // We'll report this as an error in the check_types pass.
18333 : // Determine types to avoid knockon errors.
18334 6 : for (Expression_list::const_iterator pv = this->vals_->begin();
18335 6 : pv != this->vals_->end();
18336 4 : ++pv)
18337 : {
18338 4 : if (*pv != NULL)
18339 4 : (*pv)->determine_type_no_context(gogo);
18340 : }
18341 : }
18342 : }
18343 :
18344 : Type*
18345 257216 : Composite_literal_expression::do_type()
18346 : {
18347 257216 : if (this->is_error_expression())
18348 38 : return Type::make_error_type();
18349 257178 : go_assert(this->depth_ == 0);
18350 257178 : return this->type_;
18351 : }
18352 :
18353 : // Resolve the field keys of a struct composite literal.
18354 :
18355 : bool
18356 45900 : Composite_literal_expression::resolve_struct_keys(Gogo* gogo, Type* type)
18357 : {
18358 45900 : Struct_type* st = type->struct_type();
18359 45900 : size_t field_count = st->field_count();
18360 45900 : std::vector<Expression*> vals(field_count);
18361 45900 : std::vector<unsigned long>* traverse_order = new(std::vector<unsigned long>);
18362 45900 : Expression_list::const_iterator p = this->vals_->begin();
18363 45900 : Expression* external_expr = NULL;
18364 45900 : const Named_object* external_no = NULL;
18365 171836 : while (p != this->vals_->end())
18366 : {
18367 125954 : Expression* name_expr = *p;
18368 :
18369 125954 : ++p;
18370 125954 : go_assert(p != this->vals_->end());
18371 125954 : Expression* val = *p;
18372 :
18373 125954 : ++p;
18374 :
18375 125954 : if (name_expr == NULL)
18376 : {
18377 1 : go_error_at(val->location(),
18378 : "mixture of field and value initializers");
18379 18 : return false;
18380 : }
18381 :
18382 125953 : bool bad_key = false;
18383 125953 : std::string name;
18384 125953 : const Named_object* no = NULL;
18385 125953 : switch (name_expr->classification())
18386 : {
18387 114998 : case EXPRESSION_COMPOSITE_LITERAL_KEY:
18388 114998 : name =
18389 114998 : static_cast<Composite_literal_key_expression*>(name_expr)->name();
18390 114998 : break;
18391 :
18392 5232 : case EXPRESSION_UNKNOWN_REFERENCE:
18393 5232 : name = name_expr->unknown_expression()->name();
18394 5232 : if (type->named_type() != NULL)
18395 : {
18396 : // If the named object found for this field name comes from a
18397 : // different package than the struct it is a part of, do not count
18398 : // this incorrect lookup as a usage of the object's package.
18399 5042 : no = name_expr->unknown_expression()->named_object();
18400 5042 : if (no->package() != NULL
18401 5419 : && (no->package()
18402 377 : != type->named_type()->named_object()->package()))
18403 39 : no->package()->forget_usage(name_expr);
18404 : }
18405 : break;
18406 :
18407 111 : case EXPRESSION_CONST_REFERENCE:
18408 111 : no = static_cast<Const_expression*>(name_expr)->named_object();
18409 111 : break;
18410 :
18411 1 : case EXPRESSION_TYPE:
18412 1 : {
18413 1 : Type* t = name_expr->type();
18414 1 : Named_type* nt = t->named_type();
18415 1 : if (nt == NULL)
18416 : bad_key = true;
18417 : else
18418 1 : no = nt->named_object();
18419 : }
18420 : break;
18421 :
18422 5185 : case EXPRESSION_VAR_REFERENCE:
18423 5185 : no = name_expr->var_expression()->named_object();
18424 5185 : break;
18425 :
18426 91 : case EXPRESSION_ENCLOSED_VAR_REFERENCE:
18427 91 : no = name_expr->enclosed_var_expression()->variable();
18428 91 : break;
18429 :
18430 331 : case EXPRESSION_FUNC_REFERENCE:
18431 331 : no = name_expr->func_expression()->named_object();
18432 331 : break;
18433 :
18434 : default:
18435 : bad_key = true;
18436 : break;
18437 : }
18438 120756 : if (bad_key)
18439 : {
18440 4 : go_error_at(name_expr->location(), "expected struct field name");
18441 4 : return false;
18442 : }
18443 :
18444 125949 : if (no != NULL)
18445 : {
18446 10761 : if (no->package() != NULL && external_expr == NULL)
18447 : {
18448 10761 : external_expr = name_expr;
18449 10761 : external_no = no;
18450 : }
18451 :
18452 10761 : name = no->name();
18453 :
18454 : // A predefined name won't be packed. If it starts with a
18455 : // lower case letter we need to check for that case, because
18456 : // the field name will be packed. FIXME.
18457 10761 : if (!Gogo::is_hidden_name(name)
18458 4447 : && name[0] >= 'a'
18459 10761 : && name[0] <= 'z')
18460 : {
18461 0 : Named_object* gno = gogo->lookup_global(name.c_str());
18462 0 : if (gno == no)
18463 0 : name = gogo->pack_hidden_name(name, false);
18464 : }
18465 : }
18466 :
18467 125949 : unsigned int index;
18468 125949 : const Struct_field* sf = st->find_local_field(name, &index);
18469 125949 : if (sf == NULL)
18470 : {
18471 35 : go_error_at(name_expr->location(), "unknown field %qs in %qs",
18472 12 : Gogo::message_name(name).c_str(),
18473 12 : (type->named_type() != NULL
18474 34 : ? type->named_type()->message_name().c_str()
18475 : : "unnamed struct"));
18476 12 : return false;
18477 : }
18478 125937 : if (vals[index] != NULL)
18479 : {
18480 3 : go_error_at(name_expr->location(),
18481 : "duplicate value for field %qs in %qs",
18482 1 : Gogo::message_name(name).c_str(),
18483 1 : (type->named_type() != NULL
18484 3 : ? type->named_type()->message_name().c_str()
18485 : : "unnamed struct"));
18486 1 : return false;
18487 : }
18488 :
18489 125936 : vals[index] = val;
18490 125936 : traverse_order->push_back(static_cast<unsigned long>(index));
18491 125953 : }
18492 :
18493 45882 : if (!this->all_are_names_)
18494 : {
18495 : // This is a weird case like bug462 in the testsuite.
18496 1 : if (external_expr == NULL)
18497 0 : go_error_at(this->location(), "unknown field in %qs literal",
18498 0 : (type->named_type() != NULL
18499 0 : ? type->named_type()->message_name().c_str()
18500 : : "unnamed struct"));
18501 : else
18502 3 : go_error_at(external_expr->location(), "unknown field %qs in %qs",
18503 1 : external_no->message_name().c_str(),
18504 1 : (type->named_type() != NULL
18505 3 : ? type->named_type()->message_name().c_str()
18506 : : "unnamed struct"));
18507 1 : return false;
18508 : }
18509 :
18510 45881 : Expression_list* list = new Expression_list;
18511 45881 : list->reserve(field_count);
18512 267738 : for (size_t i = 0; i < field_count; ++i)
18513 221857 : list->push_back(vals[i]);
18514 :
18515 45881 : this->vals_ = list;
18516 45881 : this->traverse_order_ = traverse_order;
18517 45881 : this->has_keys_ = false;
18518 :
18519 45881 : return true;
18520 45900 : }
18521 :
18522 : // Handle [...]{...}
18523 :
18524 : void
18525 869 : Composite_literal_expression::resolve_array_length(Type* type)
18526 : {
18527 869 : size_t size;
18528 869 : if (this->vals_ == NULL || this->vals_->empty())
18529 : size = 0;
18530 867 : else if (!this->has_keys_)
18531 690 : size = this->vals_->size();
18532 : else
18533 : {
18534 : unsigned long index = 0;
18535 : size = 0;
18536 2588 : for (Expression_list::const_iterator pv = this->vals_->begin();
18537 2765 : pv != this->vals_->end();
18538 2588 : pv += 2)
18539 : {
18540 2590 : Expression* index_expr = *pv;
18541 2590 : if (index_expr != NULL)
18542 : {
18543 2583 : Numeric_constant nc;
18544 2583 : unsigned long iv;
18545 2583 : if (!index_expr->numeric_constant_value(&nc)
18546 2583 : || nc.to_unsigned_long(&iv) != Numeric_constant::NC_UL_VALID)
18547 : {
18548 : // We will report an error when lowering.
18549 : break;
18550 : }
18551 2581 : index = iv;
18552 2583 : }
18553 :
18554 2588 : if (index >= size)
18555 2553 : size = index + 1;
18556 :
18557 2588 : ++index;
18558 : }
18559 : }
18560 :
18561 869 : Expression* elen = Expression::make_integer_ul(size, NULL, this->location());
18562 1738 : this->type_ = Type::make_array_type(type->array_type()->element_type(),
18563 : elen);
18564 869 : }
18565 :
18566 : void
18567 226843 : Composite_literal_expression::do_check_types(Gogo* gogo)
18568 : {
18569 226843 : if (this->is_error_expression() || this->type_->is_error())
18570 : {
18571 28 : go_assert(saw_errors());
18572 : return;
18573 : }
18574 226815 : go_assert(this->depth_ == 0);
18575 :
18576 226815 : Type* type = this->type_->deref();
18577 226815 : if (type->struct_type() != NULL)
18578 : {
18579 173959 : go_assert(!this->has_keys_);
18580 173959 : if (!Struct_construction_expression::check_value_types(gogo, type,
18581 : this->vals_,
18582 : this->location()))
18583 12 : this->set_is_error();
18584 : }
18585 52856 : else if (type->array_type() != NULL)
18586 : {
18587 98714 : Type* element_type = type->array_type()->element_type();
18588 49357 : if (element_type->is_error())
18589 : {
18590 1 : go_assert(saw_errors());
18591 : return;
18592 : }
18593 49356 : if (this->vals_ == NULL || this->vals_->empty())
18594 : return;
18595 : int i = 0;
18596 : for (Expression_list::const_iterator pv = this->vals_->begin();
18597 641084 : pv != this->vals_->end();
18598 595670 : ++pv, ++i)
18599 : {
18600 595670 : if (this->has_keys_)
18601 : {
18602 : // We check the key type in the lowering pass.
18603 110423 : ++pv;
18604 110423 : if (pv == this->vals_->end())
18605 : break;
18606 : }
18607 595670 : if (*pv != NULL
18608 595670 : && !Type::are_assignable(element_type, (*pv)->type(), NULL))
18609 : {
18610 10 : go_error_at((*pv)->location(),
18611 : ("incompatible type for element %d "
18612 : "in composite literal"),
18613 : i + 1);
18614 10 : this->set_is_error();
18615 : }
18616 : }
18617 : }
18618 3499 : else if (type->map_type() != NULL)
18619 : {
18620 3496 : if (this->vals_ == NULL || this->vals_->empty())
18621 : return;
18622 2653 : if (!this->has_keys_)
18623 : {
18624 0 : this->report_error(_("map composite literal must have keys"));
18625 0 : return;
18626 : }
18627 2653 : int i = 0;
18628 2653 : Map_type* mt = type->map_type();
18629 2653 : Type* key_type = mt->key_type();
18630 2653 : Type* val_type = mt->val_type();
18631 2653 : for (Expression_list::const_iterator pv = this->vals_->begin();
18632 32543 : pv != this->vals_->end();
18633 29890 : ++pv, ++i)
18634 : {
18635 29890 : if (*pv != NULL
18636 29890 : && !Type::are_assignable(key_type, (*pv)->type(), NULL))
18637 : {
18638 1 : go_error_at((*pv)->location(),
18639 : ("incompatible type for element %d key "
18640 : "in map construction"),
18641 : i + 1);
18642 1 : this->set_is_error();
18643 : }
18644 29890 : ++pv;
18645 29890 : if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
18646 : {
18647 0 : go_error_at((*pv)->location(),
18648 : ("incompatible type for element %d value "
18649 : "in map construction"),
18650 : i + 1);
18651 0 : this->set_is_error();
18652 : }
18653 : }
18654 : }
18655 : else
18656 : {
18657 3 : this->report_error(_("expected struct, slice, array, or map type "
18658 : "for composite literal"));
18659 : }
18660 : }
18661 :
18662 : // Lower a generic composite literal into a specific version based on
18663 : // the type.
18664 :
18665 : Expression*
18666 227356 : Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
18667 : Statement_inserter* inserter)
18668 : {
18669 227356 : if (this->is_error_expression() || this->type_->is_error())
18670 50 : return Expression::make_error(this->location());
18671 227306 : go_assert(this->depth_ == 0);
18672 :
18673 227306 : Type* type = this->type_;
18674 227306 : Type *pt = type->points_to();
18675 227306 : bool is_pointer = false;
18676 227306 : if (pt != NULL)
18677 : {
18678 2001 : is_pointer = true;
18679 2001 : type = pt;
18680 : }
18681 :
18682 227306 : Expression* ret;
18683 227306 : if (type->is_error())
18684 0 : return Expression::make_error(this->location());
18685 227306 : else if (type->struct_type() != NULL)
18686 174460 : ret = this->lower_struct(type);
18687 52846 : else if (type->array_type() != NULL)
18688 49351 : ret = this->lower_array(type);
18689 3495 : else if (type->map_type() != NULL)
18690 3495 : ret = this->lower_map(gogo, function, inserter, type);
18691 : else
18692 0 : go_unreachable();
18693 :
18694 227306 : if (is_pointer)
18695 2001 : ret = Expression::make_heap_expression(ret, this->location());
18696 :
18697 : return ret;
18698 : }
18699 :
18700 : // Lower a struct composite literal.
18701 :
18702 : Expression*
18703 174460 : Composite_literal_expression::lower_struct(Type* type)
18704 : {
18705 174460 : go_assert(!this->has_keys_);
18706 174460 : Struct_construction_expression* ret =
18707 174460 : new Struct_construction_expression(type, this->vals_, this->location());
18708 174460 : ret->set_traverse_order(this->traverse_order_);
18709 174460 : return ret;
18710 : }
18711 :
18712 : // Index/value/traversal-order triple.
18713 :
18714 : struct IVT_triple {
18715 : unsigned long index;
18716 : unsigned long traversal_order;
18717 : Expression* expr;
18718 1881 : IVT_triple(unsigned long i, unsigned long to, Expression *e)
18719 1881 : : index(i), traversal_order(to), expr(e) { }
18720 10509 : bool operator<(const IVT_triple& other) const
18721 10337 : { return this->index < other.index; }
18722 : };
18723 :
18724 : // Lower an array composite literal.
18725 :
18726 : Expression*
18727 49351 : Composite_literal_expression::lower_array(Type* type)
18728 : {
18729 49351 : Location location = this->location();
18730 49351 : if (this->vals_ == NULL || !this->has_keys_)
18731 48884 : return this->make_array(type, NULL, this->vals_);
18732 :
18733 467 : std::vector<unsigned long>* indexes = new std::vector<unsigned long>;
18734 467 : indexes->reserve(this->vals_->size());
18735 467 : bool indexes_out_of_order = false;
18736 467 : Expression_list* vals = new Expression_list();
18737 467 : vals->reserve(this->vals_->size());
18738 467 : unsigned long index = 0;
18739 467 : Expression_list::const_iterator p = this->vals_->begin();
18740 110874 : while (p != this->vals_->end())
18741 : {
18742 110420 : Expression* index_expr = *p;
18743 :
18744 110420 : ++p;
18745 110420 : go_assert(p != this->vals_->end());
18746 110420 : Expression* val = *p;
18747 :
18748 110420 : ++p;
18749 :
18750 110420 : if (index_expr == NULL)
18751 : {
18752 22 : if (std::find(indexes->begin(), indexes->end(), index)
18753 44 : != indexes->end())
18754 : {
18755 0 : go_error_at(val->location(),
18756 : "duplicate value for index %lu", index);
18757 0 : return Expression::make_error(location);
18758 : }
18759 22 : if (!indexes->empty())
18760 16 : indexes->push_back(index);
18761 : }
18762 : else
18763 : {
18764 110398 : if (indexes->empty() && !vals->empty())
18765 : {
18766 10 : for (size_t i = 0; i < vals->size(); ++i)
18767 6 : indexes->push_back(i);
18768 : }
18769 :
18770 110398 : Numeric_constant nc;
18771 110398 : if (!index_expr->numeric_constant_value(&nc))
18772 : {
18773 4 : go_error_at(index_expr->location(),
18774 : "index expression is not integer constant");
18775 4 : return Expression::make_error(location);
18776 : }
18777 :
18778 110394 : switch (nc.to_unsigned_long(&index))
18779 : {
18780 110387 : case Numeric_constant::NC_UL_VALID:
18781 110387 : break;
18782 1 : case Numeric_constant::NC_UL_NOTINT:
18783 1 : go_error_at(index_expr->location(),
18784 : "index expression is not integer constant");
18785 1 : return Expression::make_error(location);
18786 6 : case Numeric_constant::NC_UL_NEGATIVE:
18787 6 : go_error_at(index_expr->location(),
18788 : "index expression is negative");
18789 6 : return Expression::make_error(location);
18790 0 : case Numeric_constant::NC_UL_BIG:
18791 0 : go_error_at(index_expr->location(), "index value overflow");
18792 0 : return Expression::make_error(location);
18793 0 : default:
18794 0 : go_unreachable();
18795 : }
18796 :
18797 110387 : Named_type* ntype = Type::lookup_integer_type("int");
18798 110387 : Integer_type* inttype = ntype->integer_type();
18799 110387 : if (sizeof(index) >= static_cast<size_t>(inttype->bits() / 8)
18800 110387 : && index >> (inttype->bits() - 1) != 0)
18801 : {
18802 0 : go_error_at(index_expr->location(), "index value overflow");
18803 0 : return Expression::make_error(location);
18804 : }
18805 :
18806 110387 : if (std::find(indexes->begin(), indexes->end(), index)
18807 220774 : != indexes->end())
18808 : {
18809 2 : go_error_at(index_expr->location(),
18810 : "duplicate value for index %lu",
18811 : index);
18812 2 : return Expression::make_error(location);
18813 : }
18814 :
18815 110385 : if (!indexes->empty() && index < indexes->back())
18816 : indexes_out_of_order = true;
18817 :
18818 110385 : indexes->push_back(index);
18819 110398 : }
18820 :
18821 110407 : vals->push_back(val);
18822 :
18823 110407 : ++index;
18824 : }
18825 :
18826 454 : if (indexes->empty())
18827 : {
18828 0 : delete indexes;
18829 0 : indexes = NULL;
18830 : }
18831 :
18832 454 : std::vector<unsigned long>* traverse_order = NULL;
18833 454 : if (indexes_out_of_order)
18834 : {
18835 62 : typedef std::vector<IVT_triple> V;
18836 :
18837 62 : V v;
18838 62 : v.reserve(indexes->size());
18839 62 : std::vector<unsigned long>::const_iterator pi = indexes->begin();
18840 62 : unsigned long torder = 0;
18841 62 : for (Expression_list::const_iterator pe = vals->begin();
18842 1943 : pe != vals->end();
18843 1881 : ++pe, ++pi, ++torder)
18844 1881 : v.push_back(IVT_triple(*pi, torder, *pe));
18845 :
18846 62 : std::sort(v.begin(), v.end());
18847 :
18848 62 : delete indexes;
18849 62 : delete vals;
18850 :
18851 62 : indexes = new std::vector<unsigned long>();
18852 62 : indexes->reserve(v.size());
18853 62 : vals = new Expression_list();
18854 62 : vals->reserve(v.size());
18855 62 : traverse_order = new std::vector<unsigned long>();
18856 62 : traverse_order->reserve(v.size());
18857 :
18858 1943 : for (V::const_iterator pv = v.begin(); pv != v.end(); ++pv)
18859 : {
18860 1881 : indexes->push_back(pv->index);
18861 1881 : vals->push_back(pv->expr);
18862 1881 : traverse_order->push_back(pv->traversal_order);
18863 : }
18864 62 : }
18865 :
18866 454 : Expression* ret = this->make_array(type, indexes, vals);
18867 454 : Array_construction_expression* ace = ret->array_literal();
18868 454 : if (ace != NULL && traverse_order != NULL)
18869 55 : ace->set_traverse_order(traverse_order);
18870 : return ret;
18871 : }
18872 :
18873 : // Actually build the array composite literal. This handles
18874 : // [...]{...}.
18875 :
18876 : Expression*
18877 49338 : Composite_literal_expression::make_array(
18878 : Type* type,
18879 : const std::vector<unsigned long>* indexes,
18880 : Expression_list* vals)
18881 : {
18882 49338 : Location location = this->location();
18883 49338 : Array_type* at = type->array_type();
18884 :
18885 49338 : if (at->length() != NULL
18886 18043 : && !at->length()->is_error_expression()
18887 67381 : && this->vals_ != NULL)
18888 : {
18889 17491 : Numeric_constant nc;
18890 17491 : unsigned long val;
18891 17491 : if (at->length()->numeric_constant_value(&nc)
18892 17491 : && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID)
18893 : {
18894 17491 : if (indexes == NULL)
18895 : {
18896 17167 : if (this->vals_->size() > val)
18897 : {
18898 1 : go_error_at(location,
18899 : "too many elements in composite literal");
18900 1 : return Expression::make_error(location);
18901 : }
18902 : }
18903 : else
18904 : {
18905 324 : unsigned long max = indexes->back();
18906 324 : if (max >= val)
18907 : {
18908 5 : go_error_at(location,
18909 : ("some element keys in composite literal "
18910 : "are out of range"));
18911 5 : return Expression::make_error(location);
18912 : }
18913 : }
18914 : }
18915 17491 : }
18916 :
18917 49332 : if (at->length() != NULL)
18918 18037 : return new Fixed_array_construction_expression(type, indexes, vals,
18919 18037 : location);
18920 : else
18921 31295 : return new Slice_construction_expression(type, indexes, vals, location);
18922 : }
18923 :
18924 : // Lower a map composite literal.
18925 :
18926 : Expression*
18927 3495 : Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
18928 : Statement_inserter* inserter,
18929 : Type* type)
18930 : {
18931 3495 : Location location = this->location();
18932 3495 : Unordered_map(unsigned int, std::vector<Expression*>) st;
18933 3495 : Unordered_map(unsigned int, std::vector<Expression*>) nt;
18934 3495 : bool saw_false = false;
18935 3495 : bool saw_true = false;
18936 3495 : if (this->vals_ != NULL)
18937 : {
18938 2652 : go_assert(this->has_keys_);
18939 :
18940 32535 : for (Expression_list::iterator p = this->vals_->begin();
18941 32535 : p != this->vals_->end();
18942 29883 : p += 2)
18943 : {
18944 29885 : if (*p == NULL)
18945 : {
18946 1 : ++p;
18947 1 : go_error_at((*p)->location(),
18948 : ("map composite literal must "
18949 : "have keys for every value"));
18950 2 : return Expression::make_error(location);
18951 : }
18952 : // Make sure we have lowered the key; it may not have been
18953 : // lowered in order to handle keys for struct composite
18954 : // literals. Lower it now to get the right error message.
18955 29884 : if ((*p)->unknown_expression() != NULL)
18956 : {
18957 0 : gogo->lower_expression(function, inserter, &*p);
18958 0 : go_assert((*p)->is_error_expression());
18959 0 : return Expression::make_error(location);
18960 : }
18961 : // Check if there are duplicate constant keys.
18962 29884 : if (!(*p)->is_constant())
18963 1169 : continue;
18964 28715 : std::string sval;
18965 28715 : Numeric_constant nval;
18966 28715 : bool bval;
18967 28715 : if ((*p)->string_constant_value(&sval)) // Check string keys.
18968 : {
18969 25028 : unsigned int h = Gogo::hash_string(sval, 0);
18970 : // Search the index h in the hash map.
18971 25028 : Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
18972 25028 : mit = st.find(h);
18973 25028 : if (mit == st.end())
18974 : {
18975 : // No duplicate since h is a new index.
18976 : // Create a new vector indexed by h and add it to the hash map.
18977 25027 : std::vector<Expression*> l;
18978 25027 : l.push_back(*p);
18979 25027 : std::pair<unsigned int, std::vector<Expression*> > val(h, l);
18980 25027 : st.insert(val);
18981 25027 : }
18982 : else
18983 : {
18984 : // Do further check since index h already exists.
18985 1 : for (std::vector<Expression*>::iterator lit =
18986 1 : mit->second.begin();
18987 1 : lit != mit->second.end();
18988 0 : lit++)
18989 : {
18990 1 : std::string s;
18991 1 : bool ok = (*lit)->string_constant_value(&s);
18992 1 : go_assert(ok);
18993 1 : if (s == sval)
18994 : {
18995 1 : go_error_at((*p)->location(), ("duplicate key "
18996 : "in map literal"));
18997 1 : return Expression::make_error(location);
18998 : }
18999 1 : }
19000 : // Add this new string key to the vector indexed by h.
19001 0 : mit->second.push_back(*p);
19002 : }
19003 : }
19004 3687 : else if ((*p)->numeric_constant_value(&nval))
19005 : {
19006 : // Check numeric keys.
19007 3663 : unsigned int h = nval.hash(0);
19008 3663 : Unordered_map(unsigned int, std::vector<Expression*>)::iterator mit;
19009 3663 : mit = nt.find(h);
19010 3663 : if (mit == nt.end())
19011 : {
19012 : // No duplicate since h is a new code.
19013 : // Create a new vector indexed by h and add it to the hash map.
19014 3659 : std::vector<Expression*> l;
19015 3659 : l.push_back(*p);
19016 3659 : std::pair<unsigned int, std::vector<Expression*> > val(h, l);
19017 3659 : nt.insert(val);
19018 3659 : }
19019 : else
19020 : {
19021 : // Do further check since h already exists.
19022 8 : for (std::vector<Expression*>::iterator lit =
19023 4 : mit->second.begin();
19024 8 : lit != mit->second.end();
19025 4 : lit++)
19026 : {
19027 4 : Numeric_constant rval;
19028 4 : bool ok = (*lit)->numeric_constant_value(&rval);
19029 4 : go_assert(ok);
19030 4 : if (nval.equals(rval))
19031 : {
19032 0 : go_error_at((*p)->location(),
19033 : "duplicate key in map literal");
19034 0 : return Expression::make_error(location);
19035 : }
19036 4 : }
19037 : // Add this new numeric key to the vector indexed by h.
19038 4 : mit->second.push_back(*p);
19039 : }
19040 : }
19041 24 : else if ((*p)->boolean_constant_value(&bval))
19042 : {
19043 17 : if ((bval && saw_true) || (!bval && saw_false))
19044 : {
19045 0 : go_error_at((*p)->location(),
19046 : "duplicate key in map literal");
19047 0 : return Expression::make_error(location);
19048 : }
19049 17 : if (bval)
19050 : saw_true = true;
19051 : else
19052 7 : saw_false = true;
19053 : }
19054 28715 : }
19055 : }
19056 :
19057 3493 : return new Map_construction_expression(type, this->vals_, location);
19058 3495 : }
19059 :
19060 : // Copy.
19061 :
19062 : Expression*
19063 3 : Composite_literal_expression::do_copy()
19064 : {
19065 3 : Composite_literal_expression* ret =
19066 3 : new Composite_literal_expression(this->type_->copy_expressions(),
19067 3 : this->depth_, this->has_keys_,
19068 3 : (this->vals_ == NULL
19069 : ? NULL
19070 0 : : this->vals_->copy()),
19071 3 : this->all_are_names_,
19072 3 : this->location());
19073 3 : ret->key_path_ = this->key_path_;
19074 3 : return ret;
19075 : }
19076 :
19077 : // Dump ast representation for a composite literal expression.
19078 :
19079 : void
19080 0 : Composite_literal_expression::do_dump_expression(
19081 : Ast_dump_context* ast_dump_context) const
19082 : {
19083 0 : ast_dump_context->ostream() << "composite(";
19084 0 : ast_dump_context->dump_type(this->type_);
19085 0 : ast_dump_context->ostream() << ", {";
19086 0 : ast_dump_context->dump_expression_list(this->vals_, this->has_keys_);
19087 0 : ast_dump_context->ostream() << "})";
19088 0 : }
19089 :
19090 : // Make a composite literal expression.
19091 :
19092 : Expression*
19093 226854 : Expression::make_composite_literal(Type* type, int depth, bool has_keys,
19094 : Expression_list* vals, bool all_are_names,
19095 : Location location)
19096 : {
19097 226854 : return new Composite_literal_expression(type, depth, has_keys, vals,
19098 226854 : all_are_names, location);
19099 : }
19100 :
19101 : // Return whether this expression is a composite literal.
19102 :
19103 : bool
19104 4399637 : Expression::is_composite_literal() const
19105 : {
19106 4399637 : switch (this->classification_)
19107 : {
19108 : case EXPRESSION_COMPOSITE_LITERAL:
19109 : case EXPRESSION_STRUCT_CONSTRUCTION:
19110 : case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
19111 : case EXPRESSION_SLICE_CONSTRUCTION:
19112 : case EXPRESSION_MAP_CONSTRUCTION:
19113 : return true;
19114 3979256 : default:
19115 3979256 : return false;
19116 : }
19117 : }
19118 :
19119 : // Return whether this expression is a composite literal which is not
19120 : // constant.
19121 :
19122 : bool
19123 1079 : Expression::is_nonconstant_composite_literal() const
19124 : {
19125 1079 : switch (this->classification_)
19126 : {
19127 0 : case EXPRESSION_STRUCT_CONSTRUCTION:
19128 0 : {
19129 0 : const Struct_construction_expression *psce =
19130 : static_cast<const Struct_construction_expression*>(this);
19131 0 : return !psce->is_constant_struct();
19132 : }
19133 0 : case EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
19134 0 : {
19135 0 : const Fixed_array_construction_expression *pace =
19136 : static_cast<const Fixed_array_construction_expression*>(this);
19137 0 : return !pace->is_constant_array();
19138 : }
19139 0 : case EXPRESSION_SLICE_CONSTRUCTION:
19140 0 : {
19141 0 : const Slice_construction_expression *pace =
19142 : static_cast<const Slice_construction_expression*>(this);
19143 0 : return !pace->is_constant_array();
19144 : }
19145 : case EXPRESSION_MAP_CONSTRUCTION:
19146 : return true;
19147 1079 : default:
19148 1079 : return false;
19149 : }
19150 : }
19151 :
19152 : // Return true if this is a variable or temporary_variable.
19153 :
19154 : bool
19155 0 : Expression::is_variable() const
19156 : {
19157 0 : switch (this->classification_)
19158 : {
19159 : case EXPRESSION_VAR_REFERENCE:
19160 : case EXPRESSION_TEMPORARY_REFERENCE:
19161 : case EXPRESSION_SET_AND_USE_TEMPORARY:
19162 : case EXPRESSION_ENCLOSED_VAR_REFERENCE:
19163 : return true;
19164 0 : default:
19165 0 : return false;
19166 : }
19167 : }
19168 :
19169 : // Return true if this is a reference to a local variable.
19170 :
19171 : bool
19172 0 : Expression::is_local_variable() const
19173 : {
19174 0 : const Var_expression* ve = this->var_expression();
19175 0 : if (ve == NULL)
19176 : return false;
19177 0 : const Named_object* no = ve->named_object();
19178 0 : return (no->is_result_variable()
19179 0 : || (no->is_variable() && !no->var_value()->is_global()));
19180 : }
19181 :
19182 : // Return true if multiple evaluations are OK.
19183 :
19184 : bool
19185 2787582 : Expression::is_multi_eval_safe()
19186 : {
19187 2787582 : switch (this->classification_)
19188 : {
19189 1050133 : case EXPRESSION_VAR_REFERENCE:
19190 1050133 : {
19191 : // A variable is a simple reference if not stored in the heap.
19192 1050133 : const Named_object* no = this->var_expression()->named_object();
19193 1050133 : if (no->is_variable())
19194 2085286 : return !no->var_value()->is_in_heap();
19195 7490 : else if (no->is_result_variable())
19196 7490 : return !no->result_var_value()->is_in_heap();
19197 : else
19198 0 : go_unreachable();
19199 : }
19200 :
19201 : case EXPRESSION_TEMPORARY_REFERENCE:
19202 : return true;
19203 :
19204 837375 : default:
19205 837375 : break;
19206 : }
19207 :
19208 837375 : if (!this->is_constant())
19209 : return false;
19210 :
19211 : // Only numeric and boolean constants are really multi-evaluation
19212 : // safe. We don't want multiple copies of string constants.
19213 425230 : Type* type = this->type();
19214 496611 : return type->is_numeric_type() || type->is_boolean_type();
19215 : }
19216 :
19217 : const Named_object*
19218 348206 : Expression::named_constant() const
19219 : {
19220 348206 : if (this->classification() != EXPRESSION_CONST_REFERENCE)
19221 : return NULL;
19222 38611 : const Const_expression* ce = static_cast<const Const_expression*>(this);
19223 38611 : return ce->named_object();
19224 : }
19225 :
19226 : // Class Type_guard_expression.
19227 :
19228 : // Traversal.
19229 :
19230 : int
19231 247595 : Type_guard_expression::do_traverse(Traverse* traverse)
19232 : {
19233 247595 : if (Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT
19234 247595 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
19235 4659 : return TRAVERSE_EXIT;
19236 : return TRAVERSE_CONTINUE;
19237 : }
19238 :
19239 : Expression*
19240 13894 : Type_guard_expression::do_flatten(Gogo*, Named_object*,
19241 : Statement_inserter* inserter)
19242 : {
19243 13894 : if (this->expr_->is_error_expression()
19244 13894 : || this->expr_->type()->is_error_type())
19245 : {
19246 0 : go_assert(saw_errors());
19247 0 : return Expression::make_error(this->location());
19248 : }
19249 :
19250 13894 : if (!this->expr_->is_multi_eval_safe())
19251 : {
19252 1608 : Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_,
19253 : this->location());
19254 1608 : inserter->insert(temp);
19255 1608 : this->expr_ =
19256 1608 : Expression::make_temporary_reference(temp, this->location());
19257 : }
19258 13894 : return this;
19259 : }
19260 :
19261 : // Check types of a type guard expression. The expression must have
19262 : // an interface type, but the actual type conversion is checked at run
19263 : // time.
19264 :
19265 : void
19266 13803 : Type_guard_expression::do_check_types(Gogo*)
19267 : {
19268 13803 : Type* expr_type = this->expr_->type();
19269 13803 : if (expr_type->interface_type() == NULL)
19270 : {
19271 1 : if (!expr_type->is_error() && !this->type_->is_error())
19272 1 : this->report_error(_("type assertion only valid for interface types"));
19273 1 : this->set_is_error();
19274 : }
19275 13802 : else if (this->type_->interface_type() == NULL)
19276 : {
19277 12780 : std::string reason;
19278 25560 : if (!expr_type->interface_type()->implements_interface(this->type_,
19279 : &reason))
19280 : {
19281 3 : if (!this->type_->is_error())
19282 : {
19283 3 : if (reason.empty())
19284 0 : this->report_error(_("impossible type assertion: "
19285 : "type does not implement interface"));
19286 : else
19287 3 : go_error_at(this->location(),
19288 : ("impossible type assertion: "
19289 : "type does not implement interface (%s)"),
19290 : reason.c_str());
19291 : }
19292 3 : this->set_is_error();
19293 : }
19294 12780 : }
19295 13803 : }
19296 :
19297 : // Copy.
19298 :
19299 : Expression*
19300 0 : Type_guard_expression::do_copy()
19301 : {
19302 0 : return new Type_guard_expression(this->expr_->copy(),
19303 0 : this->type_->copy_expressions(),
19304 0 : this->location());
19305 : }
19306 :
19307 : // Return the backend representation for a type guard expression.
19308 :
19309 : Bexpression*
19310 13541 : Type_guard_expression::do_get_backend(Translate_context* context)
19311 : {
19312 13541 : Expression* conversion;
19313 13541 : if (this->type_->interface_type() != NULL)
19314 1016 : conversion = Expression::convert_interface_to_interface(context->gogo(),
19315 : this->type_,
19316 : this->expr_,
19317 : true,
19318 : this->location());
19319 : else
19320 12525 : conversion = Expression::convert_for_assignment(context->gogo(),
19321 : this->type_,
19322 : this->expr_,
19323 : this->location());
19324 :
19325 13541 : Gogo* gogo = context->gogo();
19326 13541 : Btype* bt = this->type_->get_backend(gogo);
19327 13541 : Bexpression* bexpr = conversion->get_backend(context);
19328 13541 : return gogo->backend()->convert_expression(bt, bexpr, this->location());
19329 : }
19330 :
19331 : // Dump ast representation for a type guard expression.
19332 :
19333 : void
19334 0 : Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
19335 : const
19336 : {
19337 0 : this->expr_->dump_expression(ast_dump_context);
19338 0 : ast_dump_context->ostream() << ".";
19339 0 : ast_dump_context->dump_type(this->type_);
19340 0 : }
19341 :
19342 : // Make a type guard expression.
19343 :
19344 : Expression*
19345 20347 : Expression::make_type_guard(Expression* expr, Type* type,
19346 : Location location)
19347 : {
19348 20347 : return new Type_guard_expression(expr, type, location);
19349 : }
19350 :
19351 : // Class Heap_expression.
19352 :
19353 : // Return the type of the expression stored on the heap.
19354 :
19355 : Type*
19356 693954 : Heap_expression::do_type()
19357 693954 : { return Type::make_pointer_type(this->expr_->type()); }
19358 :
19359 : // Return the backend representation for allocating an expression on the heap.
19360 :
19361 : Bexpression*
19362 204189 : Heap_expression::do_get_backend(Translate_context* context)
19363 : {
19364 204189 : Type* etype = this->expr_->type();
19365 204189 : if (this->expr_->is_error_expression() || etype->is_error())
19366 5 : return context->backend()->error_expression();
19367 :
19368 204184 : Location loc = this->location();
19369 204184 : Gogo* gogo = context->gogo();
19370 204184 : Btype* btype = this->type()->get_backend(gogo);
19371 :
19372 204184 : Expression* alloc = Expression::make_allocation(etype, loc);
19373 204184 : if (this->allocate_on_stack_)
19374 19415 : alloc->allocation_expression()->set_allocate_on_stack();
19375 204184 : Bexpression* space = alloc->get_backend(context);
19376 :
19377 204184 : Bstatement* decl;
19378 204184 : Named_object* fn = context->function();
19379 204184 : go_assert(fn != NULL);
19380 204184 : Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
19381 204184 : Bvariable* space_temp =
19382 204184 : gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
19383 : space,
19384 : Backend::variable_address_is_taken,
19385 : loc, &decl);
19386 204184 : Btype* expr_btype = etype->get_backend(gogo);
19387 :
19388 204184 : Bexpression* bexpr = this->expr_->get_backend(context);
19389 :
19390 : // If this assignment needs a write barrier, call typedmemmove. We
19391 : // don't do this in the write barrier pass because in some cases
19392 : // backend conversion can introduce new Heap_expression values.
19393 204184 : Bstatement* assn;
19394 204184 : if (!etype->has_pointer() || this->allocate_on_stack_)
19395 : {
19396 74124 : space = gogo->backend()->var_expression(space_temp, loc);
19397 74124 : Bexpression* ref =
19398 74124 : gogo->backend()->indirect_expression(expr_btype, space, true, loc);
19399 74124 : assn = gogo->backend()->assignment_statement(fndecl, ref, bexpr, loc);
19400 : }
19401 : else
19402 : {
19403 130060 : Bstatement* edecl;
19404 130060 : Bvariable* btemp =
19405 130060 : gogo->backend()->temporary_variable(fndecl, context->bblock(),
19406 : expr_btype, bexpr,
19407 : Backend::variable_address_is_taken,
19408 : loc, &edecl);
19409 130060 : Bexpression* btempref = gogo->backend()->var_expression(btemp,
19410 : loc);
19411 130060 : space = gogo->backend()->var_expression(space_temp, loc);
19412 130060 : Type* etype_ptr = Type::make_pointer_type(etype);
19413 130060 : Expression* elhs = Expression::make_backend(space, etype_ptr, loc);
19414 130060 : Expression* erhs;
19415 130060 : Expression* call;
19416 130060 : if (etype->is_direct_iface_type())
19417 : {
19418 : // Single pointer.
19419 4672 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
19420 4672 : erhs = Expression::make_backend(btempref, etype, loc);
19421 4672 : erhs = Expression::unpack_direct_iface(erhs, loc);
19422 4672 : erhs = Expression::make_unsafe_cast(uintptr_type, erhs, loc);
19423 4672 : call = Runtime::make_call(gogo, Runtime::GCWRITEBARRIER, loc, 2,
19424 : elhs, erhs);
19425 : }
19426 : else
19427 : {
19428 125388 : Expression* td = Expression::make_type_descriptor(etype, loc);
19429 125388 : Bexpression* addr =
19430 125388 : gogo->backend()->address_expression(btempref, loc);
19431 125388 : erhs = Expression::make_backend(addr, etype_ptr, loc);
19432 125388 : call = Runtime::make_call(gogo, Runtime::TYPEDMEMMOVE, loc, 3,
19433 : td, elhs, erhs);
19434 : }
19435 130060 : Statement* cs = Statement::make_statement(call, false);
19436 :
19437 130060 : space = gogo->backend()->var_expression(space_temp, loc);
19438 130060 : Bexpression* ref =
19439 130060 : gogo->backend()->indirect_expression(expr_btype, space, true, loc);
19440 130060 : Expression* eref = Expression::make_backend(ref, etype, loc);
19441 130060 : btempref = gogo->backend()->var_expression(btemp, loc);
19442 130060 : erhs = Expression::make_backend(btempref, etype, loc);
19443 130060 : Statement* as = Statement::make_assignment(eref, erhs, loc);
19444 :
19445 130060 : as = gogo->check_write_barrier(context->block(), as, cs);
19446 130060 : Bstatement* s = as->get_backend(context);
19447 :
19448 130060 : assn = gogo->backend()->compound_statement(edecl, s);
19449 : }
19450 204184 : decl = gogo->backend()->compound_statement(decl, assn);
19451 204184 : space = gogo->backend()->var_expression(space_temp, loc);
19452 204184 : return gogo->backend()->compound_expression(decl, space, loc);
19453 : }
19454 :
19455 : // Dump ast representation for a heap expression.
19456 :
19457 : void
19458 0 : Heap_expression::do_dump_expression(
19459 : Ast_dump_context* ast_dump_context) const
19460 : {
19461 0 : ast_dump_context->ostream() << "&(";
19462 0 : ast_dump_context->dump_expression(this->expr_);
19463 0 : ast_dump_context->ostream() << ")";
19464 0 : }
19465 :
19466 : // Allocate an expression on the heap.
19467 :
19468 : Expression*
19469 204263 : Expression::make_heap_expression(Expression* expr, Location location)
19470 : {
19471 204263 : return new Heap_expression(expr, location);
19472 : }
19473 :
19474 : // Class Receive_expression.
19475 :
19476 : // Return the type of a receive expression.
19477 :
19478 : Type*
19479 9704 : Receive_expression::do_type()
19480 : {
19481 9704 : if (this->is_error_expression())
19482 2 : return Type::make_error_type();
19483 9702 : Channel_type* channel_type = this->channel_->type()->channel_type();
19484 9702 : if (channel_type == NULL)
19485 : {
19486 0 : this->report_error(_("expected channel"));
19487 0 : return Type::make_error_type();
19488 : }
19489 9702 : return channel_type->element_type();
19490 : }
19491 :
19492 : // Check types for a receive expression.
19493 :
19494 : void
19495 1986 : Receive_expression::do_check_types(Gogo*)
19496 : {
19497 1986 : Type* type = this->channel_->type();
19498 1986 : if (type->is_error())
19499 : {
19500 0 : go_assert(saw_errors());
19501 0 : this->set_is_error();
19502 0 : return;
19503 : }
19504 1986 : if (type->channel_type() == NULL)
19505 : {
19506 1 : this->report_error(_("expected channel"));
19507 1 : return;
19508 : }
19509 3970 : if (!type->channel_type()->may_receive())
19510 : {
19511 1 : this->report_error(_("invalid receive on send-only channel"));
19512 1 : return;
19513 : }
19514 : }
19515 :
19516 : // Flattening for receive expressions creates a temporary variable to store
19517 : // received data in for receives.
19518 :
19519 : Expression*
19520 2042 : Receive_expression::do_flatten(Gogo*, Named_object*,
19521 : Statement_inserter* inserter)
19522 : {
19523 2042 : Channel_type* channel_type = this->channel_->type()->channel_type();
19524 2042 : if (channel_type == NULL)
19525 : {
19526 1 : go_assert(saw_errors());
19527 1 : return this;
19528 : }
19529 2041 : else if (this->channel_->is_error_expression())
19530 : {
19531 0 : go_assert(saw_errors());
19532 0 : return Expression::make_error(this->location());
19533 : }
19534 :
19535 2041 : Type* element_type = channel_type->element_type();
19536 2041 : if (this->temp_receiver_ == NULL)
19537 : {
19538 2033 : this->temp_receiver_ = Statement::make_temporary(element_type, NULL,
19539 : this->location());
19540 2033 : this->temp_receiver_->set_is_address_taken();
19541 2033 : inserter->insert(this->temp_receiver_);
19542 : }
19543 :
19544 2041 : return this;
19545 : }
19546 :
19547 : // Get the backend representation for a receive expression.
19548 :
19549 : Bexpression*
19550 2021 : Receive_expression::do_get_backend(Translate_context* context)
19551 : {
19552 2021 : Location loc = this->location();
19553 :
19554 2021 : Channel_type* channel_type = this->channel_->type()->channel_type();
19555 2021 : if (channel_type == NULL)
19556 : {
19557 0 : go_assert(this->channel_->type()->is_error());
19558 0 : return context->backend()->error_expression();
19559 : }
19560 :
19561 2021 : Gogo* gogo = context->gogo();
19562 2021 : Expression* recv_ref =
19563 2021 : Expression::make_temporary_reference(this->temp_receiver_, loc);
19564 2021 : Expression* recv_addr =
19565 2021 : Expression::make_temporary_reference(this->temp_receiver_, loc);
19566 2021 : recv_addr = Expression::make_unary(OPERATOR_AND, recv_addr, loc);
19567 2021 : Expression* recv = Runtime::make_call(gogo, Runtime::CHANRECV1, loc, 2,
19568 : this->channel_, recv_addr);
19569 2021 : Expression* ret = Expression::make_compound(recv, recv_ref, loc);
19570 2021 : ret->determine_type_no_context(gogo);
19571 2021 : return ret->get_backend(context);
19572 : }
19573 :
19574 : // Export a receive expression.
19575 :
19576 : void
19577 17 : Receive_expression::do_export(Export_function_body* efb) const
19578 : {
19579 17 : efb->write_c_string("<-");
19580 17 : this->channel_->export_expression(efb);
19581 17 : }
19582 :
19583 : // Dump ast representation for a receive expression.
19584 :
19585 : void
19586 0 : Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
19587 : {
19588 0 : ast_dump_context->ostream() << " <- " ;
19589 0 : ast_dump_context->dump_expression(channel_);
19590 0 : }
19591 :
19592 : // Import a receive expression.
19593 :
19594 : Expression*
19595 0 : Receive_expression::do_import(Import_expression* imp, Location loc)
19596 : {
19597 0 : imp->require_c_string("<-");
19598 0 : Expression* expr = Expression::import_expression(imp, loc);
19599 0 : return Expression::make_receive(expr, loc);
19600 : }
19601 :
19602 : // Make a receive expression.
19603 :
19604 : Receive_expression*
19605 4139 : Expression::make_receive(Expression* channel, Location location)
19606 : {
19607 4139 : return new Receive_expression(channel, location);
19608 : }
19609 :
19610 : // An expression which evaluates to a pointer to the type descriptor
19611 : // of a type.
19612 :
19613 : class Type_descriptor_expression : public Expression
19614 : {
19615 : public:
19616 1914692 : Type_descriptor_expression(Type* type, Location location)
19617 1914692 : : Expression(EXPRESSION_TYPE_DESCRIPTOR, location),
19618 3829384 : type_(type)
19619 : { }
19620 :
19621 : protected:
19622 : int
19623 : do_traverse(Traverse*);
19624 :
19625 : Type*
19626 2181911 : do_type()
19627 2181911 : { return Type::make_type_descriptor_ptr_type(); }
19628 :
19629 : bool
19630 1392074 : do_is_static_initializer() const
19631 1392074 : { return true; }
19632 :
19633 : void
19634 2068040 : do_determine_type(Gogo*, const Type_context*)
19635 2068040 : { }
19636 :
19637 : Expression*
19638 12525 : do_copy()
19639 12525 : { return this; }
19640 :
19641 : Bexpression*
19642 1327815 : do_get_backend(Translate_context* context)
19643 : {
19644 1327815 : return this->type_->type_descriptor_pointer(context->gogo(),
19645 1327815 : this->location());
19646 : }
19647 :
19648 : void
19649 : do_dump_expression(Ast_dump_context*) const;
19650 :
19651 : private:
19652 : // The type for which this is the descriptor.
19653 : Type* type_;
19654 : };
19655 :
19656 : int
19657 683098 : Type_descriptor_expression::do_traverse(Traverse* traverse)
19658 : {
19659 683098 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
19660 0 : return TRAVERSE_EXIT;
19661 : return TRAVERSE_CONTINUE;
19662 : }
19663 :
19664 : // Dump ast representation for a type descriptor expression.
19665 :
19666 : void
19667 0 : Type_descriptor_expression::do_dump_expression(
19668 : Ast_dump_context* ast_dump_context) const
19669 : {
19670 0 : ast_dump_context->dump_type(this->type_);
19671 0 : }
19672 :
19673 : // Make a type descriptor expression.
19674 :
19675 : Expression*
19676 1914692 : Expression::make_type_descriptor(Type* type, Location location)
19677 : {
19678 1914692 : return new Type_descriptor_expression(type, location);
19679 : }
19680 :
19681 : // An expression which evaluates to a pointer to the Garbage Collection symbol
19682 : // of a type.
19683 :
19684 : class GC_symbol_expression : public Expression
19685 : {
19686 : public:
19687 243677 : GC_symbol_expression(Type* type)
19688 243677 : : Expression(EXPRESSION_GC_SYMBOL, Linemap::predeclared_location()),
19689 243677 : type_(type)
19690 243677 : {}
19691 :
19692 : protected:
19693 : Type*
19694 212643 : do_type()
19695 212643 : { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
19696 :
19697 : bool
19698 0 : do_is_static_initializer() const
19699 0 : { return true; }
19700 :
19701 : void
19702 278070 : do_determine_type(Gogo*, const Type_context*)
19703 278070 : { }
19704 :
19705 : Expression*
19706 0 : do_copy()
19707 0 : { return this; }
19708 :
19709 : Bexpression*
19710 212643 : do_get_backend(Translate_context* context)
19711 212643 : { return this->type_->gc_symbol_pointer(context->gogo()); }
19712 :
19713 : void
19714 : do_dump_expression(Ast_dump_context*) const;
19715 :
19716 : private:
19717 : // The type which this gc symbol describes.
19718 : Type* type_;
19719 : };
19720 :
19721 : // Dump ast representation for a gc symbol expression.
19722 :
19723 : void
19724 0 : GC_symbol_expression::do_dump_expression(
19725 : Ast_dump_context* ast_dump_context) const
19726 : {
19727 0 : ast_dump_context->ostream() << "gcdata(";
19728 0 : ast_dump_context->dump_type(this->type_);
19729 0 : ast_dump_context->ostream() << ")";
19730 0 : }
19731 :
19732 : // Make a gc symbol expression.
19733 :
19734 : Expression*
19735 243677 : Expression::make_gc_symbol(Type* type)
19736 : {
19737 243677 : return new GC_symbol_expression(type);
19738 : }
19739 :
19740 : // An expression that evaluates to a pointer to a symbol holding the
19741 : // ptrmask data of a type.
19742 :
19743 : class Ptrmask_symbol_expression : public Expression
19744 : {
19745 : public:
19746 22049 : Ptrmask_symbol_expression(Type* type)
19747 22049 : : Expression(EXPRESSION_PTRMASK_SYMBOL, Linemap::predeclared_location()),
19748 22049 : type_(type)
19749 22049 : {}
19750 :
19751 : protected:
19752 : Type*
19753 44098 : do_type()
19754 44098 : { return Type::make_pointer_type(Type::lookup_integer_type("uint8")); }
19755 :
19756 : bool
19757 22049 : do_is_static_initializer() const
19758 22049 : { return true; }
19759 :
19760 : void
19761 22049 : do_determine_type(Gogo*, const Type_context*)
19762 22049 : { }
19763 :
19764 : Expression*
19765 0 : do_copy()
19766 0 : { return this; }
19767 :
19768 : Bexpression*
19769 : do_get_backend(Translate_context*);
19770 :
19771 : void
19772 : do_dump_expression(Ast_dump_context*) const;
19773 :
19774 : private:
19775 : // The type that this ptrmask symbol describes.
19776 : Type* type_;
19777 : };
19778 :
19779 : // Return the ptrmask variable.
19780 :
19781 : Bexpression*
19782 22049 : Ptrmask_symbol_expression::do_get_backend(Translate_context* context)
19783 : {
19784 22049 : Gogo* gogo = context->gogo();
19785 :
19786 : // If this type does not need a gcprog, then we can use the standard
19787 : // GC symbol.
19788 22049 : int64_t ptrsize, ptrdata;
19789 22049 : if (!this->type_->needs_gcprog(gogo, &ptrsize, &ptrdata))
19790 22036 : return this->type_->gc_symbol_pointer(gogo);
19791 :
19792 : // Otherwise we have to build a ptrmask variable, and return a
19793 : // pointer to it.
19794 :
19795 13 : Bvariable* bvar = this->type_->gc_ptrmask_var(gogo, ptrsize, ptrdata);
19796 13 : Location bloc = Linemap::predeclared_location();
19797 13 : Bexpression* bref = gogo->backend()->var_expression(bvar, bloc);
19798 13 : Bexpression* baddr = gogo->backend()->address_expression(bref, bloc);
19799 :
19800 13 : Type* uint8_type = Type::lookup_integer_type("uint8");
19801 13 : Type* pointer_uint8_type = Type::make_pointer_type(uint8_type);
19802 13 : Btype* ubtype = pointer_uint8_type->get_backend(gogo);
19803 13 : return gogo->backend()->convert_expression(ubtype, baddr, bloc);
19804 : }
19805 :
19806 : // Dump AST for a ptrmask symbol expression.
19807 :
19808 : void
19809 0 : Ptrmask_symbol_expression::do_dump_expression(
19810 : Ast_dump_context* ast_dump_context) const
19811 : {
19812 0 : ast_dump_context->ostream() << "ptrmask(";
19813 0 : ast_dump_context->dump_type(this->type_);
19814 0 : ast_dump_context->ostream() << ")";
19815 0 : }
19816 :
19817 : // Make a ptrmask symbol expression.
19818 :
19819 : Expression*
19820 22049 : Expression::make_ptrmask_symbol(Type* type)
19821 : {
19822 22049 : return new Ptrmask_symbol_expression(type);
19823 : }
19824 :
19825 : // An expression which evaluates to some characteristic of a type.
19826 : // This is only used to initialize fields of a type descriptor. Using
19827 : // a new expression class is slightly inefficient but gives us a good
19828 : // separation between the frontend and the middle-end with regard to
19829 : // how types are laid out.
19830 :
19831 : class Type_info_expression : public Expression
19832 : {
19833 : public:
19834 1155709 : Type_info_expression(Type* type, Type_info type_info)
19835 1155709 : : Expression(EXPRESSION_TYPE_INFO, Linemap::predeclared_location()),
19836 1155709 : type_(type), type_info_(type_info)
19837 1155709 : { }
19838 :
19839 : protected:
19840 : bool
19841 44098 : do_is_static_initializer() const
19842 44098 : { return true; }
19843 :
19844 : Type*
19845 : do_type();
19846 :
19847 : void
19848 1434377 : do_determine_type(Gogo*, const Type_context*)
19849 1434377 : { }
19850 :
19851 : Expression*
19852 0 : do_copy()
19853 0 : { return this; }
19854 :
19855 : Bexpression*
19856 : do_get_backend(Translate_context* context);
19857 :
19858 : void
19859 : do_dump_expression(Ast_dump_context*) const;
19860 :
19861 : private:
19862 : // The type for which we are getting information.
19863 : Type* type_;
19864 : // What information we want.
19865 : Type_info type_info_;
19866 : };
19867 :
19868 : // The type is chosen to match what the type descriptor struct
19869 : // expects.
19870 :
19871 : Type*
19872 2102869 : Type_info_expression::do_type()
19873 : {
19874 2102869 : switch (this->type_info_)
19875 : {
19876 1119053 : case TYPE_INFO_SIZE:
19877 1119053 : case TYPE_INFO_BACKEND_PTRDATA:
19878 1119053 : case TYPE_INFO_DESCRIPTOR_PTRDATA:
19879 1119053 : return Type::lookup_integer_type("uintptr");
19880 983816 : case TYPE_INFO_ALIGNMENT:
19881 983816 : case TYPE_INFO_FIELD_ALIGNMENT:
19882 983816 : return Type::lookup_integer_type("uint8");
19883 0 : default:
19884 0 : go_unreachable();
19885 : }
19886 : }
19887 :
19888 : // Return the backend representation for type information.
19889 :
19890 : Bexpression*
19891 1011701 : Type_info_expression::do_get_backend(Translate_context* context)
19892 : {
19893 1011701 : Gogo* gogo = context->gogo();
19894 1011701 : bool ok = true;
19895 1011701 : int64_t val;
19896 1011701 : switch (this->type_info_)
19897 : {
19898 285101 : case TYPE_INFO_SIZE:
19899 285101 : ok = this->type_->backend_type_size(gogo, &val);
19900 285101 : break;
19901 245954 : case TYPE_INFO_ALIGNMENT:
19902 245954 : ok = this->type_->backend_type_align(gogo, &val);
19903 245954 : break;
19904 245954 : case TYPE_INFO_FIELD_ALIGNMENT:
19905 245954 : ok = this->type_->backend_type_field_align(gogo, &val);
19906 245954 : break;
19907 22049 : case TYPE_INFO_BACKEND_PTRDATA:
19908 22049 : ok = this->type_->backend_type_ptrdata(gogo, &val);
19909 22049 : break;
19910 212643 : case TYPE_INFO_DESCRIPTOR_PTRDATA:
19911 212643 : ok = this->type_->descriptor_ptrdata(gogo, &val);
19912 212643 : break;
19913 0 : default:
19914 0 : go_unreachable();
19915 : }
19916 1011701 : if (!ok)
19917 : {
19918 3 : go_assert(saw_errors());
19919 3 : return gogo->backend()->error_expression();
19920 : }
19921 1011698 : Expression* e = Expression::make_integer_int64(val, this->type(),
19922 : this->location());
19923 1011698 : return e->get_backend(context);
19924 : }
19925 :
19926 : // Dump ast representation for a type info expression.
19927 :
19928 : void
19929 0 : Type_info_expression::do_dump_expression(
19930 : Ast_dump_context* ast_dump_context) const
19931 : {
19932 0 : ast_dump_context->ostream() << "typeinfo(";
19933 0 : ast_dump_context->dump_type(this->type_);
19934 0 : ast_dump_context->ostream() << ",";
19935 0 : ast_dump_context->ostream() <<
19936 0 : (this->type_info_ == TYPE_INFO_ALIGNMENT ? "alignment"
19937 0 : : this->type_info_ == TYPE_INFO_FIELD_ALIGNMENT ? "field alignment"
19938 0 : : this->type_info_ == TYPE_INFO_SIZE ? "size"
19939 0 : : this->type_info_ == TYPE_INFO_BACKEND_PTRDATA ? "backend_ptrdata"
19940 0 : : this->type_info_ == TYPE_INFO_DESCRIPTOR_PTRDATA ? "descriptor_ptrdata"
19941 0 : : "unknown");
19942 0 : ast_dump_context->ostream() << ")";
19943 0 : }
19944 :
19945 : // Make a type info expression.
19946 :
19947 : Expression*
19948 1155709 : Expression::make_type_info(Type* type, Type_info type_info)
19949 : {
19950 1155709 : return new Type_info_expression(type, type_info);
19951 : }
19952 :
19953 : // Slice_info_expression.
19954 :
19955 : // Return the type of the slice info.
19956 :
19957 : Type*
19958 1101756 : Slice_info_expression::do_type()
19959 : {
19960 1101756 : switch (this->slice_info_)
19961 : {
19962 367207 : case SLICE_INFO_VALUE_POINTER:
19963 734414 : return Type::make_pointer_type(
19964 734414 : this->slice_->type()->array_type()->element_type());
19965 734549 : case SLICE_INFO_LENGTH:
19966 734549 : case SLICE_INFO_CAPACITY:
19967 734549 : return Type::lookup_integer_type("int");
19968 0 : default:
19969 0 : go_unreachable();
19970 : }
19971 : }
19972 :
19973 : // Return the backend information for slice information.
19974 :
19975 : Bexpression*
19976 723602 : Slice_info_expression::do_get_backend(Translate_context* context)
19977 : {
19978 723602 : Gogo* gogo = context->gogo();
19979 723602 : Bexpression* bslice = this->slice_->get_backend(context);
19980 723602 : switch (this->slice_info_)
19981 : {
19982 723602 : case SLICE_INFO_VALUE_POINTER:
19983 723602 : case SLICE_INFO_LENGTH:
19984 723602 : case SLICE_INFO_CAPACITY:
19985 723602 : return gogo->backend()->struct_field_expression(bslice, this->slice_info_,
19986 723602 : this->location());
19987 0 : break;
19988 0 : default:
19989 0 : go_unreachable();
19990 : }
19991 : }
19992 :
19993 : // Dump ast representation for a type info expression.
19994 :
19995 : void
19996 0 : Slice_info_expression::do_dump_expression(
19997 : Ast_dump_context* ast_dump_context) const
19998 : {
19999 0 : ast_dump_context->ostream() << "sliceinfo(";
20000 0 : this->slice_->dump_expression(ast_dump_context);
20001 0 : ast_dump_context->ostream() << ",";
20002 0 : ast_dump_context->ostream() <<
20003 0 : (this->slice_info_ == SLICE_INFO_VALUE_POINTER ? "values"
20004 0 : : this->slice_info_ == SLICE_INFO_LENGTH ? "length"
20005 0 : : this->slice_info_ == SLICE_INFO_CAPACITY ? "capacity "
20006 0 : : "unknown");
20007 0 : ast_dump_context->ostream() << ")";
20008 0 : }
20009 :
20010 : // Make a slice info expression.
20011 :
20012 : Expression*
20013 692526 : Expression::make_slice_info(Expression* slice, Slice_info slice_info,
20014 : Location location)
20015 : {
20016 692526 : return new Slice_info_expression(slice, slice_info, location);
20017 : }
20018 :
20019 : // Class Slice_value_expression.
20020 :
20021 : int
20022 126120 : Slice_value_expression::do_traverse(Traverse* traverse)
20023 : {
20024 126120 : if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT
20025 126120 : || Expression::traverse(&this->valmem_, traverse) == TRAVERSE_EXIT
20026 126120 : || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT
20027 252240 : || Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT)
20028 0 : return TRAVERSE_EXIT;
20029 : return TRAVERSE_CONTINUE;
20030 : }
20031 :
20032 : // Determine type of a slice value.
20033 :
20034 : void
20035 31327 : Slice_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
20036 : {
20037 31327 : this->valmem_->determine_type_no_context(gogo);
20038 31327 : this->len_->determine_type_no_context(gogo);
20039 31327 : this->cap_->determine_type_no_context(gogo);
20040 31327 : }
20041 :
20042 : Expression*
20043 0 : Slice_value_expression::do_copy()
20044 : {
20045 0 : return new Slice_value_expression(this->type_->copy_expressions(),
20046 0 : this->valmem_->copy(),
20047 0 : this->len_->copy(), this->cap_->copy(),
20048 0 : this->location());
20049 : }
20050 :
20051 : Bexpression*
20052 405130 : Slice_value_expression::do_get_backend(Translate_context* context)
20053 : {
20054 405130 : std::vector<Bexpression*> vals(3);
20055 405130 : vals[0] = this->valmem_->get_backend(context);
20056 405130 : vals[1] = this->len_->get_backend(context);
20057 405130 : vals[2] = this->cap_->get_backend(context);
20058 :
20059 405130 : Gogo* gogo = context->gogo();
20060 405130 : Btype* btype = this->type_->get_backend(gogo);
20061 405130 : return gogo->backend()->constructor_expression(btype, vals, this->location());
20062 405130 : }
20063 :
20064 : void
20065 0 : Slice_value_expression::do_dump_expression(
20066 : Ast_dump_context* ast_dump_context) const
20067 : {
20068 0 : ast_dump_context->ostream() << "slicevalue(";
20069 0 : ast_dump_context->ostream() << "values: ";
20070 0 : this->valmem_->dump_expression(ast_dump_context);
20071 0 : ast_dump_context->ostream() << ", length: ";
20072 0 : this->len_->dump_expression(ast_dump_context);
20073 0 : ast_dump_context->ostream() << ", capacity: ";
20074 0 : this->cap_->dump_expression(ast_dump_context);
20075 0 : ast_dump_context->ostream() << ")";
20076 0 : }
20077 :
20078 : Expression*
20079 405750 : Expression::make_slice_value(Type* at, Expression* valmem, Expression* len,
20080 : Expression* cap, Location location)
20081 : {
20082 405750 : go_assert(at->is_slice_type());
20083 792334 : go_assert(valmem->is_nil_expression()
20084 : || (at->array_type()->element_type()
20085 : == valmem->type()->points_to()));
20086 405750 : return new Slice_value_expression(at, valmem, len, cap, location);
20087 : }
20088 :
20089 : // Look through the expression of a Slice_value_expression's valmem to
20090 : // find an call to makeslice. If found, return the call expression and
20091 : // the containing temporary statement (if any).
20092 :
20093 : std::pair<Call_expression*, Temporary_statement*>
20094 12132 : Expression::find_makeslice_call(Expression* expr)
20095 : {
20096 12132 : Unsafe_type_conversion_expression* utce =
20097 12159 : expr->unsafe_conversion_expression();
20098 27 : if (utce != NULL)
20099 27 : expr = utce->expr();
20100 :
20101 12132 : Slice_value_expression* sve = expr->slice_value_expression();
20102 12132 : if (sve == NULL)
20103 3529 : return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
20104 8603 : expr = sve->valmem();
20105 :
20106 8603 : utce = expr->unsafe_conversion_expression();
20107 8594 : if (utce != NULL)
20108 8594 : expr = utce->expr();
20109 :
20110 8603 : Temporary_reference_expression* tre = expr->temporary_reference_expression();
20111 2797 : Temporary_statement* ts = (tre != NULL ? tre->statement() : NULL);
20112 2797 : if (ts != NULL && ts->init() != NULL && !ts->assigned()
20113 5594 : && !ts->is_address_taken())
20114 : expr = ts->init();
20115 :
20116 8603 : Call_expression* call = expr->call_expression();
20117 8603 : if (call == NULL)
20118 27 : return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
20119 :
20120 8576 : Func_expression* fe = call->fn()->func_expression();
20121 8576 : if (fe != NULL
20122 8576 : && fe->runtime_code() == Runtime::MAKESLICE)
20123 8456 : return std::make_pair(call, ts);
20124 :
20125 120 : return std::make_pair<Call_expression*, Temporary_statement*>(NULL, NULL);
20126 : }
20127 :
20128 : // An expression that evaluates to some characteristic of a non-empty interface.
20129 : // This is used to access the method table or underlying object of an interface.
20130 :
20131 : class Interface_info_expression : public Expression
20132 : {
20133 : public:
20134 210141 : Interface_info_expression(Expression* iface, Interface_info iface_info,
20135 : Location location)
20136 210141 : : Expression(EXPRESSION_INTERFACE_INFO, location),
20137 420282 : iface_(iface), iface_info_(iface_info)
20138 : { }
20139 :
20140 : protected:
20141 : Type*
20142 : do_type();
20143 :
20144 : void
20145 398772 : do_determine_type(Gogo*, const Type_context*)
20146 398772 : { }
20147 :
20148 : Expression*
20149 0 : do_copy()
20150 : {
20151 0 : return new Interface_info_expression(this->iface_->copy(),
20152 0 : this->iface_info_, this->location());
20153 : }
20154 :
20155 : Bexpression*
20156 : do_get_backend(Translate_context* context);
20157 :
20158 : void
20159 : do_dump_expression(Ast_dump_context*) const;
20160 :
20161 : void
20162 0 : do_issue_nil_check()
20163 0 : { this->iface_->issue_nil_check(); }
20164 :
20165 : private:
20166 : // The interface for which we are getting information.
20167 : Expression* iface_;
20168 : // What information we want.
20169 : Interface_info iface_info_;
20170 : };
20171 :
20172 : // Return the type of the interface info.
20173 :
20174 : Type*
20175 1108952 : Interface_info_expression::do_type()
20176 : {
20177 1108952 : switch (this->iface_info_)
20178 : {
20179 867135 : case INTERFACE_INFO_METHODS:
20180 867135 : {
20181 867135 : typedef Unordered_map(Interface_type*, Type*) Hashtable;
20182 867135 : static Hashtable result_types;
20183 :
20184 867135 : Interface_type* itype = this->iface_->type()->interface_type();
20185 :
20186 867135 : Hashtable::const_iterator pr = result_types.find(itype);
20187 867135 : if (pr != result_types.end())
20188 859918 : return pr->second;
20189 :
20190 7217 : Type* pdt = Type::make_type_descriptor_ptr_type();
20191 7217 : if (itype->is_empty())
20192 : {
20193 811 : result_types[itype] = pdt;
20194 811 : return pdt;
20195 : }
20196 :
20197 6406 : Location loc = this->location();
20198 6406 : Struct_field_list* sfl = new Struct_field_list();
20199 6406 : sfl->push_back(
20200 19218 : Struct_field(Typed_identifier("__type_descriptor", pdt, loc)));
20201 :
20202 6406 : for (Typed_identifier_list::const_iterator p = itype->methods()->begin();
20203 28162 : p != itype->methods()->end();
20204 21756 : ++p)
20205 : {
20206 21756 : Function_type* ft = p->type()->function_type();
20207 21756 : go_assert(ft->receiver() == NULL);
20208 :
20209 21756 : const Typed_identifier_list* params = ft->parameters();
20210 21756 : Typed_identifier_list* mparams = new Typed_identifier_list();
20211 21756 : if (params != NULL)
20212 7984 : mparams->reserve(params->size() + 1);
20213 21756 : Type* vt = Type::make_pointer_type(Type::make_void_type());
20214 43512 : mparams->push_back(Typed_identifier("", vt, ft->location()));
20215 21756 : if (params != NULL)
20216 : {
20217 7984 : for (Typed_identifier_list::const_iterator pp = params->begin();
20218 18017 : pp != params->end();
20219 10033 : ++pp)
20220 10033 : mparams->push_back(*pp);
20221 : }
20222 :
20223 21756 : Typed_identifier_list* mresults = (ft->results() == NULL
20224 21756 : ? NULL
20225 19407 : : ft->results()->copy());
20226 21756 : Backend_function_type* mft =
20227 21756 : Type::make_backend_function_type(NULL, mparams, mresults,
20228 : ft->location());
20229 :
20230 21756 : std::string fname = Gogo::unpack_hidden_name(p->name());
20231 43512 : sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc)));
20232 21756 : }
20233 :
20234 6406 : Struct_type* st = Type::make_struct_type(sfl, loc);
20235 6406 : st->set_is_struct_incomparable();
20236 6406 : Pointer_type *pt = Type::make_pointer_type(st);
20237 6406 : result_types[itype] = pt;
20238 6406 : return pt;
20239 : }
20240 241817 : case INTERFACE_INFO_OBJECT:
20241 241817 : return Type::make_pointer_type(Type::make_void_type());
20242 0 : default:
20243 0 : go_unreachable();
20244 : }
20245 : }
20246 :
20247 : // Return the backend representation for interface information.
20248 :
20249 : Bexpression*
20250 281884 : Interface_info_expression::do_get_backend(Translate_context* context)
20251 : {
20252 281884 : Gogo* gogo = context->gogo();
20253 281884 : Bexpression* biface = this->iface_->get_backend(context);
20254 281884 : switch (this->iface_info_)
20255 : {
20256 281884 : case INTERFACE_INFO_METHODS:
20257 281884 : case INTERFACE_INFO_OBJECT:
20258 281884 : return gogo->backend()->struct_field_expression(biface, this->iface_info_,
20259 281884 : this->location());
20260 0 : break;
20261 0 : default:
20262 0 : go_unreachable();
20263 : }
20264 : }
20265 :
20266 : // Dump ast representation for an interface info expression.
20267 :
20268 : void
20269 0 : Interface_info_expression::do_dump_expression(
20270 : Ast_dump_context* ast_dump_context) const
20271 : {
20272 0 : bool is_empty = this->iface_->type()->interface_type()->is_empty();
20273 0 : ast_dump_context->ostream() << "interfaceinfo(";
20274 0 : this->iface_->dump_expression(ast_dump_context);
20275 0 : ast_dump_context->ostream() << ",";
20276 0 : ast_dump_context->ostream() <<
20277 0 : (this->iface_info_ == INTERFACE_INFO_METHODS && !is_empty ? "methods"
20278 0 : : this->iface_info_ == INTERFACE_INFO_TYPE_DESCRIPTOR ? "type_descriptor"
20279 0 : : this->iface_info_ == INTERFACE_INFO_OBJECT ? "object"
20280 0 : : "unknown");
20281 0 : ast_dump_context->ostream() << ")";
20282 0 : }
20283 :
20284 : // Make an interface info expression.
20285 :
20286 : Expression*
20287 210141 : Expression::make_interface_info(Expression* iface, Interface_info iface_info,
20288 : Location location)
20289 : {
20290 210141 : return new Interface_info_expression(iface, iface_info, location);
20291 : }
20292 :
20293 : // An expression that represents an interface value. The first field is either
20294 : // a type descriptor for an empty interface or a pointer to the interface method
20295 : // table for a non-empty interface. The second field is always the object.
20296 :
20297 : class Interface_value_expression : public Expression
20298 : {
20299 : public:
20300 229082 : Interface_value_expression(Type* type, Expression* first_field,
20301 : Expression* obj, Location location)
20302 229082 : : Expression(EXPRESSION_INTERFACE_VALUE, location),
20303 458164 : type_(type), first_field_(first_field), obj_(obj)
20304 : { }
20305 :
20306 : protected:
20307 : int
20308 : do_traverse(Traverse*);
20309 :
20310 : Type*
20311 847 : do_type()
20312 847 : { return this->type_; }
20313 :
20314 : void
20315 : do_determine_type(Gogo*, const Type_context*);
20316 :
20317 : Expression*
20318 0 : do_copy()
20319 : {
20320 0 : return new Interface_value_expression(this->type_->copy_expressions(),
20321 0 : this->first_field_->copy(),
20322 0 : this->obj_->copy(), this->location());
20323 : }
20324 :
20325 : Bexpression*
20326 : do_get_backend(Translate_context* context);
20327 :
20328 : void
20329 : do_dump_expression(Ast_dump_context*) const;
20330 :
20331 : private:
20332 : // The type of the interface value.
20333 : Type* type_;
20334 : // The first field of the interface (either a type descriptor or a pointer
20335 : // to the method table.
20336 : Expression* first_field_;
20337 : // The underlying object of the interface.
20338 : Expression* obj_;
20339 : };
20340 :
20341 : int
20342 0 : Interface_value_expression::do_traverse(Traverse* traverse)
20343 : {
20344 0 : if (Expression::traverse(&this->first_field_, traverse) == TRAVERSE_EXIT
20345 0 : || Expression::traverse(&this->obj_, traverse) == TRAVERSE_EXIT)
20346 0 : return TRAVERSE_EXIT;
20347 : return TRAVERSE_CONTINUE;
20348 : }
20349 :
20350 : void
20351 281130 : Interface_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
20352 : {
20353 281130 : this->first_field_->determine_type_no_context(gogo);
20354 281130 : this->obj_->determine_type_no_context(gogo);
20355 281130 : }
20356 :
20357 : Bexpression*
20358 229082 : Interface_value_expression::do_get_backend(Translate_context* context)
20359 : {
20360 229082 : std::vector<Bexpression*> vals(2);
20361 229082 : vals[0] = this->first_field_->get_backend(context);
20362 229082 : vals[1] = this->obj_->get_backend(context);
20363 :
20364 229082 : Gogo* gogo = context->gogo();
20365 229082 : Btype* btype = this->type_->get_backend(gogo);
20366 229082 : return gogo->backend()->constructor_expression(btype, vals, this->location());
20367 229082 : }
20368 :
20369 : void
20370 0 : Interface_value_expression::do_dump_expression(
20371 : Ast_dump_context* ast_dump_context) const
20372 : {
20373 0 : ast_dump_context->ostream() << "interfacevalue(";
20374 0 : ast_dump_context->ostream() <<
20375 0 : (this->type_->interface_type()->is_empty()
20376 : ? "type_descriptor: "
20377 0 : : "methods: ");
20378 0 : this->first_field_->dump_expression(ast_dump_context);
20379 0 : ast_dump_context->ostream() << ", object: ";
20380 0 : this->obj_->dump_expression(ast_dump_context);
20381 0 : ast_dump_context->ostream() << ")";
20382 0 : }
20383 :
20384 : Expression*
20385 229082 : Expression::make_interface_value(Type* type, Expression* first_value,
20386 : Expression* object, Location location)
20387 : {
20388 229082 : return new Interface_value_expression(type, first_value, object, location);
20389 : }
20390 :
20391 : // An interface method table for a pair of types: an interface type and a type
20392 : // that implements that interface.
20393 :
20394 : class Interface_mtable_expression : public Expression
20395 : {
20396 : public:
20397 66004 : Interface_mtable_expression(Interface_type* itype, Type* type,
20398 : bool is_pointer, Location location)
20399 66004 : : Expression(EXPRESSION_INTERFACE_MTABLE, location),
20400 66004 : itype_(itype), type_(type), is_pointer_(is_pointer),
20401 132008 : method_table_type_(NULL), bvar_(NULL)
20402 : { }
20403 :
20404 : protected:
20405 : int
20406 : do_traverse(Traverse*);
20407 :
20408 : Type*
20409 : do_type();
20410 :
20411 : bool
20412 0 : do_is_static_initializer() const
20413 0 : { return true; }
20414 :
20415 : void
20416 43409 : do_determine_type(Gogo*, const Type_context*)
20417 43409 : { }
20418 :
20419 : Expression*
20420 0 : do_copy()
20421 : {
20422 0 : Interface_type* itype = this->itype_->copy_expressions()->interface_type();
20423 0 : return new Interface_mtable_expression(itype,
20424 0 : this->type_->copy_expressions(),
20425 0 : this->is_pointer_, this->location());
20426 : }
20427 :
20428 : bool
20429 0 : do_is_addressable() const
20430 0 : { return true; }
20431 :
20432 : Bexpression*
20433 : do_get_backend(Translate_context* context);
20434 :
20435 : void
20436 : do_dump_expression(Ast_dump_context*) const;
20437 :
20438 : private:
20439 : // The interface type for which the methods are defined.
20440 : Interface_type* itype_;
20441 : // The type to construct the interface method table for.
20442 : Type* type_;
20443 : // Whether this table contains the method set for the receiver type or the
20444 : // pointer receiver type.
20445 : bool is_pointer_;
20446 : // The type of the method table.
20447 : Type* method_table_type_;
20448 : // The backend variable that refers to the interface method table.
20449 : Bvariable* bvar_;
20450 : };
20451 :
20452 : int
20453 0 : Interface_mtable_expression::do_traverse(Traverse* traverse)
20454 : {
20455 0 : if (Type::traverse(this->itype_, traverse) == TRAVERSE_EXIT
20456 0 : || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
20457 0 : return TRAVERSE_EXIT;
20458 : return TRAVERSE_CONTINUE;
20459 : }
20460 :
20461 : Type*
20462 217370 : Interface_mtable_expression::do_type()
20463 : {
20464 217370 : if (this->method_table_type_ != NULL)
20465 : return this->method_table_type_;
20466 :
20467 66004 : const Typed_identifier_list* interface_methods = this->itype_->methods();
20468 66004 : go_assert(!interface_methods->empty());
20469 :
20470 66004 : Struct_field_list* sfl = new Struct_field_list;
20471 66004 : Typed_identifier tid("__type_descriptor", Type::make_type_descriptor_ptr_type(),
20472 132008 : this->location());
20473 66004 : sfl->push_back(Struct_field(tid));
20474 66004 : Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
20475 66004 : for (Typed_identifier_list::const_iterator p = interface_methods->begin();
20476 510485 : p != interface_methods->end();
20477 444481 : ++p)
20478 : {
20479 : // We want C function pointers here, not func descriptors; model
20480 : // using void* pointers.
20481 444481 : Typed_identifier method(p->name(), unsafe_ptr_type, p->location());
20482 444481 : sfl->push_back(Struct_field(method));
20483 444481 : }
20484 66004 : Struct_type* st = Type::make_struct_type(sfl, this->location());
20485 66004 : st->set_is_struct_incomparable();
20486 66004 : this->method_table_type_ = st;
20487 66004 : return this->method_table_type_;
20488 66004 : }
20489 :
20490 : Bexpression*
20491 182999 : Interface_mtable_expression::do_get_backend(Translate_context* context)
20492 : {
20493 182999 : Gogo* gogo = context->gogo();
20494 182999 : Location loc = Linemap::predeclared_location();
20495 182999 : if (this->bvar_ != NULL)
20496 116995 : return gogo->backend()->var_expression(this->bvar_, this->location());
20497 :
20498 66004 : const Typed_identifier_list* interface_methods = this->itype_->methods();
20499 66004 : go_assert(!interface_methods->empty());
20500 :
20501 66004 : std::string mangled_name =
20502 : gogo->interface_method_table_name(this->itype_, this->type_,
20503 66004 : this->is_pointer_);
20504 :
20505 : // Set is_public if we are converting a named type to an interface
20506 : // type that is defined in the same package as the named type, and
20507 : // the interface has hidden methods. In that case the interface
20508 : // method table will be defined by the package that defines the
20509 : // types.
20510 66004 : bool is_public = false;
20511 66004 : if (this->type_->named_type() != NULL
20512 66004 : && (this->type_->named_type()->named_object()->package()
20513 65903 : == this->itype_->package()))
20514 : {
20515 259537 : for (Typed_identifier_list::const_iterator p = interface_methods->begin();
20516 259537 : p != interface_methods->end();
20517 217227 : ++p)
20518 : {
20519 254987 : if (Gogo::is_hidden_name(p->name()))
20520 : {
20521 : is_public = true;
20522 : break;
20523 : }
20524 : }
20525 : }
20526 :
20527 42310 : if (is_public
20528 42310 : && this->type_->named_type()->named_object()->package() != NULL)
20529 : {
20530 : // The interface conversion table is defined elsewhere.
20531 34371 : Btype* btype = this->type()->get_backend(gogo);
20532 68742 : this->bvar_ =
20533 34371 : gogo->backend()->immutable_struct_reference(mangled_name, "",
20534 : btype, loc);
20535 34371 : return gogo->backend()->var_expression(this->bvar_, this->location());
20536 : }
20537 :
20538 : // The first element is the type descriptor.
20539 31633 : Type* td_type;
20540 31633 : if (!this->is_pointer_)
20541 13998 : td_type = this->type_;
20542 : else
20543 17635 : td_type = Type::make_pointer_type(this->type_);
20544 :
20545 31633 : std::vector<Backend::Btyped_identifier> bstructfields;
20546 :
20547 : // Build an interface method table for a type: a type descriptor followed by a
20548 : // list of function pointers, one for each interface method. This is used for
20549 : // interfaces.
20550 31633 : Expression_list* svals = new Expression_list();
20551 31633 : Expression* tdescriptor = Expression::make_type_descriptor(td_type, loc);
20552 31633 : svals->push_back(tdescriptor);
20553 :
20554 31633 : Btype* tdesc_btype = tdescriptor->type()->get_backend(gogo);
20555 63266 : Backend::Btyped_identifier btd("_type", tdesc_btype, loc);
20556 31633 : bstructfields.push_back(btd);
20557 :
20558 31633 : Named_type* nt = this->type_->named_type();
20559 31633 : Struct_type* st = this->type_->struct_type();
20560 31633 : go_assert(nt != NULL || st != NULL);
20561 :
20562 31633 : for (Typed_identifier_list::const_iterator p = interface_methods->begin();
20563 217683 : p != interface_methods->end();
20564 186050 : ++p)
20565 : {
20566 186050 : bool is_ambiguous;
20567 186050 : Method* m;
20568 186050 : if (nt != NULL)
20569 185878 : m = nt->method_function(p->name(), &is_ambiguous);
20570 : else
20571 172 : m = st->method_function(p->name(), &is_ambiguous);
20572 186050 : go_assert(m != NULL);
20573 :
20574 : // See the comment in Type::method_constructor.
20575 186050 : bool use_direct_iface_stub = false;
20576 186050 : if (m->is_value_method()
20577 22460 : && this->is_pointer_
20578 191919 : && this->type_->is_direct_iface_type())
20579 : use_direct_iface_stub = true;
20580 186050 : if (!m->is_value_method()
20581 163590 : && this->is_pointer_
20582 273696 : && !this->type_->in_heap())
20583 : use_direct_iface_stub = true;
20584 186050 : Named_object* no = (use_direct_iface_stub
20585 186050 : ? m->iface_stub_object()
20586 185876 : : m->named_object());
20587 :
20588 186050 : go_assert(no->is_function() || no->is_function_declaration());
20589 :
20590 186050 : Function_type* fcn_type = (no->is_function()
20591 186050 : ? no->func_value()->type()
20592 158248 : : no->func_declaration_value()->type());
20593 186050 : Btype* fcn_btype = fcn_type->get_backend_fntype(gogo);
20594 186050 : Backend::Btyped_identifier bmtype(p->name(), fcn_btype, loc);
20595 186050 : bstructfields.push_back(bmtype);
20596 :
20597 186050 : svals->push_back(Expression::make_func_code_reference(no, loc));
20598 186050 : }
20599 :
20600 31633 : Btype *btype = gogo->backend()->struct_type(bstructfields);
20601 31633 : std::vector<Bexpression*> ctor_bexprs;
20602 31633 : for (Expression_list::const_iterator pe = svals->begin();
20603 249316 : pe != svals->end();
20604 217683 : ++pe)
20605 : {
20606 217683 : ctor_bexprs.push_back((*pe)->get_backend(context));
20607 : }
20608 31633 : Bexpression* ctor =
20609 31633 : gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
20610 :
20611 31633 : unsigned int flags = 0;
20612 31633 : if (!is_public)
20613 28244 : flags |= Backend::variable_is_hidden;
20614 31633 : this->bvar_ = gogo->backend()->immutable_struct(mangled_name, "", flags,
20615 : btype, loc);
20616 31633 : gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, flags,
20617 : btype, loc, ctor);
20618 31633 : return gogo->backend()->var_expression(this->bvar_, loc);
20619 97637 : }
20620 :
20621 : void
20622 0 : Interface_mtable_expression::do_dump_expression(
20623 : Ast_dump_context* ast_dump_context) const
20624 : {
20625 0 : ast_dump_context->ostream() << "__go_"
20626 0 : << (this->is_pointer_ ? "pimt__" : "imt_");
20627 0 : ast_dump_context->dump_type(this->itype_);
20628 0 : ast_dump_context->ostream() << "__";
20629 0 : ast_dump_context->dump_type(this->type_);
20630 0 : }
20631 :
20632 : Expression*
20633 66004 : Expression::make_interface_mtable_ref(Interface_type* itype, Type* type,
20634 : bool is_pointer, Location location)
20635 : {
20636 66004 : return new Interface_mtable_expression(itype, type, is_pointer, location);
20637 : }
20638 :
20639 : // An expression which evaluates to the offset of a field within a
20640 : // struct. This, like Type_info_expression, q.v., is only used to
20641 : // initialize fields of a type descriptor.
20642 :
20643 : class Struct_field_offset_expression : public Expression
20644 : {
20645 : public:
20646 188891 : Struct_field_offset_expression(Struct_type* type, const Struct_field* field)
20647 188891 : : Expression(EXPRESSION_STRUCT_FIELD_OFFSET,
20648 : Linemap::predeclared_location()),
20649 188891 : type_(type), field_(field)
20650 188891 : { }
20651 :
20652 : protected:
20653 : bool
20654 236552 : do_is_static_initializer() const
20655 236552 : { return true; }
20656 :
20657 : Type*
20658 311911 : do_type()
20659 311911 : { return Type::lookup_integer_type("uintptr"); }
20660 :
20661 : void
20662 192372 : do_determine_type(Gogo*, const Type_context*)
20663 192372 : { }
20664 :
20665 : Expression*
20666 0 : do_copy()
20667 0 : { return this; }
20668 :
20669 : Bexpression*
20670 : do_get_backend(Translate_context* context);
20671 :
20672 : void
20673 : do_dump_expression(Ast_dump_context*) const;
20674 :
20675 : private:
20676 : // The type of the struct.
20677 : Struct_type* type_;
20678 : // The field.
20679 : const Struct_field* field_;
20680 : };
20681 :
20682 : // Return the backend representation for a struct field offset.
20683 :
20684 : Bexpression*
20685 122178 : Struct_field_offset_expression::do_get_backend(Translate_context* context)
20686 : {
20687 122178 : const Struct_field_list* fields = this->type_->fields();
20688 122178 : Struct_field_list::const_iterator p;
20689 122178 : unsigned i = 0;
20690 122178 : for (p = fields->begin();
20691 570349 : p != fields->end();
20692 448171 : ++p, ++i)
20693 570349 : if (&*p == this->field_)
20694 : break;
20695 122178 : go_assert(&*p == this->field_);
20696 :
20697 122178 : Gogo* gogo = context->gogo();
20698 122178 : Btype* btype = this->type_->get_backend(gogo);
20699 :
20700 122178 : int64_t offset = gogo->backend()->type_field_offset(btype, i);
20701 122178 : Type* uptr_type = Type::lookup_integer_type("uintptr");
20702 122178 : Expression* ret =
20703 122178 : Expression::make_integer_int64(offset, uptr_type,
20704 : Linemap::predeclared_location());
20705 122178 : return ret->get_backend(context);
20706 : }
20707 :
20708 : // Dump ast representation for a struct field offset expression.
20709 :
20710 : void
20711 0 : Struct_field_offset_expression::do_dump_expression(
20712 : Ast_dump_context* ast_dump_context) const
20713 : {
20714 0 : ast_dump_context->ostream() << "unsafe.Offsetof(";
20715 0 : ast_dump_context->dump_type(this->type_);
20716 0 : ast_dump_context->ostream() << '.';
20717 0 : ast_dump_context->ostream() <<
20718 0 : Gogo::message_name(this->field_->field_name());
20719 0 : ast_dump_context->ostream() << ")";
20720 0 : }
20721 :
20722 : // Make an expression for a struct field offset.
20723 :
20724 : Expression*
20725 188891 : Expression::make_struct_field_offset(Struct_type* type,
20726 : const Struct_field* field)
20727 : {
20728 188891 : return new Struct_field_offset_expression(type, field);
20729 : }
20730 :
20731 : // An expression which evaluates to the address of an unnamed label.
20732 :
20733 : class Label_addr_expression : public Expression
20734 : {
20735 : public:
20736 8840 : Label_addr_expression(Label* label, Location location)
20737 8840 : : Expression(EXPRESSION_LABEL_ADDR, location),
20738 0 : label_(label)
20739 : { }
20740 :
20741 : protected:
20742 : Type*
20743 61880 : do_type()
20744 61880 : { return Type::make_pointer_type(Type::make_void_type()); }
20745 :
20746 : void
20747 17680 : do_determine_type(Gogo*, const Type_context*)
20748 17680 : { }
20749 :
20750 : Expression*
20751 0 : do_copy()
20752 0 : { return new Label_addr_expression(this->label_, this->location()); }
20753 :
20754 : Bexpression*
20755 8840 : do_get_backend(Translate_context* context)
20756 8840 : { return this->label_->get_addr(context, this->location()); }
20757 :
20758 : void
20759 0 : do_dump_expression(Ast_dump_context* ast_dump_context) const
20760 0 : { ast_dump_context->ostream() << this->label_->name(); }
20761 :
20762 : private:
20763 : // The label whose address we are taking.
20764 : Label* label_;
20765 : };
20766 :
20767 : // Make an expression for the address of an unnamed label.
20768 :
20769 : Expression*
20770 8840 : Expression::make_label_addr(Label* label, Location location)
20771 : {
20772 8840 : return new Label_addr_expression(label, location);
20773 : }
20774 :
20775 : // Class Conditional_expression.
20776 :
20777 : // Traversal.
20778 :
20779 : int
20780 217442 : Conditional_expression::do_traverse(Traverse* traverse)
20781 : {
20782 217442 : if (Expression::traverse(&this->cond_, traverse) == TRAVERSE_EXIT
20783 206217 : || Expression::traverse(&this->then_, traverse) == TRAVERSE_EXIT
20784 423659 : || Expression::traverse(&this->else_, traverse) == TRAVERSE_EXIT)
20785 11225 : return TRAVERSE_EXIT;
20786 : return TRAVERSE_CONTINUE;
20787 : }
20788 :
20789 : // Return the type of the conditional expression.
20790 :
20791 : Type*
20792 548757 : Conditional_expression::do_type()
20793 : {
20794 548757 : Type* result_type = Type::make_void_type();
20795 548757 : if (Type::are_identical(this->then_->type(), this->else_->type(),
20796 : Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
20797 : NULL))
20798 201266 : result_type = this->then_->type();
20799 347491 : else if (this->then_->is_nil_expression()
20800 347491 : || this->else_->is_nil_expression())
20801 124904 : result_type = (!this->then_->is_nil_expression()
20802 124904 : ? this->then_->type()
20803 122984 : : this->else_->type());
20804 548757 : return result_type;
20805 : }
20806 :
20807 : // Determine type for a conditional expression.
20808 :
20809 : void
20810 439882 : Conditional_expression::do_determine_type(Gogo* gogo,
20811 : const Type_context* context)
20812 : {
20813 439882 : this->cond_->determine_type_no_context(gogo);
20814 439882 : this->then_->determine_type(gogo, context);
20815 439882 : this->else_->determine_type(gogo, context);
20816 439882 : }
20817 :
20818 : // Get the backend representation of a conditional expression.
20819 :
20820 : Bexpression*
20821 380064 : Conditional_expression::do_get_backend(Translate_context* context)
20822 : {
20823 380064 : Gogo* gogo = context->gogo();
20824 380064 : Btype* result_btype = this->type()->get_backend(gogo);
20825 380064 : Bexpression* cond = this->cond_->get_backend(context);
20826 380064 : Bexpression* then = this->then_->get_backend(context);
20827 380064 : Bexpression* belse = this->else_->get_backend(context);
20828 380064 : Bfunction* bfn = context->function()->func_value()->get_decl();
20829 380064 : return gogo->backend()->conditional_expression(bfn, result_btype, cond, then,
20830 380064 : belse, this->location());
20831 : }
20832 :
20833 : // Dump ast representation of a conditional expression.
20834 :
20835 : void
20836 0 : Conditional_expression::do_dump_expression(
20837 : Ast_dump_context* ast_dump_context) const
20838 : {
20839 0 : ast_dump_context->ostream() << "(";
20840 0 : ast_dump_context->dump_expression(this->cond_);
20841 0 : ast_dump_context->ostream() << " ? ";
20842 0 : ast_dump_context->dump_expression(this->then_);
20843 0 : ast_dump_context->ostream() << " : ";
20844 0 : ast_dump_context->dump_expression(this->else_);
20845 0 : ast_dump_context->ostream() << ") ";
20846 0 : }
20847 :
20848 : // Make a conditional expression.
20849 :
20850 : Expression*
20851 381973 : Expression::make_conditional(Expression* cond, Expression* then,
20852 : Expression* else_expr, Location location)
20853 : {
20854 381973 : return new Conditional_expression(cond, then, else_expr, location);
20855 : }
20856 :
20857 : // Class Compound_expression.
20858 :
20859 : // Traversal.
20860 :
20861 : int
20862 14468 : Compound_expression::do_traverse(Traverse* traverse)
20863 : {
20864 14468 : if (Expression::traverse(&this->init_, traverse) == TRAVERSE_EXIT
20865 14468 : || Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT)
20866 0 : return TRAVERSE_EXIT;
20867 : return TRAVERSE_CONTINUE;
20868 : }
20869 :
20870 : // Return the type of the compound expression.
20871 :
20872 : Type*
20873 14131 : Compound_expression::do_type()
20874 : {
20875 14131 : return this->expr_->type();
20876 : }
20877 :
20878 : // Determine type for a compound expression.
20879 :
20880 : void
20881 103569 : Compound_expression::do_determine_type(Gogo* gogo, const Type_context* context)
20882 : {
20883 103569 : this->init_->determine_type_no_context(gogo);
20884 103569 : this->expr_->determine_type(gogo, context);
20885 103569 : }
20886 :
20887 : // Get the backend representation of a compound expression.
20888 :
20889 : Bexpression*
20890 100032 : Compound_expression::do_get_backend(Translate_context* context)
20891 : {
20892 100032 : Gogo* gogo = context->gogo();
20893 100032 : Bexpression* binit = this->init_->get_backend(context);
20894 100032 : Bfunction* bfunction = context->function()->func_value()->get_decl();
20895 100032 : Bstatement* init_stmt = gogo->backend()->expression_statement(bfunction,
20896 : binit);
20897 100032 : Bexpression* bexpr = this->expr_->get_backend(context);
20898 100032 : return gogo->backend()->compound_expression(init_stmt, bexpr,
20899 100032 : this->location());
20900 : }
20901 :
20902 : // Dump ast representation of a conditional expression.
20903 :
20904 : void
20905 0 : Compound_expression::do_dump_expression(
20906 : Ast_dump_context* ast_dump_context) const
20907 : {
20908 0 : ast_dump_context->ostream() << "(";
20909 0 : ast_dump_context->dump_expression(this->init_);
20910 0 : ast_dump_context->ostream() << ",";
20911 0 : ast_dump_context->dump_expression(this->expr_);
20912 0 : ast_dump_context->ostream() << ") ";
20913 0 : }
20914 :
20915 : // Make a compound expression.
20916 :
20917 : Expression*
20918 100033 : Expression::make_compound(Expression* init, Expression* expr, Location location)
20919 : {
20920 100033 : return new Compound_expression(init, expr, location);
20921 : }
20922 :
20923 : // Class Backend_expression.
20924 :
20925 : int
20926 0 : Backend_expression::do_traverse(Traverse*)
20927 : {
20928 0 : return TRAVERSE_CONTINUE;
20929 : }
20930 :
20931 : Expression*
20932 0 : Backend_expression::do_copy()
20933 : {
20934 0 : return new Backend_expression(this->bexpr_, this->type_->copy_expressions(),
20935 0 : this->location());
20936 : }
20937 :
20938 : void
20939 0 : Backend_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
20940 : {
20941 0 : ast_dump_context->ostream() << "backend_expression<";
20942 0 : ast_dump_context->dump_type(this->type_);
20943 0 : ast_dump_context->ostream() << ">";
20944 0 : }
20945 :
20946 : Expression*
20947 769407 : Expression::make_backend(Bexpression* bexpr, Type* type, Location location)
20948 : {
20949 769407 : return new Backend_expression(bexpr, type, location);
20950 : }
20951 :
20952 : // Import an expression. This comes at the end in order to see the
20953 : // various class definitions.
20954 :
20955 : Expression*
20956 1140540 : Expression::import_expression(Import_expression* imp, Location loc)
20957 : {
20958 1140540 : Expression* expr = Expression::import_expression_without_suffix(imp, loc);
20959 1162461 : while (true)
20960 : {
20961 1162461 : if (imp->match_c_string("("))
20962 : {
20963 18194 : imp->advance(1);
20964 18194 : Expression_list* args = new Expression_list();
20965 18194 : bool is_varargs = false;
20966 26443 : while (!imp->match_c_string(")"))
20967 : {
20968 23597 : Expression* arg = Expression::import_expression(imp, loc);
20969 23597 : if (arg->is_error_expression())
20970 : return arg;
20971 23597 : args->push_back(arg);
20972 23597 : if (imp->match_c_string(")"))
20973 : break;
20974 8571 : else if (imp->match_c_string("...)"))
20975 : {
20976 322 : imp->advance(3);
20977 322 : is_varargs = true;
20978 322 : break;
20979 : }
20980 8249 : imp->require_c_string(", ");
20981 : }
20982 18194 : imp->require_c_string(")");
20983 18194 : expr = Expression::make_call(expr, args, is_varargs, loc);
20984 18194 : expr->call_expression()->set_varargs_are_lowered();
20985 : }
20986 1144267 : else if (imp->match_c_string("["))
20987 : {
20988 3727 : imp->advance(1);
20989 3727 : Expression* start = Expression::import_expression(imp, loc);
20990 3727 : Expression* end = NULL;
20991 3727 : Expression* cap = NULL;
20992 3727 : if (imp->match_c_string(":"))
20993 : {
20994 2119 : imp->advance(1);
20995 2119 : int c = imp->peek_char();
20996 2119 : if (c == ':' || c == ']')
20997 898 : end = Expression::make_nil(loc);
20998 : else
20999 1221 : end = Expression::import_expression(imp, loc);
21000 2119 : if (imp->match_c_string(":"))
21001 : {
21002 0 : imp->advance(1);
21003 0 : cap = Expression::import_expression(imp, loc);
21004 : }
21005 : }
21006 3727 : imp->require_c_string("]");
21007 3727 : expr = Expression::make_index(expr, start, end, cap, loc);
21008 : }
21009 : else
21010 : break;
21011 : }
21012 :
21013 : return expr;
21014 : }
21015 :
21016 : // Import an expression without considering a suffix (function
21017 : // arguments, index operations, etc.).
21018 :
21019 : Expression*
21020 1140540 : Expression::import_expression_without_suffix(Import_expression* imp,
21021 : Location loc)
21022 : {
21023 1140540 : int c = imp->peek_char();
21024 1140540 : if (c == '+' || c == '-' || c == '!' || c == '^' || c == '&' || c == '*')
21025 9449 : return Unary_expression::do_import(imp, loc);
21026 : else if (c == '(')
21027 22026 : return Binary_expression::do_import(imp, loc);
21028 1109065 : else if (imp->match_c_string("$true")
21029 1107695 : || imp->match_c_string("$false")
21030 2215271 : || (imp->version() < EXPORT_FORMAT_V3
21031 0 : && (imp->match_c_string("true")
21032 0 : || imp->match_c_string("false"))))
21033 2859 : return Boolean_expression::do_import(imp, loc);
21034 1106206 : else if (c == '"')
21035 31862 : return String_expression::do_import(imp, loc);
21036 1074344 : else if (c == '-' || (c >= '0' && c <= '9'))
21037 : {
21038 : // This handles integers, floats and complex constants.
21039 979371 : return Integer_expression::do_import(imp, loc);
21040 : }
21041 94973 : else if (imp->match_c_string("<-"))
21042 0 : return Receive_expression::do_import(imp, loc);
21043 94973 : else if (imp->match_c_string("$nil")
21044 94973 : || (imp->version() < EXPORT_FORMAT_V3
21045 0 : && imp->match_c_string("nil")))
21046 621 : return Nil_expression::do_import(imp, loc);
21047 94352 : else if (imp->match_c_string("$convert")
21048 94352 : || (imp->version() < EXPORT_FORMAT_V3
21049 0 : && imp->match_c_string("convert")))
21050 18058 : return Type_conversion_expression::do_import(imp, loc);
21051 :
21052 76294 : Import_function_body* ifb = imp->ifb();
21053 76294 : if (ifb == NULL)
21054 : {
21055 0 : go_error_at(imp->location(), "import error: expected expression");
21056 0 : return Expression::make_error(loc);
21057 : }
21058 76294 : if (ifb->saw_error())
21059 0 : return Expression::make_error(loc);
21060 :
21061 76294 : if (ifb->match_c_string("$t"))
21062 3923 : return Temporary_reference_expression::do_import(ifb, loc);
21063 :
21064 72371 : return Expression::import_identifier(ifb, loc);
21065 : }
21066 :
21067 : // Import an identifier in an expression. This is a reference to a
21068 : // variable or function.
21069 :
21070 : Expression*
21071 72371 : Expression::import_identifier(Import_function_body* ifb, Location loc)
21072 : {
21073 72371 : std::string id;
21074 72371 : Package* pkg;
21075 72371 : bool is_exported;
21076 72371 : if (!Import::read_qualified_identifier(ifb, &id, &pkg, &is_exported))
21077 : {
21078 0 : if (!ifb->saw_error())
21079 0 : go_error_at(ifb->location(),
21080 : "import error for %qs: bad qualified identifier at %lu",
21081 0 : ifb->name().c_str(),
21082 0 : static_cast<unsigned long>(ifb->off()));
21083 0 : ifb->set_saw_error();
21084 0 : return Expression::make_error(loc);
21085 : }
21086 :
21087 72371 : Named_object* no = NULL;
21088 72371 : if (pkg == NULL && is_exported)
21089 63256 : no = ifb->block()->bindings()->lookup(id);
21090 63256 : if (no == NULL)
21091 : {
21092 20060 : const Package* ipkg = pkg;
21093 20060 : if (ipkg == NULL)
21094 16186 : ipkg = ifb->function()->package();
21095 20060 : if (!is_exported)
21096 5631 : id = '.' + ipkg->pkgpath() + '.' + id;
21097 20060 : no = ipkg->bindings()->lookup(id);
21098 : }
21099 20060 : if (no == NULL)
21100 6503 : no = ifb->gogo()->lookup_global(id.c_str());
21101 :
21102 6503 : if (no == NULL)
21103 : {
21104 0 : if (!ifb->saw_error())
21105 0 : go_error_at(ifb->location(),
21106 : "import error for %qs: lookup of %qs failed",
21107 0 : ifb->name().c_str(), id.c_str());
21108 0 : ifb->set_saw_error();
21109 0 : return Expression::make_error(loc);
21110 : }
21111 :
21112 72371 : if (no->is_variable() || no->is_result_variable())
21113 54239 : return Expression::make_var_reference(no, loc);
21114 18132 : else if (no->is_function() || no->is_function_declaration())
21115 18132 : return Expression::make_func_reference(no, NULL, loc);
21116 : else
21117 : {
21118 0 : if (!ifb->saw_error())
21119 0 : go_error_at(ifb->location(),
21120 : ("import error for %qs: "
21121 : "unexpected type of identifier %qs (%d)"),
21122 0 : ifb->name().c_str(),
21123 0 : id.c_str(), no->classification());
21124 0 : ifb->set_saw_error();
21125 0 : return Expression::make_error(loc);
21126 : }
21127 72371 : }
21128 :
21129 : // Class Expression_list.
21130 :
21131 : // Traverse the list.
21132 :
21133 : int
21134 22945259 : Expression_list::traverse(Traverse* traverse)
21135 : {
21136 83410968 : for (Expression_list::iterator p = this->begin();
21137 83410968 : p != this->end();
21138 60465709 : ++p)
21139 : {
21140 60670549 : if (*p != NULL)
21141 : {
21142 60381594 : if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
21143 22945259 : return TRAVERSE_EXIT;
21144 : }
21145 : }
21146 : return TRAVERSE_CONTINUE;
21147 : }
21148 :
21149 : // Copy the list.
21150 :
21151 : Expression_list*
21152 11 : Expression_list::copy()
21153 : {
21154 11 : Expression_list* ret = new Expression_list();
21155 22 : for (Expression_list::iterator p = this->begin();
21156 22 : p != this->end();
21157 11 : ++p)
21158 : {
21159 11 : if (*p == NULL)
21160 0 : ret->push_back(NULL);
21161 : else
21162 11 : ret->push_back((*p)->copy());
21163 : }
21164 11 : return ret;
21165 : }
21166 :
21167 : // Return whether an expression list has an error expression.
21168 :
21169 : bool
21170 0 : Expression_list::contains_error() const
21171 : {
21172 0 : for (Expression_list::const_iterator p = this->begin();
21173 0 : p != this->end();
21174 0 : ++p)
21175 0 : if (*p != NULL && (*p)->is_error_expression())
21176 0 : return true;
21177 : return false;
21178 : }
21179 :
21180 : // Class Numeric_constant.
21181 :
21182 : // Destructor.
21183 :
21184 41303532 : Numeric_constant::~Numeric_constant()
21185 : {
21186 41303532 : this->clear();
21187 41303532 : }
21188 :
21189 : // Copy constructor.
21190 :
21191 0 : Numeric_constant::Numeric_constant(const Numeric_constant& a)
21192 0 : : classification_(a.classification_), type_(a.type_)
21193 : {
21194 0 : switch (a.classification_)
21195 : {
21196 : case NC_INVALID:
21197 : break;
21198 0 : case NC_INT:
21199 0 : case NC_RUNE:
21200 0 : mpz_init_set(this->u_.int_val, a.u_.int_val);
21201 0 : break;
21202 0 : case NC_FLOAT:
21203 0 : mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
21204 0 : break;
21205 0 : case NC_COMPLEX:
21206 0 : mpc_init2(this->u_.complex_val, mpc_precision);
21207 0 : mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
21208 0 : break;
21209 0 : default:
21210 0 : go_unreachable();
21211 : }
21212 0 : }
21213 :
21214 : // Assignment operator.
21215 :
21216 : Numeric_constant&
21217 1029 : Numeric_constant::operator=(const Numeric_constant& a)
21218 : {
21219 1029 : this->clear();
21220 1029 : this->classification_ = a.classification_;
21221 1029 : this->type_ = a.type_;
21222 1029 : switch (a.classification_)
21223 : {
21224 : case NC_INVALID:
21225 : break;
21226 868 : case NC_INT:
21227 868 : case NC_RUNE:
21228 868 : mpz_init_set(this->u_.int_val, a.u_.int_val);
21229 868 : break;
21230 161 : case NC_FLOAT:
21231 161 : mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
21232 161 : break;
21233 0 : case NC_COMPLEX:
21234 0 : mpc_init2(this->u_.complex_val, mpc_precision);
21235 0 : mpc_set(this->u_.complex_val, a.u_.complex_val, MPC_RNDNN);
21236 0 : break;
21237 0 : default:
21238 0 : go_unreachable();
21239 : }
21240 1029 : return *this;
21241 : }
21242 :
21243 : // Check equality with another numeric constant.
21244 :
21245 : bool
21246 32 : Numeric_constant::equals(const Numeric_constant& a) const
21247 : {
21248 32 : if (this->classification_ != a.classification_)
21249 : return false;
21250 :
21251 32 : if (this->type_ != NULL && a.type_ != NULL
21252 64 : && !Type::are_identical(this->type_, a.type_,
21253 : Type::COMPARE_ALIASES, NULL))
21254 : return false;
21255 :
21256 32 : switch (a.classification_)
21257 : {
21258 : case NC_INVALID:
21259 : break;
21260 30 : case NC_INT:
21261 30 : case NC_RUNE:
21262 30 : return mpz_cmp(this->u_.int_val, a.u_.int_val) == 0;
21263 0 : case NC_FLOAT:
21264 0 : return mpfr_cmp(this->u_.float_val, a.u_.float_val) == 0;
21265 2 : case NC_COMPLEX:
21266 2 : return mpc_cmp(this->u_.complex_val, a.u_.complex_val) == 0;
21267 0 : default:
21268 0 : go_unreachable();
21269 : }
21270 : return false;
21271 : }
21272 :
21273 : // Clear the contents.
21274 :
21275 : void
21276 76896795 : Numeric_constant::clear()
21277 : {
21278 76896795 : switch (this->classification_)
21279 : {
21280 : case NC_INVALID:
21281 : break;
21282 35470057 : case NC_INT:
21283 35470057 : case NC_RUNE:
21284 35470057 : mpz_clear(this->u_.int_val);
21285 35470057 : break;
21286 112146 : case NC_FLOAT:
21287 112146 : mpfr_clear(this->u_.float_val);
21288 112146 : break;
21289 10069 : case NC_COMPLEX:
21290 10069 : mpc_clear(this->u_.complex_val);
21291 10069 : break;
21292 0 : default:
21293 0 : go_unreachable();
21294 : }
21295 76896795 : this->classification_ = NC_INVALID;
21296 76896795 : }
21297 :
21298 : // Set to an unsigned long value.
21299 :
21300 : void
21301 67214 : Numeric_constant::set_unsigned_long(Type* type, unsigned long val)
21302 : {
21303 67214 : this->clear();
21304 67214 : this->classification_ = NC_INT;
21305 67214 : this->type_ = type;
21306 67214 : mpz_init_set_ui(this->u_.int_val, val);
21307 67214 : }
21308 :
21309 : // Set to an integer value.
21310 :
21311 : void
21312 35308719 : Numeric_constant::set_int(Type* type, const mpz_t val)
21313 : {
21314 35308719 : this->clear();
21315 35308719 : this->classification_ = NC_INT;
21316 35308719 : this->type_ = type;
21317 35308719 : mpz_init_set(this->u_.int_val, val);
21318 35308719 : }
21319 :
21320 : // Set to a rune value.
21321 :
21322 : void
21323 93735 : Numeric_constant::set_rune(Type* type, const mpz_t val)
21324 : {
21325 93735 : this->clear();
21326 93735 : this->classification_ = NC_RUNE;
21327 93735 : this->type_ = type;
21328 93735 : mpz_init_set(this->u_.int_val, val);
21329 93735 : }
21330 :
21331 : // Set to a floating point value.
21332 :
21333 : void
21334 112486 : Numeric_constant::set_float(Type* type, const mpfr_t val)
21335 : {
21336 112486 : this->clear();
21337 112486 : this->classification_ = NC_FLOAT;
21338 112486 : this->type_ = type;
21339 :
21340 : // Numeric constants do not have negative zero values, so remove
21341 : // them here. They also don't have infinity or NaN values, but we
21342 : // should never see them here.
21343 112486 : int bits = 0;
21344 112486 : if (type != NULL
21345 79463 : && type->float_type() != NULL
21346 191949 : && !type->float_type()->is_abstract())
21347 118728 : bits = type->float_type()->bits();
21348 112486 : if (Numeric_constant::is_float_neg_zero(val, bits))
21349 29 : mpfr_init_set_ui(this->u_.float_val, 0, MPFR_RNDN);
21350 : else
21351 112457 : mpfr_init_set(this->u_.float_val, val, MPFR_RNDN);
21352 112486 : }
21353 :
21354 : // Set to a complex value.
21355 :
21356 : void
21357 10080 : Numeric_constant::set_complex(Type* type, const mpc_t val)
21358 : {
21359 10080 : this->clear();
21360 10080 : this->classification_ = NC_COMPLEX;
21361 10080 : this->type_ = type;
21362 :
21363 : // Avoid negative zero as in set_float.
21364 10080 : int bits = 0;
21365 10080 : if (type != NULL
21366 7143 : && type->complex_type() != NULL
21367 17223 : && !type->complex_type()->is_abstract())
21368 12102 : bits = type->complex_type()->bits() / 2;
21369 :
21370 10080 : mpfr_t real;
21371 10080 : mpfr_init_set(real, mpc_realref(val), MPFR_RNDN);
21372 10080 : if (Numeric_constant::is_float_neg_zero(real, bits))
21373 3 : mpfr_set_ui(real, 0, MPFR_RNDN);
21374 :
21375 10080 : mpfr_t imag;
21376 10080 : mpfr_init_set(imag, mpc_imagref(val), MPFR_RNDN);
21377 10080 : if (Numeric_constant::is_float_neg_zero(imag, bits))
21378 0 : mpfr_set_ui(imag, 0, MPFR_RNDN);
21379 :
21380 10080 : mpc_init2(this->u_.complex_val, mpc_precision);
21381 10080 : mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN);
21382 :
21383 10080 : mpfr_clear(real);
21384 10080 : mpfr_clear(imag);
21385 10080 : }
21386 :
21387 : // Return whether VAL, at a precision of BITS, is a negative zero.
21388 : // BITS may be zero in which case it is ignored.
21389 :
21390 : bool
21391 132646 : Numeric_constant::is_float_neg_zero(const mpfr_t val, int bits)
21392 : {
21393 132646 : if (!mpfr_signbit(val))
21394 : return false;
21395 21171 : if (mpfr_zero_p(val))
21396 : return true;
21397 21141 : mpfr_exp_t min_exp;
21398 21141 : switch (bits)
21399 : {
21400 : case 0:
21401 : return false;
21402 : case 32:
21403 : // In a denormalized float32 the exponent is -126, and there are
21404 : // 24 bits of which at least the last must be 1, so the smallest
21405 : // representable non-zero exponent is -126 - (24 - 1) == -149.
21406 : min_exp = -149;
21407 : break;
21408 11794 : case 64:
21409 : // Minimum exponent is -1022, there are 53 bits.
21410 11794 : min_exp = -1074;
21411 11794 : break;
21412 0 : default:
21413 0 : go_unreachable();
21414 : }
21415 12000 : return mpfr_get_exp(val) < min_exp;
21416 : }
21417 :
21418 : // Get an int value.
21419 :
21420 : void
21421 76497 : Numeric_constant::get_int(mpz_t* val) const
21422 : {
21423 76497 : go_assert(this->is_int());
21424 76497 : mpz_init_set(*val, this->u_.int_val);
21425 76497 : }
21426 :
21427 : // Get a rune value.
21428 :
21429 : void
21430 0 : Numeric_constant::get_rune(mpz_t* val) const
21431 : {
21432 0 : go_assert(this->is_rune());
21433 0 : mpz_init_set(*val, this->u_.int_val);
21434 0 : }
21435 :
21436 : // Get a floating point value.
21437 :
21438 : void
21439 4051 : Numeric_constant::get_float(mpfr_t* val) const
21440 : {
21441 4051 : go_assert(this->is_float());
21442 4051 : mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
21443 4051 : }
21444 :
21445 : // Get a complex value.
21446 :
21447 : void
21448 10 : Numeric_constant::get_complex(mpc_t* val) const
21449 : {
21450 10 : go_assert(this->is_complex());
21451 10 : mpc_init2(*val, mpc_precision);
21452 10 : mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
21453 10 : }
21454 :
21455 : // Express value as unsigned long if possible.
21456 :
21457 : Numeric_constant::To_unsigned_long
21458 773455 : Numeric_constant::to_unsigned_long(unsigned long* val) const
21459 : {
21460 773455 : switch (this->classification_)
21461 : {
21462 773158 : case NC_INT:
21463 773158 : case NC_RUNE:
21464 773158 : return this->mpz_to_unsigned_long(this->u_.int_val, val);
21465 284 : case NC_FLOAT:
21466 284 : return this->mpfr_to_unsigned_long(this->u_.float_val, val);
21467 13 : case NC_COMPLEX:
21468 13 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21469 : return NC_UL_NOTINT;
21470 12 : return this->mpfr_to_unsigned_long(mpc_realref(this->u_.complex_val),
21471 12 : val);
21472 0 : default:
21473 0 : go_unreachable();
21474 : }
21475 : }
21476 :
21477 : // Express integer value as unsigned long if possible.
21478 :
21479 : Numeric_constant::To_unsigned_long
21480 773452 : Numeric_constant::mpz_to_unsigned_long(const mpz_t ival,
21481 : unsigned long *val) const
21482 : {
21483 773452 : if (mpz_sgn(ival) < 0)
21484 : return NC_UL_NEGATIVE;
21485 773029 : unsigned long ui = mpz_get_ui(ival);
21486 773029 : if (mpz_cmp_ui(ival, ui) != 0)
21487 : return NC_UL_BIG;
21488 773018 : *val = ui;
21489 773018 : return NC_UL_VALID;
21490 : }
21491 :
21492 : // Express floating point value as unsigned long if possible.
21493 :
21494 : Numeric_constant::To_unsigned_long
21495 296 : Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval,
21496 : unsigned long *val) const
21497 : {
21498 296 : if (!mpfr_integer_p(fval))
21499 : return NC_UL_NOTINT;
21500 294 : mpz_t ival;
21501 294 : mpz_init(ival);
21502 294 : mpfr_get_z(ival, fval, MPFR_RNDN);
21503 294 : To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val);
21504 294 : mpz_clear(ival);
21505 294 : return ret;
21506 : }
21507 :
21508 : // Express value as memory size if possible.
21509 :
21510 : bool
21511 194238 : Numeric_constant::to_memory_size(int64_t* val) const
21512 : {
21513 194238 : switch (this->classification_)
21514 : {
21515 194233 : case NC_INT:
21516 194233 : case NC_RUNE:
21517 194233 : return this->mpz_to_memory_size(this->u_.int_val, val);
21518 5 : case NC_FLOAT:
21519 5 : return this->mpfr_to_memory_size(this->u_.float_val, val);
21520 0 : case NC_COMPLEX:
21521 0 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21522 : return false;
21523 0 : return this->mpfr_to_memory_size(mpc_realref(this->u_.complex_val), val);
21524 0 : default:
21525 0 : go_unreachable();
21526 : }
21527 : }
21528 :
21529 : // Express integer as memory size if possible.
21530 :
21531 : bool
21532 194238 : Numeric_constant::mpz_to_memory_size(const mpz_t ival, int64_t* val) const
21533 : {
21534 194238 : if (mpz_sgn(ival) < 0)
21535 : return false;
21536 194238 : if (mpz_fits_slong_p(ival))
21537 : {
21538 194238 : *val = static_cast<int64_t>(mpz_get_si(ival));
21539 194238 : return true;
21540 : }
21541 :
21542 : // Test >= 64, not > 64, because an int64_t can hold 63 bits of a
21543 : // positive value.
21544 0 : if (mpz_sizeinbase(ival, 2) >= 64)
21545 : return false;
21546 :
21547 0 : mpz_t q, r;
21548 0 : mpz_init(q);
21549 0 : mpz_init(r);
21550 0 : mpz_tdiv_q_2exp(q, ival, 32);
21551 0 : mpz_tdiv_r_2exp(r, ival, 32);
21552 0 : go_assert(mpz_fits_ulong_p(q) && mpz_fits_ulong_p(r));
21553 0 : *val = ((static_cast<int64_t>(mpz_get_ui(q)) << 32)
21554 0 : + static_cast<int64_t>(mpz_get_ui(r)));
21555 0 : mpz_clear(r);
21556 0 : mpz_clear(q);
21557 0 : return true;
21558 : }
21559 :
21560 : // Express floating point value as memory size if possible.
21561 :
21562 : bool
21563 5 : Numeric_constant::mpfr_to_memory_size(const mpfr_t fval, int64_t* val) const
21564 : {
21565 5 : if (!mpfr_integer_p(fval))
21566 : return false;
21567 5 : mpz_t ival;
21568 5 : mpz_init(ival);
21569 5 : mpfr_get_z(ival, fval, MPFR_RNDN);
21570 5 : bool ret = this->mpz_to_memory_size(ival, val);
21571 5 : mpz_clear(ival);
21572 5 : return ret;
21573 : }
21574 :
21575 : // Convert value to integer if possible.
21576 :
21577 : bool
21578 31457569 : Numeric_constant::to_int(mpz_t* val) const
21579 : {
21580 31457569 : switch (this->classification_)
21581 : {
21582 31453402 : case NC_INT:
21583 31453402 : case NC_RUNE:
21584 31453402 : mpz_init_set(*val, this->u_.int_val);
21585 31453402 : return true;
21586 4128 : case NC_FLOAT:
21587 4128 : if (!mpfr_integer_p(this->u_.float_val))
21588 : return false;
21589 4128 : mpz_init(*val);
21590 4128 : mpfr_get_z(*val, this->u_.float_val, MPFR_RNDN);
21591 4128 : return true;
21592 39 : case NC_COMPLEX:
21593 39 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val))
21594 39 : || !mpfr_integer_p(mpc_realref(this->u_.complex_val)))
21595 0 : return false;
21596 39 : mpz_init(*val);
21597 39 : mpfr_get_z(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21598 39 : return true;
21599 0 : default:
21600 0 : go_unreachable();
21601 : }
21602 : }
21603 :
21604 : // Convert value to floating point if possible.
21605 :
21606 : bool
21607 40198 : Numeric_constant::to_float(mpfr_t* val) const
21608 : {
21609 40198 : switch (this->classification_)
21610 : {
21611 19927 : case NC_INT:
21612 19927 : case NC_RUNE:
21613 19927 : mpfr_init_set_z(*val, this->u_.int_val, MPFR_RNDN);
21614 19927 : return true;
21615 20267 : case NC_FLOAT:
21616 20267 : mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
21617 20267 : return true;
21618 4 : case NC_COMPLEX:
21619 4 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21620 : return false;
21621 4 : mpfr_init_set(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21622 4 : return true;
21623 0 : default:
21624 0 : go_unreachable();
21625 : }
21626 : }
21627 :
21628 : // Convert value to complex.
21629 :
21630 : bool
21631 5034 : Numeric_constant::to_complex(mpc_t* val) const
21632 : {
21633 5034 : mpc_init2(*val, mpc_precision);
21634 5034 : switch (this->classification_)
21635 : {
21636 801 : case NC_INT:
21637 801 : case NC_RUNE:
21638 801 : mpc_set_z(*val, this->u_.int_val, MPC_RNDNN);
21639 801 : return true;
21640 600 : case NC_FLOAT:
21641 600 : mpc_set_fr(*val, this->u_.float_val, MPC_RNDNN);
21642 600 : return true;
21643 3633 : case NC_COMPLEX:
21644 3633 : mpc_set(*val, this->u_.complex_val, MPC_RNDNN);
21645 3633 : return true;
21646 0 : default:
21647 0 : go_unreachable();
21648 : }
21649 : }
21650 :
21651 : // Get the type.
21652 :
21653 : Type*
21654 6993811 : Numeric_constant::type() const
21655 : {
21656 6993811 : if (this->type_ != NULL)
21657 : return this->type_;
21658 28813 : switch (this->classification_)
21659 : {
21660 28813 : case NC_INT:
21661 28813 : return Type::make_abstract_integer_type();
21662 0 : case NC_RUNE:
21663 0 : return Type::make_abstract_character_type();
21664 0 : case NC_FLOAT:
21665 0 : return Type::make_abstract_float_type();
21666 0 : case NC_COMPLEX:
21667 0 : return Type::make_abstract_complex_type();
21668 0 : default:
21669 0 : go_unreachable();
21670 : }
21671 : }
21672 :
21673 : // If the constant can be expressed in TYPE, then set the type of the
21674 : // constant to TYPE and return true. Otherwise return false, and, if
21675 : // ISSUE_ERROR is true, report an appropriate error message.
21676 :
21677 : bool
21678 4163931 : Numeric_constant::set_type(Type* type, bool issue_error, Location loc)
21679 : {
21680 4163931 : bool ret;
21681 4163931 : if (type == NULL || type->is_error())
21682 : ret = true;
21683 4163931 : else if (type->integer_type() != NULL)
21684 8192844 : ret = this->check_int_type(type->integer_type(), issue_error, loc);
21685 67509 : else if (type->float_type() != NULL)
21686 121476 : ret = this->check_float_type(type->float_type(), issue_error, loc);
21687 6771 : else if (type->complex_type() != NULL)
21688 13542 : ret = this->check_complex_type(type->complex_type(), issue_error, loc);
21689 : else
21690 : {
21691 0 : ret = false;
21692 0 : if (issue_error)
21693 0 : go_assert(saw_errors());
21694 : }
21695 4163931 : if (ret)
21696 4162069 : this->type_ = type;
21697 4163931 : return ret;
21698 : }
21699 :
21700 : // Check whether the constant can be expressed in an integer type.
21701 :
21702 : bool
21703 4096422 : Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
21704 : Location location)
21705 : {
21706 4096422 : mpz_t val;
21707 4096422 : switch (this->classification_)
21708 : {
21709 4090930 : case NC_INT:
21710 4090930 : case NC_RUNE:
21711 4090930 : mpz_init_set(val, this->u_.int_val);
21712 4090930 : break;
21713 :
21714 5443 : case NC_FLOAT:
21715 5443 : if (!mpfr_integer_p(this->u_.float_val))
21716 : {
21717 924 : if (issue_error)
21718 : {
21719 489 : go_error_at(location,
21720 : "floating-point constant truncated to integer");
21721 489 : this->set_invalid();
21722 : }
21723 924 : return false;
21724 : }
21725 4519 : mpz_init(val);
21726 4519 : mpfr_get_z(val, this->u_.float_val, MPFR_RNDN);
21727 4519 : break;
21728 :
21729 49 : case NC_COMPLEX:
21730 49 : if (!mpfr_integer_p(mpc_realref(this->u_.complex_val))
21731 49 : || !mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21732 : {
21733 11 : if (issue_error)
21734 : {
21735 8 : go_error_at(location, "complex constant truncated to integer");
21736 8 : this->set_invalid();
21737 : }
21738 11 : return false;
21739 : }
21740 38 : mpz_init(val);
21741 38 : mpfr_get_z(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21742 38 : break;
21743 :
21744 0 : default:
21745 0 : go_unreachable();
21746 : }
21747 :
21748 4095487 : bool ret;
21749 4095487 : if (type->is_abstract())
21750 : ret = true;
21751 : else
21752 : {
21753 2250783 : int bits = mpz_sizeinbase(val, 2);
21754 2250783 : if (type->is_unsigned())
21755 : {
21756 : // For an unsigned type we can only accept a nonnegative
21757 : // number, and we must be able to represents at least BITS.
21758 967273 : ret = mpz_sgn(val) >= 0 && bits <= type->bits();
21759 : }
21760 : else
21761 : {
21762 : // For a signed type we need an extra bit to indicate the
21763 : // sign. We have to handle the most negative integer
21764 : // specially.
21765 1283510 : ret = (bits + 1 <= type->bits()
21766 1283510 : || (bits <= type->bits()
21767 1756 : && mpz_sgn(val) < 0
21768 1752 : && (mpz_scan1(val, 0)
21769 1752 : == static_cast<unsigned long>(type->bits() - 1))
21770 1752 : && mpz_scan0(val, type->bits()) == ULONG_MAX));
21771 : }
21772 : }
21773 :
21774 4095487 : if (!ret && issue_error)
21775 : {
21776 484 : go_error_at(location, "integer constant overflow");
21777 484 : this->set_invalid();
21778 : }
21779 :
21780 : return ret;
21781 : }
21782 :
21783 : // Check whether the constant can be expressed in a floating point
21784 : // type.
21785 :
21786 : bool
21787 60738 : Numeric_constant::check_float_type(Float_type* type, bool issue_error,
21788 : Location location)
21789 : {
21790 60738 : mpfr_t val;
21791 60738 : switch (this->classification_)
21792 : {
21793 22177 : case NC_INT:
21794 22177 : case NC_RUNE:
21795 22177 : mpfr_init_set_z(val, this->u_.int_val, MPFR_RNDN);
21796 22177 : break;
21797 :
21798 38554 : case NC_FLOAT:
21799 38554 : mpfr_init_set(val, this->u_.float_val, MPFR_RNDN);
21800 38554 : break;
21801 :
21802 7 : case NC_COMPLEX:
21803 7 : if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
21804 : {
21805 2 : if (issue_error)
21806 : {
21807 2 : this->set_invalid();
21808 2 : go_error_at(location,
21809 : "complex constant truncated to floating-point");
21810 : }
21811 2 : return false;
21812 : }
21813 5 : mpfr_init_set(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
21814 5 : break;
21815 :
21816 0 : default:
21817 0 : go_unreachable();
21818 : }
21819 :
21820 60736 : bool ret;
21821 60736 : if (type->is_abstract())
21822 : ret = true;
21823 43297 : else if (mpfr_nan_p(val) || mpfr_inf_p(val) || mpfr_zero_p(val))
21824 : {
21825 : // A NaN or Infinity always fits in the range of the type.
21826 : ret = true;
21827 : }
21828 : else
21829 : {
21830 39455 : mpfr_exp_t exp = mpfr_get_exp(val);
21831 39455 : mpfr_exp_t max_exp;
21832 39455 : switch (type->bits())
21833 : {
21834 : case 32:
21835 : max_exp = 128;
21836 : break;
21837 30431 : case 64:
21838 30431 : max_exp = 1024;
21839 30431 : break;
21840 0 : default:
21841 0 : go_unreachable();
21842 : }
21843 :
21844 39455 : ret = exp <= max_exp;
21845 :
21846 39455 : if (ret)
21847 : {
21848 : // Round the constant to the desired type.
21849 39449 : mpfr_t t;
21850 39449 : mpfr_init(t);
21851 39449 : switch (type->bits())
21852 : {
21853 9021 : case 32:
21854 9021 : mpfr_set_prec(t, 24);
21855 9021 : break;
21856 30428 : case 64:
21857 30428 : mpfr_set_prec(t, 53);
21858 30428 : break;
21859 0 : default:
21860 0 : go_unreachable();
21861 : }
21862 39449 : mpfr_set(t, val, MPFR_RNDN);
21863 39449 : mpfr_set(val, t, MPFR_RNDN);
21864 39449 : mpfr_clear(t);
21865 :
21866 39449 : this->set_float(type, val);
21867 : }
21868 : }
21869 :
21870 60736 : mpfr_clear(val);
21871 :
21872 60736 : if (!ret && issue_error)
21873 : {
21874 6 : go_error_at(location, "floating-point constant overflow");
21875 6 : this->set_invalid();
21876 : }
21877 :
21878 : return ret;
21879 : }
21880 :
21881 : // Check whether the constant can be expressed in a complex type.
21882 :
21883 : bool
21884 6771 : Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
21885 : Location location)
21886 : {
21887 6771 : if (type->is_abstract())
21888 : return true;
21889 :
21890 1894 : mpfr_exp_t max_exp;
21891 1894 : switch (type->bits())
21892 : {
21893 : case 64:
21894 : max_exp = 128;
21895 : break;
21896 1542 : case 128:
21897 1542 : max_exp = 1024;
21898 1542 : break;
21899 0 : default:
21900 0 : go_unreachable();
21901 : }
21902 :
21903 1894 : mpc_t val;
21904 1894 : mpc_init2(val, mpc_precision);
21905 1894 : switch (this->classification_)
21906 : {
21907 539 : case NC_INT:
21908 539 : case NC_RUNE:
21909 539 : mpc_set_z(val, this->u_.int_val, MPC_RNDNN);
21910 539 : break;
21911 :
21912 100 : case NC_FLOAT:
21913 100 : mpc_set_fr(val, this->u_.float_val, MPC_RNDNN);
21914 100 : break;
21915 :
21916 1255 : case NC_COMPLEX:
21917 1255 : mpc_set(val, this->u_.complex_val, MPC_RNDNN);
21918 1255 : break;
21919 :
21920 0 : default:
21921 0 : go_unreachable();
21922 : }
21923 :
21924 1894 : bool ret = true;
21925 1894 : if (!mpfr_nan_p(mpc_realref(val))
21926 1894 : && !mpfr_inf_p(mpc_realref(val))
21927 1894 : && !mpfr_zero_p(mpc_realref(val))
21928 1212 : && mpfr_get_exp(mpc_realref(val)) > max_exp)
21929 : {
21930 2 : if (issue_error)
21931 : {
21932 2 : go_error_at(location, "complex real part overflow");
21933 2 : this->set_invalid();
21934 : }
21935 : ret = false;
21936 : }
21937 :
21938 1894 : if (!mpfr_nan_p(mpc_imagref(val))
21939 1894 : && !mpfr_inf_p(mpc_imagref(val))
21940 1894 : && !mpfr_zero_p(mpc_imagref(val))
21941 1032 : && mpfr_get_exp(mpc_imagref(val)) > max_exp)
21942 : {
21943 0 : if (issue_error)
21944 : {
21945 0 : go_error_at(location, "complex imaginary part overflow");
21946 0 : this->set_invalid();
21947 : }
21948 : ret = false;
21949 : }
21950 :
21951 1894 : if (ret)
21952 : {
21953 : // Round the constant to the desired type.
21954 1892 : mpc_t t;
21955 1892 : switch (type->bits())
21956 : {
21957 351 : case 64:
21958 351 : mpc_init2(t, 24);
21959 351 : break;
21960 1541 : case 128:
21961 1541 : mpc_init2(t, 53);
21962 1541 : break;
21963 0 : default:
21964 0 : go_unreachable();
21965 : }
21966 1892 : mpc_set(t, val, MPC_RNDNN);
21967 1892 : mpc_set(val, t, MPC_RNDNN);
21968 1892 : mpc_clear(t);
21969 :
21970 1892 : this->set_complex(type, val);
21971 : }
21972 :
21973 1894 : mpc_clear(val);
21974 :
21975 1894 : return ret;
21976 : }
21977 :
21978 : // Return an Expression for this value.
21979 :
21980 : Expression*
21981 235215 : Numeric_constant::expression(Location loc) const
21982 : {
21983 235215 : switch (this->classification_)
21984 : {
21985 219035 : case NC_INT:
21986 219035 : return Expression::make_integer_z(&this->u_.int_val, this->type_, loc);
21987 4382 : case NC_RUNE:
21988 4382 : return Expression::make_character(&this->u_.int_val, this->type_, loc);
21989 9205 : case NC_FLOAT:
21990 9205 : return Expression::make_float(&this->u_.float_val, this->type_, loc);
21991 2593 : case NC_COMPLEX:
21992 2593 : return Expression::make_complex(&this->u_.complex_val, this->type_, loc);
21993 0 : case NC_INVALID:
21994 0 : go_assert(saw_errors());
21995 0 : return Expression::make_error(loc);
21996 0 : default:
21997 0 : go_unreachable();
21998 : }
21999 : }
22000 :
22001 : // Calculate a hash code with a given seed.
22002 :
22003 : unsigned int
22004 3663 : Numeric_constant::hash(unsigned int seed) const
22005 : {
22006 3663 : unsigned long val;
22007 3663 : const unsigned int PRIME = 97;
22008 3663 : long e = 0;
22009 3663 : double f = 1.0;
22010 3663 : mpfr_t m;
22011 :
22012 3663 : switch (this->classification_)
22013 : {
22014 : case NC_INVALID:
22015 : return PRIME;
22016 3653 : case NC_INT:
22017 3653 : case NC_RUNE:
22018 3653 : val = mpz_get_ui(this->u_.int_val);
22019 : break;
22020 4 : case NC_COMPLEX:
22021 4 : mpfr_init(m);
22022 4 : mpc_abs(m, this->u_.complex_val, MPFR_RNDN);
22023 4 : val = mpfr_get_ui(m, MPFR_RNDN);
22024 4 : mpfr_clear(m);
22025 4 : break;
22026 6 : case NC_FLOAT:
22027 6 : f = mpfr_get_d_2exp(&e, this->u_.float_val, MPFR_RNDN) * 4294967295.0;
22028 6 : val = static_cast<unsigned long>(e + static_cast<long>(f));
22029 6 : break;
22030 0 : default:
22031 0 : go_unreachable();
22032 : }
22033 :
22034 3663 : return (static_cast<unsigned int>(val) + seed) * PRIME;
22035 : }
|