#include #include #include "cdecl.h" #include "typemap.h" #include "parse.h" #include "scan.h" static int verify_specs(struct cdecl_declspec *s) { unsigned num_storage = 0; unsigned long typemap; typemap = cdecl__build_typemap(s); if (typemap == -1) return -1; if (!cdecl__typemap_is_valid(typemap)) { fprintf(stderr, "conflicting type specifiers\n"); return -1; } for (struct cdecl_declspec *c = s; c; c = c->next) { switch (cdecl_spec_kind(c)) { case CDECL_SPEC_TYPE: continue; case CDECL_SPEC_STOR: if (++num_storage > 1) { fprintf(stderr, "too many storage-class specifiers\n"); return -1; } break; case CDECL_SPEC_QUAL: /* * Since we don't support pointer types yet, all * restrict qualifiers are invalid. Other qualifiers * are always valid. */ if (c->type == CDECL_QUAL_RESTRICT) { fprintf(stderr, "only pointer types can be restrict-qualified.\n"); return -1; } break; case CDECL_SPEC_FUNC: /* * Likewise for function specifiers. */ fprintf(stderr, "only function declarations may have function specifiers.\n"); return -1; default: abort(); } } return 0; } static int verify_decl(struct cdecl *decl) { return verify_specs(decl->specifiers); } struct cdecl *cdecl_parse_decl(const char *declstr) { YY_BUFFER_STATE state; struct cdecl *decl; int rc; state = yy_scan_string(declstr); rc = yyparse(&decl); yy_delete_buffer(state); if (rc != 0) return NULL; rc = verify_decl(decl); if (rc != 0) { cdecl_free(decl); return NULL; } return decl; }