From d445fa23a25b5aa14428be2200e66c07a5c2b308 Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Thu, 20 May 2010 21:17:36 +0430 Subject: [PATCH] add union support --- ncc.c | 27 +++++++++++++++++++-------- tok.c | 1 + tok.h | 1 + 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ncc.c b/ncc.c index cc3f528..7b9c47d 100644 --- a/ncc.c +++ b/ncc.c @@ -94,15 +94,17 @@ static struct structinfo { char name[NAMELEN]; struct name fields[MAXFIELDS]; int nfields; + int isunion; int size; } structs[MAXTYPES]; static int nstructs; -static int struct_find(char *name) +static int struct_find(char *name, int isunion) { int i; for (i = 0; i < nstructs; i++) - if (!strcmp(name, structs[i].name)) + if (!strcmp(name, structs[i].name) && + structs[i].isunion == isunion) return i; die("struct not found\n"); } @@ -198,18 +200,25 @@ static void ts_binop_add(void (*o_sth)(void)) static void structdef(void *data, struct name *name, int init) { struct structinfo *si = data; - name->addr = si->size; - si->size += type_totsz(&name->type); + if (si->isunion) { + name->addr = 0; + if (si->size < type_totsz(&name->type)) + si->size = type_totsz(&name->type); + } else { + name->addr = si->size; + si->size += type_totsz(&name->type); + } memcpy(&si->fields[si->nfields++], name, sizeof(*name)); } static int readdefs(void (*def)(void *, struct name *, int init), void *data); -static int struct_create(char *name) +static int struct_create(char *name, int isunion) { int id = nstructs++; struct structinfo *si = &structs[id]; strcpy(si->name, name); + si->isunion = isunion; tok_expect('{'); while (tok_jmp('}')) { readdefs(structdef, si); @@ -226,6 +235,7 @@ static int basetype(struct type *type) int size = 4; int done = 0; int i = 0; + int isunion; char name[NAMELEN]; type->flags = 0; type->ptr = 0; @@ -253,14 +263,15 @@ static int basetype(struct type *type) case TOK_UNSIGNED: sign = 0; break; + case TOK_UNION: case TOK_STRUCT: - tok_get(); + isunion = tok_get() == TOK_UNION; tok_expect(TOK_NAME); strcpy(name, tok_id()); if (tok_see() == '{') - type->id = struct_create(name); + type->id = struct_create(name, isunion); else - type->id = struct_find(name); + type->id = struct_find(name, isunion); type->flags = T_STRUCT; type->bt = 8; return 0; diff --git a/tok.c b/tok.c index 6ccaeda..46e61fb 100644 --- a/tok.c +++ b/tok.c @@ -24,6 +24,7 @@ static struct { {"int", TOK_INT}, {"char", TOK_CHAR}, {"struct", TOK_STRUCT}, + {"union", TOK_UNION}, {"enum", TOK_ENUM}, {"if", TOK_IF}, {"else", TOK_ELSE}, diff --git a/tok.h b/tok.h index b8430e7..639f9f9 100644 --- a/tok.h +++ b/tok.h @@ -19,6 +19,7 @@ enum tok { TOK_INT, TOK_CHAR, TOK_STRUCT, + TOK_UNION, TOK_ENUM, TOK_IF, TOK_ELSE, -- 2.11.4.GIT