aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc.h1
-rw-r--r--decl.c9
-rw-r--r--expr.c21
-rw-r--r--pp.c48
4 files changed, 19 insertions, 60 deletions
diff --git a/cc.h b/cc.h
index 7a61cf3..41f7d90 100644
--- a/cc.h
+++ b/cc.h
@@ -405,7 +405,6 @@ void next(void);
_Bool peek(int);
char *expect(enum tokenkind, const char *);
_Bool consume(int);
-char *stringconcat(void);
/* type */
diff --git a/decl.c b/decl.c
index 3aa720a..2483a47 100644
--- a/decl.c
+++ b/decl.c
@@ -748,18 +748,19 @@ addmember(struct structbuilder *b, struct qualtype mt, char *name, int align, ui
static bool
staticassert(struct scope *s)
{
+ struct expr *e;
uint64_t c;
- char *msg;
if (!consume(T_STATIC_ASSERT))
return false;
expect(TLPAREN, "after _Static_assert");
c = intconstexpr(s, true);
if (consume(TCOMMA)) {
- tokencheck(&tok, TSTRINGLIT, "after static assertion expression");
- msg = stringconcat();
+ e = assignexpr(s);
+ if (!e->decayed || e->base->kind != EXPRSTRING)
+ error(&tok.loc, "expected string literal after static assertion expression");
if (!c)
- error(&tok.loc, "static assertion failed: %s", msg + (*msg != '"'));
+ error(&tok.loc, "static assertion failed: %.*s", (int)e->base->string.size, e->base->string.data);
} else if (!c) {
error(&tok.loc, "static assertion failed");
}
diff --git a/expr.c b/expr.c
index 986f438..114aa5a 100644
--- a/expr.c
+++ b/expr.c
@@ -476,14 +476,21 @@ primaryexpr(struct scope *s)
case TSTRINGLIT:
e = mkexpr(EXPRSTRING, mkarraytype(&typechar, QUALNONE, 0));
e->lvalue = true;
- src = stringconcat();
- dst = e->string.data = xmalloc(strlen(src) - 1);
- if (*src != '"')
- fatal("wide string literal not yet implemented");
- for (++src; *src != '"'; ++dst)
- *dst = unescape(&src);
+ e->string.size = 0;
+ e->string.data = NULL;
+ do {
+ e->string.data = xreallocarray(e->string.data, e->string.size + strlen(tok.lit) + 1, 1);
+ dst = e->string.data + e->string.size;
+ src = tok.lit;
+ if (*src != '"')
+ fatal("wide string literal not yet implemented");
+ for (++src; *src != '"'; ++dst)
+ *dst = unescape(&src);
+ e->string.size = dst - e->string.data;
+ next();
+ } while (tok.kind == TSTRINGLIT);
*dst = '\0';
- e->type->array.length = e->string.size = dst - e->string.data + 1;
+ e->type->array.length = ++e->string.size;
e->type->size = e->type->array.length * e->type->base->size;
e->type->incomplete = false;
e = decay(e);
diff --git a/pp.c b/pp.c
index a1e6e11..101c7c7 100644
--- a/pp.c
+++ b/pp.c
@@ -650,51 +650,3 @@ consume(int kind)
next();
return true;
}
-
-char *
-stringconcat(void)
-{
- static struct array buf;
- char *lit, *end;
- int kind = 0, newkind;
-
- assert(tok.kind == TSTRINGLIT);
- lit = tok.lit;
- next();
- if (tok.kind != TSTRINGLIT) {
- if (lit[0] == 'u' && lit[1] == '8')
- lit += 2;
- return lit;
- }
-
- /* concatenate adjacent string literals */
- buf.len = 0;
- ((char *)arrayadd(&buf, 2))[1] = '"';
- for (;;) {
- switch (*lit) {
- case 'u': if (lit[1] == '8') ++lit; /* fallthrough */
- case 'L':
- case 'U': newkind = *lit, ++lit; break;
- case '"': newkind = 0; break;
- default: assert(0);
- }
- if (kind != newkind && kind && newkind)
- error(&tok.loc, "adjacent string literals have differing prefixes");
- if (newkind)
- kind = newkind;
- arrayaddbuf(&buf, lit + 1, strlen(lit) - 2);
- if (tok.kind != TSTRINGLIT)
- break;
- lit = tok.lit;
- next();
- }
- end = arrayadd(&buf, 2);
- end[0] = '"';
- end[1] = '\0';
- lit = buf.val;
- if (kind && kind != '8')
- *lit = kind;
- else
- ++lit;
- return lit;
-}