Skip to content

Commit 8a263c7

Browse files
authored
Merge pull request #227 from sysprog21/fix-decl
Support multiple declarators in struct member decl
2 parents e04a60d + 65ca335 commit 8a263c7

File tree

4 files changed

+74
-18
lines changed

4 files changed

+74
-18
lines changed

lib/c.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,7 @@ int fputc(int c, FILE *stream)
576576
#define IS_CHUNK_GET_FREED(size) (size & CHUNK_SIZE_FREED_MASK)
577577

578578
typedef struct chunk {
579-
struct chunk *next;
580-
struct chunk *prev;
579+
struct chunk *next, *prev;
581580
int size;
582581
} chunk_t;
583582

src/defs.h

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,7 @@ typedef struct {
266266
typedef struct ref_block ref_block_t;
267267

268268
struct ref_block_list {
269-
ref_block_t *head;
270-
ref_block_t *tail;
269+
ref_block_t *head, *tail;
271270
};
272271

273272
typedef struct ref_block_list ref_block_list_t;
@@ -276,8 +275,7 @@ typedef struct insn insn_t;
276275

277276
typedef struct use_chain_node {
278277
insn_t *insn;
279-
struct use_chain_node *next;
280-
struct use_chain_node *prev;
278+
struct use_chain_node *next, *prev;
281279
} use_chain_t;
282280

283281
typedef struct var var_t;
@@ -306,8 +304,7 @@ struct var {
306304
int subscripts_idx;
307305
rename_t rename;
308306
ref_block_list_t ref_block_list; /* blocks which kill variable */
309-
use_chain_t *users_head;
310-
use_chain_t *users_tail;
307+
use_chain_t *users_head, *users_tail;
311308
struct insn *last_assign;
312309
int consumed;
313310
bool is_ternary_ret;
@@ -408,8 +405,7 @@ struct phi_operand {
408405
typedef struct phi_operand phi_operand_t;
409406

410407
struct insn {
411-
struct insn *next;
412-
struct insn *prev;
408+
struct insn *next, *prev;
413409
int idx;
414410
opcode_t opcode;
415411
var_t *rd;
@@ -423,13 +419,11 @@ struct insn {
423419
};
424420

425421
typedef struct {
426-
insn_t *head;
427-
insn_t *tail;
422+
insn_t *head, *tail;
428423
} insn_list_t;
429424

430425
typedef struct {
431-
ph2_ir_t *head;
432-
ph2_ir_t *tail;
426+
ph2_ir_t *head, *tail;
433427
} ph2_ir_list_t;
434428

435429
typedef enum { NEXT, ELSE, THEN } bb_connection_type_t;
@@ -448,8 +442,7 @@ struct symbol {
448442
typedef struct symbol symbol_t;
449443

450444
typedef struct {
451-
symbol_t *head;
452-
symbol_t *tail;
445+
symbol_t *head, *tail;
453446
} symbol_list_t;
454447

455448
struct basic_block {
@@ -519,8 +512,7 @@ struct func {
519512
};
520513

521514
typedef struct {
522-
func_t *head;
523-
func_t *tail;
515+
func_t *head, *tail;
524516
} func_list_t;
525517

526518
typedef struct {

src/parser.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,6 +2870,31 @@ void read_global_statement(void)
28702870
read_full_var_decl(v, 0, 1);
28712871
v->offset = size;
28722872
size += size_var(v);
2873+
2874+
/* Handle multiple variable declarations with same base type */
2875+
while (lex_accept(T_comma)) {
2876+
if (i >= MAX_FIELDS)
2877+
error("Too many struct fields");
2878+
2879+
var_t *nv = &type->fields[i++];
2880+
nv->type = v->type;
2881+
nv->var_name[0] = '\0';
2882+
nv->is_ptr = 0;
2883+
nv->is_func = false;
2884+
nv->is_global = false;
2885+
nv->array_size = 0;
2886+
nv->offset = 0;
2887+
nv->init_val = 0;
2888+
nv->liveness = 0;
2889+
nv->in_loop = 0;
2890+
nv->base = NULL;
2891+
nv->subscript = 0;
2892+
nv->subscripts_idx = 0;
2893+
read_inner_var_decl(nv, 0, 1);
2894+
nv->offset = size;
2895+
size += size_var(nv);
2896+
}
2897+
28732898
lex_expect(T_semicolon);
28742899
} while (!lex_accept(T_close_curly));
28752900

@@ -2922,6 +2947,32 @@ void read_global_statement(void)
29222947
read_full_var_decl(v, 0, 1);
29232948
v->offset = size;
29242949
size += size_var(v);
2950+
2951+
/* Handle multiple variable declarations with same base type
2952+
*/
2953+
while (lex_accept(T_comma)) {
2954+
if (i >= MAX_FIELDS)
2955+
error("Too many struct fields");
2956+
2957+
var_t *nv = &type->fields[i++];
2958+
nv->type = v->type;
2959+
nv->var_name[0] = '\0';
2960+
nv->is_ptr = 0;
2961+
nv->is_func = false;
2962+
nv->is_global = false;
2963+
nv->array_size = 0;
2964+
nv->offset = 0;
2965+
nv->init_val = 0;
2966+
nv->liveness = 0;
2967+
nv->in_loop = 0;
2968+
nv->base = NULL;
2969+
nv->subscript = 0;
2970+
nv->subscripts_idx = 0;
2971+
read_inner_var_decl(nv, 0, 1);
2972+
nv->offset = size;
2973+
size += size_var(nv);
2974+
}
2975+
29252976
lex_expect(T_semicolon);
29262977
} while (!lex_accept(T_close_curly));
29272978
}

tests/driver.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,20 @@ int main() {
423423
}
424424
EOF
425425

426+
# struct with multiple pointer declarations in same line
427+
try_ 42 << EOF
428+
typedef struct chunk {
429+
struct chunk *next, *prev;
430+
int size;
431+
} chunk_t;
432+
433+
int main() {
434+
chunk_t c;
435+
c.size = 42;
436+
return c.size;
437+
}
438+
EOF
439+
426440
# arrays
427441
try_ 12 << EOF
428442
int nth_of(int *a, int i) {

0 commit comments

Comments
 (0)