#ifndef WONKY_LINKAGE_CONSTRAINTS_C
#define WONKY_LINKAGE_CONSTRAINTS_C WONKY_LINKAGE_CONSTRAINTS_C
#include <linkage_constraints.h>
_Bool constraint_check_object_linkage(struct Denoted_Object *denoted_object ,struct Denoted *previous_denoted_with_same_id, struct Scope *current,struct Translation_Data *translation_data)
{
struct Linkage *linkage;
struct Denoted_Object *hold_object;
wonky_assert(current->type!=FUNCTION_SCOPE);
if(previous_denoted_with_same_id==NULL) /*NOTE*/
return 1;
if(previous_denoted_with_same_id->denotation!=DT_Object)
{
push_translation_error("redeclaration of %D",translation_data,denoted_object);
push_translation_note("previously declared as %D",translation_data,previous_denoted_with_same_id);
return 0;
}
hold_object=(struct Denoted_Object*)previous_denoted_with_same_id;
if(hold_object->linkage==LINKAGE_NONE)
{
push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);
return 0;
}
if(denoted_object->linkage==LINKAGE_NONE)
{
push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);
return 0;
}else if(denoted_object->linkage==LINKAGE_EXTERNAL || denoted_object->linkage==LINKAGE_INTERNAL)
{
struct AST_Object_Declaration *hold_object;
linkage=(denoted_object->linkage==LINKAGE_EXTERNAL?translation_data->program->external_linkage:translation_data->internal_linkage);
hold_object=check_and_push_id(denoted_object,linkage->ids,denoted_object->id,translation_data);
if(hold_object!=NULL)
{
if(hold_object->type!=ST_OBJECT_DECLARATION)
{
push_translation_error("linking an object to a function %D",translation_data,denoted_object);
push_translation_note("linking against %D",translation_data,hold_object);
return 0;
}else if(!types_are_identical(hold_object->object->object->type,denoted_object->object->type))
{
push_translation_error("linking objects with mismatching types",translation_data);
push_translation_note("%t has type %T",translation_data,denoted_object->id,denoted_object->object->type);
push_translation_note("whilst %t has type %T",translation_data,hold_object->object->id,hold_object->object->object->type);
return 0;
}else
{
return 1;
}
}else
{
return 1;
}
}else
{
wonky_assert(SHOULD_NOT_REACH_HERE);
}
}
_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);
if(previous_denoted_with_same_id==NULL)
return 1;
if(denoted_function->linkage==LINKAGE_NONE)
{
push_translation_error("redeclaration of %D",translation_data,denoted_function);
push_translation_note("previously declared as %D",translation_data,previous_denoted_with_same_id);
return 0;
}else if(denoted_function->linkage==LINKAGE_EXTERNAL || denoted_function->linkage==LINKAGE_INTERNAL)
{
linkage=(denoted_function->linkage==LINKAGE_EXTERNAL?translation_data->program->external_linkage:translation_data->internal_linkage);
function_tree=check_and_push_id(denoted_function,linkage->ids,denoted_function->id,translation_data);
if(function_tree!=NULL)
{
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("%t is linking a function to an object",translation_data,denoted_function->id);
return 0;
}
if(!types_are_identical(hold_function->type,denoted_function->type))
{
push_translation_error("linking functions with mismatching types",translation_data);
return 0;
}else
{
return 1;
}
}else
{
return 1;
}
}else
{
wonky_assert(SHOULD_NOT_REACH_HERE);
}
wonky_assert(SHOULD_NOT_REACH_HERE);
}
#endif