mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[qfcc] Add a function for checking type comparisons
It returns true if the comparison is valid without a diagnostic (usually a warning), false otherwise.
This commit is contained in:
parent
8d69ca9a99
commit
8e2fe83c27
2 changed files with 50 additions and 0 deletions
|
@ -258,6 +258,7 @@ bool type_compatible (const type_t *dst, const type_t *src) __attribute__((pure)
|
|||
bool type_assignable (const type_t *dst, const type_t *src);
|
||||
bool type_promotes (const type_t *dst, const type_t *src) __attribute__((pure));
|
||||
bool type_demotes (const type_t *dst, const type_t *src) __attribute__((pure));
|
||||
bool type_compares (const type_t *dst, const type_t *src) __attribute__((pure));
|
||||
bool type_same (const type_t *dst, const type_t *src) __attribute__((pure));
|
||||
int type_size (const type_t *type) __attribute__((pure));
|
||||
int type_count (const type_t *type) __attribute__((pure));
|
||||
|
|
|
@ -1787,6 +1787,55 @@ type_demotes (const type_t *dst, const type_t *src)
|
|||
return dst_mask & (1 << src->type);
|
||||
}
|
||||
|
||||
#define C(type) (1 << ev_##type)
|
||||
static unsigned compare_masks[ev_type_count] = {
|
||||
[ev_float] = C(float),
|
||||
[ev_int] = C(int) | C(long),
|
||||
[ev_uint] = C(uint) | C(ulong),
|
||||
[ev_double] = C(double),
|
||||
[ev_long] = C(long) | C(int),
|
||||
[ev_ulong] = C(ulong) | C(uint),
|
||||
};
|
||||
#undef C
|
||||
|
||||
bool
|
||||
type_compares (const type_t *dst, const type_t *src)
|
||||
{
|
||||
if (!dst || !src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dst = unalias_type (dst);
|
||||
src = unalias_type (src);
|
||||
if (dst == src) {
|
||||
return true;
|
||||
}
|
||||
if (type_rows (dst) != type_rows (src)
|
||||
|| type_cols (dst) != type_cols (src)) {
|
||||
return false;
|
||||
}
|
||||
if (!is_math (dst) || !is_math (src)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_boolean (dst) || is_boolean (src)) {
|
||||
// comparison between bool and lbool are ok, but not between either
|
||||
// bool and any other type
|
||||
return is_boolean (dst) && is_boolean (src);
|
||||
}
|
||||
if (is_enum (src)) {
|
||||
return is_integral (dst) && !is_enum (dst);
|
||||
}
|
||||
if (is_enum (dst)) {
|
||||
return is_integral (src) && !is_enum (src);
|
||||
}
|
||||
|
||||
dst = base_type (dst);
|
||||
src = base_type (src);
|
||||
int dst_mask = compare_masks[dst->type];
|
||||
return dst_mask & (1 << src->type);
|
||||
}
|
||||
|
||||
bool
|
||||
type_same (const type_t *dst, const type_t *src)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue