Also pass Gogo to the type verification pass.
This is a refactoring that does not change the compiler behavior.
This is in preparation for future CLs that rearrange the pass ordering.
This introduces one new call to go_get_gogo, which will be removed in
a future CL.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/536635
-967a215d6419c3db58f8f59a0c252c458abce395
+06ada1f2ab9b05e54641438db28c557c6900b2a3
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
// child class.
void
-Expression::determine_type(const Type_context* context)
+Expression::determine_type(Gogo* gogo, const Type_context* context)
{
- this->do_determine_type(context);
+ this->do_determine_type(gogo, context);
}
// Set types when there is no context.
void
-Expression::determine_type_no_context()
+Expression::determine_type_no_context(Gogo* gogo)
{
Type_context context;
- this->do_determine_type(&context);
+ this->do_determine_type(gogo, &context);
}
// Return true if two expressions refer to the same variable or struct
{ return Type::make_error_type(); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
{ return this->type_; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
void
// Determine the type of a reference to a variable.
void
-Var_expression::do_determine_type(const Type_context*)
+Var_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
if (this->variable_->is_variable())
- this->variable_->var_value()->determine_type();
+ this->variable_->var_value()->determine_type(gogo);
}
// Something takes the address of this variable. This means that we
void
Set_and_use_temporary_expression::do_determine_type(
+ Gogo* gogo,
const Type_context* context)
{
- this->expr_->determine_type(context);
+ this->expr_->determine_type(gogo, context);
}
// Take the address.
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
// Determine the type of a sink expression.
void
-Sink_expression::do_determine_type(const Type_context* context)
+Sink_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (context->type != NULL)
this->type_ = context->type;
{ return Type::make_pointer_type(Type::make_void_type()); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
// Set the type from the context.
void
-Boolean_expression::do_determine_type(const Type_context* context)
+Boolean_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
// Set the type from the context.
void
-String_expression::do_determine_type(const Type_context* context)
+String_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
{ return Type::make_string_type(); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
do_type();
void
- do_determine_type(const Type_context* context);
+ do_determine_type(Gogo*, const Type_context* context);
void
do_check_types(Gogo*);
// abstract type to a real type.
void
-Integer_expression::do_determine_type(const Type_context* context)
+Integer_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
// abstract type to a real type.
void
-Float_expression::do_determine_type(const Type_context* context)
+Float_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
// abstract type to a real type.
void
-Complex_expression::do_determine_type(const Type_context* context)
+Complex_expression::do_determine_type(Gogo*, const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
// Set the type of the const reference.
void
-Const_expression::do_determine_type(const Type_context* context)
+Const_expression::do_determine_type(Gogo*, const Type_context* context)
{
Type* ctype = this->constant_->const_value()->type();
Type* cetype = (ctype != NULL
{ return Type::make_nil_type(); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
// Determine the resulting type of the conversion.
void
-Type_conversion_expression::do_determine_type(const Type_context*)
+Type_conversion_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
Type_context subcontext(this->type_, false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
// Check that types are convertible.
// Determine abstract types for a unary expression.
void
-Unary_expression::do_determine_type(const Type_context* context)
+Unary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
switch (this->op_)
{
case OPERATOR_MINUS:
case OPERATOR_NOT:
case OPERATOR_XOR:
- this->expr_->determine_type(context);
+ this->expr_->determine_type(gogo, context);
break;
case OPERATOR_AND:
? NULL
: context->type->points_to());
Type_context subcontext(subtype, false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
break;
? NULL
: Type::make_pointer_type(context->type));
Type_context subcontext(subtype, false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
break;
// Set type for a binary expression.
void
-Binary_expression::do_determine_type(const Type_context* context)
+Binary_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
Type* tleft = this->left_->type();
Type* tright = this->right_->type();
subcontext.type = subcontext.type->make_non_abstract_type();
}
- this->left_->determine_type(&subcontext);
+ this->left_->determine_type(gogo, &subcontext);
if (is_shift_op)
{
subcontext.may_be_abstract = false;
}
- this->right_->determine_type(&subcontext);
+ this->right_->determine_type(gogo, &subcontext);
if (is_comparison)
{
}
void
-String_concat_expression::do_determine_type(const Type_context* context)
+String_concat_expression::do_determine_type(Gogo* gogo,
+ const Type_context* context)
{
Type_context subcontext(*context);
for (Expression_list::iterator pe = this->exprs_->begin();
for (Expression_list::iterator pe = this->exprs_->begin();
pe != this->exprs_->end();
++pe)
- (*pe)->determine_type(&subcontext);
+ (*pe)->determine_type(gogo, &subcontext);
}
void
// Determine the types of a method expression.
void
-Bound_method_expression::do_determine_type(const Type_context*)
+Bound_method_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
Named_object* fn = this->method_->named_object();
Function_type* fntype;
else
fntype = NULL;
if (fntype == NULL || !fntype->is_method())
- this->expr_->determine_type_no_context();
+ this->expr_->determine_type_no_context(gogo);
else
{
Type_context subcontext(fntype->receiver()->type(), false);
- this->expr_->determine_type(&subcontext);
+ this->expr_->determine_type(gogo, &subcontext);
}
}
// specific expressions. We also convert to a constant if we can.
Expression*
-Builtin_call_expression::do_lower(Gogo*, Named_object* function,
+Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
Statement_inserter* inserter, int)
{
if (this->is_error_expression())
break;
case BUILTIN_MAKE:
- return this->lower_make(inserter);
+ return this->lower_make(gogo, inserter);
case BUILTIN_RECOVER:
if (function != NULL)
// Lower a make expression.
Expression*
-Builtin_call_expression::lower_make(Statement_inserter* inserter)
+Builtin_call_expression::lower_make(Gogo* gogo, Statement_inserter* inserter)
{
Location loc = this->location();
else
{
len_arg = *parg;
- len_arg->determine_type(&int_context);
+ len_arg->determine_type(gogo, &int_context);
if (len_arg->type()->integer_type() == NULL)
{
go_error_at(len_arg->location(), "non-integer len argument in make");
if (is_slice && parg != args->end())
{
cap_arg = *parg;
- cap_arg->determine_type(&int_context);
+ cap_arg->determine_type(gogo, &int_context);
if (cap_arg->type()->integer_type() == NULL)
{
go_error_at(cap_arg->location(), "non-integer cap argument in make");
// We may be replacing this expression with a constant
// during lowering, so verify the type to report any errors.
// It's OK to verify an array type more than once.
- arg_type->verify();
+ // FIXME: Remove this reference to go_get_gogo.
+ arg_type->verify(go_get_gogo());
if (!arg_type->is_error())
{
Expression* e = arg_type->array_type()->length();
// Determine the type.
void
-Builtin_call_expression::do_determine_type(const Type_context* context)
+Builtin_call_expression::do_determine_type(Gogo* gogo,
+ const Type_context* context)
{
if (!this->determining_types())
return;
- this->fn()->determine_type_no_context();
+ this->fn()->determine_type_no_context(gogo);
const Expression_list* args = this->args();
if (args != NULL && args->size() == 2)
{
if (this->code_ == BUILTIN_SLICE)
- args->front()->determine_type_no_context();
+ args->front()->determine_type_no_context(gogo);
else
{
Type* pointer = Type::make_pointer_type(Type::make_void_type());
Type_context subcontext(pointer, false);
- args->front()->determine_type(&subcontext);
+ args->front()->determine_type(gogo, &subcontext);
}
Type* int_type = Type::lookup_integer_type("int");
Type_context subcontext(int_type, false);
- args->back()->determine_type(&subcontext);
+ args->back()->determine_type(gogo, &subcontext);
return;
}
is_print = false;
}
}
- (*pa)->determine_type(&subcontext);
+ (*pa)->determine_type(gogo, &subcontext);
if (trailing_arg_types != NULL)
{
// parameter types to set the types of the arguments.
void
-Call_expression::do_determine_type(const Type_context* context)
+Call_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
if (!this->determining_types())
return;
- this->fn_->determine_type_no_context();
+ this->fn_->determine_type_no_context(gogo);
Function_type* fntype = this->get_function_type();
const Typed_identifier_list* parameters = NULL;
if (fntype != NULL)
if (rtype->points_to() == NULL)
rtype = Type::make_pointer_type(rtype);
Type_context subcontext(rtype, false);
- (*pa)->determine_type(&subcontext);
+ (*pa)->determine_type(gogo, &subcontext);
continue;
}
}
if (parameters != NULL && pt != parameters->end())
{
Type_context subcontext(pt->type(), false);
- (*pa)->determine_type(&subcontext);
+ (*pa)->determine_type(gogo, &subcontext);
++pt;
}
else
- (*pa)->determine_type_no_context();
+ (*pa)->determine_type_no_context(gogo);
}
}
// needs to pass down to the caller.
void
-Call_result_expression::do_determine_type(const Type_context*)
+Call_result_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->call_->determine_type_no_context();
+ this->call_->determine_type_no_context(gogo);
}
// Return the backend representation. We just refer to the temporary set by the
// Set the type of an array index.
void
-Array_index_expression::do_determine_type(const Type_context*)
+Array_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->array_->determine_type_no_context();
+ this->array_->determine_type_no_context(gogo);
Type_context index_context(Type::lookup_integer_type("int"), false);
- this->start_->determine_type(&index_context);
+ this->start_->determine_type(gogo, &index_context);
if (this->end_ != NULL)
- this->end_->determine_type(&index_context);
+ this->end_->determine_type(gogo, &index_context);
if (this->cap_ != NULL)
- this->cap_->determine_type(&index_context);
+ this->cap_->determine_type(gogo, &index_context);
}
// Check types of an array index.
// Determine the type of a string index.
void
-String_index_expression::do_determine_type(const Type_context*)
+String_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->string_->determine_type_no_context();
+ this->string_->determine_type_no_context(gogo);
Type_context index_context(Type::lookup_integer_type("int"), false);
- this->start_->determine_type(&index_context);
+ this->start_->determine_type(gogo, &index_context);
if (this->end_ != NULL)
- this->end_->determine_type(&index_context);
+ this->end_->determine_type(gogo, &index_context);
}
// Check types of a string index.
// Fix the type of a map index.
void
-Map_index_expression::do_determine_type(const Type_context*)
+Map_index_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->map_->determine_type_no_context();
+ this->map_->determine_type_no_context(gogo);
Map_type* mt = this->get_map_type();
Type* key_type = mt == NULL ? NULL : mt->key_type();
Type_context subcontext(key_type, false);
- this->index_->determine_type(&subcontext);
+ this->index_->determine_type(gogo, &subcontext);
}
// Check types of a map index.
// Determine types.
void
-Interface_field_reference_expression::do_determine_type(const Type_context*)
+Interface_field_reference_expression::do_determine_type(Gogo* gogo,
+ const Type_context*)
{
- this->expr_->determine_type_no_context();
+ this->expr_->determine_type_no_context(gogo);
}
// Check the types for an interface field reference.
// Final type determination.
void
-Struct_construction_expression::do_determine_type(const Type_context*)
+Struct_construction_expression::do_determine_type(Gogo* gogo,
+ const Type_context*)
{
if (this->vals() == NULL)
return;
if (*pv != NULL)
{
Type_context subcontext(pf->type(), false);
- (*pv)->determine_type(&subcontext);
+ (*pv)->determine_type(gogo, &subcontext);
}
}
// Extra values are an error we will report elsewhere; we still want
// to determine the type to avoid knockon errors.
for (; pv != this->vals()->end(); ++pv)
- (*pv)->determine_type_no_context();
+ (*pv)->determine_type_no_context(gogo);
}
// Check types.
// Final type determination.
void
-Array_construction_expression::do_determine_type(const Type_context*)
+Array_construction_expression::do_determine_type(Gogo* gogo,
+ const Type_context*)
{
if (this->is_error_expression())
{
++pv)
{
if (*pv != NULL)
- (*pv)->determine_type(&subcontext);
+ (*pv)->determine_type(gogo, &subcontext);
}
}
// Final type determination.
void
-Map_construction_expression::do_determine_type(const Type_context*)
+Map_construction_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
if (this->vals_ == NULL)
return;
pv != this->vals_->end();
++pv)
{
- (*pv)->determine_type(&key_context);
+ (*pv)->determine_type(gogo, &key_context);
++pv;
- (*pv)->determine_type(&val_context);
+ (*pv)->determine_type(gogo, &val_context);
}
}
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
// Determine type of a slice value.
void
-Slice_value_expression::do_determine_type(const Type_context*)
+Slice_value_expression::do_determine_type(Gogo* gogo, const Type_context*)
{
- this->valmem_->determine_type_no_context();
- this->len_->determine_type_no_context();
- this->cap_->determine_type_no_context();
+ this->valmem_->determine_type_no_context(gogo);
+ this->len_->determine_type_no_context(gogo);
+ this->cap_->determine_type_no_context(gogo);
}
Expression*
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
{ return this->type_; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
{ return true; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
Expression*
{ return Type::lookup_integer_type("uintptr"); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
{ return Type::make_pointer_type(Type::make_void_type()); }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
// Determine type for a conditional expression.
void
-Conditional_expression::do_determine_type(const Type_context* context)
+Conditional_expression::do_determine_type(Gogo* gogo,
+ const Type_context* context)
{
- this->cond_->determine_type_no_context();
- this->then_->determine_type(context);
- this->else_->determine_type(context);
+ this->cond_->determine_type_no_context(gogo);
+ this->then_->determine_type(gogo, context);
+ this->else_->determine_type(gogo, context);
}
// Get the backend representation of a conditional expression.
// Determine type for a compound expression.
void
-Compound_expression::do_determine_type(const Type_context* context)
+Compound_expression::do_determine_type(Gogo* gogo, const Type_context* context)
{
- this->init_->determine_type_no_context();
- this->expr_->determine_type(context);
+ this->init_->determine_type_no_context(gogo);
+ this->expr_->determine_type(gogo, context);
}
// Get the backend representation of a compound expression.
// floating point, or complex type. TYPE_CONTEXT describes the
// expected type.
void
- determine_type(const Type_context*);
+ determine_type(Gogo*, const Type_context*);
// Check types in an expression.
void
// Determine the type when there is no context.
void
- determine_type_no_context();
+ determine_type_no_context(Gogo*);
// Return the current type of the expression. This may be changed
// by determine_type. This should not be called before the lowering
// Child class implements determining type information.
virtual void
- do_determine_type(const Type_context*) = 0;
+ do_determine_type(Gogo*, const Type_context*) = 0;
// Child class implements type checking if needed.
virtual void
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ go_unreachable(); }
void
// The type of a const is set by the declaration, not the use.
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
{ return this->reference_->type(); }
void
- do_determine_type(const Type_context* context)
- { return this->reference_->determine_type(context); }
+ do_determine_type(Gogo* gogo, const Type_context* context)
+ { return this->reference_->determine_type(gogo, context); }
Expression*
do_copy()
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
{ return this->type_; }
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
Expression*
do_copy();
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
virtual void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
virtual void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
complex_type(Type*);
Expression*
- lower_make(Statement_inserter*);
+ lower_make(Gogo*, Statement_inserter*);
bool
check_int_value(Expression*, bool is_length, bool* small);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo* gogo, const Type_context*)
{
if (this->closure_ != NULL)
- this->closure_->determine_type_no_context();
+ this->closure_->determine_type_no_context(gogo);
}
Expression*
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
do_type();
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
void
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
void
do_check_types(Gogo*);
{ return this->type_; }
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
void
do_check_types(Gogo*);
Type*
do_type();
void
- do_determine_type(const Type_context*)
- { this->expr_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->expr_->determine_type_no_context(gogo); }
Expression*
do_copy()
do_flatten(Gogo*, Named_object*, Statement_inserter*);
void
- do_determine_type(const Type_context*)
- { this->channel_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->channel_->determine_type_no_context(gogo); }
void
do_check_types(Gogo*);
{ return this->type_; }
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy();
do_type();
void
- do_determine_type(const Type_context*)
- { this->slice_->determine_type_no_context(); }
+ do_determine_type(Gogo* gogo, const Type_context*)
+ { this->slice_->determine_type_no_context(gogo); }
Expression*
do_copy()
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
do_type();
void
- do_determine_type(const Type_context*);
+ do_determine_type(Gogo*, const Type_context*);
Expression*
do_copy()
{ return this->type_; }
void
- do_determine_type(const Type_context*)
+ do_determine_type(Gogo*, const Type_context*)
{ }
Expression*
class Verify_types : public Traverse
{
public:
- Verify_types()
- : Traverse(traverse_types)
+ Verify_types(Gogo* gogo)
+ : Traverse(traverse_types),
+ gogo_(gogo)
{ }
int
type(Type*);
+
+ private:
+ Gogo* gogo_;
};
// Verify that a type is correct.
int
Verify_types::type(Type* t)
{
- if (!t->verify())
+ if (!t->verify(this->gogo_))
return TRAVERSE_SKIP_COMPONENTS;
return TRAVERSE_CONTINUE;
}
void
Gogo::verify_types()
{
- Verify_types traverse;
+ Verify_types traverse(this);
this->traverse(&traverse);
for (std::vector<Type*>::iterator p = this->verify_types_.begin();
p != this->verify_types_.end();
++p)
- (*p)->verify();
+ (*p)->verify(this);
this->verify_types_.clear();
}
class Remove_deadcode : public Traverse
{
public:
- Remove_deadcode()
+ Remove_deadcode(Gogo* gogo)
: Traverse(traverse_statements
- | traverse_expressions)
+ | traverse_expressions),
+ gogo_(gogo)
{ }
int
int
expression(Expression**);
+
+ private:
+ Gogo* gogo_;
};
// Remove deadcode in a statement.
{
*pexpr = Expression::make_boolean(bval, be->location());
Type_context context(NULL, false);
- (*pexpr)->determine_type(&context);
+ (*pexpr)->determine_type(this->gogo_, &context);
}
return TRAVERSE_CONTINUE;
}
void
Gogo::remove_deadcode()
{
- Remove_deadcode remove_deadcode;
+ Remove_deadcode remove_deadcode(this);
this->traverse(&remove_deadcode);
}
++p)
{
if ((*p)->is_function())
- (*p)->func_value()->determine_types();
+ (*p)->func_value()->determine_types(this);
else if ((*p)->is_variable())
- (*p)->var_value()->determine_type();
+ (*p)->var_value()->determine_type(this);
else if ((*p)->is_const())
- (*p)->const_value()->determine_type();
+ (*p)->const_value()->determine_type(this);
// See if a variable requires us to build an initialization
// function. We know that we will see all global variables
for (Packages::const_iterator p = this->packages_.begin();
p != this->packages_.end();
++p)
- p->second->determine_types();
+ p->second->determine_types(this);
}
// Traversal class used for type checking.
call->set_varargs_are_lowered();
Statement* s = Statement::make_return_from_call(call, location);
- s->determine_types();
+ s->determine_types(this->gogo_);
gogo->add_statement(s);
Block* b = gogo->finish_block(location);
// Work out types for unspecified variables and constants.
void
-Function::determine_types()
+Function::determine_types(Gogo* gogo)
{
if (this->block_ != NULL)
- this->block_->determine_types();
+ this->block_->determine_types(gogo);
}
// Return the function descriptor, the value you get when you refer to
// Work out types for unspecified variables and constants.
void
-Block::determine_types()
+Block::determine_types(Gogo* gogo)
{
for (Bindings::const_definitions_iterator pb =
this->bindings_->begin_definitions();
++pb)
{
if ((*pb)->is_variable())
- (*pb)->var_value()->determine_type();
+ (*pb)->var_value()->determine_type(gogo);
else if ((*pb)->is_const())
- (*pb)->const_value()->determine_type();
+ (*pb)->const_value()->determine_type(gogo);
}
for (std::vector<Statement*>::const_iterator ps = this->statements_.begin();
ps != this->statements_.end();
++ps)
- (*ps)->determine_types();
+ (*ps)->determine_types(gogo);
}
// Return true if the statements in this block may fall through.
return;
gogo->lower_block(no, outer);
- outer->determine_types();
+ outer->determine_types(gogo);
gogo->add_imported_inline_function(no);
}
// Set the type if necessary.
void
-Variable::determine_type()
+Variable::determine_type(Gogo* gogo)
{
if (this->determined_type_)
return;
this->determined_type_ = true;
if (this->preinit_ != NULL)
- this->preinit_->determine_types();
+ this->preinit_->determine_types(gogo);
// A variable in a type switch with a nil case will have the wrong
// type here. It will have an initializer which is a type guard.
else if (this->type_from_init_tuple_)
{
Expression *init = this->init_;
- init->determine_type_no_context();
+ init->determine_type_no_context(gogo);
this->type_ = this->type_from_tuple(init, true);
this->init_ = NULL;
}
else if (this->type_from_range_index_ || this->type_from_range_value_)
{
Expression* init = this->init_;
- init->determine_type_no_context();
+ init->determine_type_no_context(gogo);
this->type_ = this->type_from_range(init, this->type_from_range_index_,
true);
this->init_ = NULL;
else if (this->type_from_chan_element_)
{
Expression* init = this->init_;
- init->determine_type_no_context();
+ init->determine_type_no_context(gogo);
this->type_ = this->type_from_chan_element(init, true);
this->init_ = NULL;
}
else
{
Type_context context(this->type_, false);
- this->init_->determine_type(&context);
+ this->init_->determine_type(gogo, &context);
if (this->type_ == NULL)
{
Type* type = this->init_->type();
// Determine the type of the constant.
void
-Named_constant::determine_type()
+Named_constant::determine_type(Gogo* gogo)
{
if (this->type_ != NULL)
{
Type_context context(this->type_, false);
- this->expr_->determine_type(&context);
+ this->expr_->determine_type(gogo, &context);
}
else
{
// A constant may have an abstract type.
Type_context context(NULL, true);
- this->expr_->determine_type(&context);
+ this->expr_->determine_type(gogo, &context);
this->type_ = this->expr_->type();
go_assert(this->type_ != NULL);
}
// type. Constants may have abstract types.
void
-Package::determine_types()
+Package::determine_types(Gogo* gogo)
{
Bindings* bindings = this->bindings_;
for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
++p)
{
if ((*p)->is_const())
- (*p)->const_value()->determine_type();
+ (*p)->const_value()->determine_type(gogo);
}
}
// Set final types for unspecified variables and constants.
void
- determine_types();
+ determine_types(Gogo*);
// Return true if execution of this block may fall through to the
// next block.
// Determine types in the function.
void
- determine_types();
+ determine_types(Gogo*);
// Return an expression for the function descriptor, given the named
// object for this function. This may only be called for functions
// Determine the type of the variable if necessary.
void
- determine_type();
+ determine_type(Gogo*);
// Get the backend representation of the variable.
Bvariable*
// Determine the type of the constant if necessary.
void
- determine_type();
+ determine_type(Gogo*);
// Indicate that we found and reported an error for this constant.
void
// Determine types of constants.
void
- determine_types();
+ determine_types(Gogo*);
private:
// The package path for type reflection data.
Type* t = runtime_function_types[i];
if (t != NULL && t->named_type() != NULL)
{
- bool r = t->verify();
+ bool r = t->verify(gogo);
go_assert(r);
t->named_type()->convert(gogo);
}
// the child class.
void
-Statement::determine_types()
+Statement::determine_types(Gogo* gogo)
{
- this->do_determine_types();
+ this->do_determine_types(gogo);
}
// Read a statement from export data.
// Determine types.
void
-Temporary_statement::do_determine_types()
+Temporary_statement::do_determine_types(Gogo* gogo)
{
if (this->type_ != NULL && this->type_->is_abstract())
this->type_ = this->type_->make_non_abstract_type();
if (this->init_ != NULL)
{
if (this->type_ == NULL)
- this->init_->determine_type_no_context();
+ this->init_->determine_type_no_context(gogo);
else
{
Type_context context(this->type_, false);
- this->init_->determine_type(&context);
+ this->init_->determine_type(gogo, &context);
}
}
// Set types for the assignment.
void
-Assignment_statement::do_determine_types()
+Assignment_statement::do_determine_types(Gogo* gogo)
{
- this->lhs_->determine_type_no_context();
+ this->lhs_->determine_type_no_context(gogo);
Type* rhs_context_type = this->lhs_->type();
if (rhs_context_type->is_sink_type())
rhs_context_type = NULL;
Type_context context(rhs_context_type, false);
- this->rhs_->determine_type(&context);
+ this->rhs_->determine_type(gogo, &context);
}
// Check types for an assignment.
// Determine types.
void
-Expression_statement::do_determine_types()
+Expression_statement::do_determine_types(Gogo* gogo)
{
- this->expr_->determine_type_no_context();
+ this->expr_->determine_type_no_context(gogo);
}
// Check the types of an expression statement. The only check we do
// Determine types in a thunk statement.
void
-Thunk_statement::do_determine_types()
+Thunk_statement::do_determine_types(Gogo* gogo)
{
- this->call_->determine_type_no_context();
+ this->call_->determine_type_no_context(gogo);
}
// Check types in a thunk statement.
// We already ran the determine_types pass, so we need to run it now
// for the new statement.
- s->determine_types();
+ s->determine_types(gogo);
// Sanity check.
gogo->check_types_in_block(block);
gogo->add_statement(Statement::make_goto_statement(retaddr_label,
location));
Block* then_block = gogo->finish_block(location);
- then_block->determine_types();
+ then_block->determine_types(gogo);
Statement* s = Statement::make_if_statement(call, then_block, NULL,
location);
- s->determine_types();
+ s->determine_types(gogo);
gogo->add_statement(s);
function->func_value()->set_calls_defer_retaddr();
// We already ran the determine_types pass, so we need to run it
// just for the call statement now. The other types are known.
- call_statement->determine_types();
+ call_statement->determine_types(gogo);
gogo->add_conversions_in_block(b);
// return. This lets panic/recover work correctly.
Statement*
-Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
- Statement_inserter*)
+Return_statement::do_lower(Gogo* gogo, Named_object* function,
+ Block* enclosing, Statement_inserter*)
{
if (this->is_lowered_)
return this;
Type *rvtype = rv->result_var_value()->type();
Type_context type_context(rvtype, false);
- e->determine_type(&type_context);
+ e->determine_type(gogo, &type_context);
std::string reason;
if (Type::are_assignable(rvtype, e->type(), &reason))
}
void
-If_statement::do_determine_types()
+If_statement::do_determine_types(Gogo* gogo)
{
Type_context context(Type::lookup_bool_type(), false);
- this->cond_->determine_type(&context);
- this->then_block_->determine_types();
+ this->cond_->determine_type(gogo, &context);
+ this->then_block_->determine_types(gogo);
if (this->else_block_ != NULL)
- this->else_block_->determine_types();
+ this->else_block_->determine_types(gogo);
}
// Check types.
// Determine types.
void
-Case_clauses::Case_clause::determine_types(Type* type)
+Case_clauses::Case_clause::determine_types(Gogo* gogo, Type* type)
{
if (this->cases_ != NULL)
{
for (Expression_list::iterator p = this->cases_->begin();
p != this->cases_->end();
++p)
- (*p)->determine_type(&case_context);
+ (*p)->determine_type(gogo, &case_context);
}
if (this->statements_ != NULL)
- this->statements_->determine_types();
+ this->statements_->determine_types(gogo);
}
// Check types. Returns false if there was an error.
// Determine types.
void
-Case_clauses::determine_types(Type* type)
+Case_clauses::determine_types(Gogo* gogo, Type* type)
{
for (Clauses::iterator p = this->clauses_.begin();
p != this->clauses_.end();
++p)
- p->determine_types(type);
+ p->determine_types(gogo, type);
}
// Check types. Returns false if there was an error.
do_traverse(Traverse*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
// Determine types.
void
-Constant_switch_statement::do_determine_types()
+Constant_switch_statement::do_determine_types(Gogo* gogo)
{
- this->val_->determine_type_no_context();
- this->clauses_->determine_types(this->val_->type());
+ this->val_->determine_type_no_context(gogo);
+ this->clauses_->determine_types(gogo, this->val_->type());
}
// Check types.
// Determine types.
void
-Send_statement::do_determine_types()
+Send_statement::do_determine_types(Gogo* gogo)
{
- this->channel_->determine_type_no_context();
+ this->channel_->determine_type_no_context(gogo);
Type* type = this->channel_->type();
Type_context context;
if (type->channel_type() != NULL)
context.type = type->channel_type()->element_type();
- this->val_->determine_type(&context);
+ this->val_->determine_type(gogo, &context);
}
// Check types.
// Determine types.
void
-Select_clauses::Select_clause::determine_types()
+Select_clauses::Select_clause::determine_types(Gogo* gogo)
{
go_assert(this->is_lowered_);
if (this->statements_ != NULL)
- this->statements_->determine_types();
+ this->statements_->determine_types(gogo);
}
// Check types.
// Determine types.
void
-Select_clauses::determine_types()
+Select_clauses::determine_types(Gogo* gogo)
{
for (Clauses::iterator p = this->clauses_.begin();
p != this->clauses_.end();
++p)
- p->determine_types();
+ p->determine_types(gogo);
}
// Check types.
// Set type information for unnamed constants.
void
- determine_types();
+ determine_types(Gogo*);
// Check types in a statement. This simply checks that any
// expressions used by the statement have the right type.
// constants. Any statement which includes an expression needs to
// implement this.
virtual void
- do_determine_types()
+ do_determine_types(Gogo*)
{ }
// Implemented by child class: check types of expressions used in a
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
do_traverse_assignments(Traverse_assignments*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
{ return this->traverse_expression(traverse, &this->expr_); }
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
{ return this->block_->traverse(traverse); }
void
- do_determine_types()
- { this->block_->determine_types(); }
+ do_determine_types(Gogo* gogo)
+ { this->block_->determine_types(gogo); }
int
do_inlining_cost()
do_traverse(Traverse* traverse);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
// Determine types.
void
- determine_types();
+ determine_types(Gogo*);
// Check types.
void
// Determine types.
void
- determine_types();
+ determine_types(Gogo*);
// Check types.
void
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
void
- do_determine_types()
- { this->clauses_->determine_types(); }
+ do_determine_types(Gogo* gogo)
+ { this->clauses_->determine_types(gogo); }
void
do_check_types(Gogo*)
do_traverse_assignments(Traverse_assignments*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
do_traverse(Traverse*);
void
- do_determine_types();
+ do_determine_types(Gogo*);
void
do_check_types(Gogo*);
// Determine types of expressions. The Type parameter is the type
// of the switch value.
void
- determine_types(Type*);
+ determine_types(Gogo*, Type*);
// Check types. The Type parameter is the type of the switch value.
bool
// Determine types.
void
- determine_types(Type*);
+ determine_types(Gogo*, Type*);
// Check types.
bool
p != Type::named_builtin_types.end();
++p)
{
- bool r = (*p)->verify();
+ bool r = (*p)->verify(gogo);
go_assert(r);
(*p)->convert(gogo);
}
// Verify that the struct type is complete and valid.
bool
-Struct_type::do_verify()
+Struct_type::do_verify(Gogo*)
{
Struct_field_list* fields = this->fields_;
if (fields == NULL)
// Check that the length is valid.
bool
-Array_type::verify_length()
+Array_type::verify_length(Gogo* gogo)
{
if (this->length_ == NULL)
return true;
Type_context context(Type::lookup_integer_type("int"), false);
- this->length_->determine_type(&context);
+ this->length_->determine_type(gogo, &context);
if (this->length_->is_error_expression()
|| this->length_->type()->is_error())
// Verify the type.
bool
-Array_type::do_verify()
+Array_type::do_verify(Gogo* gogo)
{
if (this->element_type()->is_error_type())
{
this->set_is_error();
return false;
}
- if (!this->verify_length())
+ if (!this->verify_length(gogo))
{
this->length_ = Expression::make_error(this->length_->location());
this->set_is_error();
// Check that the map type is OK.
bool
-Map_type::do_verify()
+Map_type::do_verify(Gogo*)
{
// The runtime support uses "map[void]void".
if (!this->key_type_->is_comparable() && !this->key_type_->is_void_type())
// Verify.
bool
-Channel_type::do_verify()
+Channel_type::do_verify(Gogo*)
{
// We have no location for this error, but this is not something the
// ordinary user will see.
// Verify that a named type does not refer to itself.
bool
-Named_type::do_verify()
+Named_type::do_verify(Gogo*)
{
if (this->is_verified_)
return true;
// If we are called to turn unsafe.Sizeof into a constant, we may
// not have verified the type yet. We have to make sure it is
// verified, since that sets the list of dependencies.
- this->verify();
+ this->verify(gogo);
// Convert all the dependencies. If they refer indirectly back to
// this type, they will pick up the intermediate representation we just
// Verify the type.
bool
-Forward_declaration_type::do_verify()
+Forward_declaration_type::do_verify(Gogo*)
{
if (!this->is_defined() && !this->is_nil_constant_as_type())
{
// returns false if the type is invalid and we should not continue
// traversing it.
bool
- verify()
- { return this->do_verify(); }
+ verify(Gogo* gogo)
+ { return this->do_verify(gogo); }
// Bit flags to pass to are_identical and friends.
// Verify the type.
virtual bool
- do_verify()
+ do_verify(Gogo*)
{ return true; }
virtual bool
do_traverse(Traverse*);
bool
- do_verify()
- { return this->to_type_->verify(); }
+ do_verify(Gogo* gogo)
+ { return this->to_type_->verify(gogo); }
// If this is a pointer to a type that can't be in the heap, then
// the garbage collector does not have to look at this, so pretend
do_traverse(Traverse*);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const;
do_traverse(Traverse* traverse);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const;
private:
bool
- verify_length();
+ verify_length(Gogo*);
Expression*
array_type_descriptor(Gogo*, Named_type*);
do_traverse(Traverse*);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const
{ return Type::traverse(this->element_type_, traverse); }
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const
{ return Type::traverse(this->type_, traverse); }
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const;
do_traverse(Traverse* traverse);
bool
- do_verify();
+ do_verify(Gogo*);
bool
do_has_pointer() const