aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--attr.c26
-rw-r--r--cc.h1
-rw-r--r--decl.c7
3 files changed, 33 insertions, 1 deletions
diff --git a/attr.c b/attr.c
index 75ec5ef..8b06d46 100644
--- a/attr.c
+++ b/attr.c
@@ -88,3 +88,29 @@ attr(struct attr *a, enum attrkind allowed)
;
return true;
}
+
+static bool
+gnuattrspec(struct attr *a, enum attrkind allowed)
+{
+ if (!consume(T__ATTRIBUTE__))
+ return false;
+ while (parseattr(a, allowed, PREFIXGNU) || consume(TCOMMA))
+ ;
+ expect(TLPAREN, "after '__attribute__' to begin attribute specifier");
+ expect(TLPAREN, "after '__attribute__' to begin attribute specifier");
+ while (parseattr(a, allowed, PREFIXGNU) || consume(TCOMMA))
+ ;
+ expect(TRPAREN, "to end attribute specifier");
+ expect(TRPAREN, "to end attribute specifier");
+ return true;
+}
+
+bool
+gnuattr(struct attr *a, enum attrkind allowed)
+{
+ if (!gnuattrspec(a, allowed))
+ return false;
+ while (gnuattrspec(a, allowed))
+ ;
+ return true;
+}
diff --git a/cc.h b/cc.h
index 2bf61c3..e07273f 100644
--- a/cc.h
+++ b/cc.h
@@ -481,6 +481,7 @@ struct attr {
};
_Bool attr(struct attr *, enum attrkind);
+_Bool gnuattr(struct attr *, enum attrkind);
/* decl */
diff --git a/decl.c b/decl.c
index 6e0ee37..98ac497 100644
--- a/decl.c
+++ b/decl.c
@@ -171,6 +171,7 @@ tagspec(struct scope *s)
}
next();
attr(NULL, 0);
+ gnuattr(NULL, 0);
tag = NULL;
t = NULL;
et = NULL;
@@ -452,6 +453,10 @@ declspecs(struct scope *s, enum storageclass *sc, enum funcspec *fs, int *align)
expect(TRPAREN, "to close 'alignas' specifier");
break;
+ case T__ATTRIBUTE__:
+ gnuattr(NULL, 0);
+ break;
+
default:
goto done;
}
@@ -660,7 +665,7 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs
if (!allowattr)
error(&tok.loc, "attribute not allowed after parenthesized declarator");
/* attribute applies to identifier if ptr->prev == result, otherwise type ptr->prev */
- attr(NULL, 0);
+ gnuattr(NULL, 0);
attr:
break;
default: