aboutsummaryrefslogtreecommitdiffhomepage
path: root/c.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-10-12 10:06:06 +0200
committerlemon <lsof@mailbox.org>2025-10-12 10:06:06 +0200
commit3048a0b59baae16727d0c259353ff4be1ae559b4 (patch)
tree0886daf069691a4d673852c56727c7b20194d9e7 /c.c
parent097d8a16c4ccdf6405c094db6c5fa3de7943464c (diff)
typeof
Diffstat (limited to 'c.c')
-rw-r--r--c.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/c.c b/c.c
index 30ea13a..29028b2 100644
--- a/c.c
+++ b/c.c
@@ -102,6 +102,7 @@ isdecltok(struct comp *cm)
case TKWextern: case TKWstatic: case TKWinline: case TKW_Noreturn:
case TKWconst: case TKWvolatile: case TKWvoid: case TKWfloat:
case TKWdouble: case TKWregister: case TKW_Static_assert:
+ case TKW__typeof__: case TKWtypeof: case TKWtypeof_unqual:
return 1;
case TKIDENT:
return (decl = finddecl(cm, tk.s)) && decl->scls == SCTYPEDEF;
@@ -1837,6 +1838,21 @@ tagtype(struct comp *cm, enum toktag kind)
return t;
}
+static union type
+ptypeof(struct comp *cm)
+{
+ union type ty;
+ expect(cm, '(', NULL);
+ if (isdecltok(cm)) { /* typeof (type) */
+ struct declstate st = { DCASTEXPR };
+ ty = pdecl(&st, cm).ty;
+ } else { /* typeof (expr) */
+ ty = commaexpr(cm).ty;
+ }
+ expect(cm, ')', NULL);
+ return ty;
+}
+
static void
declspec(struct declstate *st, struct comp *cm)
{
@@ -1924,6 +1940,12 @@ declspec(struct declstate *st, struct comp *cm)
if (!span.ex.len) span.ex = tk.span.ex;
joinspan(&span.ex, tk.span.ex);
goto End;
+ case TKW__typeof__: case TKWtypeof:
+ lex(cm, &tk);
+ st->base = ptypeof(cm);
+ if (!span.ex.len) span.ex = tk.span.ex;
+ joinspan(&span.ex, tk.span.ex);
+ goto End;
case TKIDENT:
if (!st->base.t && !arith && (decl = finddecl(cm, tk.s))
&& decl->scls == SCTYPEDEF) {