mirror of https://github.com/rui314/chibicc
Align struct members
This commit is contained in:
parent
d16f54ba0a
commit
c821c4f709
|
@ -150,6 +150,7 @@ typedef enum {
|
|||
struct Type {
|
||||
TypeKind kind;
|
||||
int size; // sizeof() value
|
||||
int align; // alignment
|
||||
|
||||
// Pointer-to or array-of type. We intentionally use the same member
|
||||
// to represent pointer/array duality in C.
|
||||
|
@ -199,3 +200,4 @@ void add_type(Node *node);
|
|||
//
|
||||
|
||||
void codegen(Var *prog, FILE *out);
|
||||
int align_to(int n, int align);
|
||||
|
|
|
@ -33,7 +33,7 @@ static void pop(char *arg) {
|
|||
|
||||
// Round up `n` to the nearest multiple of `align`. For instance,
|
||||
// align_to(5, 8) returns 8 and align_to(11, 8) returns 16.
|
||||
static int align_to(int n, int align) {
|
||||
int align_to(int n, int align) {
|
||||
return (n + align - 1) / align * align;
|
||||
}
|
||||
|
||||
|
|
7
parse.c
7
parse.c
|
@ -592,14 +592,19 @@ static Type *struct_decl(Token **rest, Token *tok) {
|
|||
Type *ty = calloc(1, sizeof(Type));
|
||||
ty->kind = TY_STRUCT;
|
||||
struct_members(rest, tok, ty);
|
||||
ty->align = 1;
|
||||
|
||||
// Assign offsets within the struct to members.
|
||||
int offset = 0;
|
||||
for (Member *mem = ty->members; mem; mem = mem->next) {
|
||||
offset = align_to(offset, mem->ty->align);
|
||||
mem->offset = offset;
|
||||
offset += mem->ty->size;
|
||||
|
||||
if (ty->align < mem->ty->align)
|
||||
ty->align = mem->ty->align;
|
||||
}
|
||||
ty->size = offset;
|
||||
ty->size = align_to(offset, ty->align);
|
||||
|
||||
return ty;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,9 @@ int main() {
|
|||
ASSERT(32, ({ struct {int a;} x[4]; sizeof(x); }));
|
||||
ASSERT(48, ({ struct {int a[3];} x[2]; sizeof(x); }));
|
||||
ASSERT(2, ({ struct {char a; char b;} x; sizeof(x); }));
|
||||
ASSERT(9, ({ struct {char a; int b;} x; sizeof(x); }));
|
||||
ASSERT(0, ({ struct {} x; sizeof(x); }));
|
||||
ASSERT(16, ({ struct {char a; int b;} x; sizeof(x); }));
|
||||
ASSERT(16, ({ struct {int a; char b;} x; sizeof(x); }));
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
|
|
20
type.c
20
type.c
|
@ -1,7 +1,15 @@
|
|||
#include "chibicc.h"
|
||||
|
||||
Type *ty_char = &(Type){TY_CHAR, 1};
|
||||
Type *ty_int = &(Type){TY_INT, 8};
|
||||
Type *ty_char = &(Type){TY_CHAR, 1, 1};
|
||||
Type *ty_int = &(Type){TY_INT, 8, 8};
|
||||
|
||||
static Type *new_type(TypeKind kind, int size, int align) {
|
||||
Type *ty = calloc(1, sizeof(Type));
|
||||
ty->kind = kind;
|
||||
ty->size = size;
|
||||
ty->align = align;
|
||||
return ty;
|
||||
}
|
||||
|
||||
bool is_integer(Type *ty) {
|
||||
return ty->kind == TY_CHAR || ty->kind == TY_INT;
|
||||
|
@ -14,9 +22,7 @@ Type *copy_type(Type *ty) {
|
|||
}
|
||||
|
||||
Type *pointer_to(Type *base) {
|
||||
Type *ty = calloc(1, sizeof(Type));
|
||||
ty->kind = TY_PTR;
|
||||
ty->size = 8;
|
||||
Type *ty = new_type(TY_PTR, 8, 8);
|
||||
ty->base = base;
|
||||
return ty;
|
||||
}
|
||||
|
@ -29,9 +35,7 @@ Type *func_type(Type *return_ty) {
|
|||
}
|
||||
|
||||
Type *array_of(Type *base, int len) {
|
||||
Type *ty = calloc(1, sizeof(Type));
|
||||
ty->kind = TY_ARRAY;
|
||||
ty->size = base->size * len;
|
||||
Type *ty = new_type(TY_ARRAY, base->size * len, base->align);
|
||||
ty->base = base;
|
||||
ty->array_len = len;
|
||||
return ty;
|
||||
|
|
Loading…
Reference in New Issue