|
|
|
@ -51,6 +51,10 @@ namespace gcc
|
|
|
|
|
{
|
|
|
|
|
format_number = "%s\n";
|
|
|
|
|
}
|
|
|
|
|
else if (is_pointer_type(argument_type))
|
|
|
|
|
{
|
|
|
|
|
format_number = "%p\n";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
error_at(get_location(&argument->position()),
|
|
|
|
@ -256,6 +260,20 @@ namespace gcc
|
|
|
|
|
operator_code, target_type, left, right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::unary_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
switch (expression->operation())
|
|
|
|
|
{
|
|
|
|
|
case source::unary_operator::reference:
|
|
|
|
|
expression->operand().accept(this);
|
|
|
|
|
|
|
|
|
|
this->current_expression = build1_loc(get_location(&expression->position()), ADDR_EXPR,
|
|
|
|
|
build_pointer_type_for_mode(TREE_TYPE(this->current_expression), VOIDmode, true),
|
|
|
|
|
this->current_expression);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::constant_definition *definition)
|
|
|
|
|
{
|
|
|
|
|
location_t definition_location = get_location(&definition->position());
|
|
|
|
@ -344,6 +362,10 @@ namespace gcc
|
|
|
|
|
{
|
|
|
|
|
return TREE_TYPE(symbol->second);
|
|
|
|
|
}
|
|
|
|
|
error_at(get_location(&basic_type->position()),
|
|
|
|
|
"type '%s' not declared", basic_type->base_name().c_str());
|
|
|
|
|
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
else if (source::array_type_expression *array_type = type.is_array())
|
|
|
|
|
{
|
|
|
|
@ -351,14 +373,24 @@ namespace gcc
|
|
|
|
|
tree upper_bound = build_int_cst_type(integer_type_node, array_type->size);
|
|
|
|
|
tree base_type = build_type(array_type->base());
|
|
|
|
|
|
|
|
|
|
if (base_type == NULL_TREE)
|
|
|
|
|
if (base_type == NULL_TREE || base_type == error_mark_node)
|
|
|
|
|
{
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
return base_type;
|
|
|
|
|
}
|
|
|
|
|
tree range_type = build_range_type(integer_type_node, lower_bound, upper_bound);
|
|
|
|
|
|
|
|
|
|
return build_array_type(base_type, range_type);
|
|
|
|
|
}
|
|
|
|
|
else if (source::pointer_type_expression *pointer_type = type.is_pointer())
|
|
|
|
|
{
|
|
|
|
|
tree base_type = build_type(pointer_type->base());
|
|
|
|
|
|
|
|
|
|
if (base_type == NULL_TREE || base_type == error_mark_node)
|
|
|
|
|
{
|
|
|
|
|
return base_type;
|
|
|
|
|
}
|
|
|
|
|
return build_pointer_type_for_mode(base_type, VOIDmode, true);
|
|
|
|
|
}
|
|
|
|
|
else if (source::record_type_expression *record_type = type.is_record())
|
|
|
|
|
{
|
|
|
|
|
std::set<std::string> field_names;
|
|
|
|
@ -397,13 +429,8 @@ namespace gcc
|
|
|
|
|
void generic_visitor::visit(source::declaration *declaration)
|
|
|
|
|
{
|
|
|
|
|
tree declaration_type = build_type(declaration->type());
|
|
|
|
|
gcc_assert(declaration_type != NULL_TREE);
|
|
|
|
|
|
|
|
|
|
if (declaration_type == NULL_TREE)
|
|
|
|
|
{
|
|
|
|
|
error_at(get_location(&declaration->type().position()),
|
|
|
|
|
"type '%s' not declared", declaration->type().base_name().c_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
auto declaration_location = get_location(&declaration->position());
|
|
|
|
|
tree declaration_tree = build_decl(declaration_location, VAR_DECL,
|
|
|
|
|
get_identifier(declaration->identifier().c_str()), declaration_type);
|
|
|
|
@ -455,6 +482,46 @@ namespace gcc
|
|
|
|
|
ARRAY_REF, element_type, designator, index, NULL_TREE, NULL_TREE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::field_access_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
expression->base().accept(this);
|
|
|
|
|
tree field_declaration = TYPE_FIELDS(TREE_TYPE(this->current_expression));
|
|
|
|
|
|
|
|
|
|
while (field_declaration != NULL_TREE)
|
|
|
|
|
{
|
|
|
|
|
tree declaration_name = DECL_NAME(field_declaration);
|
|
|
|
|
const char *identifier_pointer = IDENTIFIER_POINTER(declaration_name);
|
|
|
|
|
|
|
|
|
|
if (expression->field() == identifier_pointer)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
field_declaration = TREE_CHAIN(field_declaration);
|
|
|
|
|
}
|
|
|
|
|
location_t expression_location = get_location(&expression->position());
|
|
|
|
|
if (field_declaration == NULL_TREE)
|
|
|
|
|
{
|
|
|
|
|
error_at(expression_location,
|
|
|
|
|
"record type does not have a field named '%s'",
|
|
|
|
|
expression->field().c_str());
|
|
|
|
|
this->current_expression = error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->current_expression = build3_loc(expression_location, COMPONENT_REF,
|
|
|
|
|
TREE_TYPE(field_declaration), this->current_expression,
|
|
|
|
|
field_declaration, NULL_TREE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::dereference_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
expression->base().accept(this);
|
|
|
|
|
|
|
|
|
|
this->current_expression = build1_loc(get_location(&expression->position()), INDIRECT_REF,
|
|
|
|
|
TREE_TYPE(TREE_TYPE(this->current_expression)), this->current_expression);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::assign_statement *statement)
|
|
|
|
|
{
|
|
|
|
|
statement->lvalue().accept(this);
|
|
|
|
|