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);
else
Map_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);
+ }
}
#endif
F 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);
+ }
}
#endif
F 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.h
void 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