F diff --git a/src/backend/print/print.c b/src/backend/print/print.c --- a/src/backend/print/print.c +++ b/src/backend/print/print.cvoid print_goto_statement_tree(FILE *out,struct AST_Goto_Statement *got){fprintf(out,"goto ");- print_token(out,got->label);+ print_denoted(out,(struct Denoted*)got->label);}void print_type(FILE *out,struct Type *type,char should_print_struct_union)fprintf(out,"macro ");return;case DT_Macro_Parameter:fprintf(out,"macro parameter ");return;- case DT_Label:+ case DT_Statement:fprintf(out,"label ");return;case DT_Object:switch(((struct Denoted_Object*)denoted)->linkage)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{case KW_PLUSPLUS:chomp(translation_data);- hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POINTER_ADDITION,translation_data);+ hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POSTFIX_INC,translation_data);break;case KW_MINUSMINUS:chomp(translation_data);- hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POINTER_ADDITION,translation_data);+ hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POSTFIX_DEC,translation_data);break;case KW_DOT:chomp(translation_data);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}/*- expression :+ constant :statement*/struct AST* parse_finish_case_statement(struct Translation_Data *translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch){+ struct AST_Expression *hold_expression;+ struct AST *hold_statement;+}/*F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.cstruct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope){struct AST_Goto_Statement *ret;+ struct Denoted_Statement *hold_statement;+ret=malloc(sizeof(struct AST_Goto_Statement));ret->type=ST_GOTO;- ret->label=label;++ hold_statement=check_label(scope,label);+ if(hold_statement==NULL)+ {+ hold_statement=(struct Denoted_Statement*)get_denoted_statement(label,NULL,NULL);+ }++ ret->label=hold_statement;++ Queue_Push(hold_statement->gotos_jumping_to_this_statement,ret);++ ret->previous_denoted_object=(struct Denoted_Object*)get_last_known_denoted_object((struct Normal_Scope*)scope);return ret;}F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.hstruct token *label;struct AST *statement;};+ struct AST_Case_Statement+ {+ enum AST_Type type;+ struct AST_Expression *expression;+ struct AST *statement;+ };struct AST_Compound_Statement{enum AST_Type type;struct AST_Goto_Statement{enum AST_Type type;- struct token *label;+ struct Denoted_Statement *label;+ struct Denoted_Object *previous_denoted_object;};struct AST_Switch_Statement{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}}+ struct Denoted* get_denoted_statement(struct token *id,struct AST *statement,struct Denoted_Object *previous_denoted_object)+ {+ struct Denoted_Statement *ret;+ ret=malloc(sizeof(struct Denoted_Statement));+ ret->denotation=DT_Statement;+ ret->label=id;+ ret->statement=statement;++ ret->previous_denoted_object=previous_denoted_object;+ ret->gotos_jumping_to_this_statement=malloc(sizeof(struct Queue));++ Queue_Init(ret->gotos_jumping_to_this_statement);++ return (struct Denoted*)ret;+ }void delete_denoted(struct Denoted *denoted){switch(denoted->denotation){- case DT_Label:- free(denoted);+ case DT_Statement:+ delete_denoted_statement((struct Denoted_Statement*)denoted);break;case DT_Object:delete_denoted_object((struct Denoted_Object*)denoted);{free(base);}+ void delete_denoted_statement(struct Denoted_Statement *statement)+ {+ if(statement->label) free(statement->label);+ if(statement->statement) delete_ast(statement->statement);+ if(statement->gotos_jumping_to_this_statement)+ {+ while(statement->gotos_jumping_to_this_statement->size>0)+ Queue_Pop(statement->gotos_jumping_to_this_statement);+ }+ free(statement);+ }void delete_denoted_wrapper(void *denoted){delete_denoted(denoted);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.henum Denotation_Type denotation;struct Struct_Union *struct_union;};+ struct Denoted_Statement+ {+ enum Denotation_Type denotation;++ struct token *label;+ struct AST *statement;+ struct Queue *gotos_jumping_to_this_statement;++ struct Denoted_Object *previous_denoted_object;+ };struct Denotation_Prototype{enum Denotation_Type denotation;struct Denoted* get_denoted_struct_union(struct Struct_Union *struct_union);struct Denoted* extract_denoted(struct Denoted_Base *base,struct Denotation_Prototype *prototype,_Bool allow_abstract);+ struct Denoted* get_denoted_statement(struct token *id,struct AST *statement,struct Denoted_Object *previous_denoted_object);struct Denoted* get_denotation_prototype(struct Map *types);void delete_denoted_struct_union(struct Denoted_Struct_Union *su);void delete_denoted_prototype(struct Denotation_Prototype *prototype);void delete_denoted_base(struct Denoted_Base *base);+ void delete_denoted_statement(struct Denoted_Statement *statement);enum Storage_Class_Specifier get_denoted_function_storage_class(struct Denoted_Function *function);F diff --git a/src/semantics/identifiers/denoted.hh b/src/semantics/identifiers/denoted.hh --- a/src/semantics/identifiers/denoted.hh +++ b/src/semantics/identifiers/denoted.hh#define AS_DENOTED_ENUM(x) ((struct Denoted_Enum*)x)#define AS_DENOTED_ENUM_CONST(x) ((struct Denoted_Enum_Const*)x)#define AS_DENOTED_STRUCT_UNION(x) ((struct Denoted_Struct_Union*)x)+ #define AS_DENOTED_STATEMENT(x) ((struct Denoted_Statement*)x)enum Denotation_Type{DT_Macro,DT_Macro_Parameter,- DT_Label,+ DT_Statement,DT_Object,DT_Typedef,DT_Function,struct Denoted_Enum;struct Denoted_Enum_Const;struct Denoted_Struct_Union;+ struct Denoted_Statement;struct Denotation_Prototype;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.cMap_Init(&ret->tags);Map_Init(&ret->ordinary);+ ret->object_order=malloc(sizeof(struct Queue));+ Queue_Init(ret->object_order);+return (struct Scope*)ret;}Map_Init(&ret->labels);+ ret->label_order=malloc(sizeof(struct Queue));+ Queue_Init(ret->label_order);return (struct Scope*)ret;}}- void* check_label(struct Scope *current,struct token *id)+ struct Denoted_Statement* check_label(struct Scope *current,struct token *id){- void *hold;- hold=NULL;- while(current!=NULL && current->type!=FUNCTION_SCOPE)- {- current=current->parent;- }+ struct Denoted_Statement *hold=NULL;+ struct Function_Scope *function_scope;++ function_scope=get_enclosing_function_scope(current);++ if(function_scope!=NULL)+ hold=Map_Check(&function_scope->labels,id->data,id->data_size);- if(current!=NULL)- {- hold=Map_Check(&((struct Function_Scope*)current)->labels,id->data,id->data_size);- }return hold;}switch(declarator->denotation){- case DT_Label:+ case DT_Statement:/*perhaps lables should be denoted*/assert(0);case DT_Function:}- struct Denoted_Function* get_enclosing_function(struct Scope *scope)+ struct Function_Scope* get_enclosing_function_scope(struct Scope *scope){struct Scope *current;current=scope;assert(current->type!=FILE_SCOPE);current=current->parent;}+ return (struct Function_Scope*)current;+ }+ struct Denoted_Object* get_last_known_denoted_object(struct Normal_Scope *scope)+ {+ if(scope->object_order->last==NULL)+ return NULL;+ else+ return (struct Denoted_Object*)scope->object_order->last->data;+ }+ struct Denoted_Function* get_enclosing_function(struct Scope *scope)+ {+ struct Function_Scope *function_scope;++ function_scope=get_enclosing_function_scope(scope);- if(current==NULL)+ if(function_scope==NULL)return NULL;/*TODO maybe return a denoted_error*/- return ((struct Function_Scope*)current)->function;+ return function_scope->function;}_Bool check_if_typedefed(struct Scope* scope,struct token *id){return 1;}- #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)+ void push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data)+ {+ struct Denoted_Statement *hold_statement;+ struct Function_Scope *current_function_scope;+ current_function_scope=get_enclosing_function_scope(current);++ hold_statement=(struct Denoted_Statement*)Map_Check(¤t_function_scope->labels,label->data,label->data_size);++ if(hold_statement!=NULL)+ {+ assert(hold_statement->denotation==DT_Statement);++ if(hold_statement->statement!=NULL)+ {+ push_translation_error("Redeclaration of label id %t",translation_data,label);+ return;+ }else+ {+ assert(hold_statement->label!=NULL);+ assert(hold_statement->gotos_jumping_to_this_statement->size>0);+ assert(hold_statement->previous_denoted_object==NULL);++ hold_statement->label=label;+ hold_statement->statement=statement;++ /*note the use of the current scope instead of the function scope*/+ hold_statement->previous_denoted_object=get_last_known_denoted_object((struct Normal_Scope*)current);++ assert(hold_statement->previous_denoted_object->denotation==DT_Object);+ }+ }else+ {++ hold_statement=(struct Denoted_Statement*)get_denoted_statement(label,statement,get_last_known_denoted_object((struct Normal_Scope*)current));+ Map_Push(¤t_function_scope->labels,label->data,label->data_size,hold_statement);+ }+ }+++ #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object){#define PO_ERROR(msg) push_translation_error(msg,translation_data,denoted_object->id);delete_denoted_object(denoted_object);return;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#include <map.h>#include <denoted.h>#include <location.h>+ #include <queue.h>enum Scope_Type;Map tags;Map ordinary;++ /*we need the object order for the unconditional jumps*/+ struct Queue *object_order; /*queue of denoted objects*/};struct Function_Scope{struct Denoted_Function *function;Map labels;++ /*here to ease checking of undeclared but used labels*/+ struct Queue *label_order; /*queue of denoted statements*/};struct Scope* get_normal_scope(struct Scope *parent,enum Scope_Type type);struct Scope* get_function_scope(struct Scope *parent,struct Denoted_Function *function);- void* check_label(struct Scope *current,struct token *id);+ struct Denoted_Statement* check_label(struct Scope *current,struct token *id);struct Denoted* check_tag(struct Scope *current,struct token *id);void* check_ordinary(struct Scope *current,struct token *id);- void push_label(struct Scope *current,struct token *id);/*TODO*/+ void push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data);void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object);void push_function(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function);void push_typedef(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Type *denoted_typedef);struct Denoted_Function* get_enclosing_function(struct Scope *scope);+ struct Function_Scope* get_enclosing_function_scope(struct Scope *scope);+ struct Denoted_Object* get_last_known_denoted_object(struct Normal_Scope *scope);void delete_scope(struct Scope *scope);void delete_normal_scope(struct Normal_Scope *scope);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_POINTER || type->specifier==TS_ARRAY || type->specifier==TS_FUNC);}+ _Bool type_is_a_variable_length_array(struct Type *type)+ {+ return 0;+ }_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_real(struct Type *type);_Bool type_is_floating(struct Type *type);_Bool type_is_derivative(struct Type *type);+ _Bool type_is_a_variable_length_array(struct Type *type);/*these return 0 if constant/volatile-ness make no sense for the type*/_Bool type_is_constant(struct Type *type);