[hackers] [scc] Add semantic analysis of initializers || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 14 Sep 2015 16:24:47 +0200 (CEST)

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