Commit 02ed921a by Ian Lance Taylor

Clean up handling of undefined types.

From-SVN: r171528
parent cf3b3080
...@@ -205,17 +205,9 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type, ...@@ -205,17 +205,9 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
if (lhs_type == rhs_type) if (lhs_type == rhs_type)
return rhs_tree; return rhs_tree;
if (lhs_type->is_error_type() || rhs_type->is_error_type()) if (lhs_type->is_error() || rhs_type->is_error())
return error_mark_node; return error_mark_node;
if (lhs_type->is_undefined() || rhs_type->is_undefined())
{
// Make sure we report the error.
lhs_type->base();
rhs_type->base();
return error_mark_node;
}
if (rhs_tree == error_mark_node || TREE_TYPE(rhs_tree) == error_mark_node) if (rhs_tree == error_mark_node || TREE_TYPE(rhs_tree) == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -2628,7 +2620,7 @@ Const_expression::do_determine_type(const Type_context* context) ...@@ -2628,7 +2620,7 @@ Const_expression::do_determine_type(const Type_context* context)
void void
Const_expression::check_for_init_loop() Const_expression::check_for_init_loop()
{ {
if (this->type_ != NULL && this->type_->is_error_type()) if (this->type_ != NULL && this->type_->is_error())
return; return;
if (this->seen_) if (this->seen_)
...@@ -2647,7 +2639,7 @@ Const_expression::check_for_init_loop() ...@@ -2647,7 +2639,7 @@ Const_expression::check_for_init_loop()
if (find_named_object.found()) if (find_named_object.found())
{ {
if (this->type_ == NULL || !this->type_->is_error_type()) if (this->type_ == NULL || !this->type_->is_error())
{ {
this->report_error(_("constant refers to itself")); this->report_error(_("constant refers to itself"));
this->type_ = Type::make_error_type(); this->type_ = Type::make_error_type();
...@@ -2661,7 +2653,7 @@ Const_expression::check_for_init_loop() ...@@ -2661,7 +2653,7 @@ Const_expression::check_for_init_loop()
void void
Const_expression::do_check_types(Gogo*) Const_expression::do_check_types(Gogo*)
{ {
if (this->type_ != NULL && this->type_->is_error_type()) if (this->type_ != NULL && this->type_->is_error())
return; return;
this->check_for_init_loop(); this->check_for_init_loop();
...@@ -3311,14 +3303,8 @@ Type_conversion_expression::do_check_types(Gogo*) ...@@ -3311,14 +3303,8 @@ Type_conversion_expression::do_check_types(Gogo*)
Type* expr_type = this->expr_->type(); Type* expr_type = this->expr_->type();
std::string reason; std::string reason;
if (type->is_error_type() if (type->is_error() || expr_type->is_error())
|| type->is_undefined()
|| expr_type->is_error_type()
|| expr_type->is_undefined())
{ {
// Make sure we emit an error for an undefined type.
type->base();
expr_type->base();
this->set_is_error(); this->set_is_error();
return; return;
} }
...@@ -4027,7 +4013,7 @@ void ...@@ -4027,7 +4013,7 @@ void
Unary_expression::do_check_types(Gogo*) Unary_expression::do_check_types(Gogo*)
{ {
Type* type = this->expr_->type(); Type* type = this->expr_->type();
if (type->is_error_type()) if (type->is_error())
{ {
this->set_is_error(); this->set_is_error();
return; return;
...@@ -5447,9 +5433,9 @@ Binary_expression::do_type() ...@@ -5447,9 +5433,9 @@ Binary_expression::do_type()
{ {
Type* left_type = this->left_->type(); Type* left_type = this->left_->type();
Type* right_type = this->right_->type(); Type* right_type = this->right_->type();
if (left_type->is_error_type()) if (left_type->is_error())
return left_type; return left_type;
else if (right_type->is_error_type()) else if (right_type->is_error())
return right_type; return right_type;
else if (!Type::are_compatible_for_binop(left_type, right_type)) else if (!Type::are_compatible_for_binop(left_type, right_type))
{ {
...@@ -5688,7 +5674,7 @@ Binary_expression::do_check_types(Gogo*) ...@@ -5688,7 +5674,7 @@ Binary_expression::do_check_types(Gogo*)
Type* left_type = this->left_->type(); Type* left_type = this->left_->type();
Type* right_type = this->right_->type(); Type* right_type = this->right_->type();
if (left_type->is_error_type() || right_type->is_error_type()) if (left_type->is_error() || right_type->is_error())
{ {
this->set_is_error(); this->set_is_error();
return; return;
...@@ -7001,7 +6987,7 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant, ...@@ -7001,7 +6987,7 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
if (arg == NULL) if (arg == NULL)
return false; return false;
Type* arg_type = arg->type(); Type* arg_type = arg->type();
if (arg_type->is_error_type() || arg_type->is_undefined()) if (arg_type->is_error())
return false; return false;
if (arg_type->is_abstract()) if (arg_type->is_abstract())
return false; return false;
...@@ -7354,8 +7340,7 @@ Builtin_call_expression::check_one_arg() ...@@ -7354,8 +7340,7 @@ Builtin_call_expression::check_one_arg()
return false; return false;
} }
if (args->front()->is_error_expression() if (args->front()->is_error_expression()
|| args->front()->type()->is_error_type() || args->front()->type()->is_error())
|| args->front()->type()->is_undefined())
{ {
this->set_is_error(); this->set_is_error();
return false; return false;
...@@ -7389,7 +7374,7 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -7389,7 +7374,7 @@ Builtin_call_expression::do_check_types(Gogo*)
arg_type = arg_type->points_to(); arg_type = arg_type->points_to();
if (this->code_ == BUILTIN_CAP) if (this->code_ == BUILTIN_CAP)
{ {
if (!arg_type->is_error_type() if (!arg_type->is_error()
&& arg_type->array_type() == NULL && arg_type->array_type() == NULL
&& arg_type->channel_type() == NULL) && arg_type->channel_type() == NULL)
this->report_error(_("argument must be array or slice " this->report_error(_("argument must be array or slice "
...@@ -7397,7 +7382,7 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -7397,7 +7382,7 @@ Builtin_call_expression::do_check_types(Gogo*)
} }
else else
{ {
if (!arg_type->is_error_type() if (!arg_type->is_error()
&& !arg_type->is_string_type() && !arg_type->is_string_type()
&& arg_type->array_type() == NULL && arg_type->array_type() == NULL
&& arg_type->map_type() == NULL && arg_type->map_type() == NULL
...@@ -7429,7 +7414,7 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -7429,7 +7414,7 @@ Builtin_call_expression::do_check_types(Gogo*)
++p) ++p)
{ {
Type* type = (*p)->type(); Type* type = (*p)->type();
if (type->is_error_type() if (type->is_error()
|| type->is_string_type() || type->is_string_type()
|| type->integer_type() != NULL || type->integer_type() != NULL
|| type->float_type() != NULL || type->float_type() != NULL
...@@ -7493,7 +7478,7 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -7493,7 +7478,7 @@ Builtin_call_expression::do_check_types(Gogo*)
} }
Type* arg1_type = args->front()->type(); Type* arg1_type = args->front()->type();
Type* arg2_type = args->back()->type(); Type* arg2_type = args->back()->type();
if (arg1_type->is_error_type() || arg2_type->is_error_type()) if (arg1_type->is_error() || arg2_type->is_error())
break; break;
Type* e1; Type* e1;
...@@ -7568,9 +7553,9 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -7568,9 +7553,9 @@ Builtin_call_expression::do_check_types(Gogo*)
else if (args->size() > 2) else if (args->size() > 2)
this->report_error(_("too many arguments")); this->report_error(_("too many arguments"));
else if (args->front()->is_error_expression() else if (args->front()->is_error_expression()
|| args->front()->type()->is_error_type() || args->front()->type()->is_error()
|| args->back()->is_error_expression() || args->back()->is_error_expression()
|| args->back()->type()->is_error_type()) || args->back()->type()->is_error())
this->set_is_error(); this->set_is_error();
else if (!Type::are_identical(args->front()->type(), else if (!Type::are_identical(args->front()->type(),
args->back()->type(), true, NULL)) args->back()->type(), true, NULL))
...@@ -8540,7 +8525,7 @@ Call_expression::do_check_types(Gogo*) ...@@ -8540,7 +8525,7 @@ Call_expression::do_check_types(Gogo*)
Function_type* fntype = this->get_function_type(); Function_type* fntype = this->get_function_type();
if (fntype == NULL) if (fntype == NULL)
{ {
if (!this->fn_->type()->is_error_type()) if (!this->fn_->type()->is_error())
this->report_error(_("expected function")); this->report_error(_("expected function"));
return; return;
} }
...@@ -9060,7 +9045,7 @@ Index_expression::do_lower(Gogo*, Named_object*, int) ...@@ -9060,7 +9045,7 @@ Index_expression::do_lower(Gogo*, Named_object*, int)
Expression* end = this->end_; Expression* end = this->end_;
Type* type = left->type(); Type* type = left->type();
if (type->is_error_type()) if (type->is_error())
return Expression::make_error(location); return Expression::make_error(location);
else if (left->is_type_expression()) else if (left->is_type_expression())
{ {
...@@ -9236,7 +9221,7 @@ Array_index_expression::do_check_types(Gogo*) ...@@ -9236,7 +9221,7 @@ Array_index_expression::do_check_types(Gogo*)
Array_type* array_type = this->array_->type()->array_type(); Array_type* array_type = this->array_->type()->array_type();
if (array_type == NULL) if (array_type == NULL)
{ {
gcc_assert(this->array_->type()->is_error_type()); gcc_assert(this->array_->type()->is_error());
return; return;
} }
...@@ -9318,7 +9303,7 @@ Array_index_expression::do_get_tree(Translate_context* context) ...@@ -9318,7 +9303,7 @@ Array_index_expression::do_get_tree(Translate_context* context)
Array_type* array_type = this->array_->type()->array_type(); Array_type* array_type = this->array_->type()->array_type();
if (array_type == NULL) if (array_type == NULL)
{ {
gcc_assert(this->array_->type()->is_error_type()); gcc_assert(this->array_->type()->is_error());
return error_mark_node; return error_mark_node;
} }
...@@ -9979,7 +9964,7 @@ Type* ...@@ -9979,7 +9964,7 @@ Type*
Field_reference_expression::do_type() Field_reference_expression::do_type()
{ {
Type* type = this->expr_->type(); Type* type = this->expr_->type();
if (type->is_error_type()) if (type->is_error())
return type; return type;
Struct_type* struct_type = type->struct_type(); Struct_type* struct_type = type->struct_type();
gcc_assert(struct_type != NULL); gcc_assert(struct_type != NULL);
...@@ -9992,7 +9977,7 @@ void ...@@ -9992,7 +9977,7 @@ void
Field_reference_expression::do_check_types(Gogo*) Field_reference_expression::do_check_types(Gogo*)
{ {
Type* type = this->expr_->type(); Type* type = this->expr_->type();
if (type->is_error_type()) if (type->is_error())
return; return;
Struct_type* struct_type = type->struct_type(); Struct_type* struct_type = type->struct_type();
gcc_assert(struct_type != NULL); gcc_assert(struct_type != NULL);
...@@ -11140,7 +11125,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context) ...@@ -11140,7 +11125,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
Array_type* array_type = this->type()->array_type(); Array_type* array_type = this->type()->array_type();
if (array_type == NULL) if (array_type == NULL)
{ {
gcc_assert(this->type()->is_error_type()); gcc_assert(this->type()->is_error());
return error_mark_node; return error_mark_node;
} }
...@@ -11659,7 +11644,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function, int) ...@@ -11659,7 +11644,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function, int)
type = type->map_type()->val_type(); type = type->map_type()->val_type();
else else
{ {
if (!type->is_error_type()) if (!type->is_error())
error_at(this->location(), error_at(this->location(),
("may only omit types within composite literals " ("may only omit types within composite literals "
"of slice, array, or map type")); "of slice, array, or map type"));
...@@ -11667,7 +11652,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function, int) ...@@ -11667,7 +11652,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function, int)
} }
} }
if (type->is_error_type()) if (type->is_error())
return Expression::make_error(this->location()); return Expression::make_error(this->location());
else if (type->struct_type() != NULL) else if (type->struct_type() != NULL)
return this->lower_struct(gogo, type); return this->lower_struct(gogo, type);
...@@ -12132,7 +12117,7 @@ Type_guard_expression::do_check_types(Gogo*) ...@@ -12132,7 +12117,7 @@ Type_guard_expression::do_check_types(Gogo*)
} }
else if (expr_type->interface_type() == NULL) else if (expr_type->interface_type() == NULL)
{ {
if (!expr_type->is_error_type() && !this->type_->is_error_type()) if (!expr_type->is_error() && !this->type_->is_error())
this->report_error(_("type assertion only valid for interface types")); this->report_error(_("type assertion only valid for interface types"));
this->set_is_error(); this->set_is_error();
} }
...@@ -12142,7 +12127,7 @@ Type_guard_expression::do_check_types(Gogo*) ...@@ -12142,7 +12127,7 @@ Type_guard_expression::do_check_types(Gogo*)
if (!expr_type->interface_type()->implements_interface(this->type_, if (!expr_type->interface_type()->implements_interface(this->type_,
&reason)) &reason))
{ {
if (!this->type_->is_error_type()) if (!this->type_->is_error())
{ {
if (reason.empty()) if (reason.empty())
this->report_error(_("impossible type assertion: " this->report_error(_("impossible type assertion: "
...@@ -12294,7 +12279,7 @@ void ...@@ -12294,7 +12279,7 @@ void
Receive_expression::do_check_types(Gogo*) Receive_expression::do_check_types(Gogo*)
{ {
Type* type = this->channel_->type(); Type* type = this->channel_->type();
if (type->is_error_type()) if (type->is_error())
{ {
this->set_is_error(); this->set_is_error();
return; return;
...@@ -12319,7 +12304,7 @@ Receive_expression::do_get_tree(Translate_context* context) ...@@ -12319,7 +12304,7 @@ Receive_expression::do_get_tree(Translate_context* context)
Channel_type* channel_type = this->channel_->type()->channel_type(); Channel_type* channel_type = this->channel_->type()->channel_type();
if (channel_type == NULL) if (channel_type == NULL)
{ {
gcc_assert(this->channel_->type()->is_error_type()); gcc_assert(this->channel_->type()->is_error());
return error_mark_node; return error_mark_node;
} }
Type* element_type = channel_type->element_type(); Type* element_type = channel_type->element_type();
......
...@@ -914,14 +914,10 @@ Named_object::get_tree(Gogo* gogo, Named_object* function) ...@@ -914,14 +914,10 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
Type* type = named_constant->type(); Type* type = named_constant->type();
if (type != NULL && !type->is_abstract()) if (type != NULL && !type->is_abstract())
{ {
if (!type->is_undefined()) if (!type->is_error())
expr_tree = fold_convert(type->get_tree(gogo), expr_tree); expr_tree = fold_convert(type->get_tree(gogo), expr_tree);
else else
{ expr_tree = error_mark_node;
// Make sure we report the error.
type->base();
expr_tree = error_mark_node;
}
} }
if (expr_tree == error_mark_node) if (expr_tree == error_mark_node)
decl = error_mark_node; decl = error_mark_node;
...@@ -1047,12 +1043,8 @@ Named_object::get_tree(Gogo* gogo, Named_object* function) ...@@ -1047,12 +1043,8 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
{ {
Result_variable* result = this->u_.result_var_value; Result_variable* result = this->u_.result_var_value;
Type* type = result->type(); Type* type = result->type();
if (type->is_error_type() || type->is_undefined()) if (type->is_error())
{ decl = error_mark_node;
// Force the error.
type->base();
decl = error_mark_node;
}
else else
{ {
gcc_assert(result->function() == function->func_value()); gcc_assert(result->function() == function->func_value());
......
...@@ -1527,7 +1527,7 @@ Check_types_traverse::constant(Named_object* named_object, bool) ...@@ -1527,7 +1527,7 @@ Check_types_traverse::constant(Named_object* named_object, bool)
&& !ctype->is_boolean_type() && !ctype->is_boolean_type()
&& !ctype->is_string_type()) && !ctype->is_string_type())
{ {
if (!ctype->is_error_type()) if (!ctype->is_error())
error_at(constant->location(), "invalid constant type"); error_at(constant->location(), "invalid constant type");
constant->set_error(); constant->set_error();
} }
......
...@@ -517,7 +517,7 @@ Assignment_statement::do_check_types(Gogo*) ...@@ -517,7 +517,7 @@ Assignment_statement::do_check_types(Gogo*)
&& this->lhs_->map_index_expression() == NULL && this->lhs_->map_index_expression() == NULL
&& !this->lhs_->is_sink_expression()) && !this->lhs_->is_sink_expression())
{ {
if (!this->lhs_->type()->is_error_type()) if (!this->lhs_->type()->is_error())
this->report_error(_("invalid left hand side of assignment")); this->report_error(_("invalid left hand side of assignment"));
return; return;
} }
...@@ -535,16 +535,8 @@ Assignment_statement::do_check_types(Gogo*) ...@@ -535,16 +535,8 @@ Assignment_statement::do_check_types(Gogo*)
this->set_is_error(); this->set_is_error();
} }
if (lhs_type->is_error_type() if (lhs_type->is_error() || rhs_type->is_error())
|| rhs_type->is_error_type() this->set_is_error();
|| lhs_type->is_undefined()
|| rhs_type->is_undefined())
{
// Make sure we get the error for an undefined type.
lhs_type->base();
rhs_type->base();
this->set_is_error();
}
} }
// Build a tree for an assignment statement. // Build a tree for an assignment statement.
...@@ -817,9 +809,9 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing) ...@@ -817,9 +809,9 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
gcc_assert(prhs != this->rhs_->end()); gcc_assert(prhs != this->rhs_->end());
if ((*plhs)->is_error_expression() if ((*plhs)->is_error_expression()
|| (*plhs)->type()->is_error_type() || (*plhs)->type()->is_error()
|| (*prhs)->is_error_expression() || (*prhs)->is_error_expression()
|| (*prhs)->type()->is_error_type()) || (*prhs)->type()->is_error())
continue; continue;
if ((*plhs)->is_sink_expression()) if ((*plhs)->is_sink_expression())
...@@ -843,9 +835,9 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing) ...@@ -843,9 +835,9 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
++plhs, ++prhs) ++plhs, ++prhs)
{ {
if ((*plhs)->is_error_expression() if ((*plhs)->is_error_expression()
|| (*plhs)->type()->is_error_type() || (*plhs)->type()->is_error()
|| (*prhs)->is_error_expression() || (*prhs)->is_error_expression()
|| (*prhs)->type()->is_error_type()) || (*prhs)->type()->is_error())
continue; continue;
if ((*plhs)->is_sink_expression()) if ((*plhs)->is_sink_expression())
...@@ -1363,7 +1355,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*, ...@@ -1363,7 +1355,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
Type* expr_type = this->expr_->type(); Type* expr_type = this->expr_->type();
if (expr_type->interface_type() == NULL) if (expr_type->interface_type() == NULL)
{ {
if (!expr_type->is_error_type() && !this->type_->is_error_type()) if (!expr_type->is_error() && !this->type_->is_error())
this->report_error(_("type assertion only valid for interface types")); this->report_error(_("type assertion only valid for interface types"));
return Statement::make_error_statement(loc); return Statement::make_error_statement(loc);
} }
...@@ -2624,16 +2616,8 @@ Return_statement::do_check_types(Gogo*) ...@@ -2624,16 +2616,8 @@ Return_statement::do_check_types(Gogo*)
i, reason.c_str()); i, reason.c_str());
this->set_is_error(); this->set_is_error();
} }
else if (pt->type()->is_error_type() else if (pt->type()->is_error() || (*pe)->type()->is_error())
|| (*pe)->type()->is_error_type() this->set_is_error();
|| pt->type()->is_undefined()
|| (*pe)->type()->is_undefined())
{
// Make sure we get the error for an undefined type.
pt->type()->base();
(*pe)->type()->base();
this->set_is_error();
}
} }
if (pt != results->end()) if (pt != results->end())
...@@ -3001,7 +2985,7 @@ void ...@@ -3001,7 +2985,7 @@ void
If_statement::do_check_types(Gogo*) If_statement::do_check_types(Gogo*)
{ {
Type* type = this->cond_->type(); Type* type = this->cond_->type();
if (type->is_error_type()) if (type->is_error())
this->set_is_error(); this->set_is_error();
else if (!type->is_boolean_type()) else if (!type->is_boolean_type())
this->report_error(_("expected boolean expression")); this->report_error(_("expected boolean expression"));
...@@ -3023,7 +3007,7 @@ tree ...@@ -3023,7 +3007,7 @@ tree
If_statement::do_get_tree(Translate_context* context) If_statement::do_get_tree(Translate_context* context)
{ {
gcc_assert(this->cond_->type()->is_boolean_type() gcc_assert(this->cond_->type()->is_boolean_type()
|| this->cond_->type()->is_error_type()); || this->cond_->type()->is_error());
tree cond_tree = this->cond_->get_tree(context); tree cond_tree = this->cond_->get_tree(context);
tree then_tree = this->then_block_->get_tree(context); tree then_tree = this->then_block_->get_tree(context);
tree else_tree = (this->else_block_ == NULL tree else_tree = (this->else_block_ == NULL
...@@ -3554,7 +3538,7 @@ Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing) ...@@ -3554,7 +3538,7 @@ Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
if (this->val_ != NULL if (this->val_ != NULL
&& (this->val_->is_error_expression() && (this->val_->is_error_expression()
|| this->val_->type()->is_error_type())) || this->val_->type()->is_error()))
return Statement::make_error_statement(loc); return Statement::make_error_statement(loc);
if (this->val_ != NULL if (this->val_ != NULL
...@@ -4023,7 +4007,7 @@ void ...@@ -4023,7 +4007,7 @@ void
Send_statement::do_check_types(Gogo*) Send_statement::do_check_types(Gogo*)
{ {
Type* type = this->channel_->type(); Type* type = this->channel_->type();
if (type->is_error_type()) if (type->is_error())
{ {
this->set_is_error(); this->set_is_error();
return; return;
...@@ -4739,7 +4723,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing) ...@@ -4739,7 +4723,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing)
index_type = range_type->channel_type()->element_type(); index_type = range_type->channel_type()->element_type();
if (this->value_var_ != NULL) if (this->value_var_ != NULL)
{ {
if (!this->value_var_->type()->is_error_type()) if (!this->value_var_->type()->is_error())
this->report_error(_("too many variables for range clause " this->report_error(_("too many variables for range clause "
"with channel")); "with channel"));
return Statement::make_error_statement(this->location()); return Statement::make_error_statement(this->location());
......
...@@ -587,11 +587,19 @@ class Type ...@@ -587,11 +587,19 @@ class Type
has_pointer() const has_pointer() const
{ return this->do_has_pointer(); } { return this->do_has_pointer(); }
// Return true if this is an error type. An error type indicates a // Return true if this is the error type. This returns false for a
// parsing error. // type which is not defined, as it is called by the parser before
// all types are defined.
bool bool
is_error_type() const; is_error_type() const;
// Return true if this is the error type or if the type is
// undefined. If the type is undefined, this will give an error.
// This should only be called after parsing is complete.
bool
is_error() const
{ return this->base()->is_error_type(); }
// Return true if this is a void type. // Return true if this is a void type.
bool bool
is_void_type() const is_void_type() const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment