Factor some code
Three places that skip (and store) tokens in some fashion can be factored a bit.
This commit is contained in:
parent
328b06a3fc
commit
21b12ea10d
1 changed files with 47 additions and 63 deletions
110
tccgen.c
110
tccgen.c
|
@ -5902,6 +5902,42 @@ static void block(int *bsym, int *csym, int is_expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This skips over a stream of tokens containing balanced {} and ()
|
||||||
|
pairs, stopping at outer ',' ';' and '}'. If STR then allocates
|
||||||
|
and stores the skipped tokens in *STR. This doesn't check if
|
||||||
|
() and {} are nested correctly, i.e. "({)}" is accepted. */
|
||||||
|
static void skip_or_save_block(TokenString **str)
|
||||||
|
{
|
||||||
|
int level = 0;
|
||||||
|
if (str)
|
||||||
|
*str = tok_str_alloc();
|
||||||
|
|
||||||
|
while ((level > 0 || (tok != '}' && tok != ',' && tok != ';'))) {
|
||||||
|
int t;
|
||||||
|
if (tok == TOK_EOF) {
|
||||||
|
if (str || level > 0)
|
||||||
|
tcc_error("unexpected end of file");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (str)
|
||||||
|
tok_str_add_tok(*str);
|
||||||
|
t = tok;
|
||||||
|
next();
|
||||||
|
if (t == '{' || t == '(') {
|
||||||
|
level++;
|
||||||
|
} else if (t == '}' || t == ')') {
|
||||||
|
level--;
|
||||||
|
if (level == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (str) {
|
||||||
|
tok_str_add(*str, -1);
|
||||||
|
tok_str_add(*str, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define EXPR_CONST 1
|
#define EXPR_CONST 1
|
||||||
#define EXPR_ANY 2
|
#define EXPR_ANY 2
|
||||||
|
|
||||||
|
@ -6256,7 +6292,7 @@ static void init_putz(Section *sec, unsigned long c, int size)
|
||||||
static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
int first, int size_only)
|
int first, int size_only)
|
||||||
{
|
{
|
||||||
int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
|
int index, array_length, n, no_oblock, nb, i;
|
||||||
int size1, align1;
|
int size1, align1;
|
||||||
int have_elem;
|
int have_elem;
|
||||||
Sym *s, *f;
|
Sym *s, *f;
|
||||||
|
@ -6429,25 +6465,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
But GNU C supports it, so we need to recurse even into
|
But GNU C supports it, so we need to recurse even into
|
||||||
subfields of structs and arrays when size_only is set. */
|
subfields of structs and arrays when size_only is set. */
|
||||||
/* just skip expression */
|
/* just skip expression */
|
||||||
parlevel = parlevel1 = 0;
|
do {
|
||||||
while ((parlevel > 0 || parlevel1 > 0 ||
|
skip_or_save_block(NULL);
|
||||||
(tok != '}' && tok != ',')) && tok != -1) {
|
} while (tok != '}' && tok != ',' && tok != -1);
|
||||||
if (tok == '(')
|
|
||||||
parlevel++;
|
|
||||||
else if (tok == ')') {
|
|
||||||
if (parlevel == 0 && parlevel1 == 0)
|
|
||||||
break;
|
|
||||||
parlevel--;
|
|
||||||
}
|
|
||||||
else if (tok == '{')
|
|
||||||
parlevel1++;
|
|
||||||
else if (tok == '}') {
|
|
||||||
if (parlevel == 0 && parlevel1 == 0)
|
|
||||||
break;
|
|
||||||
parlevel1--;
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!have_elem) {
|
if (!have_elem) {
|
||||||
/* This should happen only when we haven't parsed
|
/* This should happen only when we haven't parsed
|
||||||
|
@ -6472,7 +6492,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
int has_init, int v, int scope)
|
int has_init, int v, int scope)
|
||||||
{
|
{
|
||||||
int size, align, addr, data_offset;
|
int size, align, addr, data_offset;
|
||||||
int level;
|
|
||||||
ParseState saved_parse_state = {0};
|
ParseState saved_parse_state = {0};
|
||||||
TokenString *init_str = NULL;
|
TokenString *init_str = NULL;
|
||||||
Section *sec;
|
Section *sec;
|
||||||
|
@ -6500,33 +6519,18 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
if (!has_init)
|
if (!has_init)
|
||||||
tcc_error("unknown type size");
|
tcc_error("unknown type size");
|
||||||
/* get all init string */
|
/* get all init string */
|
||||||
init_str = tok_str_alloc();
|
|
||||||
if (has_init == 2) {
|
if (has_init == 2) {
|
||||||
|
init_str = tok_str_alloc();
|
||||||
/* only get strings */
|
/* only get strings */
|
||||||
while (tok == TOK_STR || tok == TOK_LSTR) {
|
while (tok == TOK_STR || tok == TOK_LSTR) {
|
||||||
tok_str_add_tok(init_str);
|
tok_str_add_tok(init_str);
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
tok_str_add(init_str, -1);
|
||||||
|
tok_str_add(init_str, 0);
|
||||||
} else {
|
} else {
|
||||||
level = 0;
|
skip_or_save_block(&init_str);
|
||||||
while (level > 0 || (tok != ',' && tok != ';')) {
|
|
||||||
if (tok < 0)
|
|
||||||
tcc_error("unexpected end of file in initializer");
|
|
||||||
tok_str_add_tok(init_str);
|
|
||||||
if (tok == '{')
|
|
||||||
level++;
|
|
||||||
else if (tok == '}') {
|
|
||||||
level--;
|
|
||||||
if (level <= 0) {
|
|
||||||
next();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tok_str_add(init_str, -1);
|
|
||||||
tok_str_add(init_str, 0);
|
|
||||||
|
|
||||||
/* compute size */
|
/* compute size */
|
||||||
save_parse_state(&saved_parse_state);
|
save_parse_state(&saved_parse_state);
|
||||||
|
@ -7029,7 +7033,6 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
the compilation unit only if they are used */
|
the compilation unit only if they are used */
|
||||||
if ((type.t & (VT_INLINE | VT_STATIC)) ==
|
if ((type.t & (VT_INLINE | VT_STATIC)) ==
|
||||||
(VT_INLINE | VT_STATIC)) {
|
(VT_INLINE | VT_STATIC)) {
|
||||||
int block_level;
|
|
||||||
struct InlineFunc *fn;
|
struct InlineFunc *fn;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
|
||||||
|
@ -7037,28 +7040,9 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
fn = tcc_malloc(sizeof *fn + strlen(filename));
|
fn = tcc_malloc(sizeof *fn + strlen(filename));
|
||||||
strcpy(fn->filename, filename);
|
strcpy(fn->filename, filename);
|
||||||
fn->sym = sym;
|
fn->sym = sym;
|
||||||
fn->func_str = tok_str_alloc();
|
skip_or_save_block(&fn->func_str);
|
||||||
|
dynarray_add(&tcc_state->inline_fns,
|
||||||
block_level = 0;
|
&tcc_state->nb_inline_fns, fn);
|
||||||
for(;;) {
|
|
||||||
int t;
|
|
||||||
if (tok == TOK_EOF)
|
|
||||||
tcc_error("unexpected end of file");
|
|
||||||
tok_str_add_tok(fn->func_str);
|
|
||||||
t = tok;
|
|
||||||
next();
|
|
||||||
if (t == '{') {
|
|
||||||
block_level++;
|
|
||||||
} else if (t == '}') {
|
|
||||||
block_level--;
|
|
||||||
if (block_level == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tok_str_add(fn->func_str, -1);
|
|
||||||
tok_str_add(fn->func_str, 0);
|
|
||||||
dynarray_add(&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* compute text section */
|
/* compute text section */
|
||||||
cur_text_section = ad.section;
|
cur_text_section = ad.section;
|
||||||
|
|
Loading…
Reference in a new issue