version 1.148, 2021/03/28 09:20:51 |
version 1.149, 2021/03/28 09:34:45 |
Line 556 current_initsym(void) |
|
Line 556 current_initsym(void) |
|
return ¤t_init()->initsym; |
return ¤t_init()->initsym; |
} |
} |
|
|
static const struct brace_level * |
|
current_brace_level(void) |
|
{ |
|
return current_init()->brace_level; |
|
} |
|
|
|
static struct brace_level ** |
|
current_brace_level_lvalue(void) |
|
{ |
|
return ¤t_init()->brace_level; |
|
} |
|
|
|
static void |
static void |
set_initerr(void) |
set_initerr(void) |
{ |
{ |
Line 576 set_initerr(void) |
|
Line 564 set_initerr(void) |
|
|
|
#define initerr (*current_initerr()) |
#define initerr (*current_initerr()) |
#define initsym (*current_initsym()) |
#define initsym (*current_initsym()) |
#define brace_level_rvalue (current_brace_level()) |
|
#define brace_level_lvalue (*current_brace_level_lvalue()) |
|
|
|
#ifndef DEBUG |
#ifndef DEBUG |
|
|
Line 641 brace_level_new(type_t *type, type_t *su |
|
Line 627 brace_level_new(type_t *type, type_t *su |
|
} |
} |
|
|
static void |
static void |
brace_level_set_array_dimension(int dim) |
brace_level_set_array_dimension(struct brace_level *level, int dim) |
{ |
{ |
debug_step("setting the array size to %d", dim); |
debug_step("setting the array size to %d", dim); |
brace_level_lvalue->bl_type->t_dim = dim; |
level->bl_type->t_dim = dim; |
debug_indent(); |
debug_indent(); |
brace_level_debug(brace_level_rvalue); |
brace_level_debug(level); |
} |
} |
|
|
static void |
static void |
Line 684 brace_level_next_member(struct brace_lev |
|
Line 670 brace_level_next_member(struct brace_lev |
|
void |
void |
designation_add_subscript(range_t range) |
designation_add_subscript(range_t range) |
{ |
{ |
|
struct initialization *in = current_init(); |
struct brace_level *level; |
struct brace_level *level; |
|
|
debug_enter(); |
debug_enter(); |
Line 694 designation_add_subscript(range_t range) |
|
Line 681 designation_add_subscript(range_t range) |
|
range.lo, range.hi); |
range.lo, range.hi); |
|
|
/* XXX: This call is wrong here, it must be somewhere else. */ |
/* XXX: This call is wrong here, it must be somewhere else. */ |
initstack_pop_nobrace(current_init()); |
initstack_pop_nobrace(in); |
|
|
level = brace_level_lvalue; |
level = in->brace_level; |
if (level->bl_array_of_unknown_size) { |
if (level->bl_array_of_unknown_size) { |
/* No +1 here, extend_if_array_of_unknown_size will add it. */ |
/* No +1 here, extend_if_array_of_unknown_size will add it. */ |
int auto_dim = (int)range.hi; |
int auto_dim = (int)range.hi; |
if (auto_dim > level->bl_type->t_dim) |
if (auto_dim > level->bl_type->t_dim) |
brace_level_set_array_dimension(auto_dim); |
brace_level_set_array_dimension(level, auto_dim); |
} |
} |
|
|
debug_leave(); |
debug_leave(); |
Line 731 initstack_init(void) |
|
Line 718 initstack_init(void) |
|
initsym->s_type = duptyp(initsym->s_type); |
initsym->s_type = duptyp(initsym->s_type); |
/* TODO: does 'duptyp' create a memory leak? */ |
/* TODO: does 'duptyp' create a memory leak? */ |
|
|
brace_level_lvalue = brace_level_new(NULL, initsym->s_type, 1); |
current_init()->brace_level = brace_level_new(NULL, initsym->s_type, 1); |
|
|
initialization_debug(current_init()); |
initialization_debug(current_init()); |
debug_leave(); |
debug_leave(); |
Line 780 initstack_pop_item_named_member(const ch |
|
Line 767 initstack_pop_item_named_member(const ch |
|
|
|
/* TODO: think of a better name than 'pop' */ |
/* TODO: think of a better name than 'pop' */ |
static void |
static void |
initstack_pop_item_unnamed(void) |
initstack_pop_item_unnamed(struct initialization *in) |
{ |
{ |
struct brace_level *level = brace_level_lvalue; |
struct brace_level *level = in->brace_level; |
|
|
/* |
/* |
* If the removed element was a structure member, we must go |
* If the removed element was a structure member, we must go |
Line 803 initstack_pop_item(struct initialization |
|
Line 790 initstack_pop_item(struct initialization |
|
|
|
debug_enter(); |
debug_enter(); |
|
|
level = brace_level_lvalue; |
level = in->brace_level; |
debug_indent(); |
debug_indent(); |
debug_printf("popping: "); |
debug_printf("popping: "); |
brace_level_debug(level); |
brace_level_debug(level); |
|
|
brace_level_lvalue = level->bl_enclosing; |
in->brace_level = level->bl_enclosing; |
free(level); |
free(level); |
level = brace_level_lvalue; |
level = in->brace_level; |
lint_assert(level != NULL); |
lint_assert(level != NULL); |
|
|
level->bl_remaining--; |
level->bl_remaining--; |
Line 820 initstack_pop_item(struct initialization |
|
Line 807 initstack_pop_item(struct initialization |
|
if (in->designation.head != NULL && in->designation.head->name != NULL) |
if (in->designation.head != NULL && in->designation.head->name != NULL) |
initstack_pop_item_named_member(in->designation.head->name); |
initstack_pop_item_named_member(in->designation.head->name); |
else |
else |
initstack_pop_item_unnamed(); |
initstack_pop_item_unnamed(in); |
|
|
initialization_debug(current_init()); |
initialization_debug(current_init()); |
debug_leave(); |
debug_leave(); |
Line 838 initstack_pop_brace(struct initializatio |
|
Line 825 initstack_pop_brace(struct initializatio |
|
debug_enter(); |
debug_enter(); |
initialization_debug(in); |
initialization_debug(in); |
do { |
do { |
brace = brace_level_rvalue->bl_brace; |
brace = in->brace_level->bl_brace; |
/* TODO: improve wording of the debug message */ |
/* TODO: improve wording of the debug message */ |
debug_step("loop brace=%d", brace); |
debug_step("loop brace=%d", brace); |
initstack_pop_item(in); |
initstack_pop_item(in); |
Line 866 initstack_pop_nobrace(struct initializat |
|
Line 853 initstack_pop_nobrace(struct initializat |
|
|
|
/* Extend an array of unknown size by one element */ |
/* Extend an array of unknown size by one element */ |
static void |
static void |
extend_if_array_of_unknown_size(void) |
extend_if_array_of_unknown_size(struct initialization *in) |
{ |
{ |
struct brace_level *level = brace_level_lvalue; |
struct brace_level *level = in->brace_level; |
|
|
if (level->bl_remaining != 0) |
if (level->bl_remaining != 0) |
return; |
return; |
Line 936 initstack_push_struct_or_union(struct in |
|
Line 923 initstack_push_struct_or_union(struct in |
|
* TODO: remove unnecessary 'const' for variables in functions that |
* TODO: remove unnecessary 'const' for variables in functions that |
* fit on a single screen. Keep it for larger functions. |
* fit on a single screen. Keep it for larger functions. |
*/ |
*/ |
struct brace_level *level = brace_level_lvalue; |
struct brace_level *level = in->brace_level; |
int cnt; |
int cnt; |
sym_t *m; |
sym_t *m; |
|
|
Line 993 initstack_push(struct initialization *in |
|
Line 980 initstack_push(struct initialization *in |
|
|
|
debug_enter(); |
debug_enter(); |
|
|
extend_if_array_of_unknown_size(); |
extend_if_array_of_unknown_size(in); |
|
|
level = brace_level_lvalue; |
level = in->brace_level; |
lint_assert(level->bl_remaining > 0); |
lint_assert(level->bl_remaining > 0); |
lint_assert(level->bl_type == NULL || |
lint_assert(level->bl_type == NULL || |
!is_scalar(level->bl_type->t_tspec)); |
!is_scalar(level->bl_type->t_tspec)); |
|
|
brace_level_lvalue = xcalloc(1, sizeof *brace_level_lvalue); |
in->brace_level = xcalloc(1, sizeof *in->brace_level); |
brace_level_lvalue->bl_enclosing = level; |
in->brace_level->bl_enclosing = level; |
brace_level_lvalue->bl_type = level->bl_subtype; |
in->brace_level->bl_type = level->bl_subtype; |
lint_assert(brace_level_lvalue->bl_type->t_tspec != FUNC); |
lint_assert(in->brace_level->bl_type->t_tspec != FUNC); |
|
|
again: |
again: |
level = brace_level_lvalue; |
level = in->brace_level; |
|
|
debug_step("expecting type '%s'", type_name(level->bl_type)); |
debug_step("expecting type '%s'", type_name(level->bl_type)); |
lint_assert(level->bl_type != NULL); |
lint_assert(level->bl_type != NULL); |
|
|
debug_step("pop scalar"); |
debug_step("pop scalar"); |
pop: |
pop: |
/* TODO: extract this into end_initializer_level */ |
/* TODO: extract this into end_initializer_level */ |
enclosing = brace_level_rvalue->bl_enclosing; |
enclosing = in->brace_level->bl_enclosing; |
free(level); |
free(level); |
brace_level_lvalue = enclosing; |
in->brace_level = enclosing; |
goto again; |
goto again; |
} |
} |
/* The initialization stack now expects a single scalar. */ |
/* The initialization stack now expects a single scalar. */ |
|
|
static void |
static void |
check_too_many_initializers(void) |
check_too_many_initializers(void) |
{ |
{ |
const struct brace_level *level = brace_level_rvalue; |
const struct brace_level *level = current_init()->brace_level; |
if (level->bl_remaining > 0) |
if (level->bl_remaining > 0) |
return; |
return; |
/* |
/* |
Line 1088 initstack_next_brace(struct initializati |
|
Line 1075 initstack_next_brace(struct initializati |
|
debug_enter(); |
debug_enter(); |
initialization_debug(in); |
initialization_debug(in); |
|
|
if (brace_level_rvalue->bl_type != NULL && |
if (in->brace_level->bl_type != NULL && |
is_scalar(brace_level_rvalue->bl_type->t_tspec)) { |
is_scalar(in->brace_level->bl_type->t_tspec)) { |
/* invalid initializer type %s */ |
/* invalid initializer type %s */ |
error(176, type_name(brace_level_rvalue->bl_type)); |
error(176, type_name(in->brace_level->bl_type)); |
set_initerr(); |
set_initerr(); |
} |
} |
if (!initerr) |
if (!initerr) |
Line 1099 initstack_next_brace(struct initializati |
|
Line 1086 initstack_next_brace(struct initializati |
|
if (!initerr) |
if (!initerr) |
initstack_push(in); |
initstack_push(in); |
if (!initerr) { |
if (!initerr) { |
brace_level_lvalue->bl_brace = true; |
in->brace_level->bl_brace = true; |
designation_debug(&in->designation); |
designation_debug(&in->designation); |
debug_step("expecting type '%s'", |
debug_step("expecting type '%s'", |
type_name(brace_level_rvalue->bl_type != NULL |
type_name(in->brace_level->bl_type != NULL |
? brace_level_rvalue->bl_type |
? in->brace_level->bl_type |
: brace_level_rvalue->bl_subtype)); |
: in->brace_level->bl_subtype)); |
} |
} |
|
|
initialization_debug(current_init()); |
initialization_debug(current_init()); |
Line 1117 initstack_next_nobrace(struct initializa |
|
Line 1104 initstack_next_nobrace(struct initializa |
|
{ |
{ |
debug_enter(); |
debug_enter(); |
|
|
if (brace_level_rvalue->bl_type == NULL && |
if (in->brace_level->bl_type == NULL && |
!is_scalar(brace_level_rvalue->bl_subtype->t_tspec)) { |
!is_scalar(in->brace_level->bl_subtype->t_tspec)) { |
/* {}-enclosed initializer required */ |
/* {}-enclosed initializer required */ |
error(181); |
error(181); |
/* XXX: maybe set initerr here */ |
/* XXX: maybe set initerr here */ |
Line 1128 initstack_next_nobrace(struct initializa |
|
Line 1115 initstack_next_nobrace(struct initializa |
|
check_too_many_initializers(); |
check_too_many_initializers(); |
|
|
while (!initerr) { |
while (!initerr) { |
struct brace_level *level = brace_level_lvalue; |
struct brace_level *level = in->brace_level; |
|
|
if (tn->tn_type->t_tspec == STRUCT && |
if (tn->tn_type->t_tspec == STRUCT && |
level->bl_type == tn->tn_type && |
level->bl_type == tn->tn_type && |
Line 1162 init_lbrace(void) |
|
Line 1149 init_lbrace(void) |
|
initialization_debug(in); |
initialization_debug(in); |
|
|
if ((initsym->s_scl == AUTO || initsym->s_scl == REG) && |
if ((initsym->s_scl == AUTO || initsym->s_scl == REG) && |
brace_level_rvalue->bl_enclosing == NULL) { |
in->brace_level->bl_enclosing == NULL) { |
if (tflag && |
if (tflag && |
!is_scalar(brace_level_rvalue->bl_subtype->t_tspec)) |
!is_scalar(in->brace_level->bl_subtype->t_tspec)) |
/* no automatic aggregate initialization in trad. C */ |
/* no automatic aggregate initialization in trad. C */ |
warning(188); |
warning(188); |
} |
} |
Line 1241 init_using_assign(tnode_t *rn) |
|
Line 1228 init_using_assign(tnode_t *rn) |
|
|
|
if (initsym->s_type->t_tspec == ARRAY) |
if (initsym->s_type->t_tspec == ARRAY) |
return false; |
return false; |
if (brace_level_rvalue->bl_enclosing != NULL) |
if (current_init()->brace_level->bl_enclosing != NULL) |
return false; |
return false; |
|
|
debug_step("handing over to ASSIGN"); |
debug_step("handing over to ASSIGN"); |
Line 1260 init_using_assign(tnode_t *rn) |
|
Line 1247 init_using_assign(tnode_t *rn) |
|
static void |
static void |
check_init_expr(tnode_t *tn, scl_t sclass) |
check_init_expr(tnode_t *tn, scl_t sclass) |
{ |
{ |
|
struct initialization *in = current_init(); |
tnode_t *ln; |
tnode_t *ln; |
tspec_t lt, rt; |
tspec_t lt, rt; |
struct mbl *tmem; |
struct mbl *tmem; |
Line 1267 check_init_expr(tnode_t *tn, scl_t sclas |
|
Line 1255 check_init_expr(tnode_t *tn, scl_t sclas |
|
/* Create a temporary node for the left side. */ |
/* Create a temporary node for the left side. */ |
ln = tgetblk(sizeof *ln); |
ln = tgetblk(sizeof *ln); |
ln->tn_op = NAME; |
ln->tn_op = NAME; |
ln->tn_type = tduptyp(brace_level_rvalue->bl_type); |
ln->tn_type = tduptyp(in->brace_level->bl_type); |
ln->tn_type->t_const = false; |
ln->tn_type->t_const = false; |
ln->tn_lvalue = true; |
ln->tn_lvalue = true; |
ln->tn_sym = initsym; /* better than nothing */ |
ln->tn_sym = initsym; /* better than nothing */ |
Line 1296 check_init_expr(tnode_t *tn, scl_t sclas |
|
Line 1284 check_init_expr(tnode_t *tn, scl_t sclas |
|
* XXX: Is it correct to do this conversion _after_ the typeok above? |
* XXX: Is it correct to do this conversion _after_ the typeok above? |
*/ |
*/ |
if (lt != rt || |
if (lt != rt || |
(brace_level_rvalue->bl_type->t_bitfield && tn->tn_op == CON)) |
(in->brace_level->bl_type->t_bitfield && tn->tn_op == CON)) |
tn = convert(INIT, 0, brace_level_rvalue->bl_type, tn); |
tn = convert(INIT, 0, in->brace_level->bl_type, tn); |
|
|
check_non_constant_initializer(tn, sclass); |
check_non_constant_initializer(tn, sclass); |
} |
} |
Line 1333 init_using_expr(tnode_t *tn) |
|
Line 1321 init_using_expr(tnode_t *tn) |
|
if (initerr || tn == NULL) |
if (initerr || tn == NULL) |
goto done_initstack; |
goto done_initstack; |
|
|
brace_level_lvalue->bl_remaining--; |
in->brace_level->bl_remaining--; |
debug_step("%d elements remaining", brace_level_rvalue->bl_remaining); |
debug_step("%d elements remaining", in->brace_level->bl_remaining); |
|
|
check_init_expr(tn, sclass); |
check_init_expr(tn, sclass); |
|
|
Line 1364 init_array_using_string(struct initializ |
|
Line 1352 init_array_using_string(struct initializ |
|
debug_enter(); |
debug_enter(); |
initialization_debug(current_init()); |
initialization_debug(current_init()); |
|
|
level = brace_level_lvalue; |
level = in->brace_level; |
strg = tn->tn_string; |
strg = tn->tn_string; |
|
|
/* |
/* |
Line 1384 init_array_using_string(struct initializ |
|
Line 1372 init_array_using_string(struct initializ |
|
|
|
/* Put the array at top of stack */ |
/* Put the array at top of stack */ |
initstack_push(in); |
initstack_push(in); |
level = brace_level_lvalue; |
level = in->brace_level; |
|
|
/* TODO: what if both bl_type and bl_subtype are ARRAY? */ |
/* TODO: what if both bl_type and bl_subtype are ARRAY? */ |
|
|