summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-01-20 23:06:03 -0800
committerOri Bernstein <ori@eigenstate.org>2016-01-20 23:06:03 -0800
commit6361a241f462769284053e07d51cd0638d3e94af (patch)
tree9c69b768bdccb941da1384e53745f87e4c94afa5
parent631e14604ba34ad97514cf302de75c3c3102d316 (diff)
downloadmc-6361a241f462769284053e07d51cd0638d3e94af.tar.gz
Add a distinction between label values and names.
This allows us to have labels work across scopes in assembly source.
-rw-r--r--mi/cfg.c2
-rw-r--r--parse/gram.y12
-rw-r--r--parse/infer.c4
-rw-r--r--parse/node.c6
-rw-r--r--parse/parse.h5
5 files changed, 22 insertions, 7 deletions
diff --git a/mi/cfg.c b/mi/cfg.c
index 12ecc75..349dfb9 100644
--- a/mi/cfg.c
+++ b/mi/cfg.c
@@ -214,7 +214,7 @@ Cfg *mkcfg(Node *fn, Node **nl, size_t nn)
}
}
post = mkbb(cfg);
- bprintf(buf, sizeof buf, ".R%d", nextret++);
+ bprintf(buf, sizeof buf, ".Lret.%d", nextret++);
label(cfg, mklbl(fn->loc, buf), post);
cfg->start = pre;
diff --git a/parse/gram.y b/parse/gram.y
index 0fdfed1..505ab14 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -580,7 +580,10 @@ unionelt /* nb: the ucon union type gets filled in when we have context */
| Tendln {$$ = NULL;}
;
-goto : Tgoto Tident {$$ = mkexpr($1->loc, Ojmp, mklbl($2->loc, $2->id), NULL);}
+goto : Tgoto Tident {
+ $$ = mkexpr($1->loc, Ojmp, mklbl($2->loc, ""), NULL);
+ $$->expr.args[0]->lit.lblname = strdup($2->id);
+ }
;
retexpr : Tret expr {$$ = mkexpr($1->loc, Oret, $2, NULL);}
@@ -971,7 +974,12 @@ blkbody : decl {
}
;
-label : Tcolon Tident {$$ = mklbl($2->loc, $2->id);}
+label : Tcolon Tident {
+ char buf[512];
+ genlblstr(buf, sizeof buf, $2->id);
+ $$ = mklbl($2->loc, buf);
+ $$->expr.args[0]->lit.lblname = strdup($2->id);
+ }
;
%%
diff --git a/parse/infer.c b/parse/infer.c
index 4cbeab1..54499ee 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1530,7 +1530,7 @@ static void inferexpr(Inferstate *st, Node **np, Type *ret, int *sawret)
break;
case Ojmp: /* goto void* -> void */
if (args[0]->type == Nlit && args[0]->lit.littype == Llbl)
- args[0] = getlbl(curstab(), args[0]->loc, args[0]->lit.lblval);
+ args[0] = getlbl(curstab(), args[0]->loc, args[0]->lit.lblname);
infersub(st, n, ret, sawret, &isconst);
settype(st, n, mktype(Zloc, Tyvoid));
break;
@@ -1864,7 +1864,7 @@ static void infernode(Inferstate *st, Node **np, Type *ret, int *sawret)
break;
case Nlit:
if (n->lit.littype == Llbl)
- putlbl(curstab(), n->lit.lblval, n);
+ putlbl(curstab(), n->lit.lblname, n);
break;
case Nname:
case Nuse:
diff --git a/parse/node.c b/parse/node.c
index 023dd01..038eec7 100644
--- a/parse/node.c
+++ b/parse/node.c
@@ -231,6 +231,7 @@ Node *mklbl(Srcloc loc, char *lbl)
assert(lbl != NULL);
n = mknode(loc, Nlit);
n->lit.littype = Llbl;
+ n->lit.lblname = NULL;
n->lit.lblval = strdup(lbl);
return mkexpr(loc, Olit, n, NULL);
}
@@ -238,7 +239,10 @@ Node *mklbl(Srcloc loc, char *lbl)
char *genlblstr(char *buf, size_t sz, char *suffix)
{
static int nextlbl;
- bprintf(buf, 128, ".L%d%s", nextlbl++, suffix);
+ size_t len;
+
+ len = snprintf(buf, 128, ".L%d.%s", nextlbl++, suffix);
+ assert(len <= sz);
return buf;
}
diff --git a/parse/parse.h b/parse/parse.h
index 9d9c39a..2a705c5 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -264,7 +264,10 @@ struct Node {
double fltval;
uint32_t chrval;
Str strval;
- char *lblval;
+ struct {
+ char *lblval;
+ char *lblname;
+ };
int boolval;
Node *fnval;
};