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 18ad54b003608f3060d4baf2fef00a8a2b6f0a7b
parent 6dee4df79d5f251d12e387d8425e2b05cdd60523
Author: Michael Forney <mforney@mforney.org>
Date:   Sat, 16 Feb 2019 03:39:03 -0800

Allow labels with same name as typedef

Diffstat:
Mpp.c | 3++-
Mstmt.c | 31++++++++++++++++++++-----------
Atests/label-typedef.c | 4++++
Atests/label-typedef.qbe | 7+++++++
4 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/pp.c b/pp.c @@ -112,7 +112,8 @@ next(void) bool peek(int kind) { - nextinto(&pending); + if (!pending.kind) + nextinto(&pending); if (pending.kind != kind) return false; pending.kind = TNONE; diff --git a/stmt.c b/stmt.c @@ -14,6 +14,23 @@ #include "token.h" #include "type.h" +static bool +gotolabel(struct function *f) +{ + char *name; + struct gotolabel *g; + + if (tok.kind != TIDENT) + return false; + name = tok.lit; + if (!peek(TCOLON)) + return false; + g = funcgoto(f, name); + g->defined = true; + funclabel(f, g->label); + return true; +} + /* 6.8 Statements and blocks */ void stmt(struct function *f, struct scope *s) @@ -25,6 +42,8 @@ stmt(struct function *f, struct scope *s) struct switchcases swtch = {0}; uint64_t i; + while (gotolabel(f)) + ; switch (tok.kind) { /* 6.8.1 Labeled statements */ case TCASE: @@ -55,7 +74,7 @@ stmt(struct function *f, struct scope *s) next(); s = mkscope(s); while (tok.kind != TRBRACE) { - if (!decl(s, f)) + if (gotolabel(f) || !decl(s, f)) stmt(f, s); } s = delscope(s); @@ -66,16 +85,6 @@ stmt(struct function *f, struct scope *s) case TSEMICOLON: next(); break; - case TIDENT: - name = tok.lit; - if (peek(TCOLON)) { - struct gotolabel *g = funcgoto(f, name); - g->defined = true; - funclabel(f, g->label); - stmt(f, s); - break; - } - /* fallthrough */ default: e = expr(s); v = funcexpr(f, e); diff --git a/tests/label-typedef.c b/tests/label-typedef.c @@ -0,0 +1,4 @@ +typedef int x; +void f(void) { +x:; +} diff --git a/tests/label-typedef.qbe b/tests/label-typedef.qbe @@ -0,0 +1,7 @@ +export +function $f() { +@start.1 +@body.2 +@x.3 + ret +}