aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2019-02-22 12:58:13 -0800
committerMichael Forney <mforney@mforney.org>2019-02-22 12:58:13 -0800
commit4df0c2114cd0afd7aded5e67bd9e9af35b149fab (patch)
tree5820fb19ec0ccf2dc4a212e46114771f944984d9
parenta1a5214bbae2b1b4c988e5f3d1b6415b64a890c6 (diff)
downloadcproc-4df0c2114cd0afd7aded5e67bd9e9af35b149fab.tar.xz
Keep track of built-in kind in declaration
Also, populate filescope with builtins outside of main.
-rw-r--r--decl.c8
-rw-r--r--decl.h23
-rw-r--r--deps.mk2
-rw-r--r--expr.c21
-rw-r--r--expr.h7
-rw-r--r--main.c8
-rw-r--r--scope.c23
-rw-r--r--scope.h1
8 files changed, 56 insertions, 37 deletions
diff --git a/decl.c b/decl.c
index b789708..ac72f23 100644
--- 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
index 0fb081b..5b8b83d 100644
--- 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
index 4872d72..cb8f974 100644
--- 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
index 7de75f3..30399e5 100644
--- 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
index f3ccd69..7de6635 100644
--- 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
index dd8ddb6..a42d2c1 100644
--- 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
index 6c1d5fd..bd550e8 100644
--- 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
index 34301ce..7c6b001 100644
--- 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 *);