F diff --git a/src/backend/asm/intel/intel_compile.c b/src/backend/asm/intel/intel_compile.c --- a/src/backend/asm/intel/intel_compile.c +++ b/src/backend/asm/intel/intel_compile.c[OP_NOT_EQUAL]=(map_entry)compile_not_equal_to_intel_asm,[OP_DESIGNATOR]=(map_entry)compile_designator_to_intel_asm,[OP_CONSTANT]=(map_entry)compile_constant_to_intel_asm,+ [OP_SIZEOF]=(map_entry)compile_sizeof_to_intel_asm,[OP_STRING_LITERAL]=(map_entry)compile_string_literal_to_intel_asm,[ST_COMPOUND]=(map_entry)compile_compound_statement_to_intel_asm,[ST_EXPRESSION]=(map_entry)compile_expression_statement,push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));}}+ void compile_sizeof_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Size_Of_Expression *sizeof_expression)+ {+ long long int siz = get_type_size(sizeof_expression->operand_type);+ #warning fix this so it works for any size_t size ;)+ wonky_assert(siz < 10000);/*this is here because long long int might overflow int. TODO*/++ intel_asm_memory_location_to_rax(compile_data,get_intel_asm_in_instruction_number((int)siz));+ push_intel_asm_instruction(compile_data,intel_asm_get_push(INTEL_ASM_REGISTER_RAX));+ }void compile_string_literal_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_String_Literal *literal){struct Intel_Asm_Memory_Location *string_location;F diff --git a/src/backend/asm/intel/intel_compile.h b/src/backend/asm/intel/intel_compile.h --- a/src/backend/asm/intel/intel_compile.h +++ b/src/backend/asm/intel/intel_compile.hvoid compile_conditional_expression_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Conditional_Expression *expression);void compile_function_expression_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Function_Expression *call);void compile_constant_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Constant *constant);+ void compile_sizeof_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Size_Of_Expression *sizeof_expression);void compile_string_literal_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_String_Literal *literal);void compile_designator_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Designator *designator);void compile_labeled_statement_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Labeled_Statement *labeled);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}else{- push_generic_error(translation_data->program,"unexpected 'signed' in type");+ push_translation_error("unexpected 'signed' in type",translation_data);if(ret->sign==TSIGN_SIGNED)- push_generic_note(translation_data->program,"when it is unsigned");+ push_translation_error("when it is unsigned",translation_data);else- push_generic_note(translation_data->program,"when it is already signed");+ push_translation_error("when it is already signed",translation_data);}break;case KW_UNSIGNED:}else{- push_generic_error(translation_data->program,"unexpected 'unsigned' in type");+ push_translation_error("unexpected 'unsigned' in type",translation_data);if(ret->sign==TSIGN_SIGNED)- push_generic_note(translation_data->program,"when it is signed");+ push_translation_note("when it is signed",translation_data);else- push_generic_note(translation_data->program,"when it is already unsigned");+ push_translation_note("when it is already unsigned",translation_data);}break;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_generic_error(translation_data->program,"more than one type specifier given");+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_INT;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_generic_error(translation_data->program,"more than one type specifier given");+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_VOID;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_generic_error(translation_data->program,"more than one type specifier given");+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_CHAR;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_generic_error(translation_data->program,"more than one type specifier given");+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_DOUBLE;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_generic_error(translation_data->program,"more than one type specifier given");+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_FLOAT;}else{if(ret->constraint==TC_LONG_LONG)- push_generic_error(translation_data->program,"yeah ... it's big");+ push_translation_error("yeah ... it's big",translation_data);else if(ret->constraint==TC_SHORT)- push_generic_error(translation_data->program,"long and short constraints contradict");+ push_translation_error("long and short constraints contradict",translation_data);elsewonky_assert(SHOULD_NOT_REACH_HERE);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);switch(ret->constraint){case TC_LONG:- push_generic_error(translation_data->program,"long and short constraints contradict");+ push_translation_error("long and short constraints contradict",translation_data);break;case TC_SHORT:- push_generic_error(translation_data->program,"it's not about the size, it's about how you use it");+ push_translation_error("it's not about the size, it's about how you use it",translation_data);break;case TC_LONG_LONG:- push_generic_error(translation_data->program,"long long and short constraints contradict");+ push_translation_error("long long and short constraints contradict",translation_data);break;default:/*should not be able to enter here*/switch(ret->storage_class){case SCS_EXTERN:- push_generic_error(translation_data->program,"only one extern allowed >:|");+ push_translation_error("only one extern allowed >:|",translation_data);break;case SCS_TYPEDEF:case SCS_STATIC:- push_generic_error(translation_data->program,"only one storage class allowed >:|");+ push_translation_error("only one storage class allowed >:|",translation_data);break;default:wonky_assert(SHOULD_NOT_REACH_HERE);switch(ret->storage_class){case SCS_STATIC:- push_generic_error(translation_data->program,"only one static allowed >:|");+ push_translation_error("only one static allowed >:|",translation_data);break;case SCS_EXTERN:case SCS_TYPEDEF:- push_generic_error(translation_data->program,"only one storage class allowed >:|");+ push_translation_error("only one storage class allowed >:|",translation_data);break;default:wonky_assert(SHOULD_NOT_REACH_HERE);case SCS_STATIC:case SCS_EXTERN:case SCS_TYPEDEF:- push_generic_error(translation_data->program,"only one storage class allowed >:|");+ push_translation_error("only one storage class allowed >:|",translation_data);break;default:wonky_assert(SHOULD_NOT_REACH_HERE);ret->struct_union=tag->struct_union;if(ret->struct_union->specifier!=ret->specifier){- push_generic_error(translation_data->program,"more than one type specifier");+ push_translation_error("more than one type specifier",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}if(ret->struct_union->is_finished==0)parse_struct_union_specifier_finish(translation_data,scope,ret->struct_union);if(ret->struct_union->is_finished==0){- push_generic_error(translation_data->program,"expected a struct tag or a struct definition");+ push_translation_error("expected a struct tag or a struct definition",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}}}else{base->type=get_type_error(hold_first_part);- push_generic_error(translation_data->program,"Expected a ')' at %L");+ push_translation_error("Expected a ')' at %L",translation_data);}}else{if(!get_and_check(translation_data,KW_CLOSE_SQUARE)){/*TODO error*/- push_generic_error(translation_data->program,"']' expected");+ push_translation_error("']' expected",translation_data);base->type=(struct Type*)get_type_error(base->type);delete_ast(hold_expression);+return;}}if(hold_denoted_object->denotation!=DT_Object){/*TODO error*/- push_generic_error(translation_data->program,"expected object type for bitfield");+ push_translation_error("expected object type for bitfield",translation_data);return get_denoted_error((struct Denoted*)hold_denoted_object);}if(get_and_check(translation_data,KW_COLUMN))}else{/*TODO error*/- push_generic_error(translation_data->program,"enum definition error");+ push_translation_error("enum definition error",translation_data);Queue_Push(enumeration->consts,get_denoted_error(NULL));return ;}}else{/*TODO error*/- push_generic_error(translation_data->program,"enum definition error, expected an id");+ push_translation_error("enum definition error, expected an id",translation_data);//Queue_Push(enumeration->consts,get_denoted_error(NULL));return ;}if(base->denotation==DT_Error || base->id!=NULL){/*TODO error*/- push_generic_error(translation_data->program,"unexpedted id in abstract declarator");+ push_translation_error("unexpedted id in abstract declarator",translation_data);delete_denoted_base(base);ret=base->type;return ret;return parse_initialiser_list_for_struct_union(translation_data,scope,(struct Type_Struct_Union*)type_of_initialised);else{- push_generic_error(translation_data->program,"expected aggregate type in compound initialisation, got %T instead",type_of_initialised);+ push_translation_error("expected aggregate type in compound initialisation, got %T instead",translation_data,type_of_initialised);return get_initialiser_error(NULL);}}return parse_initialiser(translation_data,scope,type_of_initialised);else{- push_generic_error(translation_data->program,"expected '=' in initialiser designation");+ push_translation_error("expected '=' in initialiser designation",translation_data);return get_initialiser_error(NULL);}if(!type_is_an_array(type_of_initialised)){- push_generic_error(translation_data->program,"expected array type in indexed initialiser, instead got a %T",type_of_initialised);+ push_translation_error("expected array type in indexed initialiser, instead got a %T",translation_data,type_of_initialised);return get_initialiser_error(NULL);}if(!type_is_struct_union(type_of_initialised)){- push_generic_error(translation_data->program,"expected struct/union type in initialiser, got %T instead",type_of_initialised);+ push_translation_error("expected struct/union type in initialiser, got %T instead",translation_data,type_of_initialised);return get_initialiser_error(NULL);}if(!check(translation_data,KW_ID)){- push_generic_error(translation_data->program,"expected id in the initialisation of type %T",type_of_initialised);+ push_translation_error("expected id in the initialisation of type %T",translation_data,type_of_initialised);return get_initialiser_error(NULL);}if(member==NULL){- push_generic_error(translation_data->program,"%t is not a member of %T",id,type_of_initialised);+ push_translation_error("%t is not a member of %T",translation_data,id,type_of_initialised);push_translation_note("in initialiser",translation_data);return get_initialiser_error(NULL);}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.cchomp(translation_data);if(get_and_check(translation_data,KW_OPEN_NORMAL)){- return (struct AST_Expression*)get_sizeof_by_type_tree(parse_type_name(translation_data,scope));+ struct AST *ret=NULL;++ if(is_type_name(translation_data,scope))+ {+ ret=(struct AST*)get_sizeof_by_type_tree(+ parse_type_name(translation_data,scope)+ );+ }else+ {+ hold_expression=parse_unary_expression(translation_data,scope);+ ret=(struct AST*)get_unary_sizeof_tree(hold_expression,translation_data);+ }++ if(!get_and_check(translation_data,KW_CLOSE_NORMAL))+ {+ push_translation_error("expected ')' in sizeof expression",translation_data);+ return get_error_tree(ret);+ }+ return ret;}else{hold_expression=parse_unary_expression(translation_data,scope);F diff --git a/src/misc/print.c b/src/misc/print.c --- a/src/misc/print.c +++ b/src/misc/print.cwonky_fprintf(out,"%WAE%WA",unary_expression->type,unary_expression->operand);}}+ void print_sizeof_expression_tree(struct wonky_stream *out,struct AST_Size_Of_Expression *sizeof_expression)+ {+ wonky_fprintf(out,"sizeof(%WT)",sizeof_expression->operand_type);+ }void print_labeled_statement_tree(struct wonky_stream *out,struct AST_Labeled_Statement *lab,short indentation){print_indentation(out,indentation);break;case OP_LOGICAL_NOT:case OP_UNARY_MINUS:- case OP_SIZEOF:case OP_ADDR_OF:case OP_DEREFERENCE:case OP_POSTFIX_INC:print_indentation(out,indentation);print_unary_expression_tree(out,(struct AST_Unary_Expression*)tree);break;+ case OP_SIZEOF:+ print_indentation(out,indentation);+ print_sizeof_expression_tree(out,(struct AST_Size_Of_Expression*)tree);+ break;case OP_STRING_LITERAL:print_indentation(out,indentation);print_string_literal(out,(struct AST_String_Literal*)tree);F diff --git a/src/misc/print.h b/src/misc/print.h --- a/src/misc/print.h +++ b/src/misc/print.hvoid print_conditional_expression_tree(struct wonky_stream *out,struct AST_Conditional_Expression *cond);void print_function_expression_tree(struct wonky_stream *out,struct AST_Function_Expression *function_call);void print_unary_expression_tree(struct wonky_stream *out,struct AST_Unary_Expression *unary_expression);+ void print_sizeof_expression_tree(struct wonky_stream *out,struct AST_Size_Of_Expression *sizeof_expression);void print_constant_tree(struct wonky_stream *out,struct AST_Constant *constant);void print_string_literal(struct wonky_stream *out,struct AST_String_Literal *string);//void print_lvalue_expression_tree(struct wonky_stream *out,struct AST_Lvalue_Expression *lval);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_Unary_Expression* get_sizeof_by_type_tree(struct Type *type)+ struct AST_Size_Of_Expression* get_sizeof_by_type_tree(struct Type *type){- return get_unary_expression_tree(NULL,get_expression_value_rvalue(get_temp_object(type)),OP_SIZEOF);+ struct AST_Size_Of_Expression *ret;++ ret=wonky_malloc(sizeof(struct AST_Size_Of_Expression));+ ret->type=OP_SIZEOF;+ ret->value=get_expression_value_rvalue(get_temp_object(get_type_unsigned_long_long_int()));++ wonky_assert(type!=NULL);+ ret->operand_type=type;++ return ret;}}}- struct AST_Unary_Expression* get_unary_sizeof_tree(struct AST_Expression *operand,struct Translation_Data *translation_data)+ struct AST_Size_Of_Expression* get_unary_sizeof_tree(struct AST_Expression *operand,struct Translation_Data *translation_data){- return (struct AST_Unary_Expression*)get_error_tree(NULL);+ return get_sizeof_by_type_tree(extract_expresion_value_type(operand->value));}struct AST_Constant* get_constant_tree(struct Expression_Value_Constant *value){/*it is just a ast node*/wonky_free(ast);break;+ case OP_SIZEOF:+ delete_ast_sizeof_expression((struct AST_Size_Of_Expression*)ast);+ break;case OP_LOGICAL_NOT:case OP_BITWISE_NOT:case OP_ADDR_OF:case OP_UNARY_PLUS:case OP_UNARY_MINUS:case OP_CAST:- case OP_SIZEOF:delete_ast_unary_expression((struct AST_Unary_Expression*)ast);break;case OP_CONSTANT:{if(unary_expression->operand!=NULL)delete_ast((struct AST*)unary_expression->operand);+ if(unary_expression->value!=NULL)+ delete_expression_value(unary_expression->value);wonky_free(unary_expression);}+ void delete_ast_sizeof_expression(struct AST_Size_Of_Expression *sizeof_expression)+ {+ if(sizeof_expression->operand_type!=NULL)+ delete_type(sizeof_expression->operand_type);+ if(sizeof_expression->value!=NULL)+ delete_expression_value(sizeof_expression->value);+ wonky_free(sizeof_expression);+ }void delete_ast_labeled_statement(struct AST_Labeled_Statement *labeled_statement){if(labeled_statement->label!=NULL)F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.hstruct AST_Expression *operand;};+ struct AST_Size_Of_Expression+ {+ enum AST_Type type;+ struct Expression_Value *value;++ /*operand_type should be the type for which we get the size of*/+ struct Type *operand_type;+ };struct AST_Labeled_Statement{struct AST_Unary_Expression* get_unary_expression_tree(struct AST_Expression *operand,struct Expression_Value *value,enum AST_Type type);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_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);+ struct AST_Size_Of_Expression* get_unary_sizeof_tree(struct AST_Expression *operand,struct Translation_Data *translation_data);+ struct AST_Size_Of_Expression* get_sizeof_by_type_tree(struct Type *type);//TODO compound literalsvoid delete_ast_string_literal(struct AST_String_Literal *string);void delete_ast_designator_expression(struct AST_Designator *designator);void delete_ast_unary_expression(struct AST_Unary_Expression *unary_expression);+ void delete_ast_sizeof_expression(struct AST_Size_Of_Expression *sizeof_expression);void delete_ast_labeled_statement(struct AST_Labeled_Statement *labeled_statement);void delete_ast_default_statement(struct AST_Default_Statement *default_statement);void delete_ast_break_continue_statement(struct AST_Break_Continue_Statement *break_continue);F diff --git a/src/semantics/ast.hh b/src/semantics/ast.hh --- a/src/semantics/ast.hh +++ b/src/semantics/ast.hhstruct AST_String_Literal;struct AST_Designator;struct AST_Unary_Expression;+ struct AST_Size_Of_Expression;struct AST_Labeled_Statement;struct AST_Case_Statement;struct AST_Default_Statement;F diff --git a/src/semantics/constraints/expression_constraints.c b/src/semantics/constraints/expression_constraints.c --- a/src/semantics/constraints/expression_constraints.c +++ b/src/semantics/constraints/expression_constraints.creturn 1;}else{- push_translation_error("constraint check violation in multiplicative expression",translation_data);+ push_translation_error("Constraint check violation in multiplicative expression",translation_data);+ push_translation_note("left type is %WT\n",translation_data,left_type);+ push_translation_note("right type is %WT\n",translation_data,right_type);return 0;}}F diff --git a/src/semantics/value/evaluation.c b/src/semantics/value/evaluation.c --- a/src/semantics/value/evaluation.c +++ b/src/semantics/value/evaluation.c/*TODO add other types*/if(type_is_integer_type(c->type))return *(long long int*)c->value;+ else+ break;-+ }+ case OP_SIZEOF:+ {+ struct AST_Size_Of_Expression *size=expression;+ return (long long int)get_type_size(size->operand_type);}}/*shouldnt reach here*/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.creturn ret;}+ struct Type* get_type_int()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_SIGNED,TC_NONE,INT_SIZE);+ }+ struct Type* get_type_unsigned_int()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_UNSIGNED,TC_NONE,INT_SIZE);+ }+ struct Type* get_type_short()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_SIGNED,TC_SHORT,INT_SIZE);+ }+ struct Type* get_type_unsigned_short()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_UNSIGNED,TC_SHORT,INT_SIZE);+ }+ struct Type* get_type_long_int()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_SIGNED,TC_LONG,INT_SIZE);+ }+ struct Type* get_type_unsigned_long_int()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_UNSIGNED,TC_LONG,INT_SIZE);+ }+ struct Type* get_type_long_long_int()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_SIGNED,TC_LONG_LONG,INT_SIZE);+ }+ struct Type* get_type_unsigned_long_long_int()+ {+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_UNSIGNED,TC_LONG_LONG,INT_SIZE);+ }+ struct Type* get_type_char()+ {+ return (struct Type*)get_type_insecure(TS_CHAR,TSIGN_SIGNED,TC_NONE,CHAR_SIZE);+ }+ struct Type* get_type_unsigned_char()+ {+ return (struct Type*)get_type_insecure(TS_CHAR,TSIGN_UNSIGNED,TC_NONE,CHAR_SIZE);+ }+ struct Type* get_type_void()+ {+ return (struct Type*)get_type_insecure(TS_VOID,TSIGN_UNSIGNED,TC_NONE,VOID_SIZE);+ }_Bool types_are_identical(struct Type *a,struct Type *b){wonky_assert(a!=NULL && b!=NULL);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 rebase_type(struct Type *rebase,struct Type *onto);struct Type_Basic* get_type_insecure(enum Type_Specifier type_specifier,enum Type_Signedness sign,enum Type_Constraint constraint,size_t type_size);++ struct Type* get_type_int();+ struct Type* get_type_unsigned_int();+ struct Type* get_type_short();+ struct Type* get_type_unsigned_short();+ struct Type* get_type_long_int();+ struct Type* get_type_unsigned_long_int();+ struct Type* get_type_long_long_int();+ struct Type* get_type_unsigned_long_long_int();+ struct Type* get_type_char();+ struct Type* get_type_unsigned_char();+ struct Type* get_type_void();+struct Type* get_type_for_promotion(struct Type *type);struct Type* get_unqualified_version_of_type(struct Type *type);F diff --git a/src/semantics/value/type.hh b/src/semantics/value/type.hh --- a/src/semantics/value/type.hh +++ b/src/semantics/value/type.hh#define WCHAR_SIZE 4#define FLOAT_SIZE 4#define DOUBLE_SIZE 8+ #define VOID_SIZE 0#define AS_BASIC_TYPE_PTR(x) ((struct Type_Basic*)x)