sizeof structs and structs-in-structs working
This commit is contained in:
parent
09f3f9b450
commit
b5a498aa52
2 changed files with 85 additions and 12 deletions
11
05/main.c
11
05/main.c
|
@ -16,4 +16,13 @@ typedef struct A {
|
||||||
long f;
|
long f;
|
||||||
} A;
|
} A;
|
||||||
|
|
||||||
typedef int x[(unsigned)-3];
|
typedef union B{
|
||||||
|
int x;
|
||||||
|
struct {
|
||||||
|
int y;
|
||||||
|
struct {long z; } c;
|
||||||
|
} c;
|
||||||
|
}B;
|
||||||
|
|
||||||
|
typedef int x[sizeof(A)];
|
||||||
|
typedef int y[sizeof(struct B)];
|
||||||
|
|
86
05/parse.b
86
05/parse.b
|
@ -30,6 +30,7 @@ function parse_tokens
|
||||||
local ident
|
local ident
|
||||||
local type
|
local type
|
||||||
local p
|
local p
|
||||||
|
local b
|
||||||
local base_type
|
local base_type
|
||||||
local base_type_end
|
local base_type_end
|
||||||
local prefix
|
local prefix
|
||||||
|
@ -80,6 +81,9 @@ function parse_tokens
|
||||||
print_type(type)
|
print_type(type)
|
||||||
putc(10)
|
putc(10)
|
||||||
|
|
||||||
|
b = ident_list_lookup(typedefs, ident)
|
||||||
|
if b != 0 goto typedef_redefinition
|
||||||
|
|
||||||
ident_list_add(typedefs, ident, type)
|
ident_list_add(typedefs, ident, type)
|
||||||
token = suffix_end
|
token = suffix_end
|
||||||
if *1token == SYMBOL_SEMICOLON goto typedef_loop_end
|
if *1token == SYMBOL_SEMICOLON goto typedef_loop_end
|
||||||
|
@ -90,15 +94,20 @@ function parse_tokens
|
||||||
token += 16 ; skip semicolon
|
token += 16 ; skip semicolon
|
||||||
goto parse_tokens_loop
|
goto parse_tokens_loop
|
||||||
:typedef_no_ident
|
:typedef_no_ident
|
||||||
token_error(tokens, .str_typedef_no_ident)
|
token_error(token, .str_typedef_no_ident)
|
||||||
:str_typedef_no_ident
|
:str_typedef_no_ident
|
||||||
string No identifier in typedef declaration.
|
string No identifier in typedef declaration.
|
||||||
byte 0
|
byte 0
|
||||||
:bad_typedef
|
:bad_typedef
|
||||||
token_error(tokens, .str_bad_typedef)
|
token_error(token, .str_bad_typedef)
|
||||||
:str_bad_typedef
|
:str_bad_typedef
|
||||||
string Bad typedef.
|
string Bad typedef.
|
||||||
byte 0
|
byte 0
|
||||||
|
:typedef_redefinition
|
||||||
|
token_error(token, .str_typedef_redefinition)
|
||||||
|
:str_typedef_redefinition
|
||||||
|
string typedef redefinition.
|
||||||
|
byte 0
|
||||||
:parse_tokens_eof
|
:parse_tokens_eof
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -618,7 +627,9 @@ function parse_base_type
|
||||||
local offset
|
local offset
|
||||||
offset = 0
|
offset = 0
|
||||||
|
|
||||||
|
if *1struct_name == 0 goto struct_unnamed
|
||||||
ident_list_add(structures, struct_name, struct)
|
ident_list_add(structures, struct_name, struct)
|
||||||
|
:struct_unnamed
|
||||||
|
|
||||||
:struct_defn_loop
|
:struct_defn_loop
|
||||||
if *1p == SYMBOL_RBRACE goto struct_defn_loop_end
|
if *1p == SYMBOL_RBRACE goto struct_defn_loop_end
|
||||||
|
@ -825,7 +836,7 @@ function type_length
|
||||||
n = type_length(type)
|
n = type_length(type)
|
||||||
return n + 9
|
return n + 9
|
||||||
:type_length_not_array
|
:type_length_not_array
|
||||||
if *1p == TYPE_STRUCT goto return_5
|
if *1p == TYPE_STRUCT goto return_9
|
||||||
if *1p != TYPE_FUNCTION goto type_length_not_function
|
if *1p != TYPE_FUNCTION goto type_length_not_function
|
||||||
local start
|
local start
|
||||||
start = type
|
start = type
|
||||||
|
@ -1487,10 +1498,13 @@ function type_sizeof
|
||||||
if c == TYPE_POINTER goto return_8
|
if c == TYPE_POINTER goto return_8
|
||||||
if c == TYPE_FUNCTION goto return_8
|
if c == TYPE_FUNCTION goto return_8
|
||||||
if c == TYPE_ARRAY goto sizeof_array
|
if c == TYPE_ARRAY goto sizeof_array
|
||||||
fputs(2, .str_sizeof_ni) ; @TODO
|
if c == TYPE_STRUCT goto sizeof_struct
|
||||||
|
|
||||||
|
fputs(2, .str_sizeof_bad) ; @TODO
|
||||||
exit(1)
|
exit(1)
|
||||||
:str_sizeof_ni
|
:str_sizeof_bad
|
||||||
string type_sizeof for this type not implemented.
|
string type_sizeof bad type.
|
||||||
|
byte 10
|
||||||
byte 0
|
byte 0
|
||||||
|
|
||||||
:sizeof_array
|
:sizeof_array
|
||||||
|
@ -1502,6 +1516,33 @@ function type_sizeof
|
||||||
c = type_sizeof(p)
|
c = type_sizeof(p)
|
||||||
return n * c
|
return n * c
|
||||||
|
|
||||||
|
:sizeof_struct
|
||||||
|
; size of struct is offset of last member + size of last member,
|
||||||
|
; rounded up to fit alignment
|
||||||
|
local align
|
||||||
|
local offset
|
||||||
|
local member
|
||||||
|
align = type_alignof(type)
|
||||||
|
p += 1
|
||||||
|
member = *8p
|
||||||
|
:sizeof_struct_loop
|
||||||
|
if *1member == 0 goto sizeof_struct_loop_end
|
||||||
|
member = memchr(member, 0) ; don't care about name
|
||||||
|
member += 1 ; skip null terminator
|
||||||
|
c = *8member
|
||||||
|
member += 8
|
||||||
|
offset = c & 0xffffffff
|
||||||
|
c >= 32 ; extract type
|
||||||
|
offset += type_sizeof(c)
|
||||||
|
goto sizeof_struct_loop
|
||||||
|
:sizeof_struct_loop_end
|
||||||
|
|
||||||
|
offset += align - 1
|
||||||
|
offset /= align
|
||||||
|
offset *= align
|
||||||
|
|
||||||
|
return offset
|
||||||
|
|
||||||
function type_alignof
|
function type_alignof
|
||||||
argument type
|
argument type
|
||||||
local p
|
local p
|
||||||
|
@ -1522,12 +1563,35 @@ function type_alignof
|
||||||
if c == TYPE_POINTER goto return_8
|
if c == TYPE_POINTER goto return_8
|
||||||
if c == TYPE_FUNCTION goto return_8
|
if c == TYPE_FUNCTION goto return_8
|
||||||
if c == TYPE_ARRAY goto alignof_array
|
if c == TYPE_ARRAY goto alignof_array
|
||||||
fputs(2, .str_alignof_ni) ; @TODO
|
if c == TYPE_STRUCT goto alignof_struct
|
||||||
exit(1)
|
|
||||||
:str_alignof_ni
|
|
||||||
string type_alignof for this type not implemented.
|
|
||||||
byte 0
|
|
||||||
|
|
||||||
|
fputs(2, .str_alignof_bad)
|
||||||
|
exit(1)
|
||||||
|
:str_alignof_bad
|
||||||
|
string type_alignof bad type.
|
||||||
|
byte 10
|
||||||
|
byte 0
|
||||||
|
:alignof_struct
|
||||||
|
; alignment of struct is max alignment of members
|
||||||
|
local align
|
||||||
|
local member
|
||||||
|
local a
|
||||||
|
align = 1
|
||||||
|
p += 1
|
||||||
|
member = *8p
|
||||||
|
:alignof_struct_loop
|
||||||
|
if *1member == 0 goto alignof_struct_loop_end
|
||||||
|
member = memchr(member, 0) ; don't care about name
|
||||||
|
member += 1 ; skip null terminator
|
||||||
|
c = *8member
|
||||||
|
member += 8
|
||||||
|
c >= 32 ; ignore offset
|
||||||
|
a = type_alignof(c)
|
||||||
|
if a <= align goto alignof_struct_loop
|
||||||
|
align = a
|
||||||
|
goto alignof_struct_loop
|
||||||
|
:alignof_struct_loop_end
|
||||||
|
return align
|
||||||
:alignof_array
|
:alignof_array
|
||||||
p = type + 9 ; skip TYPE_ARRAY and size
|
p = type + 9 ; skip TYPE_ARRAY and size
|
||||||
return type_alignof(p)
|
return type_alignof(p)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue