F diff --git a/src/backend/text/print/print.c b/src/backend/text/print/print.c --- a/src/backend/text/print/print.c +++ b/src/backend/text/print/print.c{size_t i;struct Queue_Node *it;++ push_line(gstr_to_heap("EXTERNALLY DEFINED {"),compile_data->indent,compile_data->lines);++ ++compile_data->indent;+ push_line(gstr_to_heap("FUNCTIONS {"),compile_data->indent,compile_data->lines);+ ++compile_data->indent;+ for(it=program->functions_without_a_definition->first;it!=NULL;it=it->prev)+ {+ push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);+ print_ast(compile_data,it->data);+ }+ --compile_data->indent;+ push_line(gstr_to_heap("}"),compile_data->indent,compile_data->lines);+ --compile_data->indent;++ ++compile_data->indent;+ push_line(gstr_to_heap("OBJECTS {"),compile_data->indent,compile_data->lines);+ ++compile_data->indent;+ for(it=program->external_objects_without_an_initialiser->first;it!=NULL;it=it->prev)+ {+ push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);+ print_ast(compile_data,it->data);+ }+ --compile_data->indent;+ push_line(gstr_to_heap("}"),compile_data->indent,compile_data->lines);+ --compile_data->indent;++ push_line(gstr_to_heap("}"),compile_data->indent,compile_data->lines);+for(it=program->translation_units->first;it!=NULL;it=it->prev){push_line(gstr_to_heap("TRANSLATION_UNIT {"),compile_data->indent,compile_data->lines);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{Scope_Push(scope,hold,translation_data);+ resolve_function_linkage(scope,translation_data,(struct Denoted_Function*)hold);+ push_function_declaration_into_linkage(translation_data,get_function_declaration_tree(scope,(struct Denoted_Function*)hold));}}else if(hold->denotation==DT_Object){F diff --git a/src/semantics/constraints/linkage_constraints.c b/src/semantics/constraints/linkage_constraints.c --- a/src/semantics/constraints/linkage_constraints.c +++ b/src/semantics/constraints/linkage_constraints.c_Bool constraint_check_function_linkage(struct Denoted_Function *denoted_function,struct Denoted *previous_denoted_with_same_id,struct Scope *current,struct Translation_Data *translation_data){struct Linkage *linkage;+ struct AST *function_tree;struct Denoted_Function *hold_function;wonky_assert(current->type!=FUNCTION_SCOPE);}else if(denoted_function->linkage==LINKAGE_EXTERNAL || denoted_function->linkage==LINKAGE_INTERNAL){linkage=(denoted_function->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);- hold_function=check_and_push_id(denoted_function,linkage->ids,denoted_function->id);+ function_tree=check_and_push_id(denoted_function,linkage->ids,denoted_function->id);- if(hold_function!=NULL)+ if(function_tree!=NULL){- if(hold_function->denotation!=DT_Function)++ if(function_tree->type==ST_FUNCTION_DECLARATION)+ {+ hold_function=((struct AST_Function_Declaration*)function_tree)->function;+ }else if(function_tree->type==ST_FUNCTION_DEFINITION)+ {+ hold_function=((struct AST_Function_Definition*)function_tree)->function;+ }else{- push_translation_error("linking an function to a object",translation_data);+ push_translation_error("%t is linking a function to an object",translation_data,denoted_function->id);return 0;- }else if(!types_are_identical(hold_function->type,denoted_function->type))+ }++ if(!types_are_identical(hold_function->type,denoted_function->type)){push_translation_error("linking functions with mismatching types",translation_data);return 0;F diff --git a/src/semantics/identifiers/linkage.c b/src/semantics/identifiers/linkage.c --- a/src/semantics/identifiers/linkage.c +++ b/src/semantics/identifiers/linkage.c}void push_object_into_linkage(struct Translation_Data *translation_data,struct AST_Object_Declaration *object){+ struct AST_Object_Declaration *possible_declaration;+wonky_assert(is_valid_ast((struct AST*)object));+ possible_declaration=Map_Check(translation_data->external_linkage->ids,object->object->id->data,object->object->id->data_size);++ if(possible_declaration==NULL)+ {+ if(object->object->linkage==LINKAGE_EXTERNAL)+ Map_Push(translation_data->external_linkage->ids,object->object->id->data,object->object->id->data_size,object);+ else if(object->object->linkage==LINKAGE_INTERNAL)+ Map_Push(translation_data->internal_linkage->ids,object->object->id->data,object->object->id->data_size,object);+ }else+ {+ if(object->initializer!=NULL && possible_declaration->initializer!=NULL)+ push_translation_error("reinitialisation of %t",translation_data,object->object->id);+ }- if(object->object->linkage==LINKAGE_EXTERNAL)- Map_Push(translation_data->external_linkage->ids,object->object->id->data,object->object->id->data_size,object);- else if(object->object->linkage==LINKAGE_INTERNAL)- Map_Push(translation_data->internal_linkage->ids,object->object->id->data,object->object->id->data_size,object);}void push_function_into_linkage(struct Translation_Data *translation_data,struct AST *function)}void push_function_definition_into_linkage(struct Translation_Data *translation_data,struct AST_Function_Definition *function){+ struct AST *possible_declaration;++ possible_declaration=Map_Check(translation_data->external_linkage->ids,function->function->id->data,function->function->id->data_size);+if(function->function->linkage==LINKAGE_EXTERNAL)Map_Push(translation_data->external_linkage->ids,function->function->id->data,function->function->id->data_size,function);elseMap_Push(translation_data->internal_linkage->ids,function->function->id->data,function->function->id->data_size,function);++ if(possible_declaration!=NULL)+ {+ if(possible_declaration->type==ST_FUNCTION_DEFINITION)+ push_translation_error("redefinition of function %t",translation_data,function->function->id);+ }}void push_function_declaration_into_linkage(struct Translation_Data *translation_data,struct AST_Function_Declaration *function){- if(function->function->linkage==LINKAGE_EXTERNAL)- Map_Push(translation_data->external_linkage->ids,function->function->id->data,function->function->id->data_size,function);- else- Map_Push(translation_data->internal_linkage->ids,function->function->id->data,function->function->id->data_size,function);+ struct AST *possible_definition;+ possible_definition=Map_Check(translation_data->external_linkage->ids,function->function->id->data,function->function->id->data_size);++ if(possible_definition==NULL)+ {+ if(function->function->linkage==LINKAGE_EXTERNAL)+ Map_Push(translation_data->external_linkage->ids,function->function->id->data,function->function->id->data_size,function);+ else+ Map_Push(translation_data->internal_linkage->ids,function->function->id->data,function->function->id->data_size,function);+ }}#endifF diff --git a/src/semantics/program/program.c b/src/semantics/program/program.c --- a/src/semantics/program/program.c +++ b/src/semantics/program/program.c/*TODO*/void find_functions_without_definitions(struct Program *program){-+ Map_Map_Extended(program->external_linkage->ids,(void (*)(void*,void*))push_if_tree_is_undefined_function,program->functions_without_a_definition);}/*TODO*/void find_external_objects_without_an_initialiser(struct Program *program){-+ Map_Map_Extended(program->external_linkage->ids,(void (*)(void*,void*))push_if_tree_is_uninitialised_object,program->external_objects_without_an_initialiser);+ }+ void push_if_tree_is_undefined_function(struct AST *tree,struct Queue *where_to_push)+ {+ if(tree->type==ST_FUNCTION_DECLARATION)+ Queue_Push(where_to_push,tree);+ }+ void push_if_tree_is_uninitialised_object(struct AST *tree,struct Queue *where_to_push)+ {+ if(tree->type==ST_OBJECT_DECLARATION)+ {+ struct AST_Object_Declaration *declaration;+ declaration=(struct AST_Object_Declaration*)tree;+ if(declaration->initializer==NULL)+ Queue_Push(where_to_push,tree);+ }}#endifF diff --git a/src/semantics/program/program.h b/src/semantics/program/program.h --- a/src/semantics/program/program.h +++ b/src/semantics/program/program.hvoid find_functions_without_definitions(struct Program *program);void find_external_objects_without_an_initialiser(struct Program *program);+ void push_if_tree_is_undefined_function(struct AST *tree,struct Queue *where_to_push);+ void push_if_tree_is_uninitialised_object(struct AST *tree,struct Queue *where_to_push);+#endif