[hackers] [scc] Add semantic analysis of initializers || Roberto E. Vargas Caballero
commit ca4dc0e4231ef4fa8cd322fd21beb4a99e6a0fac
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon Sep 14 13:59:00 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon Sep 14 14:02:39 2015 +0200
Add semantic analysis of initializers
diff --git a/cc1/cc1.h b/cc1/cc1.h
index da438c6..addbea9 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -375,7 +375,7 @@ extern bool isnodecmp(int op);
extern int negop(int op);
extern bool cmpnode(Node *np, TUINT val);
extern Node *decay(Node *np);
-extern void initializer(Symbol *sym);
+extern void initializer(Symbol *sym, Type *tp, int nelem);
/* cpp.c */
extern void icpp(void);
diff --git a/cc1/decl.c b/cc1/decl.c
index 000c290..13b328b 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
_AT_@ -674,7 +674,7 @@ identifier(struct decl *dcl)
if (sym->token == IDEN && sym->type->op != FTN)
emit(ODECL, sym);
if (accept('='))
- initializer(sym);
+ initializer(sym, sym->type, -1);
return sym;
redeclaration:
diff --git a/cc1/expr.c b/cc1/expr.c
index 7c405b7..6d3ed17 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -978,37 +978,74 @@ condexpr(void)
return np;
}
-/* TODO: check correctness of the initializator */
-/* TODO: emit initializer */
+static void
+initlist(Symbol *sym, Type *tp)
+{
+ int n, toomany = 0;
+ Type *newtp;
+
+ for (n = 0; ; ++n) {
+ switch (tp->op) {
+ case ARY:
+ if (tp->defined && n >= tp->n.elem && !toomany) {
+ toomany = 1;
+ warn("excess elements in array initializer");
+ sym = NULL;
+ }
+ newtp = tp->type;
+ break;
+ case STRUCT:
+ if (n >= tp->n.elem && !toomany) {
+ toomany = 1;
+ warn("excess elements in struct initializer");
+ sym = NULL;
+ } else {
+ sym = tp->p.fields[n];
+ newtp = sym->type;
+ }
+ break;
+ default:
+ newtp = tp;
+ warn("braces around scalar initializer");
+ if (n > 0 && !toomany) {
+ toomany = 1;
+ warn("excess elements in scalar initializer");
+ }
+ break;
+ }
+ initializer(sym, newtp, n);
+ if (!accept(','))
+ break;
+ }
+ expect('}');
+
+ if (tp->op == ARY && !tp->defined) {
+ tp->n.elem = n + 1;
+ tp->defined = 1;
+ }
+}
+
void
-initializer(Symbol *sym)
+initializer(Symbol *sym, Type *tp, int nelem)
{
Node *np;
- Type *tp = sym->type;
- int flags = sym->flags, scalar;
+ int flags = sym->flags;
- switch (tp->op) {
- case FTN:
+ if (tp->op == FTN)
error("function '%s' is initialized like a variable", sym->name);
- case PTR:
- case INT:
- scalar = 1;
- break;
- default:
- scalar = 0;
- break;
- }
if (accept('{')) {
- do {
- initializer(sym);
- } while (accept(','));
- expect('}');
+ initlist(sym, tp);
return;
}
- np = assignop(OINIT, varnode(sym), assign());
+ np = assign();
+
+ /* if !sym it means there are too much initializers */
+ if (!sym)
+ return;
+ np = assignop(OINIT, varnode(sym), np);
- if ((flags & (ISLOCAL|ISPRIVATE|ISGLOBAL)) != 0) {
+ if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {
if (!np->right->constant)
errorp("initializer element is not constant");
emit(OINIT, np);
Received on Mon Sep 14 2015 - 16:24:47 CEST
This archive was generated by hypermail 2.3.0
: Mon Sep 14 2015 - 16:36:10 CEST