Three places that skip (and store) tokens in some fashion can be factored a bit.
Unified · Split
| @@ -5902,6 +5902,42 @@ static void block(int *bsym, int *csym, int is_expr) · 5901 unmodified lines | |||
| 5902 | } | 5902 | } |
| 5903 | } | 5903 | } |
| 5904 | 5904 | ||
| 5905 | /* This skips over a stream of tokens containing balanced {} and () | ||
| 5906 | pairs, stopping at outer ',' ';' and '}'. If STR then allocates | ||
| 5907 | and stores the skipped tokens in *STR. This doesn't check if | ||
| 5908 | () and {} are nested correctly, i.e. "({)}" is accepted. */ | ||
| 5909 | static void skip_or_save_block(TokenString **str) | ||
| 5910 | { | ||
| 5911 | int level = 0; | ||
| 5912 | if (str) | ||
| 5913 | *str = tok_str_alloc(); | ||
| 5914 | |||
| 5915 | while ((level > 0 || (tok != '}' && tok != ',' && tok != ';'))) { | ||
| 5916 | int t; | ||
| 5917 | if (tok == TOK_EOF) { | ||
| 5918 | if (str || level > 0) | ||
| 5919 | tcc_error("unexpected end of file"); | ||
| 5920 | else | ||
| 5921 | break; | ||
| 5922 | } | ||
| 5923 | if (str) | ||
| 5924 | tok_str_add_tok(*str); | ||
| 5925 | t = tok; | ||
| 5926 | next(); | ||
| 5927 | if (t == '{' || t == '(') { | ||
| 5928 | level++; | ||
| 5929 | } else if (t == '}' || t == ')') { | ||
| 5930 | level--; | ||
| 5931 | if (level == 0) | ||
| 5932 | break; | ||
| 5933 | } | ||
| 5934 | } | ||
| 5935 | if (str) { | ||
| 5936 | tok_str_add(*str, -1); | ||
| 5937 | tok_str_add(*str, 0); | ||
| 5938 | } | ||
| 5939 | } | ||
| 5940 | |||
| 5905 | #define EXPR_CONST 1 | 5941 | #define EXPR_CONST 1 |
| 5906 | #define EXPR_ANY 2 | 5942 | #define EXPR_ANY 2 |
| 5907 | 5943 | ||
| @@ -6256,7 +6292,7 @@ static void init_putz(Section *sec, unsigned long c, int size) · 348 unmodified lines | |||
| 6256 | static void decl_initializer(CType *type, Section *sec, unsigned long c, | 6292 | static void decl_initializer(CType *type, Section *sec, unsigned long c, |
| 6257 | int first, int size_only) | 6293 | int first, int size_only) |
| 6258 | { | 6294 | { |
| 6259 | int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; | 6295 | int index, array_length, n, no_oblock, nb, i; |
| 6260 | int size1, align1; | 6296 | int size1, align1; |
| 6261 | int have_elem; | 6297 | int have_elem; |
| 6262 | Sym *s, *f; | 6298 | Sym *s, *f; |
| @@ -6429,25 +6465,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 166 unmodified lines | |||
| 6429 | But GNU C supports it, so we need to recurse even into | 6465 | But GNU C supports it, so we need to recurse even into |
| 6430 | subfields of structs and arrays when size_only is set. */ | 6466 | subfields of structs and arrays when size_only is set. */ |
| 6431 | /* just skip expression */ | 6467 | /* just skip expression */ |
| 6432 | parlevel = parlevel1 = 0; | 6468 | do { |
| 6433 | while ((parlevel > 0 || parlevel1 > 0 || | 6469 | skip_or_save_block(NULL); |
| 6434 | (tok != '}' && tok != ',')) && tok != -1) { | 6470 | } while (tok != '}' && tok != ',' && tok != -1); |
| 6435 | if (tok == '(') | ||
| 6436 | parlevel++; | ||
| 6437 | else if (tok == ')') { | ||
| 6438 | if (parlevel == 0 && parlevel1 == 0) | ||
| 6439 | break; | ||
| 6440 | parlevel--; | ||
| 6441 | } | ||
| 6442 | else if (tok == '{') | ||
| 6443 | parlevel1++; | ||
| 6444 | else if (tok == '}') { | ||
| 6445 | if (parlevel == 0 && parlevel1 == 0) | ||
| 6446 | break; | ||
| 6447 | parlevel1--; | ||
| 6448 | } | ||
| 6449 | next(); | ||
| 6450 | } | ||
| 6451 | } else { | 6471 | } else { |
| 6452 | if (!have_elem) { | 6472 | if (!have_elem) { |
| 6453 | /* This should happen only when we haven't parsed | 6473 | /* This should happen only when we haven't parsed |
| @@ -6472,7 +6492,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 18 unmodified lines | |||
| 6472 | int has_init, int v, int scope) | 6492 | int has_init, int v, int scope) |
| 6473 | { | 6493 | { |
| 6474 | int size, align, addr, data_offset; | 6494 | int size, align, addr, data_offset; |
| 6475 | int level; | ||
| 6476 | ParseState saved_parse_state = {0}; | 6495 | ParseState saved_parse_state = {0}; |
| 6477 | TokenString *init_str = NULL; | 6496 | TokenString *init_str = NULL; |
| 6478 | Section *sec; | 6497 | Section *sec; |
| @@ -6500,33 +6519,18 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 21 unmodified lines | |||
| 6500 | if (!has_init) | 6519 | if (!has_init) |
| 6501 | tcc_error("unknown type size"); | 6520 | tcc_error("unknown type size"); |
| 6502 | /* get all init string */ | 6521 | /* get all init string */ |
| 6503 | init_str = tok_str_alloc(); | ||
| 6504 | if (has_init == 2) { | 6522 | if (has_init == 2) { |
| 6523 | init_str = tok_str_alloc(); | ||
| 6505 | /* only get strings */ | 6524 | /* only get strings */ |
| 6506 | while (tok == TOK_STR || tok == TOK_LSTR) { | 6525 | while (tok == TOK_STR || tok == TOK_LSTR) { |
| 6507 | tok_str_add_tok(init_str); | 6526 | tok_str_add_tok(init_str); |
| 6508 | next(); | 6527 | next(); |
| 6509 | } | 6528 | } |
| 6529 | tok_str_add(init_str, -1); | ||
| 6530 | tok_str_add(init_str, 0); | ||
| 6510 | } else { | 6531 | } else { |
| 6511 | level = 0; | 6532 | skip_or_save_block(&init_str); |
| 6512 | while (level > 0 || (tok != ',' && tok != ';')) { | ||
| 6513 | if (tok < 0) | ||
| 6514 | tcc_error("unexpected end of file in initializer"); | ||
| 6515 | tok_str_add_tok(init_str); | ||
| 6516 | if (tok == '{') | ||
| 6517 | level++; | ||
| 6518 | else if (tok == '}') { | ||
| 6519 | level--; | ||
| 6520 | if (level <= 0) { | ||
| 6521 | next(); | ||
| 6522 | break; | ||
| 6523 | } | ||
| 6524 | } | ||
| 6525 | next(); | ||
| 6526 | } | ||
| 6527 | } | 6533 | } |
| 6528 | tok_str_add(init_str, -1); | ||
| 6529 | tok_str_add(init_str, 0); | ||
| 6530 | 6534 | ||
| 6531 | /* compute size */ | 6535 | /* compute size */ |
| 6532 | save_parse_state(&saved_parse_state); | 6536 | save_parse_state(&saved_parse_state); |
| @@ -7029,7 +7033,6 @@ static int decl0(int l, int is_for_loop_init) · 496 unmodified lines | |||
| 7029 | the compilation unit only if they are used */ | 7033 | the compilation unit only if they are used */ |
| 7030 | if ((type.t & (VT_INLINE | VT_STATIC)) == | 7034 | if ((type.t & (VT_INLINE | VT_STATIC)) == |
| 7031 | (VT_INLINE | VT_STATIC)) { | 7035 | (VT_INLINE | VT_STATIC)) { |
| 7032 | int block_level; | ||
| 7033 | struct InlineFunc *fn; | 7036 | struct InlineFunc *fn; |
| 7034 | const char *filename; | 7037 | const char *filename; |
| 7035 | 7038 | ||
| @@ -7037,28 +7040,9 @@ static int decl0(int l, int is_for_loop_init) · 1 unmodified line | |||
| 7037 | fn = tcc_malloc(sizeof *fn + strlen(filename)); | 7040 | fn = tcc_malloc(sizeof *fn + strlen(filename)); |
| 7038 | strcpy(fn->filename, filename); | 7041 | strcpy(fn->filename, filename); |
| 7039 | fn->sym = sym; | 7042 | fn->sym = sym; |
| 7040 | fn->func_str = tok_str_alloc(); | 7043 | skip_or_save_block(&fn->func_str); |
| 7041 | 7044 | dynarray_add(&tcc_state->inline_fns, | |
| 7042 | block_level = 0; | 7045 | &tcc_state->nb_inline_fns, fn); |
| 7043 | for(;;) { | ||
| 7044 | int t; | ||
| 7045 | if (tok == TOK_EOF) | ||
| 7046 | tcc_error("unexpected end of file"); | ||
| 7047 | tok_str_add_tok(fn->func_str); | ||
| 7048 | t = tok; | ||
| 7049 | next(); | ||
| 7050 | if (t == '{') { | ||
| 7051 | block_level++; | ||
| 7052 | } else if (t == '}') { | ||
| 7053 | block_level--; | ||
| 7054 | if (block_level == 0) | ||
| 7055 | break; | ||
| 7056 | } | ||
| 7057 | } | ||
| 7058 | tok_str_add(fn->func_str, -1); | ||
| 7059 | tok_str_add(fn->func_str, 0); | ||
| 7060 | dynarray_add(&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn); | ||
| 7061 | |||
| 7062 | } else { | 7046 | } else { |
| 7063 | /* compute text section */ | 7047 | /* compute text section */ |
| 7064 | cur_text_section = ad.section; | 7048 | cur_text_section = ad.section; |