#include "parse.h"
#include "scan.h"
+/*
+ * Determine if a declarator declares an identifier (other than a function
+ * parameter).
+ */
+static bool is_abstract(struct cdecl_declarator *d)
+{
+ while (d->child)
+ d = d->child;
+
+ return d->type != CDECL_DECL_IDENT;
+}
+
/*
* Verify the declaration specifiers of a declaration. If top is true, treat
* this as a top-level declaration. Otherwise, treat this as a function
{
struct cdecl_declspec *specs = decl->specifiers;
struct cdecl_declarator *d = decl->declarators;
+ bool abstract = is_abstract(d);
unsigned num_storage = 0;
unsigned long typemap;
if (typemap == -1)
return -1;
+
for (struct cdecl_declspec *c = specs; c; c = c->next) {
switch (cdecl_spec_kind(c)) {
case CDECL_SPEC_TYPE:
}
continue;
case CDECL_SPEC_STOR:
+ if (top && abstract) {
+ fprintf(stderr, "type names cannot have storage-class specifiers\n");
+ return false;
+ }
+
if (!top && c->type != CDECL_STOR_REGISTER) {
fprintf(stderr, "function parameters may only have register storage\n");
return false;
}
break;
case CDECL_SPEC_FUNC:
+ if (abstract) {
+ fprintf(stderr, "type names cannot have function specifiers\n");
+ return false;
+ }
+
if (!top || d->type != CDECL_DECL_FUNCTION) {
fprintf(stderr, "only function declarations may have function specifiers.\n");
return false;