diff options
-rw-r--r-- | attr.c | 26 | ||||
-rw-r--r-- | cc.h | 1 | ||||
-rw-r--r-- | decl.c | 7 |
3 files changed, 33 insertions, 1 deletions
@@ -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; +} @@ -481,6 +481,7 @@ struct attr { }; _Bool attr(struct attr *, enum attrkind); +_Bool gnuattr(struct attr *, enum attrkind); /* decl */ @@ -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: |