separated type and value on stack
[tinycc.git] / tcc.c
blobaec3d47358c002182068ff35f72924ea2e10498a
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <math.h>
25 #ifndef CONFIG_TCC_STATIC
26 #include <dlfcn.h>
27 #endif
29 //#define DEBUG
30 /* preprocessor debug */
31 //#define PP_DEBUG
33 /* these sizes are dummy for unix, because malloc() does not use
34 memory when the pages are not used */
35 #define TEXT_SIZE (4*1024*1024)
36 #define DATA_SIZE (4*1024*1024)
38 #define INCLUDE_STACK_SIZE 32
39 #define IFDEF_STACK_SIZE 64
40 #define VSTACK_SIZE 64
41 #define STRING_MAX_SIZE 1024
42 #define INCLUDE_PATHS_MAX 32
44 #define TOK_HASH_SIZE 521
45 #define TOK_ALLOC_INCR 256 /* must be a power of two */
46 #define SYM_HASH_SIZE 263
48 /* token symbol management */
49 typedef struct TokenSym {
50 struct TokenSym *hash_next;
51 int tok; /* token number */
52 int len;
53 char str[1];
54 } TokenSym;
56 /* constant value */
57 typedef union CValue {
58 long double ld;
59 double d;
60 float f;
61 int i;
62 unsigned int ui;
63 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
64 long long ll;
65 unsigned long long ull;
66 struct TokenSym *ts;
67 struct Sym *sym;
68 int tab[1];
69 } CValue;
71 /* value on stack */
72 typedef struct SValue {
73 int t; /* type */
74 int r; /* register + flags */
75 CValue c; /* constant */
76 } SValue;
78 /* symbol management */
79 typedef struct Sym {
80 int v; /* symbol token */
81 int t; /* associated type */
82 int c; /* associated number */
83 struct Sym *next; /* next related symbol */
84 struct Sym *prev; /* prev symbol in stack */
85 struct Sym *hash_next; /* next symbol in hash table */
86 } Sym;
88 typedef struct SymStack {
89 struct Sym *top;
90 struct Sym *hash[SYM_HASH_SIZE];
91 } SymStack;
93 /* relocation entry (currently only used for functions or variables */
94 typedef struct Reloc {
95 int type; /* type of relocation */
96 int addr; /* address of relocation */
97 struct Reloc *next; /* next relocation */
98 } Reloc;
100 #define RELOC_ADDR32 1 /* 32 bits relocation */
101 #define RELOC_REL32 2 /* 32 bits relative relocation */
104 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
105 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
106 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
108 #define FUNC_NEW 1 /* ansi function prototype */
109 #define FUNC_OLD 2 /* old function prototype */
110 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
112 /* field 'Sym.t' for macros */
113 #define MACRO_OBJ 0 /* object like macro */
114 #define MACRO_FUNC 1 /* function like macro */
116 /* type_decl() types */
117 #define TYPE_ABSTRACT 1 /* type without variable */
118 #define TYPE_DIRECT 2 /* type with variable */
120 typedef struct {
121 FILE *file;
122 char *filename;
123 int line_num;
124 } IncludeFile;
126 /* parser */
127 FILE *file;
128 int line_num;
129 int ch, ch1, tok, tok1;
130 CValue tokc, tok1c;
132 /* loc : local variable index
133 glo : global variable index
134 ind : output code ptr
135 rsym: return symbol
136 prog: output code
137 anon_sym: anonymous symbol index
139 int rsym, anon_sym,
140 prog, ind, loc, glo, const_wanted;
141 int global_expr; /* true if compound literals must be allocated
142 globally (used during initializers parsing */
143 int func_vt, func_vc; /* current function return type (used by
144 return instruction) */
145 int tok_ident;
146 TokenSym **table_ident;
147 TokenSym *hash_ident[TOK_HASH_SIZE];
148 char token_buf[STRING_MAX_SIZE + 1];
149 char *filename, *funcname;
150 /* contains global symbols which remain between each translation unit */
151 SymStack extern_stack;
152 SymStack define_stack, global_stack, local_stack, label_stack;
154 SValue vstack[VSTACK_SIZE], *vtop;
155 int *macro_ptr, *macro_ptr_allocated;
156 IncludeFile include_stack[INCLUDE_STACK_SIZE], *include_stack_ptr;
157 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
158 char *include_paths[INCLUDE_PATHS_MAX];
159 int nb_include_paths;
161 /* use GNU C extensions */
162 int gnu_ext = 1;
164 /* use Tiny C extensions */
165 int tcc_ext = 1;
167 /* The current value can be: */
168 #define VT_VALMASK 0x000f
169 #define VT_CONST 0x000a /* constant in vc
170 (must be first non register value) */
171 #define VT_LLOCAL 0x000b /* lvalue, offset on stack */
172 #define VT_LOCAL 0x000c /* offset on stack */
173 #define VT_CMP 0x000d /* the value is stored in processor flags (in vc) */
174 #define VT_JMP 0x000e /* value is the consequence of jmp true */
175 #define VT_JMPI 0x000f /* value is the consequence of jmp false */
176 #define VT_LVAL 0x0010 /* var is an lvalue */
177 #define VT_LVALN -17 /* ~VT_LVAL */
178 #define VT_FORWARD 0x0020 /* value is forward reference
179 (only used for functions) */
180 /* storage */
181 #define VT_EXTERN 0x00000040 /* extern definition */
182 #define VT_STATIC 0x00000080 /* static variable */
183 #define VT_TYPEDEF 0x00000100 /* typedef definition */
185 /* types */
186 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
188 #define VT_BTYPE_SHIFT 9
189 #define VT_INT (0 << VT_BTYPE_SHIFT) /* integer type */
190 #define VT_BYTE (1 << VT_BTYPE_SHIFT) /* signed byte type */
191 #define VT_SHORT (2 << VT_BTYPE_SHIFT) /* short type */
192 #define VT_VOID (3 << VT_BTYPE_SHIFT) /* void type */
193 #define VT_PTR (4 << VT_BTYPE_SHIFT) /* pointer increment */
194 #define VT_ENUM (5 << VT_BTYPE_SHIFT) /* enum definition */
195 #define VT_FUNC (6 << VT_BTYPE_SHIFT) /* function type */
196 #define VT_STRUCT (7 << VT_BTYPE_SHIFT) /* struct/union definition */
197 #define VT_FLOAT (8 << VT_BTYPE_SHIFT) /* IEEE float */
198 #define VT_DOUBLE (9 << VT_BTYPE_SHIFT) /* IEEE double */
199 #define VT_LDOUBLE (10 << VT_BTYPE_SHIFT) /* IEEE long double */
200 #define VT_BOOL (11 << VT_BTYPE_SHIFT) /* ISOC99 boolean type */
201 #define VT_LLONG (12 << VT_BTYPE_SHIFT) /* 64 bit integer */
202 #define VT_LONG (13 << VT_BTYPE_SHIFT) /* long integer (NEVER
203 USED as type, only
204 during parsing) */
205 #define VT_BTYPE (0xf << VT_BTYPE_SHIFT) /* mask for basic type */
206 #define VT_UNSIGNED (0x10 << VT_BTYPE_SHIFT) /* unsigned type */
207 #define VT_ARRAY (0x20 << VT_BTYPE_SHIFT) /* array type (also has VT_PTR) */
208 #define VT_BITFIELD (0x40 << VT_BTYPE_SHIFT) /* bitfield modifier */
210 #define VT_TYPE 0xfffffe00 /* type mask */
212 /* token values */
214 /* warning: the following compare tokens depend on i386 asm code */
215 #define TOK_ULT 0x92
216 #define TOK_UGE 0x93
217 #define TOK_EQ 0x94
218 #define TOK_NE 0x95
219 #define TOK_ULE 0x96
220 #define TOK_UGT 0x97
221 #define TOK_LT 0x9c
222 #define TOK_GE 0x9d
223 #define TOK_LE 0x9e
224 #define TOK_GT 0x9f
226 #define TOK_LAND 0xa0
227 #define TOK_LOR 0xa1
229 #define TOK_DEC 0xa2
230 #define TOK_MID 0xa3 /* inc/dec, to void constant */
231 #define TOK_INC 0xa4
232 #define TOK_ARROW 0xa7
233 #define TOK_DOTS 0xa8 /* three dots */
234 #define TOK_SHR 0xa9 /* unsigned shift right */
235 #define TOK_UDIV 0xb0 /* unsigned division */
236 #define TOK_UMOD 0xb1 /* unsigned modulo */
237 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
238 #define TOK_NUM 0xb3 /* number in tokc */
239 #define TOK_CCHAR 0xb4 /* char constant in tokc */
240 #define TOK_STR 0xb5 /* pointer to string in tokc */
241 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
242 #define TOK_LCHAR 0xb7
243 #define TOK_LSTR 0xb8
244 #define TOK_CFLOAT 0xb9 /* float constant */
245 #define TOK_CDOUBLE 0xc0 /* double constant */
246 #define TOK_CLDOUBLE 0xc1 /* long double constant */
248 #define TOK_SHL 0x01 /* shift left */
249 #define TOK_SAR 0x02 /* signed shift right */
251 /* assignement operators : normal operator or 0x80 */
252 #define TOK_A_MOD 0xa5
253 #define TOK_A_AND 0xa6
254 #define TOK_A_MUL 0xaa
255 #define TOK_A_ADD 0xab
256 #define TOK_A_SUB 0xad
257 #define TOK_A_DIV 0xaf
258 #define TOK_A_XOR 0xde
259 #define TOK_A_OR 0xfc
260 #define TOK_A_SHL 0x81
261 #define TOK_A_SAR 0x82
263 /* all identificators and strings have token above that */
264 #define TOK_IDENT 256
266 enum {
267 TOK_INT = TOK_IDENT,
268 TOK_VOID,
269 TOK_CHAR,
270 TOK_IF,
271 TOK_ELSE,
272 TOK_WHILE,
273 TOK_BREAK,
274 TOK_RETURN,
275 TOK_FOR,
276 TOK_EXTERN,
277 TOK_STATIC,
278 TOK_UNSIGNED,
279 TOK_GOTO,
280 TOK_DO,
281 TOK_CONTINUE,
282 TOK_SWITCH,
283 TOK_CASE,
285 /* ignored types Must have contiguous values */
286 TOK_CONST,
287 TOK_VOLATILE,
288 TOK_LONG,
289 TOK_REGISTER,
290 TOK_SIGNED,
291 TOK_AUTO,
292 TOK_INLINE,
293 TOK_RESTRICT,
295 /* unsupported type */
296 TOK_FLOAT,
297 TOK_DOUBLE,
298 TOK_BOOL,
300 TOK_SHORT,
301 TOK_STRUCT,
302 TOK_UNION,
303 TOK_TYPEDEF,
304 TOK_DEFAULT,
305 TOK_ENUM,
306 TOK_SIZEOF,
308 /* preprocessor only */
309 TOK_UIDENT, /* first "user" ident (not keyword) */
310 TOK_DEFINE = TOK_UIDENT,
311 TOK_INCLUDE,
312 TOK_IFDEF,
313 TOK_IFNDEF,
314 TOK_ELIF,
315 TOK_ENDIF,
316 TOK_DEFINED,
317 TOK_UNDEF,
318 TOK_ERROR,
319 TOK_LINE,
320 TOK___LINE__,
321 TOK___FILE__,
322 TOK___DATE__,
323 TOK___TIME__,
324 TOK___VA_ARGS__,
326 /* special identifiers */
327 TOK___FUNC__,
328 TOK_MAIN,
331 /* XXX: need to define this to use them in non ISOC99 context */
332 extern float strtof (const char *__nptr, char **__endptr);
333 extern long double strtold (const char *__nptr, char **__endptr);
335 void sum(int l);
336 void next(void);
337 void next_nomacro(void);
338 int expr_const(void);
339 void expr_eq(void);
340 void gexpr(void);
341 void decl(int l);
342 void decl_initializer(int t, int c, int first, int size_only);
343 int decl_initializer_alloc(int t, int has_init);
344 int gv(void);
345 void move_reg(int r, int s);
346 void save_reg(int r);
347 void vpop(void);
348 void vswap(void);
349 void vdup(void);
350 int get_reg(int rc);
352 void macro_subst(int **tok_str, int *tok_len,
353 Sym **nested_list, int *macro_str);
354 int save_reg_forced(int r);
355 void gen_op(int op);
356 void gen_cast(int t);
357 void vstore(void);
358 int type_size(int t, int *a);
359 int pointed_type(int t);
360 int pointed_size(int t);
361 int ist(void);
362 int type_decl(int *v, int t, int td);
363 void error(const char *fmt, ...);
364 void vset(int t, int r, int v);
366 /* true if float/double/long double type */
367 static inline int is_float(int t)
369 int bt;
370 bt = t & VT_BTYPE;
371 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
374 #include "i386-gen.c"
376 #ifdef CONFIG_TCC_STATIC
378 #define RTLD_LAZY 0x001
379 #define RTLD_NOW 0x002
380 #define RTLD_GLOBAL 0x100
382 /* dummy function for profiling */
383 void *dlopen(const char *filename, int flag)
385 return NULL;
388 const char *dlerror(void)
390 return "error";
393 typedef struct TCCSyms {
394 char *str;
395 void *ptr;
396 } TCCSyms;
398 #define TCCSYM(a) { #a, &a, },
400 /* add the symbol you want here if no dynamic linking is done */
401 static TCCSyms tcc_syms[] = {
402 TCCSYM(printf)
403 TCCSYM(fprintf)
404 TCCSYM(fopen)
405 TCCSYM(fclose)
406 { NULL, NULL },
409 void *dlsym(void *handle, char *symbol)
411 TCCSyms *p;
412 p = tcc_syms;
413 while (p->str != NULL) {
414 if (!strcmp(p->str, symbol))
415 return p->ptr;
416 p++;
418 return NULL;
421 #endif
423 static inline int isid(int c)
425 return (c >= 'a' && c <= 'z') ||
426 (c >= 'A' && c <= 'Z') ||
427 c == '_';
430 static inline int isnum(int c)
432 return c >= '0' & c <= '9';
435 static inline int toup(int c)
437 if (ch >= 'a' && ch <= 'z')
438 return ch - 'a' + 'A';
439 else
440 return ch;
443 void printline(void)
445 IncludeFile *f;
446 for(f = include_stack; f < include_stack_ptr; f++)
447 fprintf(stderr, "In file included from %s:%d:\n",
448 f->filename, f->line_num);
449 fprintf(stderr, "%s:%d: ", filename, line_num);
452 void error(const char *fmt, ...)
454 va_list ap;
455 va_start(ap, fmt);
456 printline();
457 vfprintf(stderr, fmt, ap);
458 fprintf(stderr, "\n");
459 exit(1);
460 va_end(ap);
463 void expect(const char *msg)
465 error("%s expected", msg);
468 void warning(const char *fmt, ...)
470 va_list ap;
472 va_start(ap, fmt);
473 printline();
474 fprintf(stderr, "warning: ");
475 vfprintf(stderr, fmt, ap);
476 fprintf(stderr, "\n");
477 va_end(ap);
480 void skip(int c)
482 if (tok != c)
483 error("'%c' expected", c);
484 next();
487 void test_lvalue(void)
489 if (!(vtop->r & VT_LVAL))
490 expect("lvalue");
493 TokenSym *tok_alloc(char *str, int len)
495 TokenSym *ts, **pts, **ptable;
496 int h, i;
498 if (len <= 0)
499 len = strlen(str);
500 h = 1;
501 for(i=0;i<len;i++)
502 h = ((h << 8) | (str[i] & 0xff)) % TOK_HASH_SIZE;
504 pts = &hash_ident[h];
505 while (1) {
506 ts = *pts;
507 if (!ts)
508 break;
509 if (ts->len == len && !memcmp(ts->str, str, len))
510 return ts;
511 pts = &(ts->hash_next);
514 if (tok_ident >= SYM_FIRST_ANOM)
515 error("memory full");
517 /* expand token table if needed */
518 i = tok_ident - TOK_IDENT;
519 if ((i % TOK_ALLOC_INCR) == 0) {
520 ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
521 if (!ptable)
522 error("memory full");
523 table_ident = ptable;
526 ts = malloc(sizeof(TokenSym) + len);
527 if (!ts)
528 error("memory full");
529 table_ident[i] = ts;
530 ts->tok = tok_ident++;
531 ts->len = len;
532 ts->hash_next = NULL;
533 memcpy(ts->str, str, len + 1);
534 *pts = ts;
535 return ts;
538 void add_char(char **pp, int c)
540 char *p;
541 p = *pp;
542 if (c == '\'' || c == '\"' || c == '\\') {
543 /* XXX: could be more precise if char or string */
544 *p++ = '\\';
546 if (c >= 32 && c <= 126) {
547 *p++ = c;
548 } else {
549 *p++ = '\\';
550 if (c == '\n') {
551 *p++ = 'n';
552 } else {
553 *p++ = '0' + ((c >> 6) & 7);
554 *p++ = '0' + ((c >> 3) & 7);
555 *p++ = '0' + (c & 7);
558 *pp = p;
561 /* XXX: buffer overflow */
562 char *get_tok_str(int v, CValue *cv)
564 static char buf[STRING_MAX_SIZE + 1];
565 TokenSym *ts;
566 char *p;
567 int i;
569 if (v == TOK_NUM) {
570 sprintf(buf, "%u", cv->ui);
571 return buf;
572 } else if (v == TOK_CCHAR || v == TOK_LCHAR) {
573 p = buf;
574 *p++ = '\'';
575 add_char(&p, cv->i);
576 *p++ = '\'';
577 *p = '\0';
578 return buf;
579 } else if (v == TOK_STR || v == TOK_LSTR) {
580 ts = cv->ts;
581 p = buf;
582 *p++ = '\"';
583 for(i=0;i<ts->len;i++)
584 add_char(&p, ts->str[i]);
585 *p++ = '\"';
586 *p = '\0';
587 return buf;
588 } else if (v < TOK_IDENT) {
589 p = buf;
590 *p++ = v;
591 *p = '\0';
592 return buf;
593 } else if (v < tok_ident) {
594 return table_ident[v - TOK_IDENT]->str;
595 } else {
596 /* should never happen */
597 return NULL;
601 /* push, without hashing */
602 Sym *sym_push2(Sym **ps, int v, int t, int c)
604 Sym *s;
605 s = malloc(sizeof(Sym));
606 if (!s)
607 error("memory full");
608 s->v = v;
609 s->t = t;
610 s->c = c;
611 s->next = NULL;
612 /* add in stack */
613 s->prev = *ps;
614 *ps = s;
615 return s;
618 /* find a symbol and return its associated structure. 's' is the top
619 of the symbol stack */
620 Sym *sym_find2(Sym *s, int v)
622 while (s) {
623 if (s->v == v)
624 return s;
625 s = s->prev;
627 return NULL;
630 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
632 /* find a symbol and return its associated structure. 'st' is the
633 symbol stack */
634 Sym *sym_find1(SymStack *st, int v)
636 Sym *s;
638 s = st->hash[HASH_SYM(v)];
639 while (s) {
640 if (s->v == v)
641 return s;
642 s = s->hash_next;
644 return 0;
647 Sym *sym_push1(SymStack *st, int v, int t, int c)
649 Sym *s, **ps;
650 s = sym_push2(&st->top, v, t, c);
651 /* add in hash table */
652 if (v) {
653 ps = &st->hash[HASH_SYM(v)];
654 s->hash_next = *ps;
655 *ps = s;
657 return s;
660 /* find a symbol in the right symbol space */
661 Sym *sym_find(int v)
663 Sym *s;
664 s = sym_find1(&local_stack, v);
665 if (!s)
666 s = sym_find1(&global_stack, v);
667 return s;
670 /* push a given symbol on the symbol stack */
671 Sym *sym_push(int v, int t, int c)
673 if (local_stack.top)
674 return sym_push1(&local_stack, v, t, c);
675 else
676 return sym_push1(&global_stack, v, t, c);
679 /* pop symbols until top reaches 'b' */
680 void sym_pop(SymStack *st, Sym *b)
682 Sym *s, *ss;
684 s = st->top;
685 while(s != b) {
686 ss = s->prev;
687 /* free hash table entry, except if symbol was freed (only
688 used for #undef symbols) */
689 if (s->v)
690 st->hash[HASH_SYM(s->v)] = s->hash_next;
691 free(s);
692 s = ss;
694 st->top = b;
697 /* undefined a hashed symbol (used for #undef). Its name is set to
698 zero */
699 void sym_undef(SymStack *st, Sym *s)
701 Sym **ss;
702 ss = &st->hash[HASH_SYM(s->v)];
703 while (*ss != NULL) {
704 if (*ss == s)
705 break;
706 ss = &(*ss)->hash_next;
708 *ss = s->hash_next;
709 s->v = 0;
712 /* no need to put that inline */
713 int handle_eof(void)
715 if (include_stack_ptr == include_stack)
716 return -1;
717 /* pop include stack */
718 fclose(file);
719 free(filename);
720 include_stack_ptr--;
721 file = include_stack_ptr->file;
722 filename = include_stack_ptr->filename;
723 line_num = include_stack_ptr->line_num;
724 return 0;
727 /* read next char from current input file */
728 static inline void inp(void)
730 redo:
731 /* faster than fgetc */
732 ch1 = getc_unlocked(file);
733 if (ch1 == -1) {
734 if (handle_eof() < 0)
735 return;
736 else
737 goto redo;
739 if (ch1 == '\n')
740 line_num++;
741 // printf("ch1=%c 0x%x\n", ch1, ch1);
744 /* input with '\\n' handling */
745 static inline void minp(void)
747 redo:
748 ch = ch1;
749 inp();
750 if (ch == '\\' && ch1 == '\n') {
751 inp();
752 goto redo;
754 //printf("ch=%c 0x%x\n", ch, ch);
758 /* same as minp, but also skip comments */
759 void cinp(void)
761 int c;
763 if (ch1 == '/') {
764 inp();
765 if (ch1 == '/') {
766 /* single line C++ comments */
767 inp();
768 while (ch1 != '\n' && ch1 != -1)
769 inp();
770 inp();
771 ch = ' '; /* return space */
772 } else if (ch1 == '*') {
773 /* C comments */
774 inp();
775 while (ch1 != -1) {
776 c = ch1;
777 inp();
778 if (c == '*' && ch1 == '/') {
779 inp();
780 ch = ' '; /* return space */
781 break;
784 } else {
785 ch = '/';
787 } else {
788 minp();
792 void skip_spaces(void)
794 while (ch == ' ' || ch == '\t')
795 cinp();
798 /* skip block of text until #else, #elif or #endif. skip also pairs of
799 #if/#endif */
800 void preprocess_skip()
802 int a;
803 a = 0;
804 while (1) {
805 while (ch != '\n') {
806 if (ch == -1)
807 expect("#endif");
808 cinp();
810 cinp();
811 skip_spaces();
812 if (ch == '#') {
813 cinp();
814 next_nomacro();
815 if (a == 0 &&
816 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
817 break;
818 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
819 a++;
820 else if (tok == TOK_ENDIF)
821 a--;
826 /* return the number of additionnal 'ints' necessary to store the
827 token */
828 static inline int tok_ext_size(int t)
830 switch(t) {
831 /* 4 bytes */
832 case TOK_NUM:
833 case TOK_CCHAR:
834 case TOK_LCHAR:
835 case TOK_STR:
836 case TOK_LSTR:
837 case TOK_CFLOAT:
838 return 1;
839 case TOK_CDOUBLE:
840 return 2;
841 case TOK_CLDOUBLE:
842 return LDOUBLE_SIZE / 4;
843 default:
844 return 0;
848 void tok_add(int **tok_str, int *tok_len, int t)
850 int len, *str;
851 len = *tok_len;
852 str = *tok_str;
853 if ((len & 63) == 0) {
854 str = realloc(str, (len + 64) * sizeof(int));
855 if (!str)
856 return;
857 *tok_str = str;
859 str[len++] = t;
860 *tok_len = len;
863 void tok_add2(int **tok_str, int *tok_len, int t, CValue *cv)
865 int n, i;
867 tok_add(tok_str, tok_len, t);
868 n = tok_ext_size(t);
869 for(i=0;i<n;i++)
870 tok_add(tok_str, tok_len, cv->tab[i]);
873 /* get a token from an integer array and increment pointer accordingly */
874 int tok_get(int **tok_str, CValue *cv)
876 int *p, t, n, i;
878 p = *tok_str;
879 t = *p++;
880 n = tok_ext_size(t);
881 for(i=0;i<n;i++)
882 cv->tab[i] = *p++;
883 *tok_str = p;
884 return t;
887 /* eval an expression for #if/#elif */
888 int expr_preprocess(void)
890 int *str, len, c, t;
892 str = NULL;
893 len = 0;
894 while (1) {
895 skip_spaces();
896 if (ch == '\n')
897 break;
898 next(); /* do macro subst */
899 if (tok == TOK_DEFINED) {
900 next_nomacro();
901 t = tok;
902 if (t == '(')
903 next_nomacro();
904 c = sym_find1(&define_stack, tok) != 0;
905 if (t == '(')
906 next_nomacro();
907 tok = TOK_NUM;
908 tokc.i = c;
909 } else if (tok >= TOK_IDENT) {
910 /* if undefined macro */
911 tok = TOK_NUM;
912 tokc.i = 0;
914 tok_add2(&str, &len, tok, &tokc);
916 tok_add(&str, &len, -1); /* simulate end of file */
917 tok_add(&str, &len, 0);
918 /* now evaluate C constant expression */
919 macro_ptr = str;
920 next();
921 c = expr_const();
922 macro_ptr = NULL;
923 free(str);
924 return c != 0;
927 #if defined(DEBUG)
928 void tok_print(int *str)
930 int t;
931 CValue cval;
933 while (1) {
934 t = tok_get(&str, &cval);
935 if (!t)
936 break;
937 printf(" %s", get_tok_str(t, &cval));
939 printf("\n");
941 #endif
943 /* XXX: should be more factorized */
944 void define_symbol(char *sym)
946 TokenSym *ts;
947 int *str, len;
948 CValue cval;
950 ts = tok_alloc(sym, 0);
951 str = NULL;
952 len = 0;
953 cval.i = 1;
954 tok_add2(&str, &len, TOK_NUM, &cval);
955 tok_add(&str, &len, 0);
956 sym_push1(&define_stack, ts->tok, MACRO_OBJ, (int)str);
959 void preprocess(void)
961 int size, i, c, v, t, *str, len;
962 char buf[1024], *q, *p;
963 char buf1[1024];
964 FILE *f;
965 Sym **ps, *first, *s;
967 cinp();
968 next_nomacro();
969 redo:
970 if (tok == TOK_DEFINE) {
971 next_nomacro();
972 v = tok;
973 /* XXX: should check if same macro (ANSI) */
974 first = NULL;
975 t = MACRO_OBJ;
976 /* '(' must be just after macro definition for MACRO_FUNC */
977 if (ch == '(') {
978 next_nomacro();
979 next_nomacro();
980 ps = &first;
981 while (tok != ')') {
982 if (tok == TOK_DOTS)
983 tok = TOK___VA_ARGS__;
984 s = sym_push1(&define_stack, tok | SYM_FIELD, 0, 0);
985 *ps = s;
986 ps = &s->next;
987 next_nomacro();
988 if (tok != ',')
989 break;
990 next_nomacro();
992 t = MACRO_FUNC;
994 str = NULL;
995 len = 0;
996 while (1) {
997 skip_spaces();
998 if (ch == '\n' || ch == -1)
999 break;
1000 next_nomacro();
1001 tok_add2(&str, &len, tok, &tokc);
1003 tok_add(&str, &len, 0);
1004 #ifdef PP_DEBUG
1005 printf("define %s %d: ", get_tok_str(v, NULL), t);
1006 tok_print(str);
1007 #endif
1008 s = sym_push1(&define_stack, v, t, (int)str);
1009 s->next = first;
1010 } else if (tok == TOK_UNDEF) {
1011 next_nomacro();
1012 s = sym_find1(&define_stack, tok);
1013 /* undefine symbol by putting an invalid name */
1014 if (s)
1015 sym_undef(&define_stack, s);
1016 } else if (tok == TOK_INCLUDE) {
1017 skip_spaces();
1018 if (ch == '<') {
1019 c = '>';
1020 goto read_name;
1021 } else if (ch == '\"') {
1022 c = ch;
1023 read_name:
1024 minp();
1025 q = buf;
1026 while (ch != c && ch != '\n' && ch != -1) {
1027 if ((q - buf) < sizeof(buf) - 1)
1028 *q++ = ch;
1029 minp();
1031 *q = '\0';
1032 } else {
1033 next();
1034 if (tok != TOK_STR)
1035 error("#include syntax error");
1036 /* XXX: buffer overflow */
1037 strcpy(buf, get_tok_str(tok, &tokc));
1038 c = '\"';
1040 /* eat all spaces and comments after include */
1041 /* XXX: slightly incorrect */
1042 while (ch1 != '\n' && ch1 != -1)
1043 inp();
1045 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1046 error("memory full");
1047 if (c == '\"') {
1048 /* first search in current dir if "header.h" */
1049 /* XXX: buffer overflow */
1050 size = 0;
1051 p = strrchr(filename, '/');
1052 if (p)
1053 size = p + 1 - filename;
1054 memcpy(buf1, filename, size);
1055 buf1[size] = '\0';
1056 strcat(buf1, buf);
1057 f = fopen(buf1, "r");
1058 if (f)
1059 goto found;
1061 /* now search in standard include path */
1062 for(i=nb_include_paths - 1;i>=0;i--) {
1063 strcpy(buf1, include_paths[i]);
1064 strcat(buf1, "/");
1065 strcat(buf1, buf);
1066 f = fopen(buf1, "r");
1067 if (f)
1068 goto found;
1070 error("include file '%s' not found", buf1);
1071 f = NULL;
1072 found:
1073 /* push current file in stack */
1074 /* XXX: fix current line init */
1075 include_stack_ptr->file = file;
1076 include_stack_ptr->filename = filename;
1077 include_stack_ptr->line_num = line_num;
1078 include_stack_ptr++;
1079 file = f;
1080 filename = strdup(buf1);
1081 line_num = 1;
1082 } else if (tok == TOK_IFNDEF) {
1083 c = 1;
1084 goto do_ifdef;
1085 } else if (tok == TOK_IF) {
1086 c = expr_preprocess();
1087 goto do_if;
1088 } else if (tok == TOK_IFDEF) {
1089 c = 0;
1090 do_ifdef:
1091 next_nomacro();
1092 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1093 do_if:
1094 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1095 error("memory full");
1096 *ifdef_stack_ptr++ = c;
1097 goto test_skip;
1098 } else if (tok == TOK_ELSE) {
1099 if (ifdef_stack_ptr == ifdef_stack ||
1100 (ifdef_stack_ptr[-1] & 2))
1101 error("#else after #else");
1102 c = (ifdef_stack_ptr[-1] ^= 3);
1103 goto test_skip;
1104 } else if (tok == TOK_ELIF) {
1105 if (ifdef_stack_ptr == ifdef_stack ||
1106 ifdef_stack_ptr[-1] > 1)
1107 error("#elif after #else");
1108 c = expr_preprocess();
1109 ifdef_stack_ptr[-1] = c;
1110 test_skip:
1111 if (!(c & 1)) {
1112 preprocess_skip();
1113 goto redo;
1115 } else if (tok == TOK_ENDIF) {
1116 if (ifdef_stack_ptr == ifdef_stack)
1117 expect("#if");
1118 ifdef_stack_ptr--;
1119 } else if (tok == TOK_LINE) {
1120 next();
1121 if (tok != TOK_NUM)
1122 error("#line");
1123 line_num = tokc.i;
1124 skip_spaces();
1125 if (ch != '\n') {
1126 next();
1127 if (tok != TOK_STR)
1128 error("#line");
1129 /* XXX: potential memory leak */
1130 filename = strdup(get_tok_str(tok, &tokc));
1132 } else if (tok == TOK_ERROR) {
1133 error("#error");
1135 /* ignore other preprocess commands or #! for C scripts */
1136 while (ch != '\n' && ch != -1)
1137 cinp();
1140 /* read a number in base b */
1141 int getn(b)
1143 int n, t;
1144 n = 0;
1145 while (1) {
1146 if (ch >= 'a' & ch <= 'f')
1147 t = ch - 'a' + 10;
1148 else if (ch >= 'A' & ch <= 'F')
1149 t = ch - 'A' + 10;
1150 else if (isnum(ch))
1151 t = ch - '0';
1152 else
1153 break;
1154 if (t < 0 | t >= b)
1155 break;
1156 n = n * b + t;
1157 cinp();
1159 return n;
1162 /* read a character for string or char constant and eval escape codes */
1163 int getq()
1165 int c;
1167 c = ch;
1168 minp();
1169 if (c == '\\') {
1170 if (isnum(ch)) {
1171 /* at most three octal digits */
1172 c = ch - '0';
1173 minp();
1174 if (isnum(ch)) {
1175 c = c * 8 + ch - '0';
1176 minp();
1177 if (isnum(ch)) {
1178 c = c * 8 + ch - '0';
1179 minp();
1182 return c;
1183 } else if (ch == 'x') {
1184 minp();
1185 return getn(16);
1186 } else {
1187 if (ch == 'a')
1188 c = '\a';
1189 else if (ch == 'b')
1190 c = '\b';
1191 else if (ch == 'f')
1192 c = '\f';
1193 else if (ch == 'n')
1194 c = '\n';
1195 else if (ch == 'r')
1196 c = '\r';
1197 else if (ch == 't')
1198 c = '\t';
1199 else if (ch == 'v')
1200 c = '\v';
1201 else if (ch == 'e' && gnu_ext)
1202 c = 27;
1203 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
1204 c = ch;
1205 else
1206 error("invalid escaped char");
1207 minp();
1210 return c;
1213 /* we use 64 bit numbers */
1214 #define BN_SIZE 2
1216 /* bn = (bn << shift) | or_val */
1217 void bn_lshift(unsigned int *bn, int shift, int or_val)
1219 int i;
1220 unsigned int v;
1221 for(i=0;i<BN_SIZE;i++) {
1222 v = bn[i];
1223 bn[i] = (v << shift) | or_val;
1224 or_val = v >> (32 - shift);
1228 void bn_zero(unsigned int *bn)
1230 int i;
1231 for(i=0;i<BN_SIZE;i++) {
1232 bn[i] = 0;
1236 void parse_number(void)
1238 int b, t, shift, frac_bits, s, exp_val;
1239 char *q;
1240 unsigned int n, n1;
1241 unsigned int bn[BN_SIZE];
1242 double d;
1244 /* number */
1245 q = token_buf;
1246 t = ch;
1247 cinp();
1248 *q++ = t;
1249 b = 10;
1250 if (t == '.') {
1251 /* special dot handling */
1252 if (ch >= '0' && ch <= '9') {
1253 goto float_frac_parse;
1254 } else if (ch == '.') {
1255 cinp();
1256 if (ch != '.')
1257 expect("'.'");
1258 cinp();
1259 tok = TOK_DOTS;
1260 } else {
1261 /* dots */
1262 tok = t;
1264 return;
1265 } else if (t == '0') {
1266 if (ch == 'x' || ch == 'X') {
1267 q--;
1268 cinp();
1269 b = 16;
1270 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
1271 q--;
1272 cinp();
1273 b = 2;
1276 /* parse all digits. cannot check octal numbers at this stage
1277 because of floating point constants */
1278 while (1) {
1279 if (ch >= 'a' & ch <= 'f')
1280 t = ch - 'a' + 10;
1281 else if (ch >= 'A' & ch <= 'F')
1282 t = ch - 'A' + 10;
1283 else if (isnum(ch))
1284 t = ch - '0';
1285 else
1286 break;
1287 if (t >= b)
1288 break;
1289 if (q >= token_buf + STRING_MAX_SIZE) {
1290 num_too_long:
1291 error("number too long");
1293 *q++ = ch;
1294 cinp();
1296 if (ch == '.' ||
1297 ((ch == 'e' || ch == 'E') && b == 10) ||
1298 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
1299 if (b != 10) {
1300 /* NOTE: strtox should support that for hexa numbers, but
1301 non ISOC99 libcs do not support it, so we prefer to do
1302 it by hand */
1303 /* hexadecimal or binary floats */
1304 /* XXX: handle overflows */
1305 *q = '\0';
1306 if (b == 16)
1307 shift = 4;
1308 else
1309 shift = 2;
1310 bn_zero(bn);
1311 q = token_buf;
1312 while (1) {
1313 t = *q++;
1314 if (t == '\0') {
1315 break;
1316 } else if (t >= 'a') {
1317 t = t - 'a' + 10;
1318 } else if (t >= 'A') {
1319 t = t - 'A' + 10;
1320 } else {
1321 t = t - '0';
1323 bn_lshift(bn, shift, t);
1325 frac_bits = 0;
1326 if (ch == '.') {
1327 cinp();
1328 while (1) {
1329 t = ch;
1330 if (t >= 'a' && t <= 'f') {
1331 t = t - 'a' + 10;
1332 } else if (t >= 'A' && t <= 'F') {
1333 t = t - 'A' + 10;
1334 } else if (t >= '0' && t <= '9') {
1335 t = t - '0';
1336 } else {
1337 break;
1339 if (t >= b)
1340 error("invalid digit");
1341 bn_lshift(bn, shift, t);
1342 frac_bits += shift;
1343 cinp();
1346 if (ch != 'p' && ch != 'P')
1347 error("exponent expected");
1348 cinp();
1349 s = 1;
1350 exp_val = 0;
1351 if (ch == '+') {
1352 cinp();
1353 } else if (ch == '-') {
1354 s = -1;
1355 cinp();
1357 if (ch < '0' || ch > '9')
1358 error("exponent digits expected");
1359 while (ch >= '0' && ch <= '9') {
1360 exp_val = exp_val * 10 + ch - '0';
1361 cinp();
1363 exp_val = exp_val * s;
1365 /* now we can generate the number */
1366 /* XXX: should patch directly float number */
1367 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
1368 d = ldexp(d, exp_val - frac_bits);
1369 t = toup(ch);
1370 if (t == 'F') {
1371 cinp();
1372 tok = TOK_CFLOAT;
1373 /* float : should handle overflow */
1374 tokc.f = (float)d;
1375 } else if (t == 'L') {
1376 cinp();
1377 tok = TOK_CLDOUBLE;
1378 /* XXX: not large enough */
1379 tokc.ld = (long double)d;
1380 } else {
1381 tok = TOK_CDOUBLE;
1382 tokc.d = d;
1384 } else {
1385 /* decimal floats */
1386 if (ch == '.') {
1387 if (q >= token_buf + STRING_MAX_SIZE)
1388 goto num_too_long;
1389 *q++ = ch;
1390 cinp();
1391 float_frac_parse:
1392 while (ch >= '0' && ch <= '9') {
1393 if (q >= token_buf + STRING_MAX_SIZE)
1394 goto num_too_long;
1395 *q++ = ch;
1396 cinp();
1399 if (ch == 'e' || ch == 'E') {
1400 if (q >= token_buf + STRING_MAX_SIZE)
1401 goto num_too_long;
1402 *q++ = ch;
1403 cinp();
1404 if (ch == '-' || ch == '+') {
1405 if (q >= token_buf + STRING_MAX_SIZE)
1406 goto num_too_long;
1407 *q++ = ch;
1408 cinp();
1410 if (ch < '0' || ch > '9')
1411 error("exponent digits expected");
1412 while (ch >= '0' && ch <= '9') {
1413 if (q >= token_buf + STRING_MAX_SIZE)
1414 goto num_too_long;
1415 *q++ = ch;
1416 cinp();
1419 *q = '\0';
1420 t = toup(ch);
1421 errno = 0;
1422 if (t == 'F') {
1423 cinp();
1424 tok = TOK_CFLOAT;
1425 tokc.f = strtof(token_buf, NULL);
1426 } else if (t == 'L') {
1427 cinp();
1428 tok = TOK_CLDOUBLE;
1429 tokc.ld = strtold(token_buf, NULL);
1430 } else {
1431 tok = TOK_CDOUBLE;
1432 tokc.d = strtod(token_buf, NULL);
1435 } else {
1436 /* integer number */
1437 *q = '\0';
1438 q = token_buf;
1439 if (b == 10 && *q == '0') {
1440 b = 8;
1441 q++;
1443 n = 0;
1444 while(1) {
1445 t = *q++;
1446 /* no need for checks except for base 10 / 8 errors */
1447 if (t == '\0') {
1448 break;
1449 } else if (t >= 'a') {
1450 t = t - 'a' + 10;
1451 } else if (t >= 'A') {
1452 t = t - 'A' + 10;
1453 } else {
1454 t = t - '0';
1455 if (t >= b)
1456 error("invalid digit");
1458 n1 = n;
1459 n = n * b + t;
1460 /* detect overflow */
1461 if (n < n1)
1462 error("integer constant overflow");
1464 tokc.ui = n;
1465 tok = TOK_NUM;
1466 /* XXX: add unsigned constant support (ANSI) */
1467 while (ch == 'L' || ch == 'l' || ch == 'U' || ch == 'u')
1468 cinp();
1473 /* return next token without macro substitution */
1474 void next_nomacro1(void)
1476 int b;
1477 char *q;
1478 TokenSym *ts;
1480 /* skip spaces */
1481 while(1) {
1482 while (ch == '\n') {
1483 cinp();
1484 while (ch == ' ' || ch == 9)
1485 cinp();
1486 if (ch == '#') {
1487 /* preprocessor command if # at start of line after
1488 spaces */
1489 preprocess();
1492 if (ch != ' ' && ch != '\t' && ch != '\f')
1493 break;
1494 cinp();
1496 if (isid(ch)) {
1497 q = token_buf;
1498 *q++ = ch;
1499 cinp();
1500 if (q[-1] == 'L') {
1501 if (ch == '\'') {
1502 tok = TOK_LCHAR;
1503 goto char_const;
1505 if (ch == '\"') {
1506 tok = TOK_LSTR;
1507 goto str_const;
1510 while (isid(ch) || isnum(ch)) {
1511 if (q >= token_buf + STRING_MAX_SIZE)
1512 error("ident too long");
1513 *q++ = ch;
1514 cinp();
1516 *q = '\0';
1517 ts = tok_alloc(token_buf, q - token_buf);
1518 tok = ts->tok;
1519 } else if (isnum(ch) || ch == '.') {
1520 parse_number();
1521 } else if (ch == '\'') {
1522 tok = TOK_CCHAR;
1523 char_const:
1524 minp();
1525 tokc.i = getq();
1526 if (ch != '\'')
1527 expect("\'");
1528 minp();
1529 } else if (ch == '\"') {
1530 tok = TOK_STR;
1531 str_const:
1532 minp();
1533 q = token_buf;
1534 while (ch != '\"') {
1535 b = getq();
1536 if (ch == -1)
1537 error("unterminated string");
1538 if (q >= token_buf + STRING_MAX_SIZE)
1539 error("string too long");
1540 *q++ = b;
1542 *q = '\0';
1543 tokc.ts = tok_alloc(token_buf, q - token_buf);
1544 minp();
1545 } else {
1546 q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\247..\250##\266";
1547 /* two chars */
1548 tok = ch;
1549 cinp();
1550 while (*q) {
1551 if (*q == tok && q[1] == ch) {
1552 cinp();
1553 tok = q[2] & 0xff;
1554 /* three chars tests */
1555 if (tok == TOK_SHL | tok == TOK_SAR) {
1556 if (ch == '=') {
1557 tok = tok | 0x80;
1558 cinp();
1560 } else if (tok == TOK_DOTS) {
1561 if (ch != '.')
1562 error("parse error");
1563 cinp();
1565 return;
1567 q = q + 3;
1569 /* single char substitutions */
1570 if (tok == '<')
1571 tok = TOK_LT;
1572 else if (tok == '>')
1573 tok = TOK_GT;
1577 /* return next token without macro substitution. Can read input from
1578 macro_ptr buffer */
1579 void next_nomacro()
1581 if (macro_ptr) {
1582 tok = *macro_ptr;
1583 if (tok)
1584 tok = tok_get(&macro_ptr, &tokc);
1585 } else {
1586 next_nomacro1();
1590 /* substitute args in macro_str and return allocated string */
1591 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
1593 int *st, last_tok, t, notfirst, *str, len;
1594 Sym *s;
1595 TokenSym *ts;
1596 CValue cval;
1598 str = NULL;
1599 len = 0;
1600 last_tok = 0;
1601 while(1) {
1602 t = tok_get(&macro_str, &cval);
1603 if (!t)
1604 break;
1605 if (t == '#') {
1606 /* stringize */
1607 t = tok_get(&macro_str, &cval);
1608 if (!t)
1609 break;
1610 s = sym_find2(args, t);
1611 if (s) {
1612 token_buf[0] = '\0';
1613 st = (int *)s->c;
1614 /* XXX: buffer overflow */
1615 notfirst = 0;
1616 while (*st) {
1617 if (notfirst)
1618 strcat(token_buf, " ");
1619 t = tok_get(&st, &cval);
1620 strcat(token_buf, get_tok_str(t, &cval));
1621 notfirst = 1;
1623 #ifdef PP_DEBUG
1624 printf("stringize: %s\n", token_buf);
1625 #endif
1626 /* add string */
1627 ts = tok_alloc(token_buf, 0);
1628 cval.ts = ts;
1629 tok_add2(&str, &len, TOK_STR, &cval);
1630 } else {
1631 tok_add2(&str, &len, t, &cval);
1633 } else if (t >= TOK_IDENT) {
1634 s = sym_find2(args, t);
1635 if (s) {
1636 st = (int *)s->c;
1637 /* if '##' is present before or after , no arg substitution */
1638 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
1639 while (*st)
1640 tok_add(&str, &len, *st++);
1641 } else {
1642 macro_subst(&str, &len, nested_list, st);
1644 } else {
1645 tok_add(&str, &len, t);
1647 } else {
1648 tok_add2(&str, &len, t, &cval);
1650 last_tok = t;
1652 tok_add(&str, &len, 0);
1653 return str;
1656 /* handle the '##' operator */
1657 int *macro_twosharps(int *macro_str)
1659 TokenSym *ts;
1660 int *macro_str1, macro_str1_len, *macro_ptr1;
1661 int t;
1662 char *p;
1663 CValue cval;
1665 macro_str1 = NULL;
1666 macro_str1_len = 0;
1667 tok = 0;
1668 while (1) {
1669 next_nomacro();
1670 if (tok == 0)
1671 break;
1672 while (*macro_ptr == TOK_TWOSHARPS) {
1673 macro_ptr++;
1674 macro_ptr1 = macro_ptr;
1675 t = *macro_ptr;
1676 if (t) {
1677 t = tok_get(&macro_ptr, &cval);
1678 /* XXX: we handle only most common cases:
1679 ident + ident or ident + number */
1680 if (tok >= TOK_IDENT &&
1681 (t >= TOK_IDENT || t == TOK_NUM)) {
1682 /* XXX: buffer overflow */
1683 p = get_tok_str(tok, &tokc);
1684 strcpy(token_buf, p);
1685 p = get_tok_str(t, &cval);
1686 strcat(token_buf, p);
1687 ts = tok_alloc(token_buf, 0);
1688 tok = ts->tok; /* modify current token */
1689 } else {
1690 /* cannot merge tokens: skip '##' */
1691 macro_ptr = macro_ptr1;
1692 break;
1696 tok_add2(&macro_str1, &macro_str1_len, tok, &tokc);
1698 tok_add(&macro_str1, &macro_str1_len, 0);
1699 return macro_str1;
1704 /* do macro substitution of macro_str and add result to
1705 (tok_str,tok_len). If macro_str is NULL, then input stream token is
1706 substituted. 'nested_list' is the list of all macros we got inside
1707 to avoid recursing. */
1708 void macro_subst(int **tok_str, int *tok_len,
1709 Sym **nested_list, int *macro_str)
1711 Sym *s, *args, *sa, *sa1;
1712 int *str, parlevel, len, *mstr, t, *saved_macro_ptr;
1713 int mstr_allocated, *macro_str1;
1714 CValue cval;
1716 saved_macro_ptr = macro_ptr;
1717 macro_ptr = macro_str;
1718 macro_str1 = NULL;
1719 if (macro_str) {
1720 /* first scan for '##' operator handling */
1721 macro_str1 = macro_twosharps(macro_str);
1722 macro_ptr = macro_str1;
1725 while (1) {
1726 next_nomacro();
1727 if (tok == 0)
1728 break;
1729 /* special macros */
1730 if (tok == TOK___LINE__) {
1731 cval.i = line_num;
1732 tok_add2(tok_str, tok_len, TOK_NUM, &cval);
1733 } else if (tok == TOK___FILE__) {
1734 cval.ts = tok_alloc(filename, 0);
1735 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1736 } else if (tok == TOK___DATE__) {
1737 cval.ts = tok_alloc("Jan 1 1970", 0);
1738 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1739 } else if (tok == TOK___TIME__) {
1740 cval.ts = tok_alloc("00:00:00", 0);
1741 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1742 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
1743 /* if symbol is a macro, prepare substitution */
1744 /* if nested substitution, do nothing */
1745 if (sym_find2(*nested_list, tok))
1746 goto no_subst;
1747 mstr = (int *)s->c;
1748 mstr_allocated = 0;
1749 if (s->t == MACRO_FUNC) {
1750 /* NOTE: we do not use next_nomacro to avoid eating the
1751 next token. XXX: find better solution */
1752 if (macro_ptr) {
1753 t = *macro_ptr;
1754 } else {
1755 while (ch == ' ' || ch == '\t' || ch == '\n')
1756 cinp();
1757 t = ch;
1759 if (t != '(') /* no macro subst */
1760 goto no_subst;
1762 /* argument macro */
1763 next_nomacro();
1764 next_nomacro();
1765 args = NULL;
1766 sa = s->next;
1767 while (tok != ')' && sa) {
1768 len = 0;
1769 str = NULL;
1770 parlevel = 0;
1771 while ((parlevel > 0 ||
1772 (tok != ')' &&
1773 (tok != ',' ||
1774 sa->v == (TOK___VA_ARGS__ | SYM_FIELD)))) &&
1775 tok != -1) {
1776 if (tok == '(')
1777 parlevel++;
1778 else if (tok == ')')
1779 parlevel--;
1780 tok_add2(&str, &len, tok, &tokc);
1781 next_nomacro();
1783 tok_add(&str, &len, 0);
1784 sym_push2(&args, sa->v & ~SYM_FIELD, 0, (int)str);
1785 if (tok != ',')
1786 break;
1787 next_nomacro();
1788 sa = sa->next;
1790 if (tok != ')')
1791 expect(")");
1792 /* now subst each arg */
1793 mstr = macro_arg_subst(nested_list, mstr, args);
1794 /* free memory */
1795 sa = args;
1796 while (sa) {
1797 sa1 = sa->prev;
1798 free((int *)sa->c);
1799 free(sa);
1800 sa = sa1;
1802 mstr_allocated = 1;
1804 sym_push2(nested_list, s->v, 0, 0);
1805 macro_subst(tok_str, tok_len, nested_list, mstr);
1806 /* pop nested defined symbol */
1807 sa1 = *nested_list;
1808 *nested_list = sa1->prev;
1809 free(sa1);
1810 if (mstr_allocated)
1811 free(mstr);
1812 } else {
1813 no_subst:
1814 /* no need to add if reading input stream */
1815 if (!macro_str)
1816 return;
1817 tok_add2(tok_str, tok_len, tok, &tokc);
1819 /* only replace one macro while parsing input stream */
1820 if (!macro_str)
1821 return;
1823 macro_ptr = saved_macro_ptr;
1824 if (macro_str1)
1825 free(macro_str1);
1828 /* return next token with macro substitution */
1829 void next(void)
1831 int len, *ptr;
1832 Sym *nested_list;
1834 /* special 'ungettok' case for label parsing */
1835 if (tok1) {
1836 tok = tok1;
1837 tokc = tok1c;
1838 tok1 = 0;
1839 } else {
1840 redo:
1841 if (!macro_ptr) {
1842 /* if not reading from macro substuted string, then try to substitute */
1843 len = 0;
1844 ptr = NULL;
1845 nested_list = NULL;
1846 macro_subst(&ptr, &len, &nested_list, NULL);
1847 if (ptr) {
1848 tok_add(&ptr, &len, 0);
1849 macro_ptr = ptr;
1850 macro_ptr_allocated = ptr;
1851 goto redo;
1853 if (tok == 0)
1854 goto redo;
1855 } else {
1856 next_nomacro();
1857 if (tok == 0) {
1858 /* end of macro string: free it */
1859 free(macro_ptr_allocated);
1860 macro_ptr = NULL;
1861 goto redo;
1865 #if defined(DEBUG)
1866 printf("token = %s\n", get_tok_str(tok, tokc));
1867 #endif
1870 void swap(int *p, int *q)
1872 int t;
1873 t = *p;
1874 *p = *q;
1875 *q = t;
1878 void vsetc(int t, int r, CValue *vc)
1880 if (vtop >= vstack + VSTACK_SIZE)
1881 error("memory full");
1882 /* cannot let cpu flags if other instruction are generated */
1883 /* XXX: VT_JMP test too ? */
1884 if ((vtop->r & VT_VALMASK) == VT_CMP)
1885 gv();
1886 vtop++;
1887 vtop->t = t;
1888 vtop->r = r;
1889 vtop->c = *vc;
1892 /* push integer constant */
1893 void vpushi(int v)
1895 CValue cval;
1896 cval.i = v;
1897 vsetc(VT_INT, VT_CONST, &cval);
1900 void vset(int t, int r, int v)
1902 CValue cval;
1904 cval.i = v;
1905 vsetc(t, r, &cval);
1908 void vswap(void)
1910 SValue tmp;
1912 tmp = vtop[0];
1913 vtop[0] = vtop[-1];
1914 vtop[-1] = tmp;
1917 void vdup(void)
1919 if (vtop >= vstack + VSTACK_SIZE)
1920 error("memory full");
1921 vtop++;
1922 *vtop = vtop[-1];
1925 int save_reg_forced(int r)
1927 int i, l, t;
1928 SValue *p, sv;
1930 /* store register */
1931 loc = (loc - 4) & -3;
1932 sv.t = VT_INT;
1933 sv.r = VT_LOCAL | VT_LVAL;
1934 sv.c.ul = loc;
1935 store(r, &sv);
1936 l = loc;
1938 /* modify all stack values */
1939 for(p=vstack;p<=vtop;p++) {
1940 i = p->r & VT_VALMASK;
1941 if (i == r) {
1942 if (p->r & VT_LVAL)
1943 t = VT_LLOCAL;
1944 else
1945 t = VT_LOCAL;
1946 p->r = VT_LVAL | t;
1947 p->c.ul = l;
1950 return l;
1953 /* save r to memory. and mark it as being free */
1954 void save_reg(int r)
1956 int i;
1957 SValue *p;
1959 /* modify all stack values */
1960 for(p=vstack;p<=vtop;p++) {
1961 i = p->r & VT_VALMASK;
1962 if (i == r) {
1963 save_reg_forced(r);
1964 break;
1969 /* find a free register of class 'rc'. If none, save one register */
1970 int get_reg(int rc)
1972 int r, i;
1973 SValue *p;
1975 /* find a free register */
1976 for(r=0;r<NB_REGS;r++) {
1977 if (reg_classes[r] & rc) {
1978 for(p=vstack;p<=vtop;p++) {
1979 i = p->r & VT_VALMASK;
1980 if (i == r)
1981 goto notfound;
1983 return r;
1985 notfound: ;
1988 /* no register left : free the first one on the stack (very
1989 important to start from the bottom to ensure that we don't
1990 spill registers used in gen_op()) */
1991 for(p=vstack;p<=vtop;p++) {
1992 r = p->r & VT_VALMASK;
1993 if (r < VT_CONST && (reg_classes[r] & rc)) {
1994 save_reg(r);
1995 break;
1998 return r;
2001 void save_regs(void)
2003 int r;
2004 SValue *p;
2006 for(p=vstack;p<=vtop;p++) {
2007 r = p->r & VT_VALMASK;
2008 if (r < VT_CONST) {
2009 save_reg(r);
2014 /* move register 's' to 'r', and flush previous value of r to memory
2015 if needed */
2016 void move_reg(int r, int s)
2018 SValue sv;
2020 if (r != s) {
2021 save_reg(r);
2022 sv.t = VT_INT;
2023 sv.r = s;
2024 sv.c.ul = 0;
2025 load(r, &sv);
2029 /* convert a (vtop->t, vtop->c) in register. lvalues are converted as
2030 values. Cannot be used if cannot be converted to register value
2031 (such as structures). */
2032 int gv(void)
2034 int r, bit_pos, bit_size, rc, size, align, i;
2036 /* NOTE: get_reg can modify vstack[] */
2037 if (vtop->t & VT_BITFIELD) {
2038 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
2039 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2040 /* remove bit field info to avoid loops */
2041 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2042 /* generate shifts */
2043 vpushi(32 - (bit_pos + bit_size));
2044 gen_op(TOK_SHL);
2045 vpushi(32 - bit_size);
2046 /* NOTE: transformed to SHR if unsigned */
2047 gen_op(TOK_SAR);
2048 r = gv();
2049 } else {
2050 if (is_float(vtop->t) &&
2051 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2052 /* CPUs usually cannot use float constants, so we store them
2053 generically in data segment */
2054 size = type_size(vtop->t, &align);
2055 glo = (glo + align - 1) & -align;
2056 /* XXX: not portable yet */
2057 size = size >> 2;
2058 for(i=0;i<size;i++)
2059 ((int *)glo)[i] = vtop->c.tab[i];
2060 vtop->r |= VT_LVAL;
2061 vtop->c.ul = glo;
2062 glo += size << 2;
2064 r = vtop->r & VT_VALMASK;
2065 if (r >= VT_CONST || (vtop->r & VT_LVAL)) {
2066 if (is_float(vtop->t))
2067 rc = REG_CLASS_FLOAT;
2068 else
2069 rc = REG_CLASS_INT;
2070 r = get_reg(rc);
2072 load(r, vtop);
2073 vtop->r = r;
2075 return r;
2078 /* handle constant optimizations and various machine independant opt */
2079 void gen_opc(int op)
2081 int fc, c1, c2, n;
2082 SValue *v1, *v2;
2084 v1 = vtop - 1;
2085 v2 = vtop;
2086 /* currently, we cannot do computations with forward symbols */
2087 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2088 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2089 if (c1 && c2) {
2090 fc = v2->c.i;
2091 switch(op) {
2092 case '+': v1->c.i += fc; break;
2093 case '-': v1->c.i -= fc; break;
2094 case '&': v1->c.i &= fc; break;
2095 case '^': v1->c.i ^= fc; break;
2096 case '|': v1->c.i |= fc; break;
2097 case '*': v1->c.i *= fc; break;
2098 case TOK_PDIV:
2099 case '/': v1->c.i /= fc; break; /* XXX: zero case ? */
2100 case '%': v1->c.i %= fc; break; /* XXX: zero case ? */
2101 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break; /* XXX: zero case ? */
2102 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break; /* XXX: zero case ? */
2103 case TOK_SHL: v1->c.i <<= fc; break;
2104 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
2105 case TOK_SAR: v1->c.i >>= fc; break;
2106 /* tests */
2107 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
2108 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
2109 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
2110 case TOK_NE: v1->c.i = v1->c.i != fc; break;
2111 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
2112 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
2113 case TOK_LT: v1->c.i = v1->c.i < fc; break;
2114 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
2115 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
2116 case TOK_GT: v1->c.i = v1->c.i > fc; break;
2117 /* logical */
2118 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
2119 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
2120 default:
2121 goto general_case;
2123 vtop--;
2124 } else {
2125 /* if commutative ops, put c2 as constant */
2126 if (c1 && (op == '+' || op == '&' || op == '^' ||
2127 op == '|' || op == '*')) {
2128 vswap();
2129 swap(&c1, &c2);
2131 fc = vtop->c.i;
2132 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2133 op == TOK_PDIV) &&
2134 fc == 1) ||
2135 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2136 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2137 fc == 0) ||
2138 (op == '&' &&
2139 fc == -1))) {
2140 /* nothing to do */
2141 vtop--;
2142 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2143 /* try to use shifts instead of muls or divs */
2144 if (fc > 0 && (fc & (fc - 1)) == 0) {
2145 n = -1;
2146 while (fc) {
2147 fc >>= 1;
2148 n++;
2150 vtop->c.i = n;
2151 if (op == '*')
2152 op = TOK_SHL;
2153 else if (op == TOK_PDIV)
2154 op = TOK_SAR;
2155 else
2156 op = TOK_SHR;
2158 goto general_case;
2159 } else {
2160 general_case:
2161 /* call low level op generator */
2162 /* XXX: remove explicit registers */
2163 gen_opi(op);
2168 int pointed_size(int t)
2170 return type_size(pointed_type(t), &t);
2173 /* generic gen_op: handles types problems */
2174 void gen_op(int op)
2176 int u, t1, t2, bt1, bt2, t;
2178 t1 = vtop[-1].t;
2179 t2 = vtop[0].t;
2180 bt1 = t1 & VT_BTYPE;
2181 bt2 = t2 & VT_BTYPE;
2183 if (is_float(bt1) || is_float(bt2)) {
2184 /* compute bigger type and do implicit casts */
2185 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
2186 t = VT_LDOUBLE;
2187 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
2188 t = VT_DOUBLE;
2189 } else {
2190 t = VT_FLOAT;
2192 if (op != '+' && op != '-' && op != '*' && op != '/' &&
2193 op < TOK_EQ || op > TOK_GT)
2194 error("invalid operands for binary operation");
2195 if (bt1 != t) {
2196 vswap();
2197 gen_cast(t);
2198 vswap();
2200 if (bt2 != t) {
2201 gen_cast(t);
2203 gen_opf(op);
2204 if (op >= TOK_EQ && op <= TOK_GT) {
2205 /* the result is an int */
2206 vtop->t = VT_INT;
2207 } else {
2208 vtop->t = t;
2210 } else if (op == '+' || op == '-') {
2211 if ((t1 & VT_BTYPE) == VT_PTR &&
2212 (t2 & VT_BTYPE) == VT_PTR) {
2213 if (op != '-')
2214 error("invalid type");
2215 /* XXX: check that types are compatible */
2216 u = pointed_size(t1);
2217 gen_opc(op);
2218 /* set to integer type */
2219 vtop->t = VT_INT;
2220 vpushi(u);
2221 gen_op(TOK_PDIV);
2222 } else if ((t1 & VT_BTYPE) == VT_PTR ||
2223 (t2 & VT_BTYPE) == VT_PTR) {
2224 if ((t2 & VT_BTYPE) == VT_PTR) {
2225 vswap();
2226 swap(&t1, &t2);
2228 /* stack-4 contains pointer, stack-2 value to add */
2229 vpushi(pointed_size(vtop[-1].t));
2230 gen_op('*');
2231 gen_opc(op);
2232 /* put again type if gen_opc() swaped operands */
2233 vtop->t = t1;
2234 } else {
2235 gen_opc(op);
2237 } else {
2238 /* XXX: test types and compute returned value */
2239 if ((t1 | t2) & VT_UNSIGNED ||
2240 (t1 & VT_BTYPE) == VT_PTR ||
2241 (t2 & VT_BTYPE) == VT_PTR) {
2242 if (op == TOK_SAR)
2243 op = TOK_SHR;
2244 else if (op == '/')
2245 op = TOK_UDIV;
2246 else if (op == '%')
2247 op = TOK_UMOD;
2248 else if (op == TOK_LT)
2249 op = TOK_ULT;
2250 else if (op == TOK_GT)
2251 op = TOK_UGT;
2252 else if (op == TOK_LE)
2253 op = TOK_ULE;
2254 else if (op == TOK_GE)
2255 op = TOK_UGE;
2257 gen_opc(op);
2261 /* cast 'vtop' to 't' type */
2262 void gen_cast(int t)
2264 int bits, sbt, dbt, sf, df, c, st1, dt1;
2266 /* if not lvalue, then we convert now */
2267 dbt = t & VT_BTYPE;
2268 sbt = vtop->t & VT_BTYPE;
2269 if (sbt != dbt) {
2270 sf = is_float(sbt);
2271 df = is_float(dbt);
2272 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2273 if (sf && df) {
2274 /* convert from fp to fp */
2275 if (c) {
2276 /* constant case: we can do it now */
2277 /* XXX: in ISOC, cannot do it if error in convert */
2278 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
2279 vtop->c.f = (float)vtop->c.d;
2280 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
2281 vtop->c.f = (float)vtop->c.ld;
2282 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
2283 vtop->c.d = (double)vtop->c.f;
2284 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
2285 vtop->c.d = (double)vtop->c.ld;
2286 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
2287 vtop->c.ld = (long double)vtop->c.f;
2288 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
2289 vtop->c.ld = (long double)vtop->c.d;
2290 } else {
2291 /* non constant case: generate code */
2292 gen_cvt_ftof(dbt);
2294 } else if (df) {
2295 /* convert int to fp */
2296 /* XXX: add const cases */
2297 st1 = vtop->t & (VT_BTYPE | VT_UNSIGNED);
2298 if (c) {
2299 switch(st1) {
2300 case VT_LLONG | VT_UNSIGNED:
2301 case VT_LLONG:
2302 /* well, currently not needed */
2303 goto do_itof;
2304 case VT_INT | VT_UNSIGNED:
2305 switch(dbt) {
2306 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
2307 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
2308 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
2310 break;
2311 default:
2312 switch(dbt) {
2313 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
2314 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
2315 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
2317 break;
2319 } else {
2320 do_itof:
2321 gen_cvt_itof(dbt);
2323 } else if (sf) {
2324 /* convert fp to int */
2325 dt1 = t & (VT_BTYPE | VT_UNSIGNED);
2326 /* we handle char/short/etc... with generic code */
2327 if (dt1 != VT_INT | VT_UNSIGNED &&
2328 dt1 != VT_LLONG | VT_UNSIGNED &&
2329 dt1 != VT_LLONG)
2330 dt1 = VT_INT;
2331 if (c) {
2332 switch(dt1) {
2333 case VT_LLONG | VT_UNSIGNED:
2334 case VT_LLONG:
2335 /* well, currently not needed */
2336 goto do_ftoi;
2337 case VT_INT | VT_UNSIGNED:
2338 switch(sbt) {
2339 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
2340 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
2341 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
2343 break;
2344 default:
2345 /* int case */
2346 switch(sbt) {
2347 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
2348 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
2349 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
2351 break;
2353 } else {
2354 do_ftoi:
2355 gen_cvt_ftoi(dt1);
2357 if (dt1 == VT_INT && (t & (VT_TYPE | VT_UNSIGNED)) != dt1) {
2358 /* additionnal cast for char/short/bool... */
2359 vtop->t = (vtop->t & ~VT_TYPE) | dt1;
2360 gen_cast(t);
2362 } else if (dbt == VT_BOOL) {
2363 vpushi(0);
2364 gen_op(TOK_NE);
2365 } else if ((dbt == VT_BYTE || dbt == VT_SHORT) &&
2366 !(vtop->r & VT_LVAL)) {
2367 /* no need to apply if lvalue because we do it while
2368 loading the value */
2369 if (dbt == VT_BYTE)
2370 bits = 8;
2371 else
2372 bits = 16;
2373 if (t & VT_UNSIGNED) {
2374 vpushi((1 << bits) - 1);
2375 gen_op('&');
2376 } else {
2377 bits = 32 - bits;
2378 vpushi(bits);
2379 gen_op(TOK_SHL);
2380 vpushi(bits);
2381 gen_op(TOK_SAR);
2385 vtop->t = t;
2388 /* return type size. Put alignment at 'a' */
2389 int type_size(int t, int *a)
2391 Sym *s;
2392 int bt;
2394 bt = t & VT_BTYPE;
2395 if (bt == VT_STRUCT) {
2396 /* struct/union */
2397 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
2398 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
2399 return s->c;
2400 } else if (bt == VT_PTR) {
2401 if (t & VT_ARRAY) {
2402 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
2403 return type_size(s->t, a) * s->c;
2404 } else {
2405 *a = PTR_SIZE;
2406 return PTR_SIZE;
2408 } else if (bt == VT_LDOUBLE) {
2409 *a = LDOUBLE_ALIGN;
2410 return LDOUBLE_SIZE;
2411 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2412 *a = 8;
2413 return 8;
2414 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2415 *a = 4;
2416 return 4;
2417 } else if (bt == VT_SHORT) {
2418 *a = 2;
2419 return 2;
2420 } else {
2421 /* char, void, function, _Bool */
2422 *a = 1;
2423 return 1;
2427 /* return the pointed type of t */
2428 int pointed_type(int t)
2430 Sym *s;
2431 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
2432 return s->t | (t & ~VT_TYPE);
2435 int mk_pointer(int t)
2437 int p;
2438 p = anon_sym++;
2439 sym_push(p, t, -1);
2440 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
2443 int is_compatible_types(int t1, int t2)
2445 Sym *s1, *s2;
2446 int bt1, bt2;
2448 t1 &= VT_TYPE;
2449 t2 &= VT_TYPE;
2450 bt1 = t1 & VT_BTYPE;
2451 bt2 = t2 & VT_BTYPE;
2452 if (bt1 == VT_PTR) {
2453 t1 = pointed_type(t1);
2454 /* if function, then convert implicitely to function pointer */
2455 if (bt2 != VT_FUNC) {
2456 if (bt2 != VT_PTR)
2457 return 0;
2458 t2 = pointed_type(t2);
2460 /* void matches everything */
2461 t1 &= VT_TYPE;
2462 t2 &= VT_TYPE;
2463 if (t1 == VT_VOID || t2 == VT_VOID)
2464 return 1;
2465 return is_compatible_types(t1, t2);
2466 } else if (bt1 == VT_STRUCT) {
2467 return (t2 == t1);
2468 } else if (bt1 == VT_FUNC) {
2469 if (bt2 != VT_FUNC)
2470 return 0;
2471 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
2472 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
2473 if (!is_compatible_types(s1->t, s2->t))
2474 return 0;
2475 /* XXX: not complete */
2476 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2477 return 1;
2478 if (s1->c != s2->c)
2479 return 0;
2480 while (s1 != NULL) {
2481 if (s2 == NULL)
2482 return 0;
2483 if (!is_compatible_types(s1->t, s2->t))
2484 return 0;
2485 s1 = s1->next;
2486 s2 = s2->next;
2488 if (s2)
2489 return 0;
2490 return 1;
2491 } else {
2492 /* XXX: not complete */
2493 return 1;
2497 int check_assign_types(int t1, int t2)
2499 t1 &= VT_TYPE;
2500 t2 &= VT_TYPE;
2501 if ((t1 & VT_BTYPE) == VT_PTR &&
2502 (t2 & VT_BTYPE) == VT_FUNC) {
2503 return is_compatible_types(pointed_type(t1), t2);
2504 } else {
2505 return is_compatible_types(t1, t2);
2509 /* print a type. If 'varstr' is not NULL, then the variable is also
2510 printed in the type */
2511 /* XXX: add array and function pointers */
2512 /* XXX: buffer overflows */
2513 void type_to_str(char *buf, int buf_size,
2514 int t, const char *varstr)
2516 int bt, v;
2517 Sym *s, *sa;
2518 char buf1[256];
2520 t = t & VT_TYPE;
2521 bt = t & VT_BTYPE;
2522 buf[0] = '\0';
2523 if (t & VT_UNSIGNED)
2524 strcat(buf, "unsigned ");
2525 switch(bt) {
2526 case VT_VOID:
2527 strcat(buf, "void");
2528 break;
2529 case VT_BOOL:
2530 strcat(buf, "_Bool");
2531 break;
2532 case VT_BYTE:
2533 strcat(buf, "char");
2534 break;
2535 case VT_SHORT:
2536 strcat(buf, "short");
2537 break;
2538 case VT_INT:
2539 strcat(buf, "int");
2540 break;
2541 case VT_LONG:
2542 strcat(buf, "long");
2543 break;
2544 case VT_LLONG:
2545 strcat(buf, "long long");
2546 break;
2547 case VT_FLOAT:
2548 strcat(buf, "float");
2549 break;
2550 case VT_DOUBLE:
2551 strcat(buf, "double");
2552 break;
2553 case VT_LDOUBLE:
2554 strcat(buf, "long double");
2555 break;
2556 case VT_ENUM:
2557 case VT_STRUCT:
2558 if (bt == VT_STRUCT)
2559 strcat(buf, "struct ");
2560 else
2561 strcat(buf, "enum ");
2562 v = (unsigned)t >> VT_STRUCT_SHIFT;
2563 if (v >= SYM_FIRST_ANOM)
2564 strcat(buf, "<anonymous>");
2565 else
2566 strcat(buf, get_tok_str(v, NULL));
2567 break;
2568 case VT_FUNC:
2569 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
2570 type_to_str(buf, buf_size, s->t, varstr);
2571 strcat(buf, "(");
2572 sa = s->next;
2573 while (sa != NULL) {
2574 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
2575 strcat(buf, buf1);
2576 sa = sa->next;
2577 if (sa)
2578 strcat(buf, ", ");
2580 strcat(buf, ")");
2581 goto no_var;
2582 case VT_PTR:
2583 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
2584 strcpy(buf1, "*");
2585 if (varstr)
2586 strcat(buf1, varstr);
2587 type_to_str(buf, buf_size, s->t, buf1);
2588 goto no_var;
2590 if (varstr) {
2591 strcat(buf, " ");
2592 strcat(buf, varstr);
2594 no_var: ;
2599 /* verify type compatibility to store vtop in 'st' type, and generate
2600 casts if needed */
2601 void gen_assign_cast(int dt)
2603 int st;
2604 char buf1[256], buf2[256];
2606 st = vtop->t; /* destination type */
2607 if (!check_assign_types(dt, st)) {
2608 type_to_str(buf1, sizeof(buf1), st, NULL);
2609 type_to_str(buf2, sizeof(buf2), dt, NULL);
2610 error("cannot cast '%s' to '%s'", buf1, buf2);
2612 if ((dt & VT_BTYPE) == VT_BOOL || is_float(dt)) {
2613 gen_cast(dt & VT_BTYPE);
2618 /* store vtop in lvalue pushed on stack */
2619 void vstore(void)
2621 int ft, r, t, size, align, bit_size, bit_pos;
2622 GFuncContext gf;
2624 ft = vtop[-1].t;
2625 gen_assign_cast(ft & VT_TYPE);
2627 if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
2628 /* if structure, only generate pointer */
2629 /* structure assignment : generate memcpy */
2630 /* XXX: optimize if small size */
2632 vdup();
2633 gfunc_start(&gf);
2634 /* type size */
2635 size = type_size(vtop->t, &align);
2636 vpushi(size);
2637 gfunc_param(&gf);
2638 /* source */
2639 vtop->t = VT_INT;
2640 vtop->r &= ~VT_LVAL;
2641 gfunc_param(&gf);
2642 /* destination */
2643 vswap();
2644 vtop->t = VT_INT;
2645 vtop->r &= ~VT_LVAL;
2646 gfunc_param(&gf);
2648 save_regs();
2649 vpushi((int)&memcpy);
2650 gfunc_call(&gf);
2651 /* leave source on stack */
2652 } else if (ft & VT_BITFIELD) {
2653 /* bitfield store handling */
2654 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2655 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2656 /* remove bit field info to avoid loops */
2657 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2659 /* duplicate destination */
2660 vdup();
2661 vtop[-1] = vtop[-2];
2663 /* mask and shift source */
2664 vpushi((1 << bit_size) - 1);
2665 gen_op('&');
2666 vpushi(bit_pos);
2667 gen_op(TOK_SHL);
2668 /* load destination, mask and or with source */
2669 vswap();
2670 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2671 gen_op('&');
2672 gen_op('|');
2673 /* store result */
2674 vstore();
2675 } else {
2676 r = gv(); /* generate value */
2677 /* if lvalue was saved on stack, must read it */
2678 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2679 SValue sv;
2680 t = get_reg(REG_CLASS_INT);
2681 sv.t = VT_INT;
2682 sv.r = VT_LOCAL | VT_LVAL;
2683 sv.c.ul = vtop[-1].c.ul;
2684 load(t, &sv);
2685 vtop[-1].r = t | VT_LVAL;
2687 store(r, vtop - 1);
2688 vtop--;
2689 vtop->r = r;
2690 vtop->c.i = 0;
2694 /* post defines POST/PRE add. c is the token ++ or -- */
2695 void inc(int post, int c)
2697 int r, r1;
2698 SValue sv;
2700 test_lvalue();
2701 if (post)
2702 vdup(); /* room for returned value */
2703 vdup(); /* save lvalue */
2704 r = gv();
2705 if (post) {
2706 /* duplicate value */
2707 /* XXX: handle floats */
2708 r1 = get_reg(REG_CLASS_INT);
2709 sv.t = VT_INT;
2710 sv.r = r;
2711 sv.c.ul = 0;
2712 load(r1, &sv); /* move r to r1 */
2713 /* duplicates value */
2714 vtop[-2].r = r1;
2715 vtop[-2].c.i = 0;
2717 /* add constant */
2718 vpushi(c - TOK_MID);
2719 gen_op('+');
2720 vstore(); /* store value */
2721 if (post)
2722 vpop(); /* if post op, return saved value */
2725 /* enum/struct/union declaration */
2726 int struct_decl(int u)
2728 int a, t, b, v, size, align, maxalign, c, offset;
2729 int bit_size, bit_pos, bsize, bt, lbit_pos;
2730 Sym *s, *ss, **ps;
2732 a = tok; /* save decl type */
2733 next();
2734 if (tok != '{') {
2735 v = tok;
2736 next();
2737 /* struct already defined ? return it */
2738 /* XXX: check consistency */
2739 if (s = sym_find(v | SYM_STRUCT)) {
2740 if (s->t != a)
2741 error("invalid type");
2742 goto do_decl;
2744 } else {
2745 v = anon_sym++;
2747 s = sym_push(v | SYM_STRUCT, a, 0);
2748 /* put struct/union/enum name in type */
2749 do_decl:
2750 u = u | (v << VT_STRUCT_SHIFT);
2752 if (tok == '{') {
2753 next();
2754 if (s->c)
2755 error("struct/union/enum already defined");
2756 /* cannot be empty */
2757 c = 0;
2758 maxalign = 0;
2759 ps = &s->next;
2760 bit_pos = 0;
2761 offset = 0;
2762 while (1) {
2763 if (a == TOK_ENUM) {
2764 v = tok;
2765 next();
2766 if (tok == '=') {
2767 next();
2768 c = expr_const();
2770 /* enum symbols have static storage */
2771 sym_push(v, VT_CONST | VT_STATIC, c);
2772 if (tok == ',')
2773 next();
2774 c++;
2775 } else {
2776 b = ist();
2777 while (1) {
2778 bit_size = -1;
2779 v = 0;
2780 if (tok != ':') {
2781 t = type_decl(&v, b, TYPE_DIRECT);
2782 if ((t & VT_BTYPE) == VT_FUNC ||
2783 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
2784 error("invalid type for '%s'",
2785 get_tok_str(v, NULL));
2786 } else {
2787 t = b;
2789 if (tok == ':') {
2790 next();
2791 bit_size = expr_const();
2792 /* XXX: handle v = 0 case for messages */
2793 if (bit_size < 0)
2794 error("negative width in bit-field '%s'",
2795 get_tok_str(v, NULL));
2796 if (v && bit_size == 0)
2797 error("zero width for bit-field '%s'",
2798 get_tok_str(v, NULL));
2800 size = type_size(t, &align);
2801 lbit_pos = 0;
2802 if (bit_size >= 0) {
2803 bt = t & VT_BTYPE;
2804 if (bt != VT_INT &&
2805 bt != VT_BYTE &&
2806 bt != VT_SHORT)
2807 error("bitfields must have scalar type");
2808 bsize = size * 8;
2809 if (bit_size > bsize) {
2810 error("width of '%s' exceeds its type",
2811 get_tok_str(v, NULL));
2812 } else if (bit_size == bsize) {
2813 /* no need for bit fields */
2814 bit_pos = 0;
2815 } else if (bit_size == 0) {
2816 /* XXX: what to do if only padding in a
2817 structure ? */
2818 /* zero size: means to pad */
2819 if (bit_pos > 0)
2820 bit_pos = bsize;
2821 } else {
2822 /* we do not have enough room ? */
2823 if ((bit_pos + bit_size) > bsize)
2824 bit_pos = 0;
2825 lbit_pos = bit_pos;
2826 /* XXX: handle LSB first */
2827 t |= VT_BITFIELD |
2828 (bit_pos << VT_STRUCT_SHIFT) |
2829 (bit_size << (VT_STRUCT_SHIFT + 6));
2830 bit_pos += bit_size;
2832 } else {
2833 bit_pos = 0;
2835 if (v) {
2836 /* add new memory data only if starting
2837 bit field */
2838 if (lbit_pos == 0) {
2839 if (a == TOK_STRUCT) {
2840 c = (c + align - 1) & -align;
2841 offset = c;
2842 c += size;
2843 } else {
2844 offset = 0;
2845 if (size > c)
2846 c = size;
2848 if (align > maxalign)
2849 maxalign = align;
2851 #if 0
2852 printf("add field %s offset=%d",
2853 get_tok_str(v, NULL), offset);
2854 if (t & VT_BITFIELD) {
2855 printf(" pos=%d size=%d",
2856 (t >> VT_STRUCT_SHIFT) & 0x3f,
2857 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2859 printf("\n");
2860 #endif
2861 ss = sym_push(v | SYM_FIELD, t, offset);
2862 *ps = ss;
2863 ps = &ss->next;
2865 if (tok == ';' || tok == -1)
2866 break;
2867 skip(',');
2869 skip(';');
2871 if (tok == '}')
2872 break;
2874 skip('}');
2875 /* size for struct/union, dummy for enum */
2876 s->c = (c + maxalign - 1) & -maxalign;
2878 return u;
2881 /* return 0 if no type declaration. otherwise, return the basic type
2882 and skip it.
2883 XXX: A '2' is ored to ensure non zero return if int type.
2885 int ist(void)
2887 int t, u;
2888 Sym *s;
2890 t = 0;
2891 while(1) {
2892 switch(tok) {
2893 /* basic types */
2894 case TOK_CHAR:
2895 u = VT_BYTE;
2896 basic_type:
2897 next();
2898 basic_type1:
2899 if ((t & VT_BTYPE) != 0)
2900 error("too many basic types");
2901 t |= u;
2902 break;
2903 case TOK_VOID:
2904 u = VT_VOID;
2905 goto basic_type;
2906 case TOK_SHORT:
2907 u = VT_SHORT;
2908 goto basic_type;
2909 case TOK_INT:
2910 next();
2911 break;
2912 case TOK_LONG:
2913 next();
2914 if ((t & VT_BTYPE) == VT_DOUBLE) {
2915 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2916 } else if ((t & VT_BTYPE) == VT_LONG) {
2917 t = (t & ~VT_BTYPE) | VT_LLONG;
2918 } else {
2919 u = VT_LONG;
2920 goto basic_type1;
2922 break;
2923 case TOK_BOOL:
2924 u = VT_BOOL;
2925 goto basic_type;
2926 case TOK_FLOAT:
2927 u = VT_FLOAT;
2928 goto basic_type;
2929 case TOK_DOUBLE:
2930 next();
2931 if ((t & VT_BTYPE) == VT_LONG) {
2932 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2933 } else {
2934 u = VT_DOUBLE;
2935 goto basic_type1;
2937 break;
2938 case TOK_ENUM:
2939 u = struct_decl(VT_ENUM);
2940 goto basic_type1;
2941 case TOK_STRUCT:
2942 case TOK_UNION:
2943 u = struct_decl(VT_STRUCT);
2944 goto basic_type1;
2946 /* type modifiers */
2947 case TOK_CONST:
2948 case TOK_VOLATILE:
2949 case TOK_REGISTER:
2950 case TOK_SIGNED:
2951 case TOK_AUTO:
2952 case TOK_INLINE:
2953 case TOK_RESTRICT:
2954 next();
2955 break;
2956 case TOK_UNSIGNED:
2957 t |= VT_UNSIGNED;
2958 next();
2959 break;
2961 /* storage */
2962 case TOK_EXTERN:
2963 t |= VT_EXTERN;
2964 next();
2965 break;
2966 case TOK_STATIC:
2967 t |= VT_STATIC;
2968 next();
2969 break;
2970 case TOK_TYPEDEF:
2971 t |= VT_TYPEDEF;
2972 next();
2973 break;
2974 default:
2975 s = sym_find(tok);
2976 if (!s || !(s->t & VT_TYPEDEF))
2977 goto the_end;
2978 t |= (s->t & ~VT_TYPEDEF);
2979 next();
2980 break;
2982 t |= 2;
2984 the_end:
2985 /* long is never used as type */
2986 if ((t & VT_BTYPE) == VT_LONG)
2987 t = (t & ~VT_BTYPE) | VT_INT;
2988 return t;
2991 int post_type(int t)
2993 int p, n, pt, l, t1;
2994 Sym **plast, *s, *first;
2996 if (tok == '(') {
2997 /* function declaration */
2998 next();
2999 l = 0;
3000 first = NULL;
3001 plast = &first;
3002 while (tok != ')') {
3003 /* read param name and compute offset */
3004 if (l != FUNC_OLD) {
3005 if (!(pt = ist())) {
3006 if (l) {
3007 error("invalid type");
3008 } else {
3009 l = FUNC_OLD;
3010 goto old_proto;
3013 l = FUNC_NEW;
3014 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
3015 break;
3016 pt = type_decl(&n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
3017 if ((pt & VT_BTYPE) == VT_VOID)
3018 error("parameter declared as void");
3019 } else {
3020 old_proto:
3021 n = tok;
3022 pt = VT_INT;
3023 next();
3025 /* array must be transformed to pointer according to ANSI C */
3026 pt &= ~VT_ARRAY;
3027 s = sym_push(n | SYM_FIELD, pt, 0);
3028 *plast = s;
3029 plast = &s->next;
3030 if (tok == ',') {
3031 next();
3032 if (l == FUNC_NEW && tok == TOK_DOTS) {
3033 l = FUNC_ELLIPSIS;
3034 next();
3035 break;
3039 /* if no parameters, then old type prototype */
3040 if (l == 0)
3041 l = FUNC_OLD;
3042 skip(')');
3043 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
3044 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN));
3045 /* we push a anonymous symbol which will contain the function prototype */
3046 p = anon_sym++;
3047 s = sym_push(p, t, l);
3048 s->next = first;
3049 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
3050 } else if (tok == '[') {
3051 /* array definition */
3052 next();
3053 n = -1;
3054 if (tok != ']') {
3055 n = expr_const();
3056 if (n < 0)
3057 error("invalid array size");
3059 skip(']');
3060 /* parse next post type */
3061 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
3062 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN));
3064 /* we push a anonymous symbol which will contain the array
3065 element type */
3066 p = anon_sym++;
3067 sym_push(p, t, n);
3068 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
3070 return t;
3073 /* Read a type declaration (except basic type), and return the
3074 type. If v is true, then also put variable name in 'vtop->c' */
3075 int type_decl(int *v, int t, int td)
3077 int u, p;
3078 Sym *s;
3080 t = t & -3; /* suppress the ored '2' */
3081 while (tok == '*') {
3082 next();
3083 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
3084 next();
3085 t = mk_pointer(t);
3088 /* recursive type */
3089 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3090 if (tok == '(') {
3091 next();
3092 u = type_decl(v, 0, td);
3093 skip(')');
3094 } else {
3095 u = 0;
3096 /* type identifier */
3097 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3098 *v = tok;
3099 next();
3100 } else {
3101 if (!(td & TYPE_ABSTRACT))
3102 expect("identifier");
3103 *v = 0;
3106 /* append t at the end of u */
3107 t = post_type(t);
3108 if (!u)
3109 return t;
3110 p = u;
3111 while(1) {
3112 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
3113 p = s->t;
3114 if (!p) {
3115 s->t = t;
3116 break;
3119 return u;
3122 /* define a new external reference to a function 'v' of type 'u' */
3123 Sym *external_sym(int v, int u)
3125 Sym *s;
3126 s = sym_find(v);
3127 if (!s) {
3128 /* push forward reference */
3129 s = sym_push1(&global_stack,
3130 v, u | VT_CONST | VT_FORWARD, 0);
3132 return s;
3135 void indir(void)
3137 if (vtop->r & VT_LVAL)
3138 gv();
3139 if ((vtop->t & VT_BTYPE) != VT_PTR)
3140 expect("pointer");
3141 vtop->t = pointed_type(vtop->t);
3142 if (!(vtop->t & VT_ARRAY)) /* an array is never an lvalue */
3143 vtop->r |= VT_LVAL;
3146 /* pass a parameter to a function and do type checking and casting */
3147 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
3149 int func_type;
3150 func_type = func->c;
3151 if (func_type == FUNC_OLD ||
3152 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3153 /* default casting : only need to convert float to double */
3154 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
3155 gen_cast(VT_DOUBLE);
3156 } else if (arg == NULL) {
3157 error("too many arguments to function");
3158 } else {
3159 gen_assign_cast(arg->t);
3161 gfunc_param(gf);
3164 void unary(void)
3166 int n, t, ft, fc, p, align, size;
3167 Sym *s;
3168 GFuncContext gf;
3170 if (tok == TOK_NUM || tok == TOK_CCHAR || tok == TOK_LCHAR) {
3171 vpushi(tokc.i);
3172 next();
3173 } else if (tok == TOK_CFLOAT) {
3174 vsetc(VT_FLOAT, VT_CONST, &tokc);
3175 next();
3176 } else if (tok == TOK_CDOUBLE) {
3177 vsetc(VT_DOUBLE, VT_CONST, &tokc);
3178 next();
3179 } else if (tok == TOK_CLDOUBLE) {
3180 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
3181 next();
3182 } else if (tok == TOK___FUNC__) {
3183 /* special function name identifier */
3184 /* generate (char *) type */
3185 vset(mk_pointer(VT_BYTE), VT_CONST, glo);
3186 strcpy((void *)glo, funcname);
3187 glo += strlen(funcname) + 1;
3188 next();
3189 } else if (tok == TOK_LSTR) {
3190 t = VT_INT;
3191 goto str_init;
3192 } else if (tok == TOK_STR) {
3193 /* string parsing */
3194 t = VT_BYTE;
3195 str_init:
3196 type_size(t, &align);
3197 glo = (glo + align - 1) & -align;
3198 fc = glo;
3199 /* we must declare it as an array first to use initializer parser */
3200 t = VT_CONST | VT_ARRAY | mk_pointer(t);
3201 decl_initializer(t, glo, 1, 0);
3202 glo += type_size(t, &align);
3203 /* put it as pointer */
3204 vset(t & ~VT_ARRAY, VT_CONST, fc);
3205 } else {
3206 t = tok;
3207 next();
3208 if (t == '(') {
3209 /* cast ? */
3210 if (t = ist()) {
3211 ft = type_decl(&n, t, TYPE_ABSTRACT);
3212 skip(')');
3213 /* check ISOC99 compound literal */
3214 if (tok == '{') {
3215 /* data is allocated locally by default */
3216 if (global_expr)
3217 ft |= VT_CONST;
3218 else
3219 ft |= VT_LOCAL;
3220 /* all except arrays are lvalues */
3221 if (!(ft & VT_ARRAY))
3222 ft |= VT_LVAL;
3223 fc = decl_initializer_alloc(ft, 1);
3224 vset(ft & VT_TYPE, ft & (VT_VALMASK | VT_LVAL), fc);
3225 } else {
3226 unary();
3227 gen_cast(ft);
3229 } else {
3230 gexpr();
3231 skip(')');
3233 } else if (t == '*') {
3234 unary();
3235 indir();
3236 } else if (t == '&') {
3237 unary();
3238 /* functions names must be treated as function pointers,
3239 except for unary '&' and sizeof. Since we consider that
3240 functions are not lvalues, we only have to handle it
3241 there and in function calls. */
3242 if ((vtop->t & VT_BTYPE) != VT_FUNC)
3243 test_lvalue();
3244 vtop->t = mk_pointer(vtop->t);
3245 vtop->r &= ~VT_LVAL;
3246 } else
3247 if (t == '!') {
3248 unary();
3249 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
3250 vtop->c.i = !vtop->c.i;
3251 else if ((vtop->r & VT_VALMASK) == VT_CMP)
3252 vtop->c.i = vtop->c.i ^ 1;
3253 else
3254 vset(VT_INT, VT_JMP, gtst(1, 0));
3255 } else
3256 if (t == '~') {
3257 unary();
3258 vpushi(-1);
3259 gen_op('^');
3260 } else
3261 if (t == '+') {
3262 unary();
3263 } else
3264 if (t == TOK_SIZEOF) {
3265 if (tok == '(') {
3266 next();
3267 if (t = ist())
3268 t = type_decl(&n, t, TYPE_ABSTRACT);
3269 else {
3270 /* XXX: some code could be generated: add eval
3271 flag */
3272 gexpr();
3273 t = vtop->t;
3274 vpop();
3276 skip(')');
3277 } else {
3278 unary();
3279 t = vtop->t;
3280 vpop();
3282 vpushi(type_size(t, &t));
3283 } else
3284 if (t == TOK_INC || t == TOK_DEC) {
3285 unary();
3286 inc(0, t);
3287 } else if (t == '-') {
3288 vpushi(0);
3289 unary();
3290 gen_op('-');
3291 } else
3293 s = sym_find(t);
3294 if (!s) {
3295 if (tok != '(')
3296 error("'%s' undeclared", get_tok_str(t, NULL));
3297 /* for simple function calls, we tolerate undeclared
3298 external reference */
3299 p = anon_sym++;
3300 sym_push1(&global_stack, p, 0, FUNC_OLD);
3301 /* int() function */
3302 s = external_sym(t, VT_FUNC | (p << VT_STRUCT_SHIFT));
3304 vset(s->t & VT_TYPE,
3305 s->t & (VT_VALMASK | VT_LVAL | VT_FORWARD), s->c);
3306 /* if forward reference, we must point to s */
3307 if (vtop->r & VT_FORWARD)
3308 vtop->c.sym = s;
3312 /* post operations */
3313 while (1) {
3314 if (tok == TOK_INC | tok == TOK_DEC) {
3315 inc(1, tok);
3316 next();
3317 } else if (tok == '.' | tok == TOK_ARROW) {
3318 /* field */
3319 if (tok == TOK_ARROW)
3320 indir();
3321 test_lvalue();
3322 vtop->r &= ~VT_LVAL;
3323 next();
3324 /* expect pointer on structure */
3325 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
3326 expect("struct or union");
3327 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3328 /* find field */
3329 tok |= SYM_FIELD;
3330 while (s = s->next) {
3331 if (s->v == tok)
3332 break;
3334 if (!s)
3335 error("field not found");
3336 /* add field offset to pointer */
3337 vtop->t = VT_INT; /* change type to int */
3338 vpushi(s->c);
3339 gen_op('+');
3340 /* change type to field type, and set to lvalue */
3341 vtop->t = s->t;
3342 /* an array is never an lvalue */
3343 if (!(vtop->t & VT_ARRAY))
3344 vtop->r |= VT_LVAL;
3345 next();
3346 } else if (tok == '[') {
3347 next();
3348 gexpr();
3349 gen_op('+');
3350 indir();
3351 skip(']');
3352 } else if (tok == '(') {
3353 SValue ret;
3354 Sym *sa;
3356 /* function call */
3357 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
3358 /* pointer test (no array accepted) */
3359 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3360 vtop->t = pointed_type(vtop->t);
3361 if ((vtop->t & VT_BTYPE) != VT_FUNC)
3362 goto error_func;
3363 } else {
3364 error_func:
3365 expect("function pointer");
3367 } else {
3368 vtop->r &= ~VT_LVAL; /* no lvalue */
3370 /* get return type */
3371 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
3372 save_regs(); /* save used temporary registers */
3373 gfunc_start(&gf);
3374 next();
3375 sa = s->next; /* first parameter */
3376 #ifdef INVERT_FUNC_PARAMS
3378 int *str, len, parlevel, *saved_macro_ptr;
3379 Sym *args, *s1;
3381 /* read each argument and store it on a stack */
3382 /* XXX: merge it with macro args ? */
3383 args = NULL;
3384 while (tok != ')') {
3385 len = 0;
3386 str = NULL;
3387 parlevel = 0;
3388 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
3389 tok != -1) {
3390 if (tok == '(')
3391 parlevel++;
3392 else if (tok == ')')
3393 parlevel--;
3394 tok_add2(&str, &len, tok, &tokc);
3395 next();
3397 tok_add(&str, &len, -1); /* end of file added */
3398 tok_add(&str, &len, 0);
3399 s1 = sym_push2(&args, 0, 0, (int)str);
3400 s1->next = sa; /* add reference to argument */
3401 if (sa)
3402 sa = sa->next;
3403 if (tok != ',')
3404 break;
3405 next();
3407 if (tok != ')')
3408 expect(")");
3410 /* now generate code in reverse order by reading the stack */
3411 saved_macro_ptr = macro_ptr;
3412 while (args) {
3413 macro_ptr = (int *)args->c;
3414 next();
3415 expr_eq();
3416 if (tok != -1)
3417 expect("',' or ')'");
3418 gfunc_param_typed(&gf, s, args->next);
3419 s1 = args->prev;
3420 free((int *)args->c);
3421 free(args);
3422 args = s1;
3424 macro_ptr = saved_macro_ptr;
3425 /* restore token */
3426 tok = ')';
3428 #endif
3429 /* compute first implicit argument if a structure is returned */
3430 if ((s->t & VT_BTYPE) == VT_STRUCT) {
3431 /* get some space for the returned structure */
3432 size = type_size(s->t, &align);
3433 loc = (loc - size) & -align;
3434 ret.t = s->t;
3435 ret.r = VT_LOCAL | VT_LVAL;
3436 /* pass it as 'int' to avoid structure arg passing
3437 problems */
3438 vset(VT_INT, VT_LOCAL, loc);
3439 ret.c = vtop->c;
3440 gfunc_param(&gf);
3441 } else {
3442 ret.t = s->t;
3443 ret.r = FUNC_RET_REG; /* return in register */
3444 ret.c.i = 0;
3446 #ifndef INVERT_FUNC_PARAMS
3447 while (tok != ')') {
3448 expr_eq();
3449 gfunc_param_typed(&gf, s, sa);
3450 if (sa)
3451 sa = sa->next;
3452 if (tok == ',')
3453 next();
3455 #endif
3456 if (sa)
3457 error("too few arguments to function");
3458 skip(')');
3459 gfunc_call(&gf);
3460 /* return value */
3461 vsetc(ret.t, ret.r, &ret.c);
3462 } else {
3463 break;
3468 void uneq(void)
3470 int t;
3472 unary();
3473 if (tok == '=' ||
3474 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3475 tok == TOK_A_XOR || tok == TOK_A_OR ||
3476 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3477 test_lvalue();
3478 t = tok;
3479 next();
3480 if (t == '=') {
3481 expr_eq();
3482 } else {
3483 vdup();
3484 expr_eq();
3485 gen_op(t & 0x7f);
3487 vstore();
3491 void sum(int l)
3493 int t;
3495 if (l == 0)
3496 uneq();
3497 else {
3498 sum(--l);
3499 while ((l == 0 & (tok == '*' | tok == '/' | tok == '%')) |
3500 (l == 1 & (tok == '+' | tok == '-')) |
3501 (l == 2 & (tok == TOK_SHL | tok == TOK_SAR)) |
3502 (l == 3 & ((tok >= TOK_ULE & tok <= TOK_GT) |
3503 tok == TOK_ULT | tok == TOK_UGE)) |
3504 (l == 4 & (tok == TOK_EQ | tok == TOK_NE)) |
3505 (l == 5 & tok == '&') |
3506 (l == 6 & tok == '^') |
3507 (l == 7 & tok == '|') |
3508 (l == 8 & tok == TOK_LAND) |
3509 (l == 9 & tok == TOK_LOR)) {
3510 t = tok;
3511 next();
3512 sum(l);
3513 gen_op(t);
3518 /* only used if non constant */
3519 void eand(void)
3521 int t;
3523 sum(8);
3524 t = 0;
3525 while (1) {
3526 if (tok != TOK_LAND) {
3527 if (t) {
3528 t = gtst(1, t);
3529 vset(VT_INT, VT_JMPI, t);
3531 break;
3533 t = gtst(1, t);
3534 next();
3535 sum(8);
3539 void eor(void)
3541 int t;
3543 eand();
3544 t = 0;
3545 while (1) {
3546 if (tok != TOK_LOR) {
3547 if (t) {
3548 t = gtst(0, t);
3549 vset(VT_INT, VT_JMP, t);
3551 break;
3553 t = gtst(0, t);
3554 next();
3555 eand();
3559 /* XXX: better constant handling */
3560 void expr_eq(void)
3562 int t, u, c, r1, r2;
3564 if (const_wanted) {
3565 sum(10);
3566 if (tok == '?') {
3567 c = vtop->c.i;
3568 vpop();
3569 next();
3570 gexpr();
3571 t = vtop->c.i;
3572 vpop();
3573 skip(':');
3574 expr_eq();
3575 if (c)
3576 vtop->c.i = t;
3578 } else {
3579 eor();
3580 if (tok == '?') {
3581 next();
3582 t = gtst(1, 0);
3584 gexpr();
3585 r1 = gv();
3586 vpop();
3587 skip(':');
3588 u = gjmp(0);
3590 gsym(t);
3591 expr_eq();
3592 r2 = gv();
3593 move_reg(r1, r2);
3594 vtop->r = r1;
3595 gsym(u);
3600 void gexpr(void)
3602 while (1) {
3603 expr_eq();
3604 if (tok != ',')
3605 break;
3606 vpop();
3607 next();
3611 /* parse a constant expression and return value in vtop */
3612 void expr_const1(void)
3614 int a;
3615 a = const_wanted;
3616 const_wanted = 1;
3617 expr_eq();
3618 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
3619 expect("constant");
3620 const_wanted = a;
3623 /* parse an integer constant and return its value */
3624 int expr_const(void)
3626 int c;
3627 expr_const1();
3628 c = vtop->c.i;
3629 vpop();
3630 return c;
3633 /* return the label token if current token is a label, otherwise
3634 return zero */
3635 int is_label(void)
3637 int t;
3638 CValue c;
3640 /* fast test first */
3641 if (tok < TOK_UIDENT)
3642 return 0;
3643 /* no need to save tokc since we expect an identifier */
3644 t = tok;
3645 c = tokc;
3646 next();
3647 if (tok == ':') {
3648 next();
3649 return t;
3650 } else {
3651 /* XXX: may not work in all cases (macros ?) */
3652 tok1 = tok;
3653 tok1c = tokc;
3654 tok = t;
3655 tokc = c;
3656 return 0;
3660 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
3662 int a, b, c, d;
3663 Sym *s;
3665 if (tok == TOK_IF) {
3666 /* if test */
3667 next();
3668 skip('(');
3669 gexpr();
3670 skip(')');
3671 a = gtst(1, 0);
3672 block(bsym, csym, case_sym, def_sym, case_reg);
3673 c = tok;
3674 if (c == TOK_ELSE) {
3675 next();
3676 d = gjmp(0);
3677 gsym(a);
3678 block(bsym, csym, case_sym, def_sym, case_reg);
3679 gsym(d); /* patch else jmp */
3680 } else
3681 gsym(a);
3682 } else if (tok == TOK_WHILE) {
3683 next();
3684 d = ind;
3685 skip('(');
3686 gexpr();
3687 skip(')');
3688 a = gtst(1, 0);
3689 b = 0;
3690 block(&a, &b, case_sym, def_sym, case_reg);
3691 oad(0xe9, d - ind - 5); /* jmp */
3692 gsym(a);
3693 gsym_addr(b, d);
3694 } else if (tok == '{') {
3695 next();
3696 /* declarations */
3697 s = local_stack.top;
3698 while (tok != '}') {
3699 decl(VT_LOCAL);
3700 if (tok != '}')
3701 block(bsym, csym, case_sym, def_sym, case_reg);
3703 /* pop locally defined symbols */
3704 sym_pop(&local_stack, s);
3705 next();
3706 } else if (tok == TOK_RETURN) {
3707 next();
3708 if (tok != ';') {
3709 gexpr();
3710 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
3711 /* if returning structure, must copy it to implicit
3712 first pointer arg location */
3713 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
3714 indir();
3715 vswap();
3716 /* copy structure value to pointer */
3717 vstore();
3718 } else if (is_float(func_vt)) {
3719 /* move return value to float return register */
3720 move_reg(FUNC_RET_FREG, gv());
3721 } else {
3722 /* move return value to standard return register */
3723 move_reg(FUNC_RET_REG, gv());
3725 vpop();
3727 skip(';');
3728 rsym = gjmp(rsym); /* jmp */
3729 } else if (tok == TOK_BREAK) {
3730 /* compute jump */
3731 if (!bsym)
3732 error("cannot break");
3733 *bsym = gjmp(*bsym);
3734 next();
3735 skip(';');
3736 } else if (tok == TOK_CONTINUE) {
3737 /* compute jump */
3738 if (!csym)
3739 error("cannot continue");
3740 *csym = gjmp(*csym);
3741 next();
3742 skip(';');
3743 } else if (tok == TOK_FOR) {
3744 int e;
3745 next();
3746 skip('(');
3747 if (tok != ';') {
3748 gexpr();
3749 vpop();
3751 skip(';');
3752 d = ind;
3753 c = ind;
3754 a = 0;
3755 b = 0;
3756 if (tok != ';') {
3757 gexpr();
3758 a = gtst(1, 0);
3760 skip(';');
3761 if (tok != ')') {
3762 e = gjmp(0);
3763 c = ind;
3764 gexpr();
3765 vpop();
3766 oad(0xe9, d - ind - 5); /* jmp */
3767 gsym(e);
3769 skip(')');
3770 block(&a, &b, case_sym, def_sym, case_reg);
3771 oad(0xe9, c - ind - 5); /* jmp */
3772 gsym(a);
3773 gsym_addr(b, c);
3774 } else
3775 if (tok == TOK_DO) {
3776 next();
3777 a = 0;
3778 b = 0;
3779 d = ind;
3780 block(&a, &b, case_sym, def_sym, case_reg);
3781 skip(TOK_WHILE);
3782 skip('(');
3783 gsym(b);
3784 gexpr();
3785 c = gtst(0, 0);
3786 gsym_addr(c, d);
3787 skip(')');
3788 gsym(a);
3789 skip(';');
3790 } else
3791 if (tok == TOK_SWITCH) {
3792 next();
3793 skip('(');
3794 gexpr();
3795 case_reg = gv();
3796 vpop();
3797 skip(')');
3798 a = 0;
3799 b = gjmp(0); /* jump to first case */
3800 c = 0;
3801 block(&a, csym, &b, &c, case_reg);
3802 /* if no default, jmp after switch */
3803 if (c == 0)
3804 c = ind;
3805 /* default label */
3806 gsym_addr(b, c);
3807 /* break label */
3808 gsym(a);
3809 } else
3810 if (tok == TOK_CASE) {
3811 next();
3812 a = expr_const();
3813 if (!case_sym)
3814 expect("switch");
3815 /* since a case is like a label, we must skip it with a jmp */
3816 b = gjmp(0);
3817 gsym(*case_sym);
3818 vset(VT_INT, case_reg, 0);
3819 vpushi(a);
3820 gen_op(TOK_EQ);
3821 *case_sym = gtst(1, 0);
3822 gsym(b);
3823 skip(':');
3824 block(bsym, csym, case_sym, def_sym, case_reg);
3825 } else
3826 if (tok == TOK_DEFAULT) {
3827 next();
3828 skip(':');
3829 if (!def_sym)
3830 expect("switch");
3831 if (*def_sym)
3832 error("too many 'default'");
3833 *def_sym = ind;
3834 block(bsym, csym, case_sym, def_sym, case_reg);
3835 } else
3836 if (tok == TOK_GOTO) {
3837 next();
3838 s = sym_find1(&label_stack, tok);
3839 /* put forward definition if needed */
3840 if (!s)
3841 s = sym_push1(&label_stack, tok, VT_FORWARD, 0);
3842 /* label already defined */
3843 if (s->t & VT_FORWARD)
3844 s->c = gjmp(s->c); /* jmp xxx */
3845 else
3846 oad(0xe9, s->c - ind - 5); /* jmp xxx */
3847 next();
3848 skip(';');
3849 } else {
3850 b = is_label();
3851 if (b) {
3852 /* label case */
3853 s = sym_find1(&label_stack, b);
3854 if (s) {
3855 if (!(s->t & VT_FORWARD))
3856 error("multiple defined label");
3857 gsym(s->c);
3858 s->c = ind;
3859 s->t = 0;
3860 } else {
3861 sym_push1(&label_stack, b, 0, ind);
3863 /* we accept this, but it is a mistake */
3864 if (tok == '}')
3865 warning("deprecated use of label at end of compound statement");
3866 else
3867 block(bsym, csym, case_sym, def_sym, case_reg);
3868 } else {
3869 /* expression case */
3870 if (tok != ';') {
3871 gexpr();
3872 vpop();
3874 skip(';');
3879 /* t is the array or struct type. c is the array or struct
3880 address. cur_index/cur_field is the pointer to the current
3881 value. 'size_only' is true if only size info is needed (only used
3882 in arrays) */
3883 void decl_designator(int t, int c,
3884 int *cur_index, Sym **cur_field,
3885 int size_only)
3887 Sym *s, *f;
3888 int notfirst, index, align, l;
3890 notfirst = 0;
3891 if (gnu_ext && (l = is_label()) != 0)
3892 goto struct_field;
3894 while (tok == '[' || tok == '.') {
3895 if (tok == '[') {
3896 if (!(t & VT_ARRAY))
3897 expect("array type");
3898 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3899 next();
3900 index = expr_const();
3901 if (index < 0 || (s->c >= 0 && index >= s->c))
3902 expect("invalid index");
3903 skip(']');
3904 if (!notfirst)
3905 *cur_index = index;
3906 t = pointed_type(t);
3907 c += index * type_size(t, &align);
3908 } else {
3909 next();
3910 l = tok;
3911 next();
3912 struct_field:
3913 if ((t & VT_BTYPE) != VT_STRUCT)
3914 expect("struct/union type");
3915 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3916 l |= SYM_FIELD;
3917 f = s->next;
3918 while (f) {
3919 if (f->v == l)
3920 break;
3921 f = f->next;
3923 if (!f)
3924 expect("field");
3925 if (!notfirst)
3926 *cur_field = f;
3927 t = f->t | (t & ~VT_TYPE);
3928 c += f->c;
3930 notfirst = 1;
3932 if (notfirst) {
3933 if (tok == '=') {
3934 next();
3935 } else {
3936 if (!gnu_ext)
3937 expect("=");
3939 } else {
3940 if (t & VT_ARRAY) {
3941 index = *cur_index;
3942 t = pointed_type(t);
3943 c += index * type_size(t, &align);
3944 } else {
3945 f = *cur_field;
3946 if (!f)
3947 error("too many field init");
3948 t = f->t | (t & ~VT_TYPE);
3949 c += f->c;
3952 decl_initializer(t, c, 0, size_only);
3955 /* store a value or an expression directly in global data or in local array */
3957 void init_putv(int t, int c, int v, int is_expr)
3959 int saved_global_expr, bt;
3961 if ((t & VT_VALMASK) == VT_CONST) {
3962 if (is_expr) {
3963 /* compound literals must be allocated globally in this case */
3964 saved_global_expr = global_expr;
3965 global_expr = 1;
3966 expr_const1();
3967 global_expr = saved_global_expr;
3968 } else {
3969 vpushi(v);
3971 /* XXX: do casting */
3972 /* XXX: not portable */
3973 bt = vtop->t & VT_BTYPE;
3974 switch(bt) {
3975 case VT_BYTE:
3976 *(char *)c = vtop->c.i;
3977 break;
3978 case VT_SHORT:
3979 *(short *)c = vtop->c.i;
3980 break;
3981 case VT_DOUBLE:
3982 *(double *)c = vtop->c.d;
3983 break;
3984 case VT_LDOUBLE:
3985 *(long double *)c = vtop->c.ld;
3986 break;
3987 #if 0
3988 case VT_LLONG:
3989 *(long long *)c = vtop->c.ll;
3990 break;
3991 #endif
3992 default:
3993 *(int *)c = vtop->c.i;
3994 break;
3996 vpop();
3997 } else {
3998 vset(t & VT_TYPE, t & (VT_VALMASK | VT_LVAL | VT_FORWARD), c);
3999 if (is_expr)
4000 expr_eq();
4001 else
4002 vpushi(v);
4003 vstore();
4004 vpop();
4008 /* put zeros for variable based init */
4009 void init_putz(int t, int c, int size)
4011 GFuncContext gf;
4013 if ((t & VT_VALMASK) == VT_CONST) {
4014 /* nothing to do because global are already set to zero */
4015 } else {
4016 gfunc_start(&gf);
4017 vpushi(size);
4018 gfunc_param(&gf);
4019 vpushi(0);
4020 gfunc_param(&gf);
4021 vset(VT_INT, VT_LOCAL, c);
4022 gfunc_param(&gf);
4023 vpushi((int)&memset);
4024 gfunc_call(&gf);
4028 /* 't' contains the type and storage info. c is the address of the
4029 object. 'first' is true if array '{' must be read (multi dimension
4030 implicit array init handling). 'size_only' is true if size only
4031 evaluation is wanted (only for arrays). */
4032 void decl_initializer(int t, int c, int first, int size_only)
4034 int index, array_length, n, no_oblock, nb, parlevel, i;
4035 int t1, size1, align1;
4036 Sym *s, *f;
4037 TokenSym *ts;
4039 if (t & VT_ARRAY) {
4040 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4041 n = s->c;
4042 array_length = 0;
4043 t1 = pointed_type(t);
4044 size1 = type_size(t1, &align1);
4046 no_oblock = 1;
4047 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4048 tok == '{') {
4049 skip('{');
4050 no_oblock = 0;
4053 /* only parse strings here if correct type (otherwise: handle
4054 them as ((w)char *) expressions */
4055 if ((tok == TOK_LSTR &&
4056 (t1 & VT_BTYPE) == VT_INT) ||
4057 (tok == TOK_STR &&
4058 (t1 & VT_BTYPE) == VT_BYTE)) {
4059 /* XXX: move multiple string parsing in parser ? */
4060 while (tok == TOK_STR || tok == TOK_LSTR) {
4061 ts = tokc.ts;
4062 /* compute maximum number of chars wanted */
4063 nb = ts->len;
4064 if (n >= 0 && nb > (n - array_length))
4065 nb = n - array_length;
4066 if (!size_only) {
4067 if (ts->len > nb)
4068 warning("initializer-string for array is too long");
4069 for(i=0;i<nb;i++) {
4070 init_putv(t1, c + (array_length + i) * size1,
4071 ts->str[i], 0);
4074 array_length += nb;
4075 next();
4077 /* only add trailing zero if enough storage (no
4078 warning in this case since it is standard) */
4079 if (n < 0 || array_length < n) {
4080 if (!size_only) {
4081 init_putv(t1, c + (array_length * size1), 0, 0);
4083 array_length++;
4085 } else {
4086 index = 0;
4087 while (tok != '}') {
4088 decl_designator(t, c, &index, NULL, size_only);
4089 if (n >= 0 && index >= n)
4090 error("index too large");
4091 /* must put zero in holes (note that doing it that way
4092 ensures that it even works with designators) */
4093 if (!size_only && array_length < index) {
4094 init_putz(t1, c + array_length * size1,
4095 (index - array_length) * size1);
4097 index++;
4098 if (index > array_length)
4099 array_length = index;
4100 /* special test for multi dimensional arrays (may not
4101 be strictly correct if designators are used at the
4102 same time) */
4103 if (index >= n && no_oblock)
4104 break;
4105 if (tok == '}')
4106 break;
4107 skip(',');
4110 if (!no_oblock)
4111 skip('}');
4112 /* put zeros at the end */
4113 if (!size_only && n >= 0 && array_length < n) {
4114 init_putz(t1, c + array_length * size1,
4115 (n - array_length) * size1);
4117 /* patch type size if needed */
4118 if (n < 0)
4119 s->c = array_length;
4120 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
4121 /* XXX: union needs only one init */
4122 next();
4123 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4124 f = s->next;
4125 array_length = 0;
4126 index = 0;
4127 n = s->c;
4128 while (tok != '}') {
4129 decl_designator(t, c, NULL, &f, size_only);
4130 /* fill with zero between fields */
4131 index = f->c;
4132 if (!size_only && array_length < index) {
4133 init_putz(t, c + array_length,
4134 index - array_length);
4136 index = index + type_size(f->t, &align1);
4137 if (index > array_length)
4138 array_length = index;
4139 if (tok == '}')
4140 break;
4141 skip(',');
4142 f = f->next;
4144 /* put zeros at the end */
4145 if (!size_only && array_length < n) {
4146 init_putz(t, c + array_length,
4147 n - array_length);
4149 skip('}');
4150 } else if (tok == '{') {
4151 next();
4152 decl_initializer(t, c, first, size_only);
4153 skip('}');
4154 } else if (size_only) {
4155 /* just skip expression */
4156 parlevel = 0;
4157 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4158 tok != -1) {
4159 if (tok == '(')
4160 parlevel++;
4161 else if (tok == ')')
4162 parlevel--;
4163 next();
4165 } else {
4166 init_putv(t, c, 0, 1);
4170 /* parse an initializer for type 't' if 'has_init' is true, and
4171 allocate space in local or global data space. The allocated address
4172 in returned */
4173 int decl_initializer_alloc(int t, int has_init)
4175 int size, align, addr, tok1;
4176 int *init_str, init_len, level, *saved_macro_ptr;
4178 size = type_size(t, &align);
4179 /* If unknown size, we must evaluate it before
4180 evaluating initializers because
4181 initializers can generate global data too
4182 (e.g. string pointers or ISOC99 compound
4183 literals). It also simplifies local
4184 initializers handling */
4185 init_len = 0;
4186 init_str = NULL;
4187 saved_macro_ptr = NULL; /* avoid warning */
4188 tok1 = 0;
4189 if (size < 0) {
4190 if (!has_init)
4191 error("unknown type size");
4192 /* get all init string */
4193 level = 0;
4194 while (level > 0 || (tok != ',' && tok != ';')) {
4195 if (tok < 0)
4196 error("unexpected end of file in initializer");
4197 tok_add2(&init_str, &init_len, tok, &tokc);
4198 if (tok == '{')
4199 level++;
4200 else if (tok == '}') {
4201 if (level == 0)
4202 break;
4203 level--;
4205 next();
4207 tok1 = tok;
4208 tok_add(&init_str, &init_len, -1);
4209 tok_add(&init_str, &init_len, 0);
4211 /* compute size */
4212 saved_macro_ptr = macro_ptr;
4213 macro_ptr = init_str;
4214 next();
4215 decl_initializer(t, 0, 1, 1);
4216 /* prepare second initializer parsing */
4217 macro_ptr = init_str;
4218 next();
4220 /* if still unknown size, error */
4221 size = type_size(t, &align);
4222 if (size < 0)
4223 error("unknown type size");
4225 if ((t & VT_VALMASK) == VT_LOCAL) {
4226 loc = (loc - size) & -align;
4227 addr = loc;
4228 } else {
4229 glo = (glo + align - 1) & -align;
4230 addr = glo;
4231 /* very important to increment global
4232 pointer at this time because
4233 initializers themselves can create new
4234 initializers */
4235 glo += size;
4237 if (has_init) {
4238 decl_initializer(t, addr, 1, 0);
4239 /* restore parse state if needed */
4240 if (init_str) {
4241 free(init_str);
4242 macro_ptr = saved_macro_ptr;
4243 tok = tok1;
4246 return addr;
4250 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
4251 void decl(int l)
4253 int *a, t, b, v, u, addr, has_init, size, align;
4254 Sym *sym;
4256 while (1) {
4257 b = ist();
4258 if (!b) {
4259 /* skip redundant ';' */
4260 /* XXX: find more elegant solution */
4261 if (tok == ';') {
4262 next();
4263 continue;
4265 /* special test for old K&R protos without explicit int
4266 type. Only accepted when defining global data */
4267 if (l == VT_LOCAL || tok < TOK_DEFINE)
4268 break;
4269 b = VT_INT;
4271 if (((b & VT_BTYPE) == VT_ENUM ||
4272 (b & VT_BTYPE) == VT_STRUCT) &&
4273 tok == ';') {
4274 /* we accept no variable after */
4275 next();
4276 continue;
4278 while (1) { /* iterate thru each declaration */
4279 t = type_decl(&v, b, TYPE_DIRECT);
4280 #if 0
4282 char buf[500];
4283 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
4284 printf("type = '%s'\n", buf);
4286 #endif
4287 if (tok == '{') {
4288 if (l == VT_LOCAL)
4289 error("cannot use local functions");
4290 if (!(t & VT_FUNC))
4291 expect("function definition");
4292 /* patch forward references */
4293 if ((sym = sym_find(v)) && (sym->t & VT_FORWARD)) {
4294 greloc_patch(sym, ind);
4295 sym->t = VT_CONST | t;
4296 } else {
4297 /* put function address */
4298 sym_push1(&global_stack, v, VT_CONST | t, ind);
4300 funcname = get_tok_str(v, NULL);
4301 /* push a dummy symbol to enable local sym storage */
4302 sym_push1(&local_stack, 0, 0, 0);
4303 /* define parameters */
4304 sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4305 /* XXX: the following is x86 dependant -> move it to
4306 x86 code gen */
4307 addr = 8;
4308 /* if the function returns a structure, then add an
4309 implicit pointer parameter */
4310 func_vt = sym->t;
4311 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
4312 func_vc = addr;
4313 addr += 4;
4315 while (sym = sym->next) {
4316 u = sym->t;
4317 sym_push(sym->v & ~SYM_FIELD,
4318 u | VT_LOCAL | VT_LVAL,
4319 addr);
4320 size = type_size(u, &align);
4321 size = (size + 3) & ~3;
4322 #ifdef FUNC_STRUCT_PARAM_AS_PTR
4323 /* structs are passed as pointer */
4324 if ((u & VT_BTYPE) == VT_STRUCT) {
4325 size = 4;
4327 #endif
4328 addr += size;
4330 loc = 0;
4331 o(0xe58955); /* push %ebp, mov %esp, %ebp */
4332 a = (int *)oad(0xec81, 0); /* sub $xxx, %esp */
4333 rsym = 0;
4334 block(NULL, NULL, NULL, NULL, 0);
4335 gsym(rsym);
4336 o(0xc3c9); /* leave, ret */
4337 *a = (-loc + 3) & -4; /* align local size to word &
4338 save local variables */
4339 sym_pop(&label_stack, NULL); /* reset label stack */
4340 sym_pop(&local_stack, NULL); /* reset local stack */
4341 funcname = ""; /* for safety */
4342 func_vt = VT_VOID; /* for safety */
4343 break;
4344 } else {
4345 if (b & VT_TYPEDEF) {
4346 /* save typedefed type */
4347 /* XXX: test storage specifiers ? */
4348 sym_push(v, t | VT_TYPEDEF, 0);
4349 } else if ((t & VT_BTYPE) == VT_FUNC) {
4350 /* external function definition */
4351 external_sym(v, t);
4352 } else {
4353 /* not lvalue if array */
4354 if (!(t & VT_ARRAY))
4355 t |= VT_LVAL;
4356 if (b & VT_EXTERN) {
4357 /* external variable */
4358 external_sym(v, t);
4359 } else {
4360 u = l;
4361 if (t & VT_STATIC)
4362 u = VT_CONST;
4363 u |= t;
4364 has_init = (tok == '=');
4365 if (has_init)
4366 next();
4367 addr = decl_initializer_alloc(u, has_init);
4368 if (l == VT_CONST) {
4369 /* global scope: see if already defined */
4370 sym = sym_find(v);
4371 if (!sym)
4372 goto do_def;
4373 if (!is_compatible_types(sym->t, u))
4374 error("incompatible types for redefinition of '%s'",
4375 get_tok_str(v, NULL));
4376 if (!(sym->t & VT_FORWARD))
4377 error("redefinition of '%s'", get_tok_str(v, NULL));
4378 greloc_patch(sym, addr);
4379 } else {
4380 do_def:
4381 sym_push(v, u, addr);
4385 if (tok != ',') {
4386 skip(';');
4387 break;
4389 next();
4395 /* put all global symbols in the extern stack and do all the
4396 resolving which can be done without using external symbols from DLLs */
4397 /* XXX: could try to verify types, but would not to save them in
4398 extern_stack too */
4399 void resolve_global_syms(void)
4401 Sym *s, *s1, *ext_sym;
4402 Reloc **p;
4404 s = global_stack.top;
4405 while (s != NULL) {
4406 s1 = s->prev;
4407 /* do not save static or typedefed symbols or types */
4408 if (!(s->t & (VT_STATIC | VT_TYPEDEF)) &&
4409 !(s->v & (SYM_FIELD | SYM_STRUCT)) &&
4410 (s->v < SYM_FIRST_ANOM)) {
4411 ext_sym = sym_find1(&extern_stack, s->v);
4412 if (!ext_sym) {
4413 /* if the symbol do not exist, we simply save it */
4414 sym_push1(&extern_stack, s->v, s->t, s->c);
4415 } else if (ext_sym->t & VT_FORWARD) {
4416 /* external symbol already exists, but only as forward
4417 definition */
4418 if (!(s->t & VT_FORWARD)) {
4419 /* s is not forward, so we can relocate all symbols */
4420 greloc_patch(ext_sym, s->c);
4421 } else {
4422 /* the two symbols are forward: merge them */
4423 p = (Reloc **)&ext_sym->c;
4424 while (*p != NULL)
4425 p = &(*p)->next;
4426 *p = (Reloc *)s->c;
4428 } else {
4429 /* external symbol already exists and is defined :
4430 patch all references to it */
4431 if (!(s->t & VT_FORWARD))
4432 error("'%s' defined twice", get_tok_str(s->v, NULL));
4433 greloc_patch(s, ext_sym->c);
4436 s = s1;
4440 /* compile a C file. Return non zero if errors. */
4441 int tcc_compile_file(const char *filename1)
4443 Sym *define_start;
4445 filename = (char *)filename1;
4447 line_num = 1;
4448 funcname = "";
4449 file = fopen(filename, "r");
4450 if (!file)
4451 error("file '%s' not found", filename);
4452 include_stack_ptr = include_stack;
4453 ifdef_stack_ptr = ifdef_stack;
4455 vtop = vstack - 1;
4456 anon_sym = SYM_FIRST_ANOM;
4458 define_start = define_stack.top;
4459 inp();
4460 ch = '\n'; /* needed to parse correctly first preprocessor command */
4461 next();
4462 decl(VT_CONST);
4463 if (tok != -1)
4464 expect("declaration");
4465 fclose(file);
4467 /* reset define stack, but leave -Dsymbols (may be incorrect if
4468 they are undefined) */
4469 sym_pop(&define_stack, define_start);
4471 resolve_global_syms();
4473 sym_pop(&global_stack, NULL);
4475 return 0;
4478 /* open a dynamic library so that its symbol are available for
4479 compiled programs */
4480 void open_dll(char *libname)
4482 char buf[1024];
4483 void *h;
4485 snprintf(buf, sizeof(buf), "lib%s.so", libname);
4486 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
4487 if (!h)
4488 error((char *)dlerror());
4491 void resolve_extern_syms(void)
4493 Sym *s, *s1;
4494 char *str;
4495 int addr;
4497 s = extern_stack.top;
4498 while (s != NULL) {
4499 s1 = s->prev;
4500 if (s->t & VT_FORWARD) {
4501 /* if there is at least one relocation to do, then find it
4502 and patch it */
4503 if (s->c) {
4504 str = get_tok_str(s->v, NULL);
4505 addr = (int)dlsym(NULL, str);
4506 if (!addr)
4507 error("unresolved external reference '%s'", str);
4508 greloc_patch(s, addr);
4511 s = s1;
4515 /* output a binary file (for testing) */
4516 void build_exe(char *filename)
4518 FILE *f;
4519 f = fopen(filename, "w");
4520 fwrite((void *)prog, 1, ind - prog, f);
4521 fclose(f);
4524 int main(int argc, char **argv)
4526 Sym *s;
4527 int (*t)();
4528 char *p, *r, *outfile;
4529 int optind;
4531 include_paths[0] = "/usr/include";
4532 include_paths[1] = "/usr/lib/tcc";
4533 include_paths[2] = "/usr/local/lib/tcc";
4534 nb_include_paths = 3;
4536 /* add all tokens */
4537 tok_ident = TOK_IDENT;
4538 p = "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0auto\0inline\0restrict\0float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0";
4539 while (*p) {
4540 r = p;
4541 while (*r++);
4542 tok_alloc(p, r - p - 1);
4543 p = r;
4546 /* standard defines */
4547 define_symbol("__STDC__");
4548 #ifdef __i386__
4549 define_symbol("__i386__");
4550 #endif
4551 /* tiny C specific defines */
4552 define_symbol("__TINYC__");
4554 glo = (int)malloc(DATA_SIZE);
4555 memset((void *)glo, 0, DATA_SIZE);
4556 prog = (int)malloc(TEXT_SIZE);
4557 ind = prog;
4559 optind = 1;
4560 outfile = NULL;
4561 while (1) {
4562 if (optind >= argc) {
4563 show_help:
4564 printf("tcc version 0.9.2 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n"
4565 "usage: tcc [-Idir] [-Dsym] [-llib] [-i infile] infile [infile_args...]\n");
4566 return 1;
4568 r = argv[optind];
4569 if (r[0] != '-')
4570 break;
4571 optind++;
4572 if (r[1] == 'I') {
4573 if (nb_include_paths >= INCLUDE_PATHS_MAX)
4574 error("too many include paths");
4575 include_paths[nb_include_paths++] = r + 2;
4576 } else if (r[1] == 'D') {
4577 define_symbol(r + 2);
4578 } else if (r[1] == 'l') {
4579 open_dll(r + 2);
4580 } else if (r[1] == 'i') {
4581 if (optind >= argc)
4582 goto show_help;
4583 tcc_compile_file(argv[optind++]);
4584 } else if (r[1] == 'o') {
4585 /* currently, only for testing, so not documented */
4586 if (optind >= argc)
4587 goto show_help;
4588 outfile = argv[optind++];
4589 } else {
4590 fprintf(stderr, "invalid option -- '%s'\n", r);
4591 exit(1);
4595 tcc_compile_file(argv[optind]);
4597 resolve_extern_syms();
4599 if (outfile) {
4600 build_exe(outfile);
4601 return 0;
4602 } else {
4603 s = sym_find1(&extern_stack, TOK_MAIN);
4604 if (!s || (s->t & VT_FORWARD))
4605 error("main() not defined");
4606 t = (int (*)())s->c;
4607 return (*t)(argc - optind, argv + optind);