F diff --git a/src/frontend/parse/parse_expression.c b/src/frontend/parse/parse_expression.c
--- a/src/frontend/parse/parse_expression.c
+++ b/src/frontend/parse/parse_expression.c
if(hold_expression==NULL)
{ push_translation_error("expected cast expression after unary '+' operator",translation_data); goto error; }
else
- return (struct AST_Expression*)get_unary_arithmetic_tree(hold_expression,OP_UNARY_PLUS,translation_data);
+ return (struct AST_Expression*)get_unary_plus_minus_expression(hold_expression,OP_UNARY_PLUS,translation_data);
case KW_MINUS:
chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
if(hold_expression==NULL)
{ push_translation_error("expected cast expression after unary '-' operator",translation_data); goto error; }
else
- return (struct AST_Expression*)get_unary_arithmetic_tree(hold_expression,OP_UNARY_MINUS,translation_data);
+ return (struct AST_Expression*)get_unary_plus_minus_expression(hold_expression,OP_UNARY_MINUS,translation_data);
case KW_EXCLAMATION:
chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
if(hold_expression==NULL)
{ push_translation_error("expected cast expression after unary '!' operator",translation_data); goto error; }
else
- return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_LOGICAL_NOT,translation_data);
+ return (struct AST_Expression*) get_unary_logical_not_expression(hold_expression,translation_data);
case KW_TILDE:
chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
if(hold_expression==NULL)
{ push_translation_error("expected cast expression after unary '~' operator",translation_data); goto error; }
else
- return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_BITWISE_NOT,translation_data);
+ return (struct AST_Expression*) get_unary_bitwise_not_expression(hold_expression,translation_data);
case KW_STAR:
chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
if(hold_expression==NULL)
{ push_translation_error("expected cast expression after unary '*' operator",translation_data); goto error; }
else
- return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_DEREFERENCE,translation_data);
+ return (struct AST_Expression*) get_indirection_expression_tree(hold_expression,translation_data);
case KW_AND:
chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
if(hold_expression==NULL)
{ push_translation_error("expected cast expression after unary '&' operator",translation_data); goto error; }
else
- return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_ADDR_OF,translation_data);
+ return (struct AST_Expression*) get_address_expression_tree(hold_expression,translation_data);
case KW_SIZEOF:
chomp(translation_data);
if(get_and_check(translation_data,KW_OPEN_NORMAL))
F diff --git a/src/semantics/ast.c b/src/semantics/ast.c
--- a/src/semantics/ast.c
+++ b/src/semantics/ast.c
/*TODO could optimise this*/
ret->right=(struct AST_Expression*)get_designator_tree(id,(struct Scope*)struct_union->inner_namespace,translation_data);
+ ret->value=ret->right->value; /*BEWARE*/
- /*
- if(left_type->is_const || !(ret->right->is_modifiable))
- ret->is_modifiable=0;
- else
- ret->is_modifiable=1;
- */
return ret;
}
/*TODO beware const type qualifier*/
struct AST_Binary_Expression* get_struct_union_member_trough_ptr_tree(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)
{
- return get_struct_union_member_tree((struct AST_Expression*)get_indirection_expression_tree(left,translation_data),id,translation_data);
+ struct AST_Expression *hold_derefernced;
+ hold_derefernced=(struct AST_Expression*)get_indirection_expression_tree(left,translation_data);
+ if(hold_derefernced==NULL)
+ {
+ push_translation_error("in struct/union member access trough pointer",translation_data);
+ return NULL;
+ }else
+ {
+ return get_struct_union_member_tree(hold_derefernced,id,translation_data);
+ }
}
struct AST_Conditional_Expression* get_conditional_expression_tree(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data)
}
-
-
- struct AST_Unary_Expression* get_unary_arithmetic_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ struct AST_Unary_Expression* get_unary_plus_minus_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
{
struct Type *operand_type;
-
- if(operation==OP_UNARY_PLUS || operation==OP_UNARY_MINUS)
+ if(constraint_check_unary_plus_minus(operand,operation,translation_data))
{
operand=get_promoted_expression(operand,translation_data);
operand_type=extract_expresion_value_type(operand->value,translation_data);
-
- if(type_is_arithmetic(operand_type))
- {
- return get_unary_expression_tree(
- operand,
- get_expression_value_rvalue(get_temp_object(operand_type)),
- operation
- );
- }else
- {
- push_translation_error("expected scalar type for operand in unary operation",translation_data);
- return NULL;
- }
+ return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),operation);
+ }else
+ {
+ delete_ast((struct AST*)operand);
+ return NULL;
+ }
+ }
+ struct AST_Unary_Expression* get_unary_bitwise_not_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+ if(constraint_check_unary_bitwise_not(operand,translation_data))
+ {
+ operand=get_promoted_expression(operand,translation_data);
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),OP_BITWISE_NOT);
+ }else
+ {
+ delete_ast((struct AST*)operand);
+ return NULL;
+ }
+ }
+ struct AST_Unary_Expression* get_unary_logical_not_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+ if(constraint_check_unary_logical_not(operand,translation_data))
+ {
+ operand=get_promoted_expression(operand,translation_data);
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),OP_LOGICAL_NOT);
+ }else
+ {
+ delete_ast((struct AST*)operand);
+ return NULL;
}
}
-
struct AST_Unary_Expression* get_postfix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
{
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_Unary_Expression* get_indirection_expression_tree(struct AST_Expression *operand,struct Translation_Data *translation_data);
struct AST_Unary_Expression* get_address_expression_tree(struct AST_Expression *operand,struct Translation_Data *translation_data);
struct AST_Unary_Expression* get_sizeof_by_type_tree(struct Type *type);
- struct AST_Unary_Expression* get_unary_arithmetic_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+
+
+
+ struct AST_Unary_Expression* get_unary_plus_minus_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ struct AST_Unary_Expression* get_unary_bitwise_not_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
+ struct AST_Unary_Expression* get_unary_logical_not_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
+
+
struct AST_Unary_Expression* get_postfix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
struct AST_Unary_Expression* get_prefix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
struct AST_Unary_Expression* get_unary_sizeof_tree(struct AST_Expression *operand,struct Translation_Data *translation_data);
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 Enum *enumerator;
size_t size;
- char is_const:1;
- char is_volatile:1;
+ _Bool is_const:1;
+ _Bool is_volatile:1;
};
F diff --git a/src/semantics/value/constraints.c b/src/semantics/value/constraints.c
--- a/src/semantics/value/constraints.c
+++ b/src/semantics/value/constraints.c
{
struct Type *operand_type;
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;
+ }
+ }
+ char constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+ 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;
return 0;
}
}
- char constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
- {
- return 1;
- }
char constraint_check_sizeof_by_type(struct Type *type)
{
return 1;
{
return 1;
}
- char constraint_check_unary_arithmetic_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ /*
+ * operand shall have arithmetic type
+ */
+ char constraint_check_unary_plus_minus(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
{
- return 1;
+ struct Type *operand_type;
+ 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
+ */
+ char constraint_check_unary_bitwise_not(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+ 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
+ */
+ char constraint_check_unary_logical_not(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+ 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
F diff --git a/src/semantics/value/constraints.h b/src/semantics/value/constraints.h
--- a/src/semantics/value/constraints.h
+++ b/src/semantics/value/constraints.h
char constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
char constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);
char constraint_check_sizeof_by_type(struct Type *type);
- char constraint_check_unary_arithmetic_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ char constraint_check_unary_plus_minus(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ char constraint_check_unary_bitwise_not(struct AST_Expression *operand,struct Translation_Data *translation_data);
+ char constraint_check_unary_logical_not(struct AST_Expression *operand,struct Translation_Data *translation_data);
char constraint_check_postfix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
char constraint_check_prefix_inc_dec_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
char constraint_check_sizeof_expression(struct AST_Expression *expression,struct Translation_Data *translation_data);
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
ret->inner_namespace=(struct Normal_Scope*)get_normal_scope(scope,BLOCK_SCOPE);
ret->is_finished=0;
ret->has_constant_member=0;
- ret->id;
+ ret->id=id;
return ret;
}
}else
{
struct Queue_Node *it;
- for(it=((struct Type_Struct_Union*)type)->struct_union->members->first;it!=NULL;it=it)
+ for(it=((struct Type_Struct_Union*)type)->struct_union->members->first;it!=NULL;it=it->prev)
{
if( type_is_constant_or_has_constant_member(((struct Denoted_Object*)it->data)->object->type))
return 1;
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
struct Map *node;
struct Struct_Union *struct_union;
- char is_const:1;
- char is_volatile:1;
+ _Bool is_const:1;
+ _Bool is_volatile:1;
};
struct Struct_Union
{
struct Queue *members;
struct Normal_Scope *inner_namespace;
- char is_finished:1;
- char has_constant_member:1;
+ _Bool is_finished:1;
+ _Bool has_constant_member:1;
};
struct Type_Bit_Field
{
enum Type_Constraint constraint;
enum Type_Signedness sign;
size_t size;
- char is_const:1;
+ _Bool is_const:1;
char is_volatile:1;
};
struct Type_Pointer