diff --git a/parse.c b/parse.c index bbdf6d0ddb451390c7c0b308593ccce71fefa5c4..6dbd5d519d69b2a1afc81fbff452ee34ef1ebd82 100644 --- a/parse.c +++ b/parse.c @@ -1705,6 +1705,7 @@ static Node *func_args(void) { // | "(" expr ")" // | "sizeof" "(" type-name ")" // | "sizeof" unary +// | "_Alignof" "(" type-name ")" // | ident func-args? // | str // | num @@ -1739,6 +1740,13 @@ static Node *primary(void) { return new_num(node->ty->size, tok); } + if (tok = consume("_Alignof")) { + expect("("); + Type *ty = type_name(); + expect(")"); + return new_num(ty->align, tok); + } + if (tok = consume_ident()) { // Function call if (consume("(")) { diff --git a/tests b/tests index 9c43e505cc275f31a686b112c287d43a2bd422c4..52bb2f6e77e1bcfb181efe98bfc2a98f3aaaf0db 100644 --- a/tests +++ b/tests @@ -632,6 +632,16 @@ int main() { ; + assert(1, _Alignof(char), "_Alignof(char)"); + assert(2, _Alignof(short), "_Alignof(short)"); + assert(4, _Alignof(int), "_Alignof(int)"); + assert(8, _Alignof(long), "_Alignof(long)"); + assert(8, _Alignof(long long), "_Alignof(long long)"); + assert(1, _Alignof(char[3]), "_Alignof(char[3])"); + assert(4, _Alignof(int[3]), "_Alignof(int[3])"); + assert(1, _Alignof(struct {char a; char b;}[2]), "_Alignof(struct {char a; char b;}[2])"); + assert(8, _Alignof(struct {char a; long b;}[2]), "_Alignof(struct {char a; long b;}[2])"); + printf("OK\n"); return 0; } diff --git a/tokenize.c b/tokenize.c index e8c3ba9e0eedcfdf5204f25e2bc5a6c604070fb1..54f1cea717106ebb75975c177a2bb7dc391bc612 100644 --- a/tokenize.c +++ b/tokenize.c @@ -151,7 +151,7 @@ static char *starts_with_reserved(char *p) { "char", "sizeof", "struct", "typedef", "short", "long", "void", "_Bool", "enum", "static", "break", "continue", "goto", "switch", "case", "default", - "extern"}; + "extern", "_Alignof"}; for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++) { int len = strlen(kw[i]);