WONKY



LOG | FILES | OVERVIEW


F diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt
include_directories(src/semantics/identifiers)
include_directories(src/semantics/memory)
include_directories(src/semantics/value)
+ include_directories(src/semantics/constraints)
include_directories(src/misc)
src/semantics/value/type.c
src/semantics/value/evaluation.c
src/semantics/value/constant.c
- src/semantics/value/constraints.c
+ src/semantics/constraints/expression_constraints.c
+ src/semantics/constraints/statement_constraints.c
src/semantics/value/value.c
src/semantics/identifiers/denoted.c
src/semantics/identifiers/scope.c
F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c --- a/src/frontend/parse/parse_declaration.c +++ b/src/frontend/parse/parse_declaration.c
if(parse_function_definitions && get_and_check(translation_data,KW_OPEN_CURLY))
{
struct Type_Function *function_type;
+ struct Denoted_Function *hold_function;
+
+ hold_function=(struct Denoted_Function*)hold;
function_type=(struct Type_Function*)((struct Denoted_Function*)hold)->type;
- ((struct Denoted_Function*)hold) ->body=
+
+
+ hold_function->function_scope=(struct Function_Scope*)get_function_scope(scope,(struct Denoted_Function*)hold);
+
+ function_type->function_prototype_scope->parent=(struct Scope*)hold_function->function_scope;
+
+ hold_function->body=
(struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,(struct Scope*)function_type->function_prototype_scope);
Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold));
break;
F diff --git a/src/frontend/parse/parse_statement.c b/src/frontend/parse/parse_statement.c --- a/src/frontend/parse/parse_statement.c +++ b/src/frontend/parse/parse_statement.c
if(translation_data->tokens->size==0)
return NULL;
-
-
switch(kw_get(translation_data))
{
case KW_NOTYPE:
push_translation_error("statement expected",translation_data);
return (struct AST*)get_error_tree(NULL);
-
case KW_OPEN_CURLY:
chomp(translation_data);
return parse_finish_compound_statement(translation_data,scope);
chomp(translation_data);
return parse_finish_default_statement(translation_data,scope);
case KW_ID:
- /*TODO check if id is in function scope*/
- if(0)
+ if(check(translation_data,KW_COLUMN,1))
{
return parse_finish_labeled_statement(translation_data,scope,ST_LABEL);
}else
struct AST_Labeled_Statement *ret;
if(check(translation_data,KW_ID,0))
{
- ret=get_labeled_statement_tree(Queue_Pop(translation_data->tokens),NULL,type);
+ ret=get_labeled_statement_tree(Queue_Pop(translation_data->tokens),NULL,type,translation_data,scope);
if(get_and_check(translation_data,KW_COLUMN))
{
ret->statement=parse_statement(translation_data,scope);
struct AST* parse_finish_default_statement(struct Translation_Data* translation_data,struct Scope *scope)
{
struct AST_Labeled_Statement *ret;
- ret=get_labeled_statement_tree(NULL,NULL,ST_DEFAULT);
+ ret=get_labeled_statement_tree(NULL,NULL,ST_DEFAULT,translation_data,scope);
if(get_and_check(translation_data,KW_COLUMN))
{
ret->statement=parse_statement(translation_data,scope);
struct AST_Return_Statement *hold;
if(get_and_check(translation_data,KW_SEMI_COLUMN))
{
- hold=get_return_statement_tree(get_nop_tree());
+ hold=get_return_statement_tree(get_nop_tree(),translation_data,scope);
return (struct AST*)hold;
}
- hold=get_return_statement_tree(parse_expression(translation_data,scope));
+ hold=get_return_statement_tree(parse_expression(translation_data,scope),translation_data,scope);
if(get_and_check(translation_data,KW_SEMI_COLUMN))
{
return (struct AST*)hold;
F diff --git a/src/frontend/parse/parse_statement.h b/src/frontend/parse/parse_statement.h --- a/src/frontend/parse/parse_statement.h +++ b/src/frontend/parse/parse_statement.h
#include <program.h>
+ struct AST* parse_statement(struct Translation_Data* translation_data,struct Scope *scope);
struct AST* parse_finish_compound_statement(struct Translation_Data* translation_data,struct Scope *scope);
- struct AST* parse_op_e_cl_st(struct Translation_Data* translation_data,struct Scope *scope);
+ //struct AST* parse_op_e_cl_st(struct Translation_Data* translation_data,struct Scope *scope);
struct AST* parse_finish_if_statement(struct Translation_Data* translation_data,struct Scope *scope);
struct AST* parse_finish_switch_statement(struct Translation_Data* translation_data,struct Scope *scope);
struct AST* parse_finish_do_while_statement(struct Translation_Data* translation_data,struct Scope *scope);
F diff --git a/src/program/gcc_error.c b/src/program/gcc_error.c --- a/src/program/gcc_error.c +++ b/src/program/gcc_error.c
char* get_string_for_type_error(struct Type *type,struct Translation_Data *translation_data)
{
char *ret;
+ struct Type *current;
- ret=gstr_to_heap("type");
+ ret=gstr_to_heap("");
+ current=type;
+
+ while(type_is_derivative(current))
+ {
+ switch(current->specifier)
+ {
+
+ case TS_POINTER:
+ ret=gstr_append_and_consume(gstr_to_heap("*"),ret);
+ current=((struct Type_Pointer*)current)->points_to;
+ break;
+ case TS_ARRAY:
+ ret=gstr_append_and_consume(gstr_to_heap("("),ret);
+ ret=gstr_append_and_consume(ret,gstr_to_heap(")[]"));
+ current=((struct Type_Array*)current)->is_array_of;
+ break;
+ case TS_FUNC: /*TODO*/
+ goto hack;
+ default:
+ assert(0);
+ }
+ }
+ hack:
+ switch(current->specifier)
+ {
+ case TS_DOUBLE:
+ ret=gstr_append_and_consume(gstr_to_heap("double"),ret);
+ break;
+ case TS_FLOAT:
+ ret=gstr_append_and_consume(gstr_to_heap("float"),ret);
+ break;
+ case TS_INT:
+ ret=gstr_append_and_consume(gstr_to_heap("int"),ret);
+ break;
+ case TS_CHAR:
+ ret=gstr_append_and_consume(gstr_to_heap("char"),ret);
+ break;
+ default:
+ ret=gstr_append_and_consume(gstr_to_heap("type"),ret);
+ }
return ret;
}
char* get_string_for_denoted_error(struct Denoted *denoted,struct Translation_Data *translation_data)
F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.c
struct AST_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data)
{
struct Type *operand_type;
- if(!type_is_scalar(type))
+ if(!type_is_scalar(type) || operand->type==ERROR)
{
push_translation_error("cast type needs to be of scalar type",translation_data);
push_translation_note("got %T instead",translation_data,type);
struct AST_Function_Expression* get_function_expression_tree(struct AST_Expression *id,struct Queue *arg_list,struct Translation_Data *translation_data)
{
+
struct AST_Function_Expression *ret;
struct Type_Function *id_type;
size_t i;
id_type=(struct Type_Function*)extract_expresion_value_type(id->value,translation_data);
ret=malloc(sizeof(struct AST_Function_Expression));
ret->type=OP_FUNCTION;
- ret->value=get_expression_value_rvalue(get_temp_object(id_type->return_type));
+ ret->value=NULL; /*So, we need to know if there is some error somewhere before we can begin extracting lvalue information*/
ret->id=id;
ret->number_of_arguments=arg_list->size;
assert(arg_list->size==0);
- if(constraint_check_function_expression(ret,translation_data))
+ if(constraint_check_function_expression(ret,translation_data) && id->type!=ERROR && id_type->specifier!=TS_ERROR)
+ {
+ ret->value=get_expression_value_rvalue(get_temp_object(id_type->return_type));
return ret;
+ }
else
+ {
return (struct AST_Function_Expression*)get_error_tree((struct AST*)ret);
+ }
}
struct AST_Unary_Expression* get_unary_expression_tree(struct AST_Expression *operand,struct Expression_Value *value,enum AST_Type type)
{
{
push_translation_error("using undeclared id in expression",translation_data);
free(ret);
- return NULL;
+ return (struct AST_Designator*)get_error_tree(NULL);
}else
{
switch(hold_denoted->denotation)
}
- struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST* statement,enum AST_Type type)
+ struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST* statement,enum AST_Type type,struct Translation_Data *translation_data,struct Scope *scope)
{
struct AST_Labeled_Statement *ret;
ret=malloc(sizeof(struct AST_Labeled_Statement));
ret->type=ST_FOR;
return ret;
}
- struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression)
+ struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression,struct Translation_Data *translation_data,struct Scope *scope)
{
struct AST_Return_Statement *ret;
- ret=malloc(sizeof(struct AST_If_Statement));
- ret->type=ST_RETURN;
- ret->return_expression=return_expression;
- return ret;
+ struct Denoted_Function *hold_function;
+ struct Type *return_type;
+
+ hold_function=get_enclosing_function(scope);
+ return_type=((struct Type_Function*)hold_function->type)->return_type;
+
+ if(constraint_check_return_statement(return_expression,return_type,translation_data))
+ {
+ ret=malloc(sizeof(struct AST_If_Statement));
+ ret->type=ST_RETURN;
+ if(return_expression==NULL)
+ ret->return_expression=NULL;
+ else
+ ret->return_expression=(struct AST*)get_cast_expression_tree((struct AST_Expression*)return_expression,return_type,translation_data);
+
+ return ret;
+ }else
+ {
+ return (struct AST_Return_Statement*)get_error_tree(return_expression);
+ }
}
struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope)
F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.h
- struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST* statement,enum AST_Type type);
+ struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST* statement,enum AST_Type type,struct Translation_Data *translation_data,struct Scope *scope);
struct AST_Compound_Statement* get_compound_statement_tree(struct Scope *parent_scope);
struct AST_If_Statement* get_if_statement_tree();
struct AST_Switch_Statement* get_switch_statement_tree();
struct AST_While_Statement* get_while_statement_tree();
struct AST_Do_While_Statement* get_do_while_statement_tree();
struct AST_For_Statement* get_for_statement_tree();
- struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression);
+ struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression,struct Translation_Data *translation_data,struct Scope *scope);
struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope);
struct AST* get_nop_tree();
struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Type *definition);
F diff --git a/src/semantics/constraints/constraints.h b/src/semantics/constraints/constraints.h new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/constraints.h
+ #ifndef WONKY_CONSTRAINTS_H
+ #define WONKY_CONSTRAINTS_H WONKY_CONSTRAINTS_H
+
+ #include<expression_constraints.h>
+ #include<statement_constraints.h>
+
+ #endif
F diff --git a/src/semantics/constraints/expression_constraints.c b/src/semantics/constraints/expression_constraints.c new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/expression_constraints.c
+ #ifndef WONKY_EXPRESSION_CONSTRAINTS_C
+ #define WONKY_EXPRESSION_CONSTRAINTS_C WONKY_EXPRESSION_CONSTRAINTS_C
+ #include <expression_constraints.h>
+
+ /*the operands of % shall both have an integer type 6.5.5*/
+ _Bool constraint_check_modulo_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+ if(!type_is_integer_type(left_type))
+ {
+ push_translation_error("expected integer type in right operand of modulo operation",translation_data);
+ return 0;
+ }
+ if(!type_is_integer_type(right_type))
+ {
+ push_translation_error("expected integer type in right operand of modulo operation",translation_data);
+ return 0;
+ }
+ return 1;
+ }
+ /*constraints only on modulo operation 6.5.5*/
+ _Bool constraint_check_multiplicative_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ if(operation==OP_REMAINDER)
+ {
+ return constraint_check_modulo_expression(left,right,translation_data);
+ }else
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+
+ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("constraint check violation in multiplicative expression",translation_data);
+ return 0;
+ }
+ }
+ assert(0);
+ }
+ /*for addition both operands shall have arithmetic type, or one operand shall be of pointer type and the other of integer type.
+ * for subtraction one of the following shall hold
+ * both operands shall have arihtmetic type
+ * both operands are pointers to qualified or unqualified versions of compatible object types
+ * left operand is a pointer to an object type and the right operand has integer type*/
+ _Bool constraint_check_additive_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+
+ assert(operation==OP_SUBTRACTION || operation==OP_ADDITION);
+
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+ if(operation==OP_ADDITION) // operation is '+'
+ {
+ if(type_is_arithmetic(left_type))
+ {
+ if(type_is_arithmetic(right_type))
+ {
+ return 1;
+ }else if(type_is_pointer_to_object(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("unexpected type of right operand of addition",translation_data);
+ return 0;
+ }
+ }else if(type_is_pointer_to_object(left_type))
+ {
+ if(type_is_arithmetic(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("unexpected type of right operand of addition",translation_data);
+ return 0;
+ }
+ }else
+ {
+ push_translation_error("unexpected type of left operand of addition",translation_data);
+ return 0;
+ }
+ }else // operation is '-'
+ {
+ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
+ {
+ return 1;
+ }else if(type_is_pointer_to_object(left_type))
+ {
+ if(type_is_integer_type(right_type) || type_is_pointer_to_object(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("unexpected type of right operand of addition",translation_data);
+ return 0;
+ }
+ }else
+ {
+ push_translation_error("unexpected type of left operand of addition",translation_data);
+ return 0;
+ }
+ }
+
+ }
+ /*each of the operands shall have integer type 6.5.7*/
+ _Bool constraint_check_shift_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+ if(type_is_integer_type(left_type) && type_is_integer_type(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("both operands of shift operation must be of integer type",translation_data);
+ return 0;
+ }
+ }
+ _Bool constraint_check_bitwise_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ return 1;
+ }
+ /*
+ * One of the following shall hold:
+ * both operands have real type
+ * both operands are pointers to qualified or unqualified versions of compatible object types
+ * both operands are pointers to qualified or unqualified versions of compatible incomplete type
+ *
+ * */
+ _Bool constraint_check_relational_operation(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ return 1;
+ }
+ /* One of the following shall hold:
+ * both operands have arithmetic type
+ * both operands are pointers to qualified or unqualified versions of compatible types
+ * one operand is a pointer to object or incomplete type and the other is a pointer to a qualified or unqualified version of void
+ * one operand is a pointer and the other is a null pointer constant*/
+ _Bool constraint_check_equality_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
+ {
+ return 1;
+ }else if(type_is_pointer_to_object(left_type))
+ {
+ if(type_is_pointer_to_object(right_type))
+ {
+ if(types_are_compatible(left_type,right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("checking for equality between pointers of incompatible types",translation_data);
+ return 0;
+ }
+ }else if(ast_is_null_pointer_constant((struct AST*)right) || type_is_pointer_to_void(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("rhs is not a pointer",translation_data);
+ return 0;
+ }
+ }else if(type_is_pointer_to_object(right_type))
+ {
+ if(ast_is_null_pointer_constant((struct AST*)left) || type_is_pointer_to_void(left_type))
+ return 1;
+ else
+ {
+ push_translation_error("lhs is not a pointer",translation_data);
+ return 0;
+ }
+ }else if(type_is_pointer_to_incomplete_type(left_type))
+ {
+ if(type_is_pointer_to_void(right_type) || ast_is_null_pointer_constant((struct AST*)right))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("rhs is not a pointer",translation_data);
+ return 0;
+ }
+ }else if(type_is_pointer_to_incomplete_type(right_type))
+ {
+ if(type_is_pointer_to_void(left_type) || ast_is_null_pointer_constant((struct AST*)left))
+ {
+ return 1;
+ }
+ else
+ {
+ push_translation_error("lhs is not a pointer",translation_data);
+ return 0;
+ }
+ }else if(left_type->specifier==TS_POINTER)
+ {
+ if(ast_is_null_pointer_constant((struct AST*)right))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("rhs is not a null constant",translation_data);
+ return 0;
+ }
+ }else if(right_type->specifier==TS_POINTER)
+ {
+ if(ast_is_null_pointer_constant((struct AST*)left))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("lhs is not a null constant",translation_data);
+ return 0;
+ }
+ }
+ }
+ /*each of the operands shall have scallar type 6.5.13 6.5.14*/
+ _Bool constraint_check_logical_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+
+ if(type_is_scalar(left_type) && type_is_scalar(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("both operands of logical expression must be of scallar type",translation_data);
+ return 0;
+ }
+ }
+ /*
+ left operand is a modifiable lvalue
+
+ One of the following shall hold:
+ 1. Left operand has qualified or unqualified arithmetic type and the
+ right has arithmetic type
+
+ 2. The left operand has a qualified or unqualified version of a
+ structure or union type compatible with the type of the right
+
+ 3. Both operands are pointers to qualified or unqualified versions
+ of compatible types, and the type pointed ot by the left has all
+ the qualifiers of the type pointed by the right
+
+ 4. One operand is a pointer to an object to or incomplete type and the
+ other is a pointer to a qualified or unqualified version of void,
+ and the type pointed to by the left has all the qualifiers of the
+ type pointed to by the right
+
+ 5. The left operand is a pointer and the right is a null pointer
+ constant
+
+ 6. The left operand has type _Bool and
+ the right is a pointer
+
+ 6.5.16.1
+ * */
+ _Bool constraint_check_simple_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+
+ if(!expression_value_is_modifiable(left->value))
+ {
+ push_translation_error("left operand of assignment operator must be modifiable",translation_data);
+ return 0;
+ }
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+
+ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
+ {
+ return 1;
+ }else if(type_is_struct_union(left_type) && types_are_compatible_unqualified(left_type,right_type))
+ {
+ return 1;
+ }else if(left_type->specifier==TS_POINTER && types_are_compatible_unqualified(left_type,right_type))
+ {
+ return 1;
+ }else if(left_type->specifier==TS_POINTER && ast_is_null_pointer_constant((struct AST*)right))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("constraint check violation in simple assignment expression",translation_data);
+ return 0;
+ }
+ //TODO ADD _BOOL TS
+ }
+ /*
+ left operand is a modifiable lvalue
+ if += or -=
+ 1. left operand shall be a pointer to an object and the right operand shall be of integer type
+ 2. left operand shall be qualified or unqualified arithmetic type and the right shall be an arithmetic type
+ else
+ each operand shall have arithmetic type consistent with those allowed by the corresponding binary operator
+
+ 6.5.16.2
+ */
+ _Bool constraint_check_compound_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ if(!expression_value_is_modifiable(left->value))
+ {
+ push_translation_error("left operand of assignment operator must be modifiable",translation_data);
+ return 0;
+ }
+
+ switch(operation)
+ {
+ case OP_ADD_ASSIGN:
+ case OP_SUBTRACT_ASSIGN:
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+ if(left_type->specifier==TS_POINTER && type_is_integer_type(right_type))
+ {
+ return 1;
+ }else if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("constraint check violation in compound assignment expression",translation_data);
+ return 0;
+ }
+ assert(0);
+ case OP_MULTIPLY_ASSIGN:
+ case OP_DIV_ASSIGN:
+ case OP_REMAINDER_ASSIGN:
+ return constraint_check_multiplicative_expression(left,right,operation,translation_data);
+ case OP_SHIFT_RIGHT_ASSIGN:
+ case OP_SHIFT_LEFT_ASSIGN:
+ return constraint_check_shift_expression(left,right,operation,translation_data);
+ case OP_AND_ASSIGN:
+ case OP_XOR_ASSIGN:
+ case OP_PIPE_ASSIGN:
+ return constraint_check_bitwise_expression(left,right,operation,translation_data);
+ default:
+ assert(0);
+ }
+ }
+ /*
+ none that I could see
+ */
+ _Bool constraint_check_comma_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
+ {
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+ return 1;
+ }
+ /*
+ one of the expressions shall have type pointer to object the other shall have integer
+ */
+ _Bool constraint_check_array_subscript_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+ struct Type *right_type;
+
+ if(left->type==ERROR || right->type==ERROR)
+ return 0;
+
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+
+ if(type_is_pointer(left_type) && type_is_integer_type(right_type))
+ {
+ return 1;
+ }else if(type_is_pointer(right_type) && type_is_integer_type(left_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("constraint check violation in array subscript expression",translation_data);
+ return 0;
+ }
+
+ }
+ /*
+ left is (un)qualified struct or union, second is an id of a memeber of the struct or union
+ NOTE: we don't check if id is a member of the struct or union here
+ */
+ _Bool constraint_check_struct_union_member_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+
+ if(left->type==ERROR)
+ return 0;
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ return type_is_struct_union(left_type);
+ }
+ /*
+ see above
+ */
+ _Bool constraint_check_struct_union_member_trough_ptr_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+
+ if(left->type==ERROR)
+ return 0;
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ if(type_is_pointer_to_object(left_type))
+ {
+ left_type=((struct Type_Pointer*)left_type)->points_to;
+ return type_is_struct_union(left_type);
+ }else
+ {
+ push_translation_error("constraint check violation in member access expression",translation_data);
+ return 0;
+ }
+ }
+ /*
+ First operand shall have scaller type
+ One of the following shall hold for the second and third operands
+ both operands have arithmetic type
+ both operands have the same structure or union type
+ both operands have void type
+ both operands are pointers of (un)qualified versions of compatible types
+ one operand is a pointer and the other is a null pointer constant
+ one operand is a pointer to an object or incomplete type and the other is a pointer to a (un)qualified version of void
+ */
+ _Bool constraint_check_conditional_expression(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data)
+ {
+ struct Type *left_type;
+
+ if(left->type==ERROR || center->type==ERROR || right->type==ERROR)
+ return 0;
+
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ if(!type_is_arithmetic(left_type))
+ {
+ push_translation_error("first operand of conditional expression must be of arithmetic type",translation_data);
+ return 0;
+ }else
+ {
+ struct Type *center_type;
+ struct Type *right_type;
+
+ right_type=extract_expresion_value_type(right->value,translation_data);
+ center_type=extract_expresion_value_type(center->value,translation_data);
+
+ if(type_is_arithmetic(right_type) && type_is_arithmetic(center_type))
+ {
+ return 1;
+ }else if(type_is_struct_union(center_type) && types_are_compatible(center_type,right_type))
+ {
+ return 1;
+ }else if(center_type->specifier==TS_VOID && right_type->specifier==TS_VOID)
+ {
+ return 1;
+ }else if(type_is_pointer(center_type) && types_are_compatible(center_type,right_type))
+ {
+ return 1;
+ }else if(type_is_pointer(center_type) && ast_is_null_pointer_constant((struct AST*)right))
+ {
+ return 1;
+ }else if(type_is_pointer(right_type) && ast_is_null_pointer_constant((struct AST*)center))
+ {
+ return 1;
+ }else if( (type_is_pointer_to_object(center_type) || type_is_pointer_to_incomplete_type(center_type)) && type_is_pointer_to_void(right_type))
+ {
+ return 1;
+ }else if( (type_is_pointer_to_object(center_type) || type_is_pointer_to_incomplete_type(center_type)) && type_is_pointer_to_void(right_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("constraint check violation in member contitional expression",translation_data);
+ return 0;
+ }
+ }
+ }
+ _Bool constraint_check_function_expression(struct AST_Function_Expression *proposed_function,struct Translation_Data *translation_data)
+ {
+ struct Type *expected_argument_type;
+ struct Type *given_argument_type;
+ struct Type_Function *proposed_function_type;
+ size_t i;
+
+ if(proposed_function->type==ERROR)
+ return 0;
+
+ proposed_function_type=(struct Type_Function*)extract_expresion_value_type(proposed_function->id->value,translation_data);
+ if(proposed_function_type->specifier!=TS_FUNC)
+ {
+ push_translation_error("is not a function",translation_data);
+ return 0;
+ }
+
+ if(proposed_function_type->number_of_arguments!=proposed_function->number_of_arguments)
+ {
+ push_translation_error("mismatching number of arguments",translation_data);
+ return 0;
+ }
+
+ for(i=0;i<proposed_function->number_of_arguments;++i)
+ {
+
+ if(proposed_function->arg_list[i]->type==ERROR)
+ return 0;
+
+ expected_argument_type=proposed_function_type->arguments[i]->object->type;
+ given_argument_type=extract_expresion_value_type(proposed_function->arg_list[i]->value,translation_data);
+
+ if(!types_are_compatible_unqualified(expected_argument_type,given_argument_type))
+ {
+ push_translation_error("incompatible types of argument",translation_data);
+ return 0;
+ }
+ }
+ return 1;
+ }
+ _Bool constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+
+ if(operand->type==ERROR)
+ return 0;
+
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(operand_type->specifier==TS_POINTER)
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("needs pointer type",translation_data);
+ return 0;
+ }
+ }
+ _Bool constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+
+ if(operand->type==ERROR)
+ return 0;
+
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(operand->value->type==VALUE_FUNCTION_DESIGNATOR || operand->type==OP_ARR_SUBSCRIPT || operand->type==OP_DEREFERENCE)
+ {
+ return 1;
+ }else if(operand->value->type==VALUE_LVALUE)
+ {
+ struct Object *hold_operand_object;
+ hold_operand_object=((struct Expression_Value_LValue*)operand->value)->object;
+ if(hold_operand_object->kind==OBJECT_KIND_BITFIELD || hold_operand_object->storage_class==SCS_REGISTER)
+ {
+ push_translation_error("can't get the address of such an operand",translation_data);
+ return 0;
+ }else
+ {
+ return 1;
+ }
+ }else
+ {
+ push_translation_error("cast type needs to be of scalar type",translation_data);
+ return 0;
+ }
+ }
+ _Bool constraint_check_sizeof_by_type(struct Type *type)
+ {
+ if(type->specifier==TS_ERROR)
+ return 0;
+ else
+ return 1;
+ }
+ _Bool constraint_check_sizeof_expression(struct AST_Expression *expression,struct Translation_Data *translation_data)
+ {
+ if(expression->type==ERROR)
+ return 0;
+ else
+ return 1;
+ }
+ /*
+ * operand shall have arithmetic type
+ */
+ _Bool constraint_check_unary_plus_minus(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+
+ if(operand->type==ERROR)
+ return 0;
+
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(type_is_arithmetic(operand_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("operan of unary +/- must be of arithmetic type",translation_data);
+ return 0;
+ }
+ }
+ /*
+ * operand shall have integer type
+ */
+ _Bool constraint_check_unary_bitwise_not(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+
+ if(operand->type==ERROR)
+ return 0;
+
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(type_is_integer_type(operand_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("operand of unary ~ must be of integer type",translation_data);
+ return 0;
+ }
+ }
+ /*
+ * operand shall have scalar type
+ */
+ _Bool constraint_check_unary_logical_not(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+
+ if(operand->type==ERROR)
+ return 0;
+
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(type_is_scalar(operand_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("operand of unary ! operand must be of scallar type",translation_data);
+ return 0;
+ }
+
+ }
+ /*
+ operand is a modifiable lvalue and has a (un)qualified real or pointer type
+ * */
+ _Bool constraint_check_postfix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+
+ if(operand->type==ERROR)
+ return 0;
+
+ if(!expression_value_is_modifiable(operand->value))
+ {
+ push_translation_error("expected modifiable lvalue as operand to the ++/-- operator",translation_data);
+ return 0;
+ }
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(type_is_real(operand_type) || type_is_pointer(operand_type))
+ {
+ return 1;
+ }else
+ {
+ push_translation_error("expected real or pointer type as the type of the operand in the ++/-- operator",translation_data);
+ return 0;
+ }
+ }
+ /*
+ operand is a modifiable lvalue and has a (un)qualified real or pointer type
+ * */
+ _Bool constraint_check_prefix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ if(operand->type==ERROR)
+ return 0;
+ return constraint_check_postfix_inc_dec_expression(operand,operation,translation_data);
+ }
+ _Bool constraint_check_cast_expression(struct Type *type,struct AST_Expression *expression,struct Translation_Data *translation_data)
+ {
+ if(expression->type==ERROR || type->specifier==TS_ERROR)
+ return 0;
+ return 1;
+ }
+ #endif
F diff --git a/src/semantics/constraints/expression_constraints.h b/src/semantics/constraints/expression_constraints.h new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/expression_constraints.h
+ #ifndef WONKY_EXPRESSION_CONSTRAINTS_H
+ #define WONKY_EXPRESSION_CONSTRAINTS_H WONKY_EXPRESSION_CONSTRAINTS_H
+ #include <ast.h>
+
+ _Bool constraint_check_modulo_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
+ _Bool constraint_check_multiplicative_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_additive_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_shift_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_bitwise_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_relational_operation(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_equality_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
+ _Bool constraint_check_logical_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_simple_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
+ _Bool constraint_check_compound_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_comma_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
+ _Bool constraint_check_array_subscript_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
+ _Bool constraint_check_struct_union_member_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data);
+ _Bool constraint_check_struct_union_member_trough_ptr_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data);
+ _Bool constraint_check_conditional_expression(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data);
+ _Bool constraint_check_function_expression(struct AST_Function_Expression *proposed_function,struct Translation_Data *translation_data);
+ _Bool constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
+ _Bool constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
+ _Bool constraint_check_sizeof_by_type(struct Type *type);
+ _Bool constraint_check_unary_plus_minus(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_unary_bitwise_not(struct AST_Expression *operand,struct Translation_Data *translation_data);
+ _Bool constraint_check_unary_logical_not(struct AST_Expression *operand,struct Translation_Data *translation_data);
+ _Bool constraint_check_postfix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_prefix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ _Bool constraint_check_sizeof_expression(struct AST_Expression *expression,struct Translation_Data *translation_data);
+ _Bool constraint_check_cast_expression(struct Type *type,struct AST_Expression *expression,struct Translation_Data *translation_data);
+
+
+ #endif
F diff --git a/src/semantics/constraints/statement_constraints.c b/src/semantics/constraints/statement_constraints.c new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/statement_constraints.c
+ #ifndef WONKY_STATEMENT_CONSTRAINTS_C
+ #define WONKY_STATEMENT_CONSTRAINTS_C WONKY_STATEMENT_CONSTRAINTS_C
+ #include <statement_constraints.h>
+
+
+ _Bool constraint_check_return_statement(struct AST *return_expression,struct Type *return_type,struct Translation_Data *translation_data)
+ {
+
+ if(return_expression==NULL)
+ {
+ return 1;
+ }else if(return_expression->type==ERROR || return_type->specifier==TS_ERROR )
+ {
+ return 0;
+ }else
+ {
+
+ struct Type *expression_type;
+ struct Expression_Value *value;
+
+ value=((struct AST_Expression*)return_expression)->value;
+ expression_type=extract_expresion_value_type(value,translation_data);
+
+ if(!types_are_identical(expression_type,return_type))
+ {
+ push_translation_error("Returned expression should have %T type, got %T instead",translation_data,return_type,expression_type);
+ return 0;
+ }else
+ {
+ return 1;
+ }
+ }
+
+
+ assert(0);
+
+ }
+ #endif
F diff --git a/src/semantics/constraints/statement_constraints.h b/src/semantics/constraints/statement_constraints.h new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/statement_constraints.h
+ #ifndef WONKY_STATEMENT_CONSTRAINTS_H
+ #define WONKY_STATEMENT_CONSTRAINTS_H WONKY_STATEMENT_CONSTRAINTS_H
+ #include <ast.h>
+ #include <type.h>
+
+
+
+ /*_Bool constraint_check_case_statement(struct ,struct Translation_Data *translation_data);*/
+ /*_Bool constraint_check_default(struct ,struct Translation_Data *translation_data);*/
+ _Bool constraint_check_label(struct AST_Labeled_Statement *label,struct AST_Compound_Statement *function_block,struct Translation_Data *translation_data);
+
+ /*must have scallar controlling expression*/
+ _Bool constraint_check_if_statement(struct AST_If_Statement *if_statement,struct Translation_Data *translation_data);
+ /*must have integer controlling expresion*/
+ _Bool constraint_check_switch_statement(struct AST_Switch_Statement *switch_statement,struct Translation_Data *translation_data);
+
+ /*
+ the controlling statement shall have scalar type
+ the declaration part shall only declare identifiers for objects having storage class auto or reigster
+ */
+ _Bool constraint_check_while_statement(struct AST_While_Statement *while_statement,struct Translation_Data *translation_data);
+ _Bool constraint_check_do_while_statement(struct AST_Do_While_Statement *do_while_statement,struct Translation_Data *translation_data);
+ _Bool constraint_check_for_statement(struct AST_For_Statement *for_statement,struct Translation_Data *translation_data);
+
+ _Bool constraint_check_goto_statement(struct AST_Goto_Statement *goto_statement,struct Translation_Data *translation_data);
+ _Bool constraint_check_continue_statement(struct AST_Labeled_Statement *continue_statement,struct Translation_Data *translation_data);
+ _Bool constraint_check_break_statement(struct AST* break_statement,struct Translation_Data *translation_data);
+
+ /*must be in a function and must return with the function return type , empty expressions are premmited under functions returning void*/
+ _Bool constraint_check_return_statement(struct AST *return_expression,struct Type *return_type,struct Translation_Data *translation_data);
+
+
+ #endif
F diff --git a/src/semantics/identifiers/denoted.c b/src/semantics/identifiers/denoted.c --- a/src/semantics/identifiers/denoted.c +++ b/src/semantics/identifiers/denoted.c
ret->location=NULL;
ret->function_specifier=fs;
ret->body=NULL;
+ ret->function_scope=NULL;
return (struct Denoted*)ret;
}
F diff --git a/src/semantics/identifiers/denoted.h b/src/semantics/identifiers/denoted.h --- a/src/semantics/identifiers/denoted.h +++ b/src/semantics/identifiers/denoted.h
struct Location *location;
enum Function_Specifier function_specifier;
+ struct Function_Scope *function_scope;
struct AST_Compound_Statement *body;
};
struct Denoted_Object
F diff --git a/src/semantics/identifiers/scope.c b/src/semantics/identifiers/scope.c --- a/src/semantics/identifiers/scope.c +++ b/src/semantics/identifiers/scope.c
return (struct Scope*)ret;
}
- struct Scope* get_function_scope(struct Scope *parent)
+ struct Scope* get_function_scope(struct Scope *parent,struct Denoted_Function *function)
{
struct Function_Scope *ret;
assert(parent!=NULL && parent->type==FILE_SCOPE);
ret=malloc(sizeof(struct Function_Scope));
ret->type=FUNCTION_SCOPE;
ret->parent=parent;
+ ret->function=function;
Map_Init(&ret->labels);
}
+ struct Denoted_Function* get_enclosing_function(struct Scope *scope)
+ {
+ struct Scope *current;
+ current=scope;
+ while(current->type!=FUNCTION_SCOPE && current!=NULL)
+ {
+ assert(current->type!=FILE_SCOPE);
+ current=current->parent;
+ }
+
+ if(current==NULL)
+ return NULL;/*TODO maybe return a denoted_error*/
+
+ return ((struct Function_Scope*)current)->function;
+ }
_Bool check_if_typedefed(struct Scope* scope,struct token *id)
{
struct Denoted *hold;
F diff --git a/src/semantics/identifiers/scope.h b/src/semantics/identifiers/scope.h --- a/src/semantics/identifiers/scope.h +++ b/src/semantics/identifiers/scope.h
{
enum Scope_Type type;
struct Scope *parent;
+
+ struct Denoted_Function *function;
Map labels;
};
struct Scope* get_normal_scope(struct Scope *parent,enum Scope_Type type);
- struct Scope* get_function_scope(struct Scope *parent);
+ struct Scope* get_function_scope(struct Scope *parent,struct Denoted_Function *function);
void* check_label(struct Scope *current,struct token *id);
struct Denoted* check_tag(struct Scope *current,struct token *id);
void Scope_Push(struct Scope *scope,struct Denoted *declarator,struct Translation_Data *translation_data);
+ struct Denoted_Function* get_enclosing_function(struct Scope *scope);
+
void delete_scope(struct Scope *scope);
void delete_normal_scope(struct Normal_Scope *scope);
void delete_function_scope(struct Function_Scope *scope);
F diff --git a/src/semantics/value/constraints.c b/src/semantics/value/constraints.c deleted file mode 100644 --- a/src/semantics/value/constraints.c +++ /dev/null
- #ifndef WONKY_CONSTRAINTS_C
- #define WONKY_CONSTRAINTS_C WONKY_CONSTRAINTS_C
- #include <constraints.h>
-
- /*the operands of % shall both have an integer type 6.5.5*/
- _Bool constraint_check_modulo_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
- if(!type_is_integer_type(left_type))
- {
- push_translation_error("expected integer type in right operand of modulo operation",translation_data);
- return 0;
- }
- if(!type_is_integer_type(right_type))
- {
- push_translation_error("expected integer type in right operand of modulo operation",translation_data);
- return 0;
- }
- return 1;
- }
- /*constraints only on modulo operation 6.5.5*/
- _Bool constraint_check_multiplicative_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
- {
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- if(operation==OP_REMAINDER)
- {
- return constraint_check_modulo_expression(left,right,translation_data);
- }else
- {
- struct Type *left_type;
- struct Type *right_type;
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
-
- if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("constraint check violation in multiplicative expression",translation_data);
- return 0;
- }
- }
- assert(0);
- }
- /*for addition both operands shall have arithmetic type, or one operand shall be of pointer type and the other of integer type.
- * for subtraction one of the following shall hold
- * both operands shall have arihtmetic type
- * both operands are pointers to qualified or unqualified versions of compatible object types
- * left operand is a pointer to an object type and the right operand has integer type*/
- _Bool constraint_check_additive_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
-
- assert(operation==OP_SUBTRACTION || operation==OP_ADDITION);
-
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
- if(operation==OP_ADDITION) // operation is '+'
- {
- if(type_is_arithmetic(left_type))
- {
- if(type_is_arithmetic(right_type))
- {
- return 1;
- }else if(type_is_pointer_to_object(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("unexpected type of right operand of addition",translation_data);
- return 0;
- }
- }else if(type_is_pointer_to_object(left_type))
- {
- if(type_is_arithmetic(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("unexpected type of right operand of addition",translation_data);
- return 0;
- }
- }else
- {
- push_translation_error("unexpected type of left operand of addition",translation_data);
- return 0;
- }
- }else // operation is '-'
- {
- if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
- {
- return 1;
- }else if(type_is_pointer_to_object(left_type))
- {
- if(type_is_integer_type(right_type) || type_is_pointer_to_object(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("unexpected type of right operand of addition",translation_data);
- return 0;
- }
- }else
- {
- push_translation_error("unexpected type of left operand of addition",translation_data);
- return 0;
- }
- }
-
- }
- /*each of the operands shall have integer type 6.5.7*/
- _Bool constraint_check_shift_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
- if(type_is_integer_type(left_type) && type_is_integer_type(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("both operands of shift operation must be of integer type",translation_data);
- return 0;
- }
- }
- _Bool constraint_check_bitwise_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
- {
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- return 1;
- }
- /*
- * One of the following shall hold:
- * both operands have real type
- * both operands are pointers to qualified or unqualified versions of compatible object types
- * both operands are pointers to qualified or unqualified versions of compatible incomplete type
- *
- * */
- _Bool constraint_check_relational_operation(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
- {
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- return 1;
- }
- /* One of the following shall hold:
- * both operands have arithmetic type
- * both operands are pointers to qualified or unqualified versions of compatible types
- * one operand is a pointer to object or incomplete type and the other is a pointer to a qualified or unqualified version of void
- * one operand is a pointer and the other is a null pointer constant*/
- _Bool constraint_check_equality_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
- if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
- {
- return 1;
- }else if(type_is_pointer_to_object(left_type))
- {
- if(type_is_pointer_to_object(right_type))
- {
- if(types_are_compatible(left_type,right_type))
- {
- return 1;
- }else
- {
- push_translation_error("checking for equality between pointers of incompatible types",translation_data);
- return 0;
- }
- }else if(ast_is_null_pointer_constant((struct AST*)right) || type_is_pointer_to_void(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("rhs is not a pointer",translation_data);
- return 0;
- }
- }else if(type_is_pointer_to_object(right_type))
- {
- if(ast_is_null_pointer_constant((struct AST*)left) || type_is_pointer_to_void(left_type))
- return 1;
- else
- {
- push_translation_error("lhs is not a pointer",translation_data);
- return 0;
- }
- }else if(type_is_pointer_to_incomplete_type(left_type))
- {
- if(type_is_pointer_to_void(right_type) || ast_is_null_pointer_constant((struct AST*)right))
- {
- return 1;
- }else
- {
- push_translation_error("rhs is not a pointer",translation_data);
- return 0;
- }
- }else if(type_is_pointer_to_incomplete_type(right_type))
- {
- if(type_is_pointer_to_void(left_type) || ast_is_null_pointer_constant((struct AST*)left))
- {
- return 1;
- }
- else
- {
- push_translation_error("lhs is not a pointer",translation_data);
- return 0;
- }
- }else if(left_type->specifier==TS_POINTER)
- {
- if(ast_is_null_pointer_constant((struct AST*)right))
- {
- return 1;
- }else
- {
- push_translation_error("rhs is not a null constant",translation_data);
- return 0;
- }
- }else if(right_type->specifier==TS_POINTER)
- {
- if(ast_is_null_pointer_constant((struct AST*)left))
- {
- return 1;
- }else
- {
- push_translation_error("lhs is not a null constant",translation_data);
- return 0;
- }
- }
- }
- /*each of the operands shall have scallar type 6.5.13 6.5.14*/
- _Bool constraint_check_logical_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
-
- if(type_is_scalar(left_type) && type_is_scalar(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("both operands of logical expression must be of scallar type",translation_data);
- return 0;
- }
- }
- /*
- left operand is a modifiable lvalue
-
- One of the following shall hold:
- 1. Left operand has qualified or unqualified arithmetic type and the
- right has arithmetic type
-
- 2. The left operand has a qualified or unqualified version of a
- structure or union type compatible with the type of the right
-
- 3. Both operands are pointers to qualified or unqualified versions
- of compatible types, and the type pointed ot by the left has all
- the qualifiers of the type pointed by the right
-
- 4. One operand is a pointer to an object to or incomplete type and the
- other is a pointer to a qualified or unqualified version of void,
- and the type pointed to by the left has all the qualifiers of the
- type pointed to by the right
-
- 5. The left operand is a pointer and the right is a null pointer
- constant
-
- 6. The left operand has type _Bool and
- the right is a pointer
-
- 6.5.16.1
- * */
- _Bool constraint_check_simple_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
-
- if(!expression_value_is_modifiable(left->value))
- {
- push_translation_error("left operand of assignment operator must be modifiable",translation_data);
- return 0;
- }
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
-
- if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
- {
- return 1;
- }else if(type_is_struct_union(left_type) && types_are_compatible_unqualified(left_type,right_type))
- {
- return 1;
- }else if(left_type->specifier==TS_POINTER && types_are_compatible_unqualified(left_type,right_type))
- {
- return 1;
- }else if(left_type->specifier==TS_POINTER && ast_is_null_pointer_constant((struct AST*)right))
- {
- return 1;
- }else
- {
- push_translation_error("constraint check violation in simple assignment expression",translation_data);
- return 0;
- }
- //TODO ADD _BOOL TS
- }
- /*
- left operand is a modifiable lvalue
- if += or -=
- 1. left operand shall be a pointer to an object and the right operand shall be of integer type
- 2. left operand shall be qualified or unqualified arithmetic type and the right shall be an arithmetic type
- else
- each operand shall have arithmetic type consistent with those allowed by the corresponding binary operator
-
- 6.5.16.2
- */
- _Bool constraint_check_compound_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- if(!expression_value_is_modifiable(left->value))
- {
- push_translation_error("left operand of assignment operator must be modifiable",translation_data);
- return 0;
- }
-
- switch(operation)
- {
- case OP_ADD_ASSIGN:
- case OP_SUBTRACT_ASSIGN:
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
- if(left_type->specifier==TS_POINTER && type_is_integer_type(right_type))
- {
- return 1;
- }else if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("constraint check violation in compound assignment expression",translation_data);
- return 0;
- }
- assert(0);
- case OP_MULTIPLY_ASSIGN:
- case OP_DIV_ASSIGN:
- case OP_REMAINDER_ASSIGN:
- return constraint_check_multiplicative_expression(left,right,operation,translation_data);
- case OP_SHIFT_RIGHT_ASSIGN:
- case OP_SHIFT_LEFT_ASSIGN:
- return constraint_check_shift_expression(left,right,operation,translation_data);
- case OP_AND_ASSIGN:
- case OP_XOR_ASSIGN:
- case OP_PIPE_ASSIGN:
- return constraint_check_bitwise_expression(left,right,operation,translation_data);
- default:
- assert(0);
- }
- }
- /*
- none that I could see
- */
- _Bool constraint_check_comma_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
- {
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
- return 1;
- }
- /*
- one of the expressions shall have type pointer to object the other shall have integer
- */
- _Bool constraint_check_array_subscript_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
- struct Type *right_type;
-
- if(left->type==ERROR || right->type==ERROR)
- return 0;
-
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- right_type=extract_expresion_value_type(right->value,translation_data);
-
- if(type_is_pointer(left_type) && type_is_integer_type(right_type))
- {
- return 1;
- }else if(type_is_pointer(right_type) && type_is_integer_type(left_type))
- {
- return 1;
- }else
- {
- push_translation_error("constraint check violation in array subscript expression",translation_data);
- return 0;
- }
-
- }
- /*
- left is (un)qualified struct or union, second is an id of a memeber of the struct or union
- NOTE: we don't check if id is a member of the struct or union here
- */
- _Bool constraint_check_struct_union_member_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
-
- if(left->type==ERROR)
- return 0;
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- return type_is_struct_union(left_type);
- }
- /*
- see above
- */
- _Bool constraint_check_struct_union_member_trough_ptr_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
-
- if(left->type==ERROR)
- return 0;
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- if(type_is_pointer_to_object(left_type))
- {
- left_type=((struct Type_Pointer*)left_type)->points_to;
- return type_is_struct_union(left_type);
- }else
- {
- push_translation_error("constraint check violation in member access expression",translation_data);
- return 0;
- }
- }
- /*
- First operand shall have scaller type
- One of the following shall hold for the second and third operands
- both operands have arithmetic type
- both operands have the same structure or union type
- both operands have void type
- both operands are pointers of (un)qualified versions of compatible types
- one operand is a pointer and the other is a null pointer constant
- one operand is a pointer to an object or incomplete type and the other is a pointer to a (un)qualified version of void
- */
- _Bool constraint_check_conditional_expression(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data)
- {
- struct Type *left_type;
-
- if(left->type==ERROR || center->type==ERROR || right->type==ERROR)
- return 0;
-
- left_type=extract_expresion_value_type(left->value,translation_data);
- if(!type_is_arithmetic(left_type))
- {
- push_translation_error("first operand of conditional expression must be of arithmetic type",translation_data);
- return 0;
- }else
- {
- struct Type *center_type;
- struct Type *right_type;
-
- right_type=extract_expresion_value_type(right->value,translation_data);
- center_type=extract_expresion_value_type(center->value,translation_data);
-
- if(type_is_arithmetic(right_type) && type_is_arithmetic(center_type))
- {
- return 1;
- }else if(type_is_struct_union(center_type) && types_are_compatible(center_type,right_type))
- {
- return 1;
- }else if(center_type->specifier==TS_VOID && right_type->specifier==TS_VOID)
- {
- return 1;
- }else if(type_is_pointer(center_type) && types_are_compatible(center_type,right_type))
- {
- return 1;
- }else if(type_is_pointer(center_type) && ast_is_null_pointer_constant((struct AST*)right))
- {
- return 1;
- }else if(type_is_pointer(right_type) && ast_is_null_pointer_constant((struct AST*)center))
- {
- return 1;
- }else if( (type_is_pointer_to_object(center_type) || type_is_pointer_to_incomplete_type(center_type)) && type_is_pointer_to_void(right_type))
- {
- return 1;
- }else if( (type_is_pointer_to_object(center_type) || type_is_pointer_to_incomplete_type(center_type)) && type_is_pointer_to_void(right_type))
- {
- return 1;
- }else
- {
- push_translation_error("constraint check violation in member contitional expression",translation_data);
- return 0;
- }
- }
- }
- _Bool constraint_check_function_expression(struct AST_Function_Expression *proposed_function,struct Translation_Data *translation_data)
- {
- struct Type *expected_argument_type;
- struct Type *given_argument_type;
- struct Type_Function *proposed_function_type;
- size_t i;
-
- if(proposed_function->type==ERROR)
- return 0;
-
- proposed_function_type=(struct Type_Function*)extract_expresion_value_type(proposed_function->id->value,translation_data);
- if(proposed_function_type->specifier!=TS_FUNC)
- {
- push_translation_error("is not a function",translation_data);
- return 0;
- }
-
- if(proposed_function_type->number_of_arguments!=proposed_function->number_of_arguments)
- {
- push_translation_error("mismatching number of arguments",translation_data);
- return 0;
- }
-
- for(i=0;i<proposed_function->number_of_arguments;++i)
- {
- expected_argument_type=proposed_function_type->arguments[i]->object->type;
- given_argument_type=extract_expresion_value_type(proposed_function->arg_list[i]->value,translation_data);
- if(!types_are_compatible_unqualified(expected_argument_type,given_argument_type))
- {
- push_translation_error("incompatible types of argument",translation_data);
- return 0;
- }
- }
- return 1;
- }
- _Bool constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
-
- if(operand->type==ERROR)
- return 0;
-
- operand_type=extract_expresion_value_type(operand->value,translation_data);
- if(operand_type->specifier==TS_POINTER)
- {
- return 1;
- }else
- {
- push_translation_error("needs pointer type",translation_data);
- return 0;
- }
- }
- _Bool constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
-
- if(operand->type==ERROR)
- return 0;
-
- operand_type=extract_expresion_value_type(operand->value,translation_data);
- if(operand->value->type==VALUE_FUNCTION_DESIGNATOR || operand->type==OP_ARR_SUBSCRIPT || operand->type==OP_DEREFERENCE)
- {
- return 1;
- }else if(operand->value->type==VALUE_LVALUE)
- {
- struct Object *hold_operand_object;
- hold_operand_object=((struct Expression_Value_LValue*)operand->value)->object;
- if(hold_operand_object->kind==OBJECT_KIND_BITFIELD || hold_operand_object->storage_class==SCS_REGISTER)
- {
- push_translation_error("can't get the address of such an operand",translation_data);
- return 0;
- }else
- {
- return 1;
- }
- }else
- {
- push_translation_error("cast type needs to be of scalar type",translation_data);
- return 0;
- }
- }
- _Bool constraint_check_sizeof_by_type(struct Type *type)
- {
- if(type->specifier==TS_ERROR)
- return 0;
- else
- return 1;
- }
- _Bool constraint_check_sizeof_expression(struct AST_Expression *expression,struct Translation_Data *translation_data)
- {
- if(expression->type==ERROR)
- return 0;
- else
- return 1;
- }
- /*
- * operand shall have arithmetic type
- */
- _Bool constraint_check_unary_plus_minus(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
-
- if(operand->type==ERROR)
- return 0;
-
- operand_type=extract_expresion_value_type(operand->value,translation_data);
- if(type_is_arithmetic(operand_type))
- {
- return 1;
- }else
- {
- push_translation_error("operan of unary +/- must be of arithmetic type",translation_data);
- return 0;
- }
- }
- /*
- * operand shall have integer type
- */
- _Bool constraint_check_unary_bitwise_not(struct AST_Expression *operand,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
-
- if(operand->type==ERROR)
- return 0;
-
- operand_type=extract_expresion_value_type(operand->value,translation_data);
- if(type_is_integer_type(operand_type))
- {
- return 1;
- }else
- {
- push_translation_error("operand of unary ~ must be of integer type",translation_data);
- return 0;
- }
- }
- /*
- * operand shall have scalar type
- */
- _Bool constraint_check_unary_logical_not(struct AST_Expression *operand,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
-
- if(operand->type==ERROR)
- return 0;
-
- operand_type=extract_expresion_value_type(operand->value,translation_data);
- if(type_is_scalar(operand_type))
- {
- return 1;
- }else
- {
- push_translation_error("operand of unary ! operand must be of scallar type",translation_data);
- return 0;
- }
-
- }
- /*
- operand is a modifiable lvalue and has a (un)qualified real or pointer type
- * */
- _Bool constraint_check_postfix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
-
- if(operand->type==ERROR)
- return 0;
-
- if(!expression_value_is_modifiable(operand->value))
- {
- push_translation_error("expected modifiable lvalue as operand to the ++/-- operator",translation_data);
- return 0;
- }
- operand_type=extract_expresion_value_type(operand->value,translation_data);
- if(type_is_real(operand_type) || type_is_pointer(operand_type))
- {
- return 1;
- }else
- {
- push_translation_error("expected real or pointer type as the type of the operand in the ++/-- operator",translation_data);
- return 0;
- }
- }
- /*
- operand is a modifiable lvalue and has a (un)qualified real or pointer type
- * */
- _Bool constraint_check_prefix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- if(operand->type==ERROR)
- return 0;
- return constraint_check_postfix_inc_dec_expression(operand,operation,translation_data);
- }
- _Bool constraint_check_cast_expression(struct Type *type,struct AST_Expression *expression,struct Translation_Data *translation_data)
- {
- if(expression->type==ERROR || type->specifier==TS_ERROR)
- return 0;
- return 1;
- }
- #endif
F diff --git a/src/semantics/value/constraints.h b/src/semantics/value/constraints.h deleted file mode 100644 --- a/src/semantics/value/constraints.h +++ /dev/null
- #ifndef WONKY_CONSTRAINTS_H
- #define WONKY_CONSTRAINTS_H WONKY_CONSTRAINTS_H
- #include <constraints.hh>
- #include <ast.h>
-
- _Bool constraint_check_modulo_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
- _Bool constraint_check_multiplicative_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_additive_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_shift_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_bitwise_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_relational_operation(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_equality_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
- _Bool constraint_check_logical_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_simple_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
- _Bool constraint_check_compound_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_comma_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
- _Bool constraint_check_array_subscript_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
- _Bool constraint_check_struct_union_member_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data);
- _Bool constraint_check_struct_union_member_trough_ptr_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data);
- _Bool constraint_check_conditional_expression(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data);
- _Bool constraint_check_function_expression(struct AST_Function_Expression *proposed_function,struct Translation_Data *translation_data);
- _Bool constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
- _Bool constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
- _Bool constraint_check_sizeof_by_type(struct Type *type);
- _Bool constraint_check_unary_plus_minus(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_unary_bitwise_not(struct AST_Expression *operand,struct Translation_Data *translation_data);
- _Bool constraint_check_unary_logical_not(struct AST_Expression *operand,struct Translation_Data *translation_data);
- _Bool constraint_check_postfix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_prefix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
- _Bool constraint_check_sizeof_expression(struct AST_Expression *expression,struct Translation_Data *translation_data);
- _Bool constraint_check_cast_expression(struct Type *type,struct AST_Expression *expression,struct Translation_Data *translation_data);
-
-
- #endif
F diff --git a/src/semantics/value/constraints.hh b/src/semantics/value/constraints.hh deleted file mode 100644 --- a/src/semantics/value/constraints.hh +++ /dev/null
- #ifndef WONKY_CONSTRAINTS_HH
- #define WONKY_CONSTRAINTS_HH WONKY_CONSTRAINTS_HH
-
- #endif
F diff --git a/src/semantics/value/type.c b/src/semantics/value/type.c --- a/src/semantics/value/type.c +++ b/src/semantics/value/type.c
{
return (type->specifier==TS_FLOAT || type->specifier==TS_DOUBLE);
}
+ _Bool type_is_derivative(struct Type *type)
+ {
+ return (type->specifier==TS_POINTER || type->specifier==TS_ARRAY || type->specifier==TS_FUNC);
+ }
_Bool type_is_constant(struct Type *type)
{
switch(type->specifier)
F diff --git a/src/semantics/value/type.h b/src/semantics/value/type.h --- a/src/semantics/value/type.h +++ b/src/semantics/value/type.h
_Bool type_is_pointer_to_void(struct Type *type);
_Bool type_is_real(struct Type *type);
_Bool type_is_floating(struct Type *type);
+ _Bool type_is_derivative(struct Type *type);
/*these return 0 if constant/volatile-ness make no sense for the type*/
_Bool type_is_constant(struct Type *type);