From 591853a8ddd01258a5dbf9484a3fd2114e5e87e7 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Sun, 24 Mar 2024 00:06:47 -0700 Subject: attr: Add support for GNU syntax References: https://todo.sr.ht/~mcf/cproc/68 --- attr.c | 26 ++++++++++++++++++++++++++ cc.h | 1 + decl.c | 7 ++++++- 3 files changed, 33 insertions(+), 1 deletion(-) 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: -- cgit v1.2.3