Exemplo n.º 1
0
bool types_compatible_ignore_qualifiers(const type_t *type1,
                                        const type_t *type2)
{
	assert(!is_typeref(type1));
	assert(!is_typeref(type2));

	/* shortcut: the same type is always compatible */
	if (type1 == type2)
		return true;

	if (type1->kind != type2->kind) {
		/* enum types are compatible to their base integer type */
		if ((type1->kind == TYPE_ENUM
		     && is_type_atomic(type2, type1->enumt.base.akind))
		    || (type2->kind == TYPE_ENUM
		     && is_type_atomic(type1, type2->enumt.base.akind)))
		    return true;
		/* error types are compatible to everything to avoid follow-up errors */
		if (!is_type_valid(type1) || !is_type_valid(type2))
			return true;
		return false;
	}

	switch (type1->kind) {
	case TYPE_FUNCTION:
		return function_types_compatible(&type1->function, &type2->function);
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
		return type1->atomic.akind == type2->atomic.akind;
	case TYPE_ARRAY:
		return array_types_compatible(&type1->array, &type2->array);
	case TYPE_POINTER: {
		const type_t *const to1 = skip_typeref(type1->pointer.points_to);
		const type_t *const to2 = skip_typeref(type2->pointer.points_to);
		return types_compatible(to1, to2);
	}
	case TYPE_REFERENCE: {
		const type_t *const to1 = skip_typeref(type1->reference.refers_to);
		const type_t *const to2 = skip_typeref(type2->reference.refers_to);
		return types_compatible(to1, to2);
	}
	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION:
		return type1->compound.compound == type2->compound.compound;
	case TYPE_ENUM:
		return type1->enumt.enume == type2->enumt.enume;
	case TYPE_ERROR:
	case TYPE_VOID:
		return true;
	case TYPE_TYPEDEF:
	case TYPE_TYPEOF:
		break; /* we already tested for is_typeref() above */
	case TYPE_BUILTIN_TEMPLATE:
		panic("unexpected type");
	}
	panic("invalid type kind");
}
Exemplo n.º 2
0
bool types_compatible(const type_t *type1, const type_t *type2)
{
	assert(!is_typeref(type1));
	assert(!is_typeref(type2));

	/* shortcut: the same type is always compatible */
	if (type1 == type2)
		return true;

	if (!is_type_valid(type1) || !is_type_valid(type2))
		return true;

	if (type1->base.qualifiers != type2->base.qualifiers)
		return false;
	if (type1->kind != type2->kind)
		return false;

	switch (type1->kind) {
	case TYPE_FUNCTION:
		return function_types_compatible(&type1->function, &type2->function);
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
		return type1->atomic.akind == type2->atomic.akind;
	case TYPE_ARRAY:
		return array_types_compatible(&type1->array, &type2->array);

	case TYPE_POINTER: {
		const type_t *const to1 = skip_typeref(type1->pointer.points_to);
		const type_t *const to2 = skip_typeref(type2->pointer.points_to);
		return types_compatible(to1, to2);
	}

	case TYPE_REFERENCE: {
		const type_t *const to1 = skip_typeref(type1->reference.refers_to);
		const type_t *const to2 = skip_typeref(type2->reference.refers_to);
		return types_compatible(to1, to2);
	}

	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION: {
		break;
	}
	case TYPE_ENUM:
		/* TODO: not implemented */
		break;

	case TYPE_ERROR:
		/* Hmm, the error type should be compatible to all other types */
		return true;
	case TYPE_TYPEDEF:
	case TYPE_TYPEOF:
		panic("typerefs not skipped in compatible types?!?");
	}

	return false;
}
Exemplo n.º 3
0
bool types_compatible(const type_t *type1, const type_t *type2)
{
	assert(!is_typeref(type1));
	assert(!is_typeref(type2));

	/* shortcut: the same type is always compatible */
	if (type1 == type2)
		return true;

	if (type1->base.qualifiers == type2->base.qualifiers &&
	    type1->kind            == type2->kind) {
		switch (type1->kind) {
		case TYPE_FUNCTION:
			return function_types_compatible(&type1->function, &type2->function);
		case TYPE_ATOMIC:
		case TYPE_IMAGINARY:
		case TYPE_COMPLEX:
			return type1->atomic.akind == type2->atomic.akind;
		case TYPE_ARRAY:
			return array_types_compatible(&type1->array, &type2->array);

		case TYPE_POINTER: {
			const type_t *const to1 = skip_typeref(type1->pointer.points_to);
			const type_t *const to2 = skip_typeref(type2->pointer.points_to);
			return types_compatible(to1, to2);
		}

		case TYPE_REFERENCE: {
			const type_t *const to1 = skip_typeref(type1->reference.refers_to);
			const type_t *const to2 = skip_typeref(type2->reference.refers_to);
			return types_compatible(to1, to2);
		}

		case TYPE_COMPOUND_STRUCT:
		case TYPE_COMPOUND_UNION:
			break;

		case TYPE_ENUM:
			/* TODO: not implemented */
			break;

		case TYPE_ERROR:
		case TYPE_VOID:
			return true;

		case TYPE_TYPEDEF:
		case TYPE_TYPEOF:
			panic("typeref not skipped");
		case TYPE_BUILTIN_TEMPLATE:
			panic("unexpected type");
		}
	}

	return !is_type_valid(type1) || !is_type_valid(type2);
}