Skip to content
Snippets Groups Projects
Commit 6f24dbde authored by Rui Ueyama's avatar Rui Ueyama
Browse files

Add a notion of an incomplete array type

parent 42f60757
Branches
No related merge requests found
......@@ -201,18 +201,21 @@ typedef enum {
struct Type {
TypeKind kind;
int size; // sizeof() value
int align; // alignment
Type *base; // pointer or array
int array_len; // array
Member *members; // struct
Type *return_ty; // function
int size; // sizeof() value
int align; // alignment
bool is_incomplete; // incomplete type
Type *base; // pointer or array
int array_len; // array
Member *members; // struct
Type *return_ty; // function
};
// Struct member
struct Member {
Member *next;
Type *ty;
Token *tok; // for error message
char *name;
int offset;
};
......
......@@ -372,14 +372,27 @@ static Type *abstract_declarator(Type *ty) {
return type_suffix(ty);
}
// type-suffix = ("[" num "]" type-suffix)?
// type-suffix = ("[" num? "]" type-suffix)?
static Type *type_suffix(Type *ty) {
if (!consume("["))
return ty;
int sz = expect_number();
expect("]");
int sz = 0;
bool is_incomplete = true;
if (!consume("]")) {
sz = expect_number();
is_incomplete = false;
expect("]");
}
Token *tok = token;
ty = type_suffix(ty);
return array_of(ty, sz);
if (ty->is_incomplete)
error_tok(tok, "incomplete element type");
ty = array_of(ty, sz);
ty->is_incomplete = is_incomplete;
return ty;
}
// type-name = basetype abstract-declarator type-suffix
......@@ -430,6 +443,9 @@ static Type *struct_decl(void) {
// Assign offsets within the struct to members.
int offset = 0;
for (Member *mem = ty->members; mem; mem = mem->next) {
if (mem->ty->is_incomplete)
error_tok(mem->tok, "incomplete struct member");
offset = align_to(offset, mem->ty->align);
mem->offset = offset;
offset += mem->ty->size;
......@@ -501,6 +517,7 @@ static Type *enum_specifier(void) {
// struct-member = basetype declarator type-suffix ";"
static Member *struct_member(void) {
Type *ty = basetype(NULL);
Token *tok = token;
char *name = NULL;
ty = declarator(ty, &name);
ty = type_suffix(ty);
......@@ -509,6 +526,7 @@ static Member *struct_member(void) {
Member *mem = calloc(1, sizeof(Member));
mem->name = name;
mem->ty = ty;
mem->tok = tok;
return mem;
}
......@@ -587,14 +605,18 @@ static void global_var(void) {
StorageClass sclass;
Type *ty = basetype(&sclass);
char *name = NULL;
Token *tok = token;
ty = declarator(ty, &name);
ty = type_suffix(ty);
expect(";");
if (sclass == TYPEDEF)
if (sclass == TYPEDEF) {
push_scope(name)->type_def = ty;
else
} else {
if (ty->is_incomplete)
error_tok(tok, "incomplete type");
new_gvar(name, ty, true);
}
}
// declaration = basetype declarator type-suffix ("=" expr)? ";"
......@@ -603,9 +625,10 @@ static Node *declaration(void) {
Token *tok = token;
StorageClass sclass;
Type *ty = basetype(&sclass);
if (consume(";"))
if (tok = consume(";"))
return new_node(ND_NULL, tok);
tok = token;
char *name = NULL;
ty = declarator(ty, &name);
ty = type_suffix(ty);
......@@ -620,6 +643,9 @@ static Node *declaration(void) {
error_tok(tok, "variable declared void");
Var *var = new_lvar(name, ty);
if (ty->is_incomplete)
error_tok(tok, "incomplete type");
if (consume(";"))
return new_node(ND_NULL, tok);
......@@ -1081,6 +1107,8 @@ static Node *primary(void) {
if (consume("(")) {
if (is_typename()) {
Type *ty = type_name();
if (ty->is_incomplete)
error_tok(tok, "incomplete type");
expect(")");
return new_num(ty->size, tok);
}
......@@ -1089,6 +1117,8 @@ static Node *primary(void) {
Node *node = unary();
add_type(node);
if (node->ty->is_incomplete)
error_tok(node->tok, "incomplete type");
return new_num(node->ty->size, tok);
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment