Skip to content

Commit

Permalink
Parser: implement typeof_unqual
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexu committed Nov 6, 2023
1 parent cecbb57 commit 97c3de2
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 11 deletions.
23 changes: 13 additions & 10 deletions src/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@ fn nextExternDecl(p: *Parser) void {
.keyword_typeof,
.keyword_typeof1,
.keyword_typeof2,
.keyword_typeof_unqual,
.keyword_extension,
.keyword_bit_int,
=> if (parens == 0) return,
Expand Down Expand Up @@ -1332,8 +1333,13 @@ pub const DeclSpec = struct {
/// : keyword_typeof '(' typeName ')'
/// | keyword_typeof '(' expr ')'
fn typeof(p: *Parser) Error!?Type {
var unqual = false;
switch (p.tok_ids[p.tok_i]) {
.keyword_typeof, .keyword_typeof1, .keyword_typeof2 => p.tok_i += 1,
.keyword_typeof_unqual => {
p.tok_i += 1;
unqual = true;
},
else => return null,
}
const l_paren = try p.expectToken(.l_paren);
Expand All @@ -1342,7 +1348,7 @@ fn typeof(p: *Parser) Error!?Type {
const typeof_ty = try p.arena.create(Type);
typeof_ty.* = .{
.data = ty.data,
.qual = ty.qual.inheritFromTypeof(),
.qual = if (unqual) .{} else ty.qual.inheritFromTypeof(),
.specifier = ty.specifier,
};

Expand All @@ -1356,15 +1362,18 @@ fn typeof(p: *Parser) Error!?Type {
try p.expectClosing(l_paren, .r_paren);
// Special case nullptr_t since it's defined as typeof(nullptr)
if (typeof_expr.ty.is(.nullptr_t)) {
return Type{ .specifier = .nullptr_t, .qual = typeof_expr.ty.qual.inheritFromTypeof() };
return Type{
.specifier = .nullptr_t,
.qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
};
}

const inner = try p.arena.create(Type.Expr);
inner.* = .{
.node = typeof_expr.node,
.ty = .{
.data = typeof_expr.ty.data,
.qual = typeof_expr.ty.qual.inheritFromTypeof(),
.qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
.specifier = typeof_expr.ty.specifier,
},
};
Expand Down Expand Up @@ -4571,6 +4580,7 @@ fn nextStmt(p: *Parser, l_brace: TokenIndex) !void {
.keyword_typeof,
.keyword_typeof1,
.keyword_typeof2,
.keyword_typeof_unqual,
.keyword_extension,
=> if (parens == 0) return,
.keyword_pragma => p.skipToPragmaSentinel(),
Expand Down Expand Up @@ -7150,13 +7160,6 @@ fn checkComplexArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex,
}
}

fn checkVariableBuiltinArgument(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32, tag: Builtin.Tag) !void {
switch (tag) {
.__builtin_va_start, .__va_start, .va_start => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx),
else => {},
}
}

fn callExpr(p: *Parser, lhs: Result) Error!Result {
const l_paren = p.tok_i;
p.tok_i += 1;
Expand Down
8 changes: 7 additions & 1 deletion src/Tokenizer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ pub const Token = struct {
keyword_true,
keyword_false,
keyword_nullptr,
keyword_typeof_unqual,

// Preprocessor directives
keyword_include,
Expand Down Expand Up @@ -445,6 +446,7 @@ pub const Token = struct {
.keyword_true,
.keyword_false,
.keyword_nullptr,
.keyword_typeof_unqual,
=> return true,
else => return false,
}
Expand Down Expand Up @@ -650,6 +652,7 @@ pub const Token = struct {
.keyword_true => "true",
.keyword_false => "false",
.keyword_nullptr => "nullptr",
.keyword_typeof_unqual => "typeof_unqual",
.keyword_include => "include",
.keyword_include_next => "include_next",
.keyword_embed => "embed",
Expand Down Expand Up @@ -835,6 +838,7 @@ pub const Token = struct {
.keyword_true,
.keyword_false,
.keyword_nullptr,
.keyword_typeof_unqual,
.keyword_elifdef,
.keyword_elifndef,
=> if (standard.atLeast(.c2x)) kw else .identifier,
Expand Down Expand Up @@ -921,6 +925,7 @@ pub const Token = struct {
.{ "true", .keyword_true },
.{ "false", .keyword_false },
.{ "nullptr", .keyword_nullptr },
.{ "typeof_unqual", .keyword_typeof_unqual },

// Preprocessor directives
.{ "include", .keyword_include },
Expand Down Expand Up @@ -2094,7 +2099,7 @@ test "digraphs" {
}

test "C23 keywords" {
try expectTokensExtra("true false alignas alignof bool static_assert thread_local nullptr", &.{
try expectTokensExtra("true false alignas alignof bool static_assert thread_local nullptr typeof_unqual", &.{
.keyword_true,
.keyword_false,
.keyword_c23_alignas,
Expand All @@ -2103,6 +2108,7 @@ test "C23 keywords" {
.keyword_c23_static_assert,
.keyword_c23_thread_local,
.keyword_nullptr,
.keyword_typeof_unqual,
}, .c2x);
}

Expand Down
9 changes: 9 additions & 0 deletions test/cases/ast/typeof_unqual.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var: 'const int'
name: a

var: 'typeof(<expr>: const int)'
name: b

var: 'typeof(<expr>: int)'
name: c

4 changes: 4 additions & 0 deletions test/cases/typeof_unqual.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//aro-args -std=c2x
const int a;
typeof(a) b;
typeof_unqual(a) c;

0 comments on commit 97c3de2

Please sign in to comment.