X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/f2f75f25ecc377fb95877449aa12314ee1385a1f..bbfdea24b2b940031e86e990bc457785dd378b58:/src/normalize.c diff --git a/src/normalize.c b/src/normalize.c index e6502d2..eac71f3 100644 --- a/src/normalize.c +++ b/src/normalize.c @@ -24,19 +24,42 @@ #include "cdecl-internal.h" /* - * Totally order the declaration specifier types by defining an injection into - * the natural numbers. + * Partially order the declaration specifiers by assigning each specifier + * type an appropriate integer value. These values need not be unique for + * specifiers that never appear together. + * + * This implementation relies implicitly on the specific enumeration values. + * These values are expected to be stable as they are exposed library API. */ -static unsigned order_spec(struct cdecl_declspec *spec) +static int order_spec(const struct cdecl_declspec *spec) { - switch (spec->type) { -# include "ordspecs.h" - default: - assert(0); + unsigned kind = cdecl_spec_kind(spec); + unsigned ret = spec->type; + + /* General sequence: storage, function, qualifier, type */ + switch (kind) { + case CDECL_SPEC_QUAL: + ret |= CDECL_SPEC_FUNC; + break; + case CDECL_SPEC_TYPE: + /* Manually reorder some elements that are in the wrong place */ + switch (ret) { + case CDECL_TYPE_INT: + ret += 2; /* OK because "float int" is invalid. */ + break; + case CDECL_TYPE_SIGNED: + case CDECL_TYPE_UNSIGNED: + ret = CDECL_TYPE_VOID; + break; + } + ret |= CDECL_SPEC_FUNC|CDECL_SPEC_QUAL; } + + return ret; } -static int compare_specs(struct cdecl_declspec *a, struct cdecl_declspec *b) +static int compare_specs(const struct cdecl_declspec *a, + const struct cdecl_declspec *b) { return order_spec(a) - order_spec(b); }