예제 #1
0
int check_entity(const ir_entity *entity)
{
	bool fine = true;

	ir_linkage linkage = get_entity_linkage(entity);
	if (linkage & IR_LINKAGE_NO_CODEGEN) {
		if (!is_method_entity(entity)) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not a function", entity);
			fine = false;
		} else if (get_entity_irg(entity) == NULL) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but has no ir-graph anyway", entity);
			fine = false;
		}
		if (!is_externally_visible(entity)) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not externally visible", entity);
			fine = false;
		}
	}
	check_external_linkage(entity, IR_LINKAGE_WEAK, "WEAK");
	check_external_linkage(entity, IR_LINKAGE_GARBAGE_COLLECT,
	                       "GARBAGE_COLLECT");
	check_external_linkage(entity, IR_LINKAGE_MERGE, "MERGE");

	ir_type const *const type  = get_entity_type(entity);
	ir_type const *const owner = get_entity_owner(entity);
	switch (get_entity_kind(entity)) {
	case IR_ENTITY_ALIAS:
		if (!is_segment_type(owner)) {
			report_error("alias entity %+F has non-segment owner %+F", entity,
			             owner);
			fine = false;
		}
		break;

	case IR_ENTITY_NORMAL: {
		ir_initializer_t const *const init = get_entity_initializer(entity);
		if (init)
			fine &= check_initializer(init, type, entity);

		if (!is_data_type(type)) {
			report_error("normal entity %+F has non-data type %+F", entity,
			             type);
			fine = false;
		}
		break;
	}

	case IR_ENTITY_COMPOUND_MEMBER:
		if (!is_compound_type(owner)) {
			report_error("compound member entity %+F has non-compound owner %+F",
			             entity, owner);
			fine = false;
		}
		break;

	case IR_ENTITY_LABEL:
		if (type != get_code_type()) {
			report_error("label entity %+F has non-code type %+F", entity,
			             type);
			fine = false;
		}
		break;

	case IR_ENTITY_METHOD:
		if (!is_Method_type(type)) {
			report_error("method entity %+F has non-method type %+F", entity,
			             type);
			fine = false;
		}
		ir_graph *irg = get_entity_irg(entity);
		if (irg != NULL) {
			ir_entity *irg_entity = get_irg_entity(irg);
			if (irg_entity != entity) {
				report_error("entity(%+F)->irg->entity(%+F) relation invalid",
				             entity, irg_entity);
				fine = false;
			}
		}
		break;
	case IR_ENTITY_PARAMETER:
		if (!is_frame_type(owner)) {
			report_error("parameter entity %+F has non-frame owner %+F",
			             entity, owner);
			fine = false;
		}
		if (!is_data_type(type)) {
			report_error("parameter entity %+F has non-data type %+F", entity,
			             type);
			fine = false;
		}
		break;

	case IR_ENTITY_UNKNOWN:
		break;

	case IR_ENTITY_SPILLSLOT:
		if (is_frame_type(owner)) {
			report_error("spillslot %+F must be on frame type", entity);
			fine = false;
		}
		break;
	}
	if (is_frame_type(owner) && entity_has_definition(entity)) {
		report_error("entity %+F on frame %+F has initialized", entity, owner);
		fine = false;
	}

	return fine;
}
예제 #2
0
파일: trverify.c 프로젝트: qznc/libfirm
int check_entity(const ir_entity *entity)
{
	bool        fine    = true;
	ir_type    *tp      = get_entity_type(entity);
	ir_linkage  linkage = get_entity_linkage(entity);

	fine &= constants_on_wrong_irg(entity);

	if (is_method_entity(entity)) {
		ir_graph *irg = get_entity_irg(entity);
		if (irg != NULL) {
			ir_entity *irg_entity = get_irg_entity(irg);
			if (irg_entity != entity) {
				report_error("entity(%+F)->irg->entity(%+F) relation invalid",
				             entity, irg_entity);
				fine = false;
			}
		}
		if (get_entity_peculiarity(entity) == peculiarity_existent) {
			ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(entity));
			if (impl == NULL) {
				report_error("inherited method entity %+F must have constant pointing to existent entity.", entity);
				fine = false;
			}
		}
	}

	if (linkage & IR_LINKAGE_NO_CODEGEN) {
		if (!is_method_entity(entity)) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not a function", entity);
			fine = false;
		} else if (get_entity_irg(entity) == NULL) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but has no ir-graph anyway", entity);
			fine = false;
		}
		if (get_entity_visibility(entity) != ir_visibility_external) {
			report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not externally visible", entity);
			fine = false;
		}
	}
	check_external_linkage(entity, IR_LINKAGE_WEAK, "WEAK");
	check_external_linkage(entity, IR_LINKAGE_GARBAGE_COLLECT,
	                       "GARBAGE_COLLECT");
	check_external_linkage(entity, IR_LINKAGE_MERGE, "MERGE");

	if (is_atomic_entity(entity) && entity->initializer != NULL) {
		ir_mode *mode = NULL;
		ir_initializer_t *initializer = entity->initializer;
		switch (initializer->kind) {
		case IR_INITIALIZER_CONST:
			mode = get_irn_mode(get_initializer_const_value(initializer));
			break;
		case IR_INITIALIZER_TARVAL:
			mode = get_tarval_mode(get_initializer_tarval_value(initializer));
			break;
		case IR_INITIALIZER_NULL:
		case IR_INITIALIZER_COMPOUND:
			break;
		}
		if (mode != NULL && mode != get_type_mode(tp)) {
			report_error("initializer of entity %+F has wrong mode.", entity);
			fine = false;
		}
	}
	return fine;
}