Unified · Split
| @@ -270,6 +270,7 @@ int rsym, anon_sym, · 269 unmodified lines | |||
| 270 | prog, ind, loc; | 270 | prog, ind, loc; |
| 271 | /* expression generation modifiers */ | 271 | /* expression generation modifiers */ |
| 272 | int const_wanted; /* true if constant wanted */ | 272 | int const_wanted; /* true if constant wanted */ |
| 273 | int nocode_wanted; /* true if no code generation wanted for an expression */ | ||
| 273 | int global_expr; /* true if compound literals must be allocated | 274 | int global_expr; /* true if compound literals must be allocated |
| 274 | globally (used during initializers parsing */ | 275 | globally (used during initializers parsing */ |
| 275 | int func_vt, func_vc; /* current function return type (used by | 276 | int func_vt, func_vc; /* current function return type (used by |
| @@ -490,83 +491,20 @@ static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224< · 214 unmodified lines | |||
| 490 | #define TOK_IDENT 256 | 491 | #define TOK_IDENT 256 |
| 491 | 492 | ||
| 492 | enum { | 493 | enum { |
| 493 | TOK_INT = TOK_IDENT, | 494 | TOK_LAST = TOK_IDENT - 1, |
| 494 | TOK_VOID, | ||
| 495 | TOK_CHAR, | ||
| 496 | TOK_IF, | ||
| 497 | TOK_ELSE, | ||
| 498 | TOK_WHILE, | ||
| 499 | TOK_BREAK, | ||
| 500 | TOK_RETURN, | ||
| 501 | TOK_FOR, | ||
| 502 | TOK_EXTERN, | ||
| 503 | TOK_STATIC, | ||
| 504 | TOK_UNSIGNED, | ||
| 505 | TOK_GOTO, | ||
| 506 | TOK_DO, | ||
| 507 | TOK_CONTINUE, | ||
| 508 | TOK_SWITCH, | ||
| 509 | TOK_CASE, | ||
| 510 | |||
| 511 | /* ignored types Must have contiguous values */ | ||
| 512 | TOK_CONST, | ||
| 513 | TOK_VOLATILE, | ||
| 514 | TOK_LONG, | ||
| 515 | TOK_REGISTER, | ||
| 516 | TOK_SIGNED, | ||
| 517 | TOK___SIGNED__, /* gcc keyword */ | ||
| 518 | TOK_AUTO, | ||
| 519 | TOK_INLINE, | ||
| 520 | TOK___INLINE__, /* gcc keyword */ | ||
| 521 | TOK_RESTRICT, | ||
| 522 | |||
| 523 | /* unsupported type */ | ||
| 524 | TOK_FLOAT, | ||
| 525 | TOK_DOUBLE, | ||
| 526 | TOK_BOOL, | ||
| 527 | |||
| 528 | TOK_SHORT, | ||
| 529 | TOK_STRUCT, | ||
| 530 | TOK_UNION, | ||
| 531 | TOK_TYPEDEF, | ||
| 532 | TOK_DEFAULT, | ||
| 533 | TOK_ENUM, | ||
| 534 | TOK_SIZEOF, | ||
| 535 | TOK___ATTRIBUTE__, | ||
| 536 | |||
| 537 | /* preprocessor only */ | ||
| 538 | TOK_UIDENT, /* first "user" ident (not keyword) */ | ||
| 539 | TOK_DEFINE = TOK_UIDENT, | ||
| 540 | TOK_INCLUDE, | ||
| 541 | TOK_IFDEF, | ||
| 542 | TOK_IFNDEF, | ||
| 543 | TOK_ELIF, | ||
| 544 | TOK_ENDIF, | ||
| 545 | TOK_DEFINED, | ||
| 546 | TOK_UNDEF, | ||
| 547 | TOK_ERROR, | ||
| 548 | TOK_LINE, | ||
| 549 | |||
| 550 | #define DEF(id, str) id, | 495 | #define DEF(id, str) id, |
| 551 | #include "tcctok.h" | 496 | #include "tcctok.h" |
| 552 | #undef DEF | 497 | #undef DEF |
| 553 | }; | 498 | }; |
| 554 | 499 | ||
| 555 | char *tcc_keywords = | 500 | static const char *tcc_keywords = |
| 556 | "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0" | ||
| 557 | "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0" | ||
| 558 | "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0" | ||
| 559 | "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0" | ||
| 560 | "sizeof\0__attribute__\0" | ||
| 561 | /* the following are not keywords. They are included to ease parsing */ | ||
| 562 | "define\0include\0ifdef\0ifndef\0elif\0endif\0" | ||
| 563 | "defined\0undef\0error\0line\0" | ||
| 564 | /* builtin functions */ | ||
| 565 | #define DEF(id, str) str "\0" | 501 | #define DEF(id, str) str "\0" |
| 566 | #include "tcctok.h" | 502 | #include "tcctok.h" |
| 567 | #undef DEF | 503 | #undef DEF |
| 568 | ; | 504 | ; |
| 569 | 505 | ||
| 506 | #define TOK_UIDENT TOK_DEFINE | ||
| 507 | |||
| 570 | #ifdef WIN32 | 508 | #ifdef WIN32 |
| 571 | #define snprintf _snprintf | 509 | #define snprintf _snprintf |
| 572 | #endif | 510 | #endif |
| @@ -590,13 +528,16 @@ extern long double strtold (const char *__nptr, char **__endptr); · 17 unmodified lines | |||
| 590 | static char *pstrcpy(char *buf, int buf_size, const char *s); | 528 | static char *pstrcpy(char *buf, int buf_size, const char *s); |
| 591 | static char *pstrcat(char *buf, int buf_size, const char *s); | 529 | static char *pstrcat(char *buf, int buf_size, const char *s); |
| 592 | 530 | ||
| 593 | void sum(int l); | 531 | static void sum(int l); |
| 594 | void next(void); | 532 | static void next(void); |
| 595 | void next_nomacro(void); | 533 | static void next_nomacro(void); |
| 534 | static int parse_expr_type(void); | ||
| 535 | static int expr_type(void); | ||
| 536 | static int unary_type(void); | ||
| 596 | static int expr_const(void); | 537 | static int expr_const(void); |
| 597 | void expr_eq(void); | 538 | static void expr_eq(void); |
| 598 | void gexpr(void); | 539 | static void gexpr(void); |
| 599 | void decl(int l); | 540 | static void decl(int l); |
| 600 | static void decl_initializer(int t, Section *sec, unsigned long c, | 541 | static void decl_initializer(int t, Section *sec, unsigned long c, |
| 601 | int first, int size_only); | 542 | int first, int size_only); |
| 602 | static void decl_initializer_alloc(int t, AttributeDef *ad, int r, | 543 | static void decl_initializer_alloc(int t, AttributeDef *ad, int r, |
| @@ -1301,12 +1242,12 @@ char *get_tok_str(int v, CValue *cv) · 698 unmodified lines | |||
| 1301 | switch(v) { | 1242 | switch(v) { |
| 1302 | case TOK_CINT: | 1243 | case TOK_CINT: |
| 1303 | case TOK_CUINT: | 1244 | case TOK_CUINT: |
| 1304 | /* XXX: not quite exact, but useful for ## in macros */ | 1245 | /* XXX: not quite exact, but only useful for testing */ |
| 1305 | sprintf(p, "%u", cv->ui); | 1246 | sprintf(p, "%u", cv->ui); |
| 1306 | break; | 1247 | break; |
| 1307 | case TOK_CLLONG: | 1248 | case TOK_CLLONG: |
| 1308 | case TOK_CULLONG: | 1249 | case TOK_CULLONG: |
| 1309 | /* XXX: not quite exact, but useful for ## in macros */ | 1250 | /* XXX: not quite exact, but only useful for testing */ |
| 1310 | sprintf(p, "%Lu", cv->ull); | 1251 | sprintf(p, "%Lu", cv->ull); |
| 1311 | break; | 1252 | break; |
| 1312 | case TOK_CCHAR: | 1253 | case TOK_CCHAR: |
| @@ -1321,6 +1262,7 @@ char *get_tok_str(int v, CValue *cv) · 8 unmodified lines | |||
| 1321 | len = cstr->size - 1; | 1262 | len = cstr->size - 1; |
| 1322 | for(i=0;i<len;i++) | 1263 | for(i=0;i<len;i++) |
| 1323 | add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]); | 1264 | add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]); |
| 1265 | cstr_ccat(&cstr_buf, '\0'); | ||
| 1324 | break; | 1266 | break; |
| 1325 | case TOK_STR: | 1267 | case TOK_STR: |
| 1326 | case TOK_LSTR: | 1268 | case TOK_LSTR: |
| @@ -2754,7 +2696,7 @@ static inline void next_nomacro1(void) · 1427 unmodified lines | |||
| 2754 | 2696 | ||
| 2755 | /* return next token without macro substitution. Can read input from | 2697 | /* return next token without macro substitution. Can read input from |
| 2756 | macro_ptr buffer */ | 2698 | macro_ptr buffer */ |
| 2757 | void next_nomacro() | 2699 | static void next_nomacro(void) |
| 2758 | { | 2700 | { |
| 2759 | if (macro_ptr) { | 2701 | if (macro_ptr) { |
| 2760 | redo: | 2702 | redo: |
| @@ -2772,7 +2714,7 @@ void next_nomacro() · 11 unmodified lines | |||
| 2772 | } | 2714 | } |
| 2773 | 2715 | ||
| 2774 | /* substitute args in macro_str and return allocated string */ | 2716 | /* substitute args in macro_str and return allocated string */ |
| 2775 | int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) | 2717 | static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) |
| 2776 | { | 2718 | { |
| 2777 | int *st, last_tok, t, notfirst; | 2719 | int *st, last_tok, t, notfirst; |
| 2778 | Sym *s; | 2720 | Sym *s; |
| @@ -2894,7 +2836,7 @@ static int *macro_twosharps(void) · 115 unmodified lines | |||
| 2894 | p2 = get_tok_str(t, &cval); | 2836 | p2 = get_tok_str(t, &cval); |
| 2895 | cstr_cat(&cstr, p2); | 2837 | cstr_cat(&cstr, p2); |
| 2896 | cstr_ccat(&cstr, '\0'); | 2838 | cstr_ccat(&cstr, '\0'); |
| 2897 | 2839 | ||
| 2898 | if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && | 2840 | if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && |
| 2899 | (t >= TOK_IDENT || t == TOK_PPNUM)) { | 2841 | (t >= TOK_IDENT || t == TOK_PPNUM)) { |
| 2900 | if (tok == TOK_PPNUM) { | 2842 | if (tok == TOK_PPNUM) { |
| @@ -3130,7 +3072,7 @@ static void macro_subst(TokenString *tok_str, · 229 unmodified lines | |||
| 3130 | } | 3072 | } |
| 3131 | 3073 | ||
| 3132 | /* return next token with macro substitution */ | 3074 | /* return next token with macro substitution */ |
| 3133 | void next(void) | 3075 | static void next(void) |
| 3134 | { | 3076 | { |
| 3135 | Sym *nested_list, *s; | 3077 | Sym *nested_list, *s; |
| 3136 | TokenString str; | 3078 | TokenString str; |
| @@ -3670,7 +3612,7 @@ void vpop(void) · 533 unmodified lines | |||
| 3670 | v = vtop->r & VT_VALMASK; | 3612 | v = vtop->r & VT_VALMASK; |
| 3671 | #ifdef TCC_TARGET_I386 | 3613 | #ifdef TCC_TARGET_I386 |
| 3672 | /* for x86, we need to pop the FP stack */ | 3614 | /* for x86, we need to pop the FP stack */ |
| 3673 | if (v == REG_ST0) { | 3615 | if (v == REG_ST0 && !nocode_wanted) { |
| 3674 | o(0xd9dd); /* fstp %st(1) */ | 3616 | o(0xd9dd); /* fstp %st(1) */ |
| 3675 | } else | 3617 | } else |
| 3676 | #endif | 3618 | #endif |
| @@ -4045,8 +3987,12 @@ void gen_opic(int op) · 368 unmodified lines | |||
| 4045 | vtop->c.i += fc; | 3987 | vtop->c.i += fc; |
| 4046 | } else { | 3988 | } else { |
| 4047 | general_case: | 3989 | general_case: |
| 4048 | /* call low level op generator */ | 3990 | if (!nocode_wanted) { |
| 4049 | gen_opi(op); | 3991 | /* call low level op generator */ |
| 3992 | gen_opi(op); | ||
| 3993 | } else { | ||
| 3994 | vtop--; | ||
| 3995 | } | ||
| 4050 | } | 3996 | } |
| 4051 | } | 3997 | } |
| 4052 | } | 3998 | } |
| @@ -4107,7 +4053,11 @@ void gen_opif(int op) · 54 unmodified lines | |||
| 4107 | vtop--; | 4053 | vtop--; |
| 4108 | } else { | 4054 | } else { |
| 4109 | general_case: | 4055 | general_case: |
| 4110 | gen_opf(op); | 4056 | if (!nocode_wanted) { |
| 4057 | gen_opf(op); | ||
| 4058 | } else { | ||
| 4059 | vtop--; | ||
| 4060 | } | ||
| 4111 | } | 4061 | } |
| 4112 | } | 4062 | } |
| 4113 | 4063 | ||
| @@ -4355,7 +4305,7 @@ void gen_cast(int t) · 241 unmodified lines | |||
| 4355 | dbt = t & (VT_BTYPE | VT_UNSIGNED); | 4305 | dbt = t & (VT_BTYPE | VT_UNSIGNED); |
| 4356 | sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED); | 4306 | sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED); |
| 4357 | 4307 | ||
| 4358 | if (sbt != dbt) { | 4308 | if (sbt != dbt && !nocode_wanted) { |
| 4359 | sf = is_float(sbt); | 4309 | sf = is_float(sbt); |
| 4360 | df = is_float(dbt); | 4310 | df = is_float(dbt); |
| 4361 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; | 4311 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| @@ -4749,25 +4699,30 @@ void vstore(void) · 387 unmodified lines | |||
| 4749 | /* if structure, only generate pointer */ | 4699 | /* if structure, only generate pointer */ |
| 4750 | /* structure assignment : generate memcpy */ | 4700 | /* structure assignment : generate memcpy */ |
| 4751 | /* XXX: optimize if small size */ | 4701 | /* XXX: optimize if small size */ |
| 4752 | vdup(); | 4702 | if (!nocode_wanted) { |
| 4753 | gfunc_start(&gf, FUNC_CDECL); | 4703 | vdup(); |
| 4754 | /* type size */ | 4704 | gfunc_start(&gf, FUNC_CDECL); |
| 4755 | size = type_size(vtop->t, &align); | 4705 | /* type size */ |
| 4756 | vpushi(size); | 4706 | size = type_size(vtop->t, &align); |
| 4757 | gfunc_param(&gf); | 4707 | vpushi(size); |
| 4758 | /* source */ | 4708 | gfunc_param(&gf); |
| 4759 | vtop->t = VT_INT; | 4709 | /* source */ |
| 4760 | gaddrof(); | 4710 | vtop->t = VT_INT; |
| 4761 | gfunc_param(&gf); | 4711 | gaddrof(); |
| 4762 | /* destination */ | 4712 | gfunc_param(&gf); |
| 4763 | vswap(); | 4713 | /* destination */ |
| 4764 | vtop->t = VT_INT; | 4714 | vswap(); |
| 4765 | gaddrof(); | 4715 | vtop->t = VT_INT; |
| 4766 | gfunc_param(&gf); | 4716 | gaddrof(); |
| 4767 | 4717 | gfunc_param(&gf); | |
| 4768 | save_regs(0); | 4718 | |
| 4769 | vpush_global_sym(func_old_type, TOK_memcpy); | 4719 | save_regs(0); |
| 4770 | gfunc_call(&gf); | 4720 | vpush_global_sym(func_old_type, TOK_memcpy); |
| 4721 | gfunc_call(&gf); | ||
| 4722 | } else { | ||
| 4723 | vswap(); | ||
| 4724 | vpop(); | ||
| 4725 | } | ||
| 4771 | /* leave source on stack */ | 4726 | /* leave source on stack */ |
| 4772 | } else if (ft & VT_BITFIELD) { | 4727 | } else if (ft & VT_BITFIELD) { |
| 4773 | /* bitfield store handling */ | 4728 | /* bitfield store handling */ |
| @@ -4801,33 +4756,35 @@ void vstore(void) · 27 unmodified lines | |||
| 4801 | vswap(); | 4756 | vswap(); |
| 4802 | } | 4757 | } |
| 4803 | #endif | 4758 | #endif |
| 4804 | rc = RC_INT; | 4759 | if (!nocode_wanted) { |
| 4805 | if (is_float(ft)) | 4760 | rc = RC_INT; |
| 4806 | rc = RC_FLOAT; | 4761 | if (is_float(ft)) |
| 4807 | r = gv(rc); /* generate value */ | 4762 | rc = RC_FLOAT; |
| 4808 | /* if lvalue was saved on stack, must read it */ | 4763 | r = gv(rc); /* generate value */ |
| 4809 | if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) { | 4764 | /* if lvalue was saved on stack, must read it */ |
| 4810 | SValue sv; | 4765 | if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) { |
| 4811 | t = get_reg(RC_INT); | 4766 | SValue sv; |
| 4812 | sv.t = VT_INT; | 4767 | t = get_reg(RC_INT); |
| 4813 | sv.r = VT_LOCAL | VT_LVAL; | 4768 | sv.t = VT_INT; |
| 4814 | sv.c.ul = vtop[-1].c.ul; | 4769 | sv.r = VT_LOCAL | VT_LVAL; |
| 4815 | load(t, &sv); | 4770 | sv.c.ul = vtop[-1].c.ul; |
| 4816 | vtop[-1].r = t | VT_LVAL; | 4771 | load(t, &sv); |
| 4817 | } | 4772 | vtop[-1].r = t | VT_LVAL; |
| 4818 | store(r, vtop - 1); | 4773 | } |
| 4819 | /* two word case handling : store second register at word + 4 */ | 4774 | store(r, vtop - 1); |
| 4820 | if ((ft & VT_BTYPE) == VT_LLONG) { | 4775 | /* two word case handling : store second register at word + 4 */ |
| 4821 | vswap(); | 4776 | if ((ft & VT_BTYPE) == VT_LLONG) { |
| 4822 | /* convert to int to increment easily */ | 4777 | vswap(); |
| 4823 | vtop->t = VT_INT; | 4778 | /* convert to int to increment easily */ |
| 4824 | gaddrof(); | 4779 | vtop->t = VT_INT; |
| 4825 | vpushi(4); | 4780 | gaddrof(); |
| 4826 | gen_op('+'); | 4781 | vpushi(4); |
| 4827 | vtop->r |= VT_LVAL; | 4782 | gen_op('+'); |
| 4828 | vswap(); | 4783 | vtop->r |= VT_LVAL; |
| 4829 | /* XXX: it works because r2 is spilled last ! */ | 4784 | vswap(); |
| 4830 | store(vtop->r2, vtop - 1); | 4785 | /* XXX: it works because r2 is spilled last ! */ |
| 4786 | store(vtop->r2, vtop - 1); | ||
| 4787 | } | ||
| 4831 | } | 4788 | } |
| 4832 | vswap(); | 4789 | vswap(); |
| 4833 | vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ | 4790 | vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ |
| @@ -5188,6 +5145,11 @@ int parse_btype(int *type_ptr, AttributeDef *ad) · 354 unmodified lines | |||
| 5188 | case TOK___ATTRIBUTE__: | 5145 | case TOK___ATTRIBUTE__: |
| 5189 | parse_attribute(ad); | 5146 | parse_attribute(ad); |
| 5190 | break; | 5147 | break; |
| 5148 | /* GNUC typeof */ | ||
| 5149 | case TOK_TYPEOF: | ||
| 5150 | next(); | ||
| 5151 | u = parse_expr_type(); | ||
| 5152 | goto basic_type1; | ||
| 5191 | default: | 5153 | default: |
| 5192 | s = sym_find(tok); | 5154 | s = sym_find(tok); |
| 5193 | if (!s || !(s->t & VT_TYPEDEF)) | 5155 | if (!s || !(s->t & VT_TYPEDEF)) |
| @@ -5367,7 +5329,7 @@ static void indir(void) · 173 unmodified lines | |||
| 5367 | { | 5329 | { |
| 5368 | if ((vtop->t & VT_BTYPE) != VT_PTR) | 5330 | if ((vtop->t & VT_BTYPE) != VT_PTR) |
| 5369 | expect("pointer"); | 5331 | expect("pointer"); |
| 5370 | if (vtop->r & VT_LVAL) | 5332 | if ((vtop->r & VT_LVAL) && !nocode_wanted) |
| 5371 | gv(RC_INT); | 5333 | gv(RC_INT); |
| 5372 | vtop->t = pointed_type(vtop->t); | 5334 | vtop->t = pointed_type(vtop->t); |
| 5373 | /* an array is never an lvalue */ | 5335 | /* an array is never an lvalue */ |
| @@ -5394,10 +5356,31 @@ void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg) · 20 unmodified lines | |||
| 5394 | } else { | 5356 | } else { |
| 5395 | gen_assign_cast(arg->t); | 5357 | gen_assign_cast(arg->t); |
| 5396 | } | 5358 | } |
| 5397 | gfunc_param(gf); | 5359 | if (!nocode_wanted) { |
| 5360 | gfunc_param(gf); | ||
| 5361 | } else { | ||
| 5362 | vpop(); | ||
| 5363 | } | ||
| 5364 | } | ||
| 5365 | |||
| 5366 | /* parse an expression of the form '(type)' or '(expr)' and return its | ||
| 5367 | type */ | ||
| 5368 | static int parse_expr_type(void) | ||
| 5369 | { | ||
| 5370 | int ft, n; | ||
| 5371 | AttributeDef ad; | ||
| 5372 | |||
| 5373 | skip('('); | ||
| 5374 | if (parse_btype(&ft, &ad)) { | ||
| 5375 | ft = type_decl(&ad, &n, ft, TYPE_ABSTRACT); | ||
| 5376 | } else { | ||
| 5377 | ft = expr_type(); | ||
| 5378 | } | ||
| 5379 | skip(')'); | ||
| 5380 | return ft; | ||
| 5398 | } | 5381 | } |
| 5399 | 5382 | ||
| 5400 | void unary(void) | 5383 | static void unary(void) |
| 5401 | { | 5384 | { |
| 5402 | int n, t, ft, align, size, r; | 5385 | int n, t, ft, align, size, r; |
| 5403 | Sym *s; | 5386 | Sym *s; |
| @@ -5515,25 +5498,17 @@ void unary(void) · 111 unmodified lines | |||
| 5515 | vpushi(0); | 5498 | vpushi(0); |
| 5516 | gen_op('+'); | 5499 | gen_op('+'); |
| 5517 | } else | 5500 | } else |
| 5518 | if (t == TOK_SIZEOF) { | 5501 | if (t == TOK_SIZEOF || t == TOK_ALIGNOF) { |
| 5519 | if (tok == '(') { | 5502 | if (tok == '(') { |
| 5520 | next(); | 5503 | ft = parse_expr_type(); |
| 5521 | if (parse_btype(&t, &ad)) { | ||
| 5522 | t = type_decl(&ad, &n, t, TYPE_ABSTRACT); | ||
| 5523 | } else { | ||
| 5524 | /* XXX: some code could be generated: add eval | ||
| 5525 | flag */ | ||
| 5526 | gexpr(); | ||
| 5527 | t = vtop->t; | ||
| 5528 | vpop(); | ||
| 5529 | } | ||
| 5530 | skip(')'); | ||
| 5531 | } else { | 5504 | } else { |
| 5532 | unary(); | 5505 | ft = unary_type(); |
| 5533 | t = vtop->t; | ||
| 5534 | vpop(); | ||
| 5535 | } | 5506 | } |
| 5536 | vpushi(type_size(t, &t)); | 5507 | size = type_size(ft, &align); |
| 5508 | if (t == TOK_SIZEOF) | ||
| 5509 | vpushi(size); | ||
| 5510 | else | ||
| 5511 | vpushi(align); | ||
| 5537 | } else | 5512 | } else |
| 5538 | if (t == TOK_INC || t == TOK_DEC) { | 5513 | if (t == TOK_INC || t == TOK_DEC) { |
| 5539 | unary(); | 5514 | unary(); |
| @@ -5627,8 +5602,10 @@ void unary(void) · 87 unmodified lines | |||
| 5627 | } | 5602 | } |
| 5628 | /* get return type */ | 5603 | /* get return type */ |
| 5629 | s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT); | 5604 | s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT); |
| 5630 | save_regs(0); /* save used temporary registers */ | 5605 | if (!nocode_wanted) { |
| 5631 | gfunc_start(&gf, s->r); | 5606 | save_regs(0); /* save used temporary registers */ |
| 5607 | gfunc_start(&gf, s->r); | ||
| 5608 | } | ||
| 5632 | next(); | 5609 | next(); |
| 5633 | sa = s->next; /* first parameter */ | 5610 | sa = s->next; /* first parameter */ |
| 5634 | #ifdef INVERT_FUNC_PARAMS | 5611 | #ifdef INVERT_FUNC_PARAMS |
| @@ -5693,7 +5670,10 @@ void unary(void) · 58 unmodified lines | |||
| 5693 | problems */ | 5670 | problems */ |
| 5694 | vset(VT_INT, VT_LOCAL, loc); | 5671 | vset(VT_INT, VT_LOCAL, loc); |
| 5695 | ret.c = vtop->c; | 5672 | ret.c = vtop->c; |
| 5696 | gfunc_param(&gf); | 5673 | if (!nocode_wanted) |
| 5674 | gfunc_param(&gf); | ||
| 5675 | else | ||
| 5676 | vtop--; | ||
| 5697 | } else { | 5677 | } else { |
| 5698 | ret.t = s->t; | 5678 | ret.t = s->t; |
| 5699 | ret.r2 = VT_CONST; | 5679 | ret.r2 = VT_CONST; |
| @@ -5723,7 +5703,10 @@ void unary(void) · 23 unmodified lines | |||
| 5723 | if (sa) | 5703 | if (sa) |
| 5724 | error("too few arguments to function"); | 5704 | error("too few arguments to function"); |
| 5725 | skip(')'); | 5705 | skip(')'); |
| 5726 | gfunc_call(&gf); | 5706 | if (!nocode_wanted) |
| 5707 | gfunc_call(&gf); | ||
| 5708 | else | ||
| 5709 | vtop--; | ||
| 5727 | /* return value */ | 5710 | /* return value */ |
| 5728 | vsetc(ret.t, ret.r, &ret.c); | 5711 | vsetc(ret.t, ret.r, &ret.c); |
| 5729 | vtop->r2 = ret.r2; | 5712 | vtop->r2 = ret.r2; |
| @@ -5733,7 +5716,7 @@ void unary(void) · 3 unmodified lines | |||
| 5733 | } | 5716 | } |
| 5734 | } | 5717 | } |
| 5735 | 5718 | ||
| 5736 | void uneq(void) | 5719 | static void uneq(void) |
| 5737 | { | 5720 | { |
| 5738 | int t; | 5721 | int t; |
| 5739 | 5722 | ||
| @@ -5756,7 +5739,7 @@ void uneq(void) · 16 unmodified lines | |||
| 5756 | } | 5739 | } |
| 5757 | } | 5740 | } |
| 5758 | 5741 | ||
| 5759 | void sum(int l) | 5742 | static void sum(int l) |
| 5760 | { | 5743 | { |
| 5761 | int t; | 5744 | int t; |
| 5762 | 5745 | ||
| @@ -5784,7 +5767,7 @@ void sum(int l) · 21 unmodified lines | |||
| 5784 | } | 5767 | } |
| 5785 | 5768 | ||
| 5786 | /* only used if non constant */ | 5769 | /* only used if non constant */ |
| 5787 | void eand(void) | 5770 | static void eand(void) |
| 5788 | { | 5771 | { |
| 5789 | int t; | 5772 | int t; |
| 5790 | 5773 | ||
| @@ -5804,7 +5787,7 @@ void eand(void) · 13 unmodified lines | |||
| 5804 | } | 5787 | } |
| 5805 | } | 5788 | } |
| 5806 | 5789 | ||
| 5807 | void eor(void) | 5790 | static void eor(void) |
| 5808 | { | 5791 | { |
| 5809 | int t; | 5792 | int t; |
| 5810 | 5793 | ||
| @@ -5825,7 +5808,7 @@ void eor(void) · 14 unmodified lines | |||
| 5825 | } | 5808 | } |
| 5826 | 5809 | ||
| 5827 | /* XXX: better constant handling */ | 5810 | /* XXX: better constant handling */ |
| 5828 | void expr_eq(void) | 5811 | static void expr_eq(void) |
| 5829 | { | 5812 | { |
| 5830 | int tt, u, r1, r2, rc, t1, t2, t, bt1, bt2; | 5813 | int tt, u, r1, r2, rc, t1, t2, t, bt1, bt2; |
| 5831 | SValue sv; | 5814 | SValue sv; |
| @@ -5925,7 +5908,7 @@ void expr_eq(void) · 93 unmodified lines | |||
| 5925 | } | 5908 | } |
| 5926 | } | 5909 | } |
| 5927 | 5910 | ||
| 5928 | void gexpr(void) | 5911 | static void gexpr(void) |
| 5929 | { | 5912 | { |
| 5930 | while (1) { | 5913 | while (1) { |
| 5931 | expr_eq(); | 5914 | expr_eq(); |
| @@ -5936,6 +5919,35 @@ void gexpr(void) · 4 unmodified lines | |||
| 5936 | } | 5919 | } |
| 5937 | } | 5920 | } |
| 5938 | 5921 | ||
| 5922 | /* parse an expression and return its type without any side effect. */ | ||
| 5923 | static int expr_type(void) | ||
| 5924 | { | ||
| 5925 | int a, t; | ||
| 5926 | |||
| 5927 | a = nocode_wanted; | ||
| 5928 | nocode_wanted = 1; | ||
| 5929 | gexpr(); | ||
| 5930 | t = vtop->t; | ||
| 5931 | vpop(); | ||
| 5932 | nocode_wanted = a; | ||
| 5933 | return t; | ||
| 5934 | } | ||
| 5935 | |||
| 5936 | /* parse a unary expression and return its type without any side | ||
| 5937 | effect. */ | ||
| 5938 | static int unary_type(void) | ||
| 5939 | { | ||
| 5940 | int a, t; | ||
| 5941 | |||
| 5942 | a = nocode_wanted; | ||
| 5943 | nocode_wanted = 1; | ||
| 5944 | unary(); | ||
| 5945 | t = vtop->t; | ||
| 5946 | vpop(); | ||
| 5947 | nocode_wanted = a; | ||
| 5948 | return t; | ||
| 5949 | } | ||
| 5950 | |||
| 5939 | /* parse a constant expression and return value in vtop. */ | 5951 | /* parse a constant expression and return value in vtop. */ |
| 5940 | static void expr_const1(void) | 5952 | static void expr_const1(void) |
| 5941 | { | 5953 | { |
| @@ -5960,7 +5972,7 @@ static int expr_const(void) · 18 unmodified lines | |||
| 5960 | 5972 | ||
| 5961 | /* return the label token if current token is a label, otherwise | 5973 | /* return the label token if current token is a label, otherwise |
| 5962 | return zero */ | 5974 | return zero */ |
| 5963 | int is_label(void) | 5975 | static int is_label(void) |
| 5964 | { | 5976 | { |
| 5965 | int t; | 5977 | int t; |
| 5966 | CValue c; | 5978 | CValue c; |
| @@ -5985,7 +5997,7 @@ int is_label(void) · 18 unmodified lines | |||
| 5985 | } | 5997 | } |
| 5986 | } | 5998 | } |
| 5987 | 5999 | ||
| 5988 | void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg) | 6000 | static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg) |
| 5989 | { | 6001 | { |
| 5990 | int a, b, c, d; | 6002 | int a, b, c, d; |
| 5991 | Sym *s; | 6003 | Sym *s; |
| @@ -6819,8 +6831,52 @@ void analyse_function(void) · 827 unmodified lines | |||
| 6819 | } | 6831 | } |
| 6820 | #endif | 6832 | #endif |
| 6821 | 6833 | ||
| 6834 | /* parse an old style function declaration list */ | ||
| 6835 | /* XXX: check multiple parameter */ | ||
| 6836 | static void func_decl_list(Sym *func_sym) | ||
| 6837 | { | ||
| 6838 | AttributeDef ad; | ||
| 6839 | int b, v, t; | ||
| 6840 | Sym *s; | ||
| 6841 | /* parse each declaration */ | ||
| 6842 | while (tok != '{' && tok != ';' && tok != TOK_EOF) { | ||
| 6843 | if (!parse_btype(&b, &ad)) | ||
| 6844 | expect("declaration list"); | ||
| 6845 | if (((b & VT_BTYPE) == VT_ENUM || | ||
| 6846 | (b & VT_BTYPE) == VT_STRUCT) && | ||
| 6847 | tok == ';') { | ||
| 6848 | /* we accept no variable after */ | ||
| 6849 | } else { | ||
| 6850 | for(;;) { | ||
| 6851 | t = type_decl(&ad, &v, b, TYPE_DIRECT); | ||
| 6852 | /* find parameter in function parameter list */ | ||
| 6853 | s = func_sym->next; | ||
| 6854 | while (s != NULL) { | ||
| 6855 | if ((s->v & ~SYM_FIELD) == v) | ||
| 6856 | goto found; | ||
| 6857 | s = s->next; | ||
| 6858 | } | ||
| 6859 | error("declaration for parameter '%s' but no such parameter", | ||
| 6860 | get_tok_str(v, NULL)); | ||
| 6861 | found: | ||
| 6862 | /* check that no storage specifier except 'register' was given */ | ||
| 6863 | if (t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF)) | ||
| 6864 | error("storage class specified for '%s'", get_tok_str(v, NULL)); | ||
| 6865 | /* we can add the type (NOTE: it could be local to the function) */ | ||
| 6866 | s->t = t; | ||
| 6867 | /* accept other parameters */ | ||
| 6868 | if (tok == ',') | ||
| 6869 | next(); | ||
| 6870 | else | ||
| 6871 | break; | ||
| 6872 | } | ||
| 6873 | } | ||
| 6874 | skip(';'); | ||
| 6875 | } | ||
| 6876 | } | ||
| 6877 | |||
| 6822 | /* 'l' is VT_LOCAL or VT_CONST to define default storage type */ | 6878 | /* 'l' is VT_LOCAL or VT_CONST to define default storage type */ |
| 6823 | void decl(int l) | 6879 | static void decl(int l) |
| 6824 | { | 6880 | { |
| 6825 | int t, b, v, has_init, r; | 6881 | int t, b, v, has_init, r; |
| 6826 | Sym *sym; | 6882 | Sym *sym; |
| @@ -6856,6 +6912,14 @@ void decl(int l) · 29 unmodified lines | |||
| 6856 | printf("type = '%s'\n", buf); | 6912 | printf("type = '%s'\n", buf); |
| 6857 | } | 6913 | } |
| 6858 | #endif | 6914 | #endif |
| 6915 | if ((t & VT_BTYPE) == VT_FUNC) { | ||
| 6916 | /* if old style function prototype, we accept a | ||
| 6917 | declaration list */ | ||
| 6918 | sym = sym_find(((unsigned)t >> VT_STRUCT_SHIFT)); | ||
| 6919 | if (sym->c == FUNC_OLD) | ||
| 6920 | func_decl_list(sym); | ||
| 6921 | } | ||
| 6922 | |||
| 6859 | if (tok == '{') { | 6923 | if (tok == '{') { |
| 6860 | #ifdef CONFIG_REG_VARS | 6924 | #ifdef CONFIG_REG_VARS |
| 6861 | TokenString func_str; | 6925 | TokenString func_str; |
| @@ -7392,7 +7456,7 @@ int tcc_run(TCCState *s1, int argc, char **argv) · 530 unmodified lines | |||
| 7392 | 7456 | ||
| 7393 | TCCState *tcc_new(void) | 7457 | TCCState *tcc_new(void) |
| 7394 | { | 7458 | { |
| 7395 | char *p, *r; | 7459 | const char *p, *r; |
| 7396 | TCCState *s; | 7460 | TCCState *s; |
| 7397 | 7461 | ||
| 7398 | s = tcc_mallocz(sizeof(TCCState)); | 7462 | s = tcc_mallocz(sizeof(TCCState)); |