Replace type expression with traits
This commit is contained in:
@ -84,11 +84,6 @@ namespace gcc
|
||||
list_length(TYPE_ARG_TYPES(symbol_type)) - 1, arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else if (TREE_TYPE(symbol_type) == void_type_node)
|
||||
{
|
||||
append_statement(stmt);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = stmt;
|
||||
@ -136,10 +131,10 @@ namespace gcc
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::call_expression *expression)
|
||||
void generic_visitor::visit(boot::procedure_call *call)
|
||||
{
|
||||
location_t call_location = get_location(&expression->position());
|
||||
expression->callable().accept(this);
|
||||
location_t call_location = get_location(&call->position());
|
||||
call->callable().accept(this);
|
||||
|
||||
tree expression_type = TYPE_P(this->current_expression)
|
||||
? this->current_expression
|
||||
@ -147,17 +142,17 @@ namespace gcc
|
||||
|
||||
if (TYPE_P(this->current_expression) && TREE_CODE(expression_type) == RECORD_TYPE)
|
||||
{
|
||||
build_record_call(call_location, this->current_expression, expression->arguments);
|
||||
build_record_call(call_location, this->current_expression, call->arguments);
|
||||
}
|
||||
else if (TREE_CODE(expression_type) == FUNCTION_TYPE)
|
||||
{
|
||||
this->current_expression = build1(ADDR_EXPR,
|
||||
build_pointer_type_for_mode(expression_type, VOIDmode, true), this->current_expression);
|
||||
build_procedure_call(call_location, this->current_expression, expression->arguments);
|
||||
build_procedure_call(call_location, this->current_expression, call->arguments);
|
||||
}
|
||||
else if (is_pointer_type(expression_type) && TREE_CODE(TREE_TYPE(expression_type)) == FUNCTION_TYPE)
|
||||
{
|
||||
build_procedure_call(call_location, this->current_expression, expression->arguments);
|
||||
build_procedure_call(call_location, this->current_expression, call->arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -178,11 +173,6 @@ namespace gcc
|
||||
cast_target, this->current_expression);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::type_expression *expression)
|
||||
{
|
||||
this->current_expression = build_type(expression->body());
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::program *program)
|
||||
{
|
||||
for (boot::constant_definition *const constant : program->constants)
|
||||
@ -226,10 +216,7 @@ namespace gcc
|
||||
DECL_ARGUMENTS(fndecl) = chainon(DECL_ARGUMENTS(fndecl), declaration_tree);
|
||||
parameter_type = TREE_CHAIN(parameter_type);
|
||||
}
|
||||
for (boot::statement *const body_statement : program->body)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(program->body);
|
||||
tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl),
|
||||
build_int_cst_type(integer_type_node, 0));
|
||||
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
|
||||
@ -248,6 +235,19 @@ namespace gcc
|
||||
cgraph_node::finalize_function(fndecl, true);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::block *block)
|
||||
{
|
||||
for (boot::constant_definition *const constant : block->constants)
|
||||
{
|
||||
constant->accept(this);
|
||||
}
|
||||
for (boot::variable_declaration *const variable : block->variables)
|
||||
{
|
||||
variable->accept(this);
|
||||
}
|
||||
visit_statements(block->body);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::procedure_definition *definition)
|
||||
{
|
||||
tree declaration_type = build_procedure_type(definition->heading());
|
||||
@ -903,13 +903,13 @@ namespace gcc
|
||||
|
||||
void generic_visitor::visit(boot::variable_expression *expression)
|
||||
{
|
||||
auto symbol = this->lookup(expression->name());
|
||||
auto symbol = this->lookup(expression->name);
|
||||
|
||||
if (symbol == NULL_TREE)
|
||||
{
|
||||
error_at(get_location(&expression->position()),
|
||||
"symbol '%s' not declared in the current scope",
|
||||
expression->name().c_str());
|
||||
expression->name.c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else
|
||||
@ -964,40 +964,40 @@ namespace gcc
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::traits_expression *trait)
|
||||
{
|
||||
tree type_expression = build_type(trait->type());
|
||||
|
||||
if (trait->name == "size")
|
||||
{
|
||||
this->current_expression = build1(CONVERT_EXPR, elna_word_type_node, size_in_bytes(type_expression));
|
||||
}
|
||||
else if (trait->name == "alignment")
|
||||
{
|
||||
this->current_expression = build_int_cstu(elna_word_type_node, TYPE_ALIGN_UNIT(type_expression));
|
||||
}
|
||||
else if (trait->name == "min" && is_integral_type(type_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MIN_VALUE(type_expression);
|
||||
}
|
||||
else if (trait->name == "max" && is_integral_type(type_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MAX_VALUE(type_expression);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(get_location(&trait->position()), "type '%s' does not have property '%s'",
|
||||
print_type(type_expression).c_str(), trait->name.c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::field_access_expression *expression)
|
||||
{
|
||||
expression->base().accept(this);
|
||||
location_t expression_location = get_location(&expression->position());
|
||||
|
||||
if (TYPE_P(this->current_expression))
|
||||
{
|
||||
if (expression->field() == "size")
|
||||
{
|
||||
this->current_expression = build1(CONVERT_EXPR, elna_word_type_node,
|
||||
size_in_bytes(this->current_expression));
|
||||
}
|
||||
else if (expression->field() == "alignment")
|
||||
{
|
||||
this->current_expression = build_int_cstu(elna_word_type_node,
|
||||
TYPE_ALIGN_UNIT(this->current_expression));
|
||||
}
|
||||
else if (expression->field() == "min" && is_integral_type(this->current_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MIN_VALUE(this->current_expression);
|
||||
}
|
||||
else if (expression->field() == "max" && is_integral_type(this->current_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MAX_VALUE(this->current_expression);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(expression_location, "type '%s' does not have property '%s'",
|
||||
print_type(this->current_expression).c_str(), expression->field().c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
|
||||
}
|
||||
else if (is_aggregate_type(TREE_TYPE(this->current_expression)))
|
||||
if (is_aggregate_type(TREE_TYPE(this->current_expression)))
|
||||
{
|
||||
tree field_declaration = TYPE_FIELDS(TREE_TYPE(this->current_expression));
|
||||
|
||||
@ -1026,6 +1026,12 @@ namespace gcc
|
||||
field_declaration, NULL_TREE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(expression_location, "type '%s' does not have a field named '%s'",
|
||||
print_type(TREE_TYPE(this->current_expression)).c_str(), expression->field().c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::dereference_expression *expression)
|
||||
@ -1049,7 +1055,7 @@ namespace gcc
|
||||
if (TREE_CODE(lvalue) == CONST_DECL)
|
||||
{
|
||||
error_at(statement_location, "cannot modify constant '%s'",
|
||||
statement->lvalue().is_variable()->name().c_str());
|
||||
statement->lvalue().is_variable()->name.c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else if (is_assignable_from(TREE_TYPE(lvalue), rvalue))
|
||||
@ -1083,10 +1089,7 @@ namespace gcc
|
||||
if (statement->alternative() != nullptr)
|
||||
{
|
||||
enter_scope();
|
||||
for (const auto body_statement : *statement->alternative())
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(*statement->alternative());
|
||||
tree mapping = leave_scope();
|
||||
append_statement(mapping);
|
||||
}
|
||||
@ -1120,10 +1123,7 @@ namespace gcc
|
||||
append_statement(then_label_expr);
|
||||
enter_scope();
|
||||
|
||||
for (const auto body_statement : branch.statements)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(branch.statements);
|
||||
tree mapping = leave_scope();
|
||||
append_statement(mapping);
|
||||
append_statement(goto_endif);
|
||||
@ -1160,11 +1160,18 @@ namespace gcc
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::call_statement *statement)
|
||||
void generic_visitor::visit_statements(const std::vector<boot::statement *>& statements)
|
||||
{
|
||||
statement->body().accept(this);
|
||||
append_statement(this->current_expression);
|
||||
this->current_expression = NULL_TREE;
|
||||
for (boot::statement *const statement : statements)
|
||||
{
|
||||
statement->accept(this);
|
||||
|
||||
if (this->current_expression != NULL_TREE && this->current_expression != error_mark_node)
|
||||
{
|
||||
append_statement(this->current_expression);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::return_statement *statement)
|
||||
@ -1181,15 +1188,14 @@ namespace gcc
|
||||
this->current_expression);
|
||||
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
|
||||
append_statement(return_stmt);
|
||||
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::defer_statement *statement)
|
||||
{
|
||||
enter_scope();
|
||||
for (boot::statement *const body_statement : statement->statements)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(statement->statements);
|
||||
defer(leave_scope());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user