diff options
-rw-r--r-- | decl.c | 8 | ||||
-rw-r--r-- | decl.h | 23 | ||||
-rw-r--r-- | deps.mk | 2 | ||||
-rw-r--r-- | expr.c | 21 | ||||
-rw-r--r-- | expr.h | 7 | ||||
-rw-r--r-- | main.c | 8 | ||||
-rw-r--r-- | scope.c | 23 | ||||
-rw-r--r-- | scope.h | 1 |
8 files changed, 56 insertions, 37 deletions
@@ -18,14 +18,6 @@ #include "token.h" #include "type.h" -struct declaration builtinvalist = {.kind = DECLTYPE, .type = &typevalist}; -struct declaration builtinvastart = {.kind = DECLBUILTIN}; -struct declaration builtinvaarg = {.kind = DECLBUILTIN}; -struct declaration builtinvacopy = {.kind = DECLBUILTIN}; -struct declaration builtinvaend = {.kind = DECLBUILTIN}; -struct declaration builtinoffsetof = {.kind = DECLBUILTIN}; -struct declaration builtinalloca = {.kind = DECLBUILTIN}; - static struct list tentativedefns = {&tentativedefns, &tentativedefns}; enum storageclass { @@ -12,27 +12,34 @@ enum linkage { LINKEXTERN, }; +enum builtinkind { + BUILTINVALIST, + BUILTINVASTART, + BUILTINVAARG, + BUILTINVACOPY, + BUILTINVAEND, + BUILTINOFFSETOF, + BUILTINALLOCA, +}; + struct declaration { enum declarationkind kind; enum linkage linkage; struct type *type; struct value *value; + + /* objects and functions */ struct list link; int align; /* may be more strict than type requires */ _Bool tentative, defined; + + /* built-ins */ + enum builtinkind builtin; }; struct scope; struct function; -extern struct declaration builtinvalist; -extern struct declaration builtinvastart; -extern struct declaration builtinvaarg; -extern struct declaration builtinvacopy; -extern struct declaration builtinvaend; -extern struct declaration builtinoffsetof; -extern struct declaration builtinalloca; - struct declaration *mkdecl(enum declarationkind, struct type *, enum linkage); _Bool decl(struct scope *, struct function *); struct type *typename(struct scope *); @@ -10,7 +10,7 @@ init.o: init.c util.h decl.h expr.h init.h pp.h token.h type.h main.o: main.c util.h arg.h decl.h pp.h scope.h token.h pp.o: pp.c util.h pp.h scan.h token.h scan.o: scan.c util.h scan.h token.h -scope.o: scope.c util.h htab.h scope.h +scope.o: scope.c util.h decl.h htab.h scope.h type.h siphash.o: siphash.c stmt.o: stmt.c util.h backend.h decl.h expr.h pp.h scope.h stmt.h token.h \ type.h @@ -436,30 +436,35 @@ postfixexpr(struct scope *s, struct expression *r) case TLPAREN: /* function call */ next(); if (r->kind == EXPRIDENT && r->ident.decl->kind == DECLBUILTIN) { - if (r->ident.decl == &builtinvastart) { + switch (r->ident.decl->builtin) { + case BUILTINVASTART: e = mkexpr(EXPRBUILTIN, &typevoid, 0); e->builtin.kind = BUILTINVASTART; e->builtin.arg = exprconvert(assignexpr(s), &typevalistptr); expect(TCOMMA, "after va_list"); free(expect(TIDENT, "after ','")); // XXX: check that this was actually a parameter name? - } else if (r->ident.decl == &builtinvaarg) { + break; + case BUILTINVAARG: e = mkexpr(EXPRBUILTIN, NULL, 0); e->builtin.kind = BUILTINVAARG; e->builtin.arg = exprconvert(assignexpr(s), &typevalistptr); expect(TCOMMA, "after va_list"); e->type = typename(s); - } else if (r->ident.decl == &builtinvacopy) { + break; + case BUILTINVACOPY: e = mkexpr(EXPRASSIGN, typevalist.base, 0); e->assign.l = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr)); expect(TCOMMA, "after target va_list"); e->assign.r = mkunaryexpr(TMUL, exprconvert(assignexpr(s), &typevalistptr)); e = exprconvert(e, &typevoid); - } else if (r->ident.decl == &builtinvaend) { + break; + case BUILTINVAEND: e = mkexpr(EXPRBUILTIN, &typevoid, 0); e->builtin.kind = BUILTINVAEND; exprconvert(assignexpr(s), &typevalistptr); - } else if (r->ident.decl == &builtinoffsetof) { + break; + case BUILTINOFFSETOF: t = typename(s); expect(TCOMMA, "after type name"); name = expect(TIDENT, "after ','"); @@ -470,11 +475,13 @@ postfixexpr(struct scope *s, struct expression *r) error(&tok.loc, "struct/union has no member named '%s'", name); e = mkconstexpr(&typeulong, offset); free(name); - } else if (r->ident.decl == &builtinalloca) { + break; + case BUILTINALLOCA: e = mkexpr(EXPRBUILTIN, mkpointertype(&typevoid), 0); e->builtin.kind = BUILTINALLOCA; e->builtin.arg = exprconvert(assignexpr(s), &typeulong); - } else { + break; + default: fatal("internal error; unknown builtin"); } expect(TRPAREN, "after builtin parameters"); @@ -77,12 +77,7 @@ struct expression { struct expression *exprs; } comma; struct { - enum { - BUILTINVASTART, - BUILTINVAARG, - BUILTINVAEND, - BUILTINALLOCA, - } kind; + int kind; struct expression *arg; } builtin; struct value *temp; @@ -49,13 +49,7 @@ main(int argc, char *argv[]) next(); } } else { - scopeputdecl(&filescope, "__builtin_va_list", &builtinvalist); - scopeputdecl(&filescope, "__builtin_va_start", &builtinvastart); - scopeputdecl(&filescope, "__builtin_va_copy", &builtinvacopy); - scopeputdecl(&filescope, "__builtin_va_arg", &builtinvaarg); - scopeputdecl(&filescope, "__builtin_va_end", &builtinvaend); - scopeputdecl(&filescope, "__builtin_offsetof", &builtinoffsetof); - scopeputdecl(&filescope, "__builtin_alloca", &builtinalloca); + scopeinit(); while (tok.kind != TEOF) { if (!decl(&filescope, NULL)) error(&tok.loc, "expected declaration or function definition"); @@ -3,11 +3,34 @@ #include <stdint.h> #include <string.h> #include "util.h" +#include "decl.h" #include "htab.h" #include "scope.h" +#include "type.h" struct scope filescope; +void +scopeinit(void) +{ + static struct builtin { + char *name; + struct declaration decl; + } builtins[] = { + {"__builtin_va_list", {.kind = DECLTYPE, .type = &typevalist}}, + {"__builtin_va_start", {.kind = DECLBUILTIN, .builtin = BUILTINVASTART}}, + {"__builtin_va_copy", {.kind = DECLBUILTIN, .builtin = BUILTINVACOPY}}, + {"__builtin_va_arg", {.kind = DECLBUILTIN, .builtin = BUILTINVAARG}}, + {"__builtin_va_end", {.kind = DECLBUILTIN, .builtin = BUILTINVAEND}}, + {"__builtin_offsetof", {.kind = DECLBUILTIN, .builtin = BUILTINOFFSETOF}}, + {"__builtin_alloca", {.kind = DECLBUILTIN, .builtin = BUILTINALLOCA}}, + }; + struct builtin *b; + + for (b = builtins; b < builtins + LEN(builtins); ++b) + scopeputdecl(&filescope, b->name, &b->decl); +} + struct scope * mkscope(struct scope *parent) { @@ -7,6 +7,7 @@ struct scope { struct scope *parent; }; +void scopeinit(void); struct scope *mkscope(struct scope *); struct scope *delscope(struct scope *); |