History

added alignof and typeof - better sizeof support - fixed get_tok_str() for TOK_PPNUM

bellard committed 24 years ago

Commit 43f30311 parent c0180c41 file · +227 −163Browse files

Unified · Split

tcc.c+227−163
@@ -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 */
272int const_wanted; /* true if constant wanted */272int const_wanted; /* true if constant wanted */
273int nocode_wanted; /* true if no code generation wanted for an expression */
273int global_expr; /* true if compound literals must be allocated274int global_expr; /* true if compound literals must be allocated
274 globally (used during initializers parsing */275 globally (used during initializers parsing */
275int func_vt, func_vc; /* current function return type (used by276int 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 256491#define TOK_IDENT 256
491 492
492enum {493enum {
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 DEF497#undef DEF
553};498};
554 499
555char *tcc_keywords = 500static 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 DEF503#undef DEF
568;504;
569 505
506#define TOK_UIDENT TOK_DEFINE
507
570#ifdef WIN32508#ifdef WIN32
571#define snprintf _snprintf509#define snprintf _snprintf
572#endif510#endif
@@ -590,13 +528,16 @@ extern long double strtold (const char *__nptr, char **__endptr); · 17 unmodified lines
590static char *pstrcpy(char *buf, int buf_size, const char *s);528static char *pstrcpy(char *buf, int buf_size, const char *s);
591static char *pstrcat(char *buf, int buf_size, const char *s);529static char *pstrcat(char *buf, int buf_size, const char *s);
592 530
593void sum(int l);531static void sum(int l);
594void next(void);532static void next(void);
595void next_nomacro(void);533static void next_nomacro(void);
534static int parse_expr_type(void);
535static int expr_type(void);
536static int unary_type(void);
596static int expr_const(void);537static int expr_const(void);
597void expr_eq(void);538static void expr_eq(void);
598void gexpr(void);539static void gexpr(void);
599void decl(int l);540static void decl(int l);
600static void decl_initializer(int t, Section *sec, unsigned long c, 541static void decl_initializer(int t, Section *sec, unsigned long c,
601 int first, int size_only);542 int first, int size_only);
602static void decl_initializer_alloc(int t, AttributeDef *ad, int r, 543static 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 from2697/* return next token without macro substitution. Can read input from
2756 macro_ptr buffer */2698 macro_ptr buffer */
2757void next_nomacro()2699static 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 */
2775int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)2717static 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 */
3133void next(void)3075static 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_I3863613#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 } else3617 } else
3676#endif3618#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#endif4758#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 */
5368static 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
5400void unary(void)5383static 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 } else5512 } 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_PARAMS5611#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
5736void uneq(void)5719static 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
5759void sum(int l)5742static 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 */
5787void eand(void)5770static 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
5807void eor(void)5790static 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 */
5828void expr_eq(void)5811static 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
5928void gexpr(void)5911static 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. */
5923static 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. */
5938static 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. */
5940static void expr_const1(void)5952static 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, otherwise5973/* return the label token if current token is a label, otherwise
5962 return zero */5974 return zero */
5963int is_label(void)5975static 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
5988void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)6000static 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#endif6832#endif
6821 6833
6834/* parse an old style function declaration list */
6835/* XXX: check multiple parameter */
6836static 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 */
6823void decl(int l)6879static 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#endif6914#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_VARS6924#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
7393TCCState *tcc_new(void)7457TCCState *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));