X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/90d2c82cd8b19562c71965d1bfa8e4b612ea4026..0c61f9637a469ac7a28b5a329551b03e6ad14d62:/src/typemap.c diff --git a/src/typemap.c b/src/typemap.c index 61456dd..918a037 100644 --- a/src/typemap.c +++ b/src/typemap.c @@ -1,7 +1,28 @@ +/* + * Helpers for dealing with type specifiers. + * Copyright © 2011, 2021 Nick Bowler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include #include #include +#include + #include "cdecl.h" -#include "typemap.h" +#include "cdecl-internal.h" /* * We can represent type specifiers as a bitmap, which gives us a finite @@ -10,30 +31,32 @@ * 2 times. Treat it as a special case, assigning an unused bit to represent * the second long. */ -#define CDECL_TYPE_LLONG 31 +#define CDECL_TYPE_LLONG (CDECL_SPEC_TYPE + 31) + +static inline unsigned long spec_bit(unsigned type) +{ + return 1ul << (type & (CDECL_SPEC_TYPE - 1)); +} static unsigned long add_typespec(unsigned long map, struct cdecl_declspec *s) { - if (s->type >= CDECL_TYPE_LLONG) { - fprintf(stderr, "invalid type specifier\n"); - return -1; - } + assert(s->type >= CDECL_SPEC_TYPE && s->type < CDECL_TYPE_LLONG); if (s->type == CDECL_TYPE_LONG) { - if (map & (1ul<type)) { + if (map & spec_bit(s->type)) { fprintf(stderr, "duplicate type specifier\n"); return -1; } - return map | (1ul<type); + return map | spec_bit(s->type); } unsigned long cdecl__build_typemap(struct cdecl_declspec *s)