cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 4df0c2114cd0afd7aded5e67bd9e9af35b149fab
parent a1a5214bbae2b1b4c988e5f3d1b6415b64a890c6
Author: Michael Forney <mforney@mforney.org>
Date:   Fri, 22 Feb 2019 12:58:13 -0800

Keep track of built-in kind in declaration

Also, populate filescope with builtins outside of main.

Diffstat:
Mdecl.c | 8--------
Mdecl.h | 23+++++++++++++++--------
Mdeps.mk | 2+-
Mexpr.c | 21++++++++++++++-------
Mexpr.h | 7+------
Mmain.c | 8+-------
Mscope.c | 23+++++++++++++++++++++++
Mscope.h | 1+
8 files changed, 56 insertions(+), 37 deletions(-)

diff --git a/decl.c b/decl.c @@ -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 { diff --git a/decl.h b/decl.h @@ -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 *); diff --git a/deps.mk b/deps.mk @@ -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 diff --git a/expr.c b/expr.c @@ -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"); diff --git a/expr.h b/expr.h @@ -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; diff --git a/main.c b/main.c @@ -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"); diff --git a/scope.c b/scope.c @@ -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) { diff --git a/scope.h b/scope.h @@ -7,6 +7,7 @@ struct scope { struct scope *parent; }; +void scopeinit(void); struct scope *mkscope(struct scope *); struct scope *delscope(struct scope *);