Beispiel #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");
}
Beispiel #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;
}
Beispiel #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);
}
Beispiel #4
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)
		return false;
	return types_compatible_ignore_qualifiers(type1, type2);
}
Beispiel #5
0
bool is_type_complete(type_t const *const type)
{
	assert(!is_typeref(type));

	switch (type->kind) {
	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION:
		return type->compound.compound->complete;

	case TYPE_ARRAY:
		return type->array.size_expression || type->array.size_constant;

	case TYPE_ATOMIC:
	case TYPE_ENUM:
	case TYPE_COMPLEX:
	case TYPE_IMAGINARY:
	case TYPE_FUNCTION:
	case TYPE_POINTER:
	case TYPE_REFERENCE:
	case TYPE_ERROR:
		return true;

	case TYPE_VOID:
		return false;

	case TYPE_TYPEDEF:
	case TYPE_TYPEOF:
	case TYPE_BUILTIN_TEMPLATE:
		break;
	}

	panic("invalid type");
}
Beispiel #6
0
bool is_type_integer(const type_t *type)
{
	assert(!is_typeref(type));
	if (!is_type_arithmetic(type))
		return false;
	return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_INTEGER);
}
Beispiel #7
0
bool is_type_incomplete(const type_t *type)
{
	assert(!is_typeref(type));

	switch(type->kind) {
	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION: {
		const compound_type_t *compound_type = &type->compound;
		return !compound_type->compound->complete;
	}
	case TYPE_ENUM:
		return false;

	case TYPE_ARRAY:
		return type->array.size_expression == NULL
			&& !type->array.size_constant;

	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
		return type->atomic.akind == ATOMIC_TYPE_VOID;

	case TYPE_FUNCTION:
	case TYPE_POINTER:
	case TYPE_REFERENCE:
	case TYPE_ERROR:
		return false;

	case TYPE_TYPEDEF:
	case TYPE_TYPEOF:
		panic("is_type_incomplete called without typerefs skipped");
	}

	panic("invalid type found");
}
Beispiel #8
0
bool is_type_signed(const type_t *type)
{
	assert(!is_typeref(type));
	if (!is_type_arithmetic(type))
		return false;
	return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_SIGNED);
}
Beispiel #9
0
/**
 * get alignment of a type when used inside a compound.
 * Some ABIs are broken and alignment inside a compound is different from
 * recommended alignment of a type
 */
static unsigned get_type_alignment_compound(type_t *const type)
{
	assert(!is_typeref(type));
	if (type->kind == TYPE_ATOMIC)
		return atomic_type_properties[type->atomic.akind].struct_alignment;
	return get_type_alignment(type);
}
Beispiel #10
0
bool is_type_float(const type_t *type)
{
	assert(!is_typeref(type));

	if (type->kind != TYPE_ATOMIC)
		return false;

	return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_FLOAT);
}
Beispiel #11
0
bool is_type_scalar(const type_t *type)
{
	assert(!is_typeref(type));

	if (type->kind == TYPE_POINTER)
		return true;

	return is_type_arithmetic(type);
}
Beispiel #12
0
bool is_type_complex(const type_t *type)
{
	assert(!is_typeref(type));

	if (type->kind != TYPE_ATOMIC)
		return false;

	return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_COMPLEX);
}
Beispiel #13
0
bool is_type_integer(const type_t *type)
{
	assert(!is_typeref(type));

	if (type->kind == TYPE_ENUM)
		return true;
	if (type->kind != TYPE_ATOMIC)
		return false;

	return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_INTEGER);
}
Beispiel #14
0
bool is_type_signed(const type_t *type)
{
	assert(!is_typeref(type));

	/* enum types are int for now */
	if (type->kind == TYPE_ENUM)
		return true;
	if (type->kind != TYPE_ATOMIC)
		return false;

	return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_SIGNED);
}
Beispiel #15
0
type_t *get_unqualified_type(type_t *type)
{
	assert(!is_typeref(type));

	if (type->base.qualifiers == TYPE_QUALIFIER_NONE)
		return type;

	type_t *unqualified_type          = duplicate_type(type);
	unqualified_type->base.qualifiers = TYPE_QUALIFIER_NONE;

	return identify_new_type(unqualified_type);
}
Beispiel #16
0
static type_t *add_modifiers(type_t *type, decl_modifiers_t modifiers)
{
	if (is_typeref(type) || !is_type_function(type)) {
		return type;
	}

	if ((type->function.modifiers & modifiers) == modifiers)
		return type;

	type_t* new_type = duplicate_type(type);
	new_type->function.modifiers |= modifiers;
	return identify_new_type(new_type);
}
Beispiel #17
0
static type_t *change_calling_convention(type_t *type, cc_kind_t cconv)
{
	if (is_typeref(type) || !is_type_function(type)) {
		return type;
	}

	if (type->function.calling_convention == cconv)
		return type;

	type_t* new_type = duplicate_type(type);
	new_type->function.calling_convention = cconv;
	return identify_new_type(new_type);
}
Beispiel #18
0
bool is_type_arithmetic(const type_t *type)
{
	assert(!is_typeref(type));

	switch(type->kind) {
	case TYPE_ENUM:
		return true;
	case TYPE_ATOMIC:
	case TYPE_COMPLEX:
	case TYPE_IMAGINARY:
		return test_atomic_type_flag(type->atomic.akind, ATOMIC_TYPE_FLAG_ARITHMETIC);
	default:
		return false;
	}
}
Beispiel #19
0
bool is_type_arithmetic(const type_t *type)
{
	assert(!is_typeref(type));

	switch (type->kind) {
	case TYPE_ATOMIC:
	case TYPE_COMPLEX:
	case TYPE_ENUM:
	case TYPE_IMAGINARY:
		return true;

	default:
		return false;
	}
}
Beispiel #20
0
bool is_type_enum(const type_t *type)
{
	assert(!is_typeref(type));
	return type->kind == TYPE_ENUM;
}
Beispiel #21
0
bool is_type_complex(const type_t *type)
{
	assert(!is_typeref(type));
	return type->kind == TYPE_COMPLEX;
}