WONKY



LOG | FILES | OVERVIEW


#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