diff options
-rw-r--r-- | cc.h | 1 | ||||
-rw-r--r-- | decl.c | 9 | ||||
-rw-r--r-- | expr.c | 21 | ||||
-rw-r--r-- | pp.c | 48 |
4 files changed, 19 insertions, 60 deletions
@@ -405,7 +405,6 @@ void next(void); _Bool peek(int); char *expect(enum tokenkind, const char *); _Bool consume(int); -char *stringconcat(void); /* type */ @@ -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"); } @@ -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); @@ -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; -} |