From 95781b8d80c98b37ecce87a8a4771013aa89add9 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sun, 11 Aug 2019 09:53:31 +0900 Subject: [PATCH] Add void type --- chibicc.h | 2 ++ parse.c | 13 +++++++++---- tests | 2 ++ tokenize.c | 2 +- type.c | 8 ++++++++ 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/chibicc.h b/chibicc.h index 509d595..30a26fd 100644 --- a/chibicc.h +++ b/chibicc.h @@ -164,6 +164,7 @@ Program *program(); // typedef enum { + TY_VOID, TY_CHAR, TY_SHORT, TY_INT, @@ -192,6 +193,7 @@ struct Member { }; int align_to(int n, int align); +Type *void_type(); Type *char_type(); Type *short_type(); Type *int_type(); diff --git a/parse.c b/parse.c index 7557efd..03e8eeb 100644 --- a/parse.c +++ b/parse.c @@ -170,11 +170,13 @@ Program *program() { } // type-specifier = builtin-type | struct-decl | typedef-name -// builtin-type = "char" | "short" | "int" | "long" +// builtin-type = "void" | "char" | "short" | "int" | "long" Type *type_specifier() { if (!is_typename(token)) error_tok(token, "typename expected"); + if (consume("void")) + return void_type(); if (consume("char")) return char_type(); if (consume("short")) @@ -364,8 +366,11 @@ Node *declaration() { char *name = NULL; ty = declarator(ty, &name); ty = type_suffix(ty); - Var *var = push_var(name, ty, true); + if (ty->kind == TY_VOID) + error_tok(tok, "variable declared void"); + + Var *var = push_var(name, ty, true); if (consume(";")) return new_node(ND_NULL, tok); @@ -383,8 +388,8 @@ Node *read_expr_stmt() { } bool is_typename() { - return peek("char") || peek("short") || peek("int") || peek("long") || - peek("struct") || find_typedef(token); + return peek("void") || peek("char") || peek("short") || peek("int") || + peek("long") || peek("struct") || find_typedef(token); } // stmt = "return" expr ";" diff --git a/tests b/tests index 6aec64f..bb0073a 100644 --- a/tests +++ b/tests @@ -273,6 +273,8 @@ int main() { assert(3, *g1_ptr(), "*g1_ptr()"); + { void *x; } + printf("OK\n"); return 0; } diff --git a/tokenize.c b/tokenize.c index 3eae8c5..8acdfdf 100644 --- a/tokenize.c +++ b/tokenize.c @@ -153,7 +153,7 @@ char *starts_with_reserved(char *p) { // Keyword static char *kw[] = {"return", "if", "else", "while", "for", "int", "char", "sizeof", "struct", "typedef", "short", - "long"}; + "long", "void"}; for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++) { int len = strlen(kw[i]); diff --git a/type.c b/type.c index 5c6bb8b..403cfbc 100644 --- a/type.c +++ b/type.c @@ -11,6 +11,10 @@ Type *new_type(TypeKind kind, int align) { return ty; } +Type *void_type() { + return new_type(TY_VOID, 1); +} + Type *char_type() { return new_type(TY_CHAR, 1); } @@ -47,6 +51,8 @@ Type *array_of(Type *base, int size) { } int size_of(Type *ty) { + assert(ty->kind != TY_VOID); + switch (ty->kind) { case TY_CHAR: return 1; @@ -144,6 +150,8 @@ void visit(Node *node) { if (!node->lhs->ty->base) error_tok(node->tok, "invalid pointer dereference"); node->ty = node->lhs->ty->base; + if (node->ty->kind == TY_VOID) + error_tok(node->tok, "dereferencing a void pointer"); return; case ND_SIZEOF: node->kind = ND_NUM; -- GitLab