cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 7c2089414f2d6476c093a08bb7305e72a89b552c
parent de85378a20b2a190d4e8a5ce3156a8bdbc682bcc
Author: Andrew Chambers <andrewchambers@fastmail.com>
Date:   Wed, 27 Feb 2019 20:42:23 +1300

Implement __typeof__.

Diffstat:
Mdecl.c | 9+++++++++
Mpp.c | 1+
Atests/typeof.c | 20++++++++++++++++++++
Atests/typeof.qbe | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtoken.h | 1+
5 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/decl.c b/decl.c @@ -325,6 +325,15 @@ declspecs(struct scope *s, enum storageclass *sc, enum funcspecifier *fs, int *a ++ntypes; next(); break; + case T__TYPEOF__: + next(); + expect(TLPAREN, "after '__typeof__'"); + t = typename(s); + if (!t) + t = expr(s)->type; + ++ntypes; + expect(TRPAREN, "to close '__typeof__'"); + break; /* 6.7.5 Alignment specifier */ case T_ALIGNAS: diff --git a/pp.c b/pp.c @@ -27,6 +27,7 @@ keyword(struct token *tok) {"_Noreturn", T_NORETURN}, {"_Static_assert", T_STATIC_ASSERT}, {"_Thread_local", T_THREAD_LOCAL}, + {"__typeof__", T__TYPEOF__}, {"auto", TAUTO}, {"break", TBREAK}, {"case", TCASE}, diff --git a/tests/typeof.c b/tests/typeof.c @@ -0,0 +1,20 @@ +int v; +typedef int* t; +int f() {v = 1; return 0;} +int main() { + __typeof__(f()) x = 123; + __typeof__(t) y = &x; + + if (x != 123) + return 1; + if (*y != 123) + return 2; + if (sizeof(y) != sizeof(int*)) + return 3; + if (sizeof(x) != sizeof(int)) + return 4; + if (v != 0) + return 5; + + return 0; +} diff --git a/tests/typeof.qbe b/tests/typeof.qbe @@ -0,0 +1,54 @@ +export +function w $f() { +@start.1 +@body.2 + storew 1, $v + ret 0 +} +export +function w $main() { +@start.3 + %.1 =l alloc4 4 + %.3 =l alloc8 8 +@body.4 + %.2 =l add %.1, 0 + storew 123, %.2 + %.4 =l add %.3, 0 + storel %.1, %.4 + %.5 =w loadsw %.1 + %.6 =w cnew %.5, 123 + %.7 =w cnew %.6, 0 + jnz %.7, @if_true.5, @if_false.6 +@if_true.5 + ret 1 +@if_false.6 + %.8 =l loadl %.3 + %.9 =w loadsw %.8 + %.10 =w cnew %.9, 123 + %.11 =w cnew %.10, 0 + jnz %.11, @if_true.7, @if_false.8 +@if_true.7 + ret 2 +@if_false.8 + %.12 =w cnel 8, 8 + %.13 =w cnew %.12, 0 + jnz %.13, @if_true.9, @if_false.10 +@if_true.9 + ret 3 +@if_false.10 + %.14 =w cnel 4, 4 + %.15 =w cnew %.14, 0 + jnz %.15, @if_true.11, @if_false.12 +@if_true.11 + ret 4 +@if_false.12 + %.16 =w loadsw $v + %.17 =w cnew %.16, 0 + %.18 =w cnew %.17, 0 + jnz %.18, @if_true.13, @if_false.14 +@if_true.13 + ret 5 +@if_false.14 + ret 0 +} +export data $v = align 4 { z 4 } diff --git a/token.h b/token.h @@ -54,6 +54,7 @@ enum tokenkind { T_NORETURN, T_STATIC_ASSERT, T_THREAD_LOCAL, + T__TYPEOF__, /* punctuator */ TLBRACK,