update
[tinycc.git] / tcc.c
blob9ff67a8353c91eadcde946f53dc39ba32dd33d8c
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 int tab[1];
68 struct Sym *sym;
69 } CValue;
71 /* value on stack */
72 typedef struct SValue {
73 int t;
74 CValue c;
75 } SValue;
77 /* symbol management */
78 typedef struct Sym {
79 int v; /* symbol token */
80 int t; /* associated type */
81 int c; /* associated number */
82 struct Sym *next; /* next related symbol */
83 struct Sym *prev; /* prev symbol in stack */
84 struct Sym *hash_next; /* next symbol in hash table */
85 } Sym;
87 typedef struct SymStack {
88 struct Sym *top;
89 struct Sym *hash[SYM_HASH_SIZE];
90 } SymStack;
92 /* relocation entry (currently only used for functions or variables */
93 typedef struct Reloc {
94 int type; /* type of relocation */
95 int addr; /* address of relocation */
96 struct Reloc *next; /* next relocation */
97 } Reloc;
99 #define RELOC_ADDR32 1 /* 32 bits relocation */
100 #define RELOC_REL32 2 /* 32 bits relative relocation */
103 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
104 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
105 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
107 #define FUNC_NEW 1 /* ansi function prototype */
108 #define FUNC_OLD 2 /* old function prototype */
109 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
111 /* field 'Sym.t' for macros */
112 #define MACRO_OBJ 0 /* object like macro */
113 #define MACRO_FUNC 1 /* function like macro */
115 /* type_decl() types */
116 #define TYPE_ABSTRACT 1 /* type without variable */
117 #define TYPE_DIRECT 2 /* type with variable */
119 typedef struct {
120 FILE *file;
121 char *filename;
122 int line_num;
123 } IncludeFile;
125 /* parser */
126 FILE *file;
127 int line_num;
128 int ch, ch1, tok, tok1;
129 CValue tokc, tok1c;
131 /* loc : local variable index
132 glo : global variable index
133 ind : output code ptr
134 rsym: return symbol
135 prog: output code
136 anon_sym: anonymous symbol index
138 int rsym, anon_sym,
139 prog, ind, loc, glo, const_wanted;
140 int global_expr; /* true if compound literals must be allocated
141 globally (used during initializers parsing */
142 int func_vt, func_vc; /* current function return type (used by
143 return instruction) */
144 int tok_ident;
145 TokenSym **table_ident;
146 TokenSym *hash_ident[TOK_HASH_SIZE];
147 char token_buf[STRING_MAX_SIZE + 1];
148 char *filename, *funcname;
149 /* contains global symbols which remain between each translation unit */
150 SymStack extern_stack;
151 SymStack define_stack, global_stack, local_stack, label_stack;
153 SValue vstack[VSTACK_SIZE], *vtop;
154 int *macro_ptr, *macro_ptr_allocated;
155 IncludeFile include_stack[INCLUDE_STACK_SIZE], *include_stack_ptr;
156 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
157 char *include_paths[INCLUDE_PATHS_MAX];
158 int nb_include_paths;
160 /* use GNU C extensions */
161 int gnu_ext = 1;
163 /* use Tiny C extensions */
164 int tcc_ext = 1;
166 /* The current value can be: */
167 #define VT_VALMASK 0x000f
168 #define VT_CONST 0x000a /* constant in vc
169 (must be first non register value) */
170 #define VT_LLOCAL 0x000b /* lvalue, offset on stack */
171 #define VT_LOCAL 0x000c /* offset on stack */
172 #define VT_CMP 0x000d /* the value is stored in processor flags (in vc) */
173 #define VT_JMP 0x000e /* value is the consequence of jmp true */
174 #define VT_JMPI 0x000f /* value is the consequence of jmp false */
175 #define VT_LVAL 0x0010 /* var is an lvalue */
176 #define VT_LVALN -17 /* ~VT_LVAL */
177 #define VT_FORWARD 0x0020 /* value is forward reference
178 (only used for functions) */
179 /* storage */
180 #define VT_EXTERN 0x00000040 /* extern definition */
181 #define VT_STATIC 0x00000080 /* static variable */
182 #define VT_TYPEDEF 0x00000100 /* typedef definition */
184 /* types */
185 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
187 #define VT_BTYPE_SHIFT 9
188 #define VT_INT (0 << VT_BTYPE_SHIFT) /* integer type */
189 #define VT_BYTE (1 << VT_BTYPE_SHIFT) /* signed byte type */
190 #define VT_SHORT (2 << VT_BTYPE_SHIFT) /* short type */
191 #define VT_VOID (3 << VT_BTYPE_SHIFT) /* void type */
192 #define VT_PTR (4 << VT_BTYPE_SHIFT) /* pointer increment */
193 #define VT_ENUM (5 << VT_BTYPE_SHIFT) /* enum definition */
194 #define VT_FUNC (6 << VT_BTYPE_SHIFT) /* function type */
195 #define VT_STRUCT (7 << VT_BTYPE_SHIFT) /* struct/union definition */
196 #define VT_FLOAT (8 << VT_BTYPE_SHIFT) /* IEEE float */
197 #define VT_DOUBLE (9 << VT_BTYPE_SHIFT) /* IEEE double */
198 #define VT_LDOUBLE (10 << VT_BTYPE_SHIFT) /* IEEE long double */
199 #define VT_BOOL (11 << VT_BTYPE_SHIFT) /* ISOC99 boolean type */
200 #define VT_LLONG (12 << VT_BTYPE_SHIFT) /* 64 bit integer */
201 #define VT_LONG (13 << VT_BTYPE_SHIFT) /* long integer (NEVER
202 USED as type, only
203 during parsing) */
204 #define VT_BTYPE (0xf << VT_BTYPE_SHIFT) /* mask for basic type */
205 #define VT_UNSIGNED (0x10 << VT_BTYPE_SHIFT) /* unsigned type */
206 #define VT_ARRAY (0x20 << VT_BTYPE_SHIFT) /* array type (also has VT_PTR) */
207 #define VT_BITFIELD (0x40 << VT_BTYPE_SHIFT) /* bitfield modifier */
209 #define VT_TYPE 0xfffffe00 /* type mask */
211 /* token values */
213 /* warning: the following compare tokens depend on i386 asm code */
214 #define TOK_ULT 0x92
215 #define TOK_UGE 0x93
216 #define TOK_EQ 0x94
217 #define TOK_NE 0x95
218 #define TOK_ULE 0x96
219 #define TOK_UGT 0x97
220 #define TOK_LT 0x9c
221 #define TOK_GE 0x9d
222 #define TOK_LE 0x9e
223 #define TOK_GT 0x9f
225 #define TOK_LAND 0xa0
226 #define TOK_LOR 0xa1
228 #define TOK_DEC 0xa2
229 #define TOK_MID 0xa3 /* inc/dec, to void constant */
230 #define TOK_INC 0xa4
231 #define TOK_ARROW 0xa7
232 #define TOK_DOTS 0xa8 /* three dots */
233 #define TOK_SHR 0xa9 /* unsigned shift right */
234 #define TOK_UDIV 0xb0 /* unsigned division */
235 #define TOK_UMOD 0xb1 /* unsigned modulo */
236 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
237 #define TOK_NUM 0xb3 /* number in tokc */
238 #define TOK_CCHAR 0xb4 /* char constant in tokc */
239 #define TOK_STR 0xb5 /* pointer to string in tokc */
240 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
241 #define TOK_LCHAR 0xb7
242 #define TOK_LSTR 0xb8
243 #define TOK_CFLOAT 0xb9 /* float constant */
244 #define TOK_CDOUBLE 0xc0 /* double constant */
245 #define TOK_CLDOUBLE 0xc1 /* long double constant */
247 #define TOK_SHL 0x01 /* shift left */
248 #define TOK_SAR 0x02 /* signed shift right */
250 /* assignement operators : normal operator or 0x80 */
251 #define TOK_A_MOD 0xa5
252 #define TOK_A_AND 0xa6
253 #define TOK_A_MUL 0xaa
254 #define TOK_A_ADD 0xab
255 #define TOK_A_SUB 0xad
256 #define TOK_A_DIV 0xaf
257 #define TOK_A_XOR 0xde
258 #define TOK_A_OR 0xfc
259 #define TOK_A_SHL 0x81
260 #define TOK_A_SAR 0x82
262 /* all identificators and strings have token above that */
263 #define TOK_IDENT 256
265 enum {
266 TOK_INT = TOK_IDENT,
267 TOK_VOID,
268 TOK_CHAR,
269 TOK_IF,
270 TOK_ELSE,
271 TOK_WHILE,
272 TOK_BREAK,
273 TOK_RETURN,
274 TOK_FOR,
275 TOK_EXTERN,
276 TOK_STATIC,
277 TOK_UNSIGNED,
278 TOK_GOTO,
279 TOK_DO,
280 TOK_CONTINUE,
281 TOK_SWITCH,
282 TOK_CASE,
284 /* ignored types Must have contiguous values */
285 TOK_CONST,
286 TOK_VOLATILE,
287 TOK_LONG,
288 TOK_REGISTER,
289 TOK_SIGNED,
290 TOK_AUTO,
291 TOK_INLINE,
292 TOK_RESTRICT,
294 /* unsupported type */
295 TOK_FLOAT,
296 TOK_DOUBLE,
297 TOK_BOOL,
299 TOK_SHORT,
300 TOK_STRUCT,
301 TOK_UNION,
302 TOK_TYPEDEF,
303 TOK_DEFAULT,
304 TOK_ENUM,
305 TOK_SIZEOF,
307 /* preprocessor only */
308 TOK_UIDENT, /* first "user" ident (not keyword) */
309 TOK_DEFINE = TOK_UIDENT,
310 TOK_INCLUDE,
311 TOK_IFDEF,
312 TOK_IFNDEF,
313 TOK_ELIF,
314 TOK_ENDIF,
315 TOK_DEFINED,
316 TOK_UNDEF,
317 TOK_ERROR,
318 TOK_LINE,
319 TOK___LINE__,
320 TOK___FILE__,
321 TOK___DATE__,
322 TOK___TIME__,
323 TOK___VA_ARGS__,
325 /* special identifiers */
326 TOK___FUNC__,
327 TOK_MAIN,
330 /* XXX: need to define this to use them in non ISOC99 context */
331 extern float strtof (const char *__nptr, char **__endptr);
332 extern long double strtold (const char *__nptr, char **__endptr);
334 void sum(int l);
335 void next(void);
336 void next_nomacro(void);
337 int expr_const(void);
338 void expr_eq(void);
339 void gexpr(void);
340 void decl(int l);
341 void decl_initializer(int t, int c, int first, int size_only);
342 int decl_initializer_alloc(int t, int has_init);
343 int gv(void);
344 void move_reg(int r, int s);
345 void save_reg(int r);
346 void vpop(void);
347 void vswap(void);
348 void vdup(void);
349 int get_reg(int rc);
351 void macro_subst(int **tok_str, int *tok_len,
352 Sym **nested_list, int *macro_str);
353 int save_reg_forced(int r);
354 void gen_op(int op);
355 void gen_cast(int t);
356 void vstore(void);
357 int type_size(int t, int *a);
358 int pointed_type(int t);
359 int pointed_size(int t);
360 int ist(void);
361 int type_decl(int *v, int t, int td);
362 void error(const char *fmt, ...);
363 void vset(int t, int v);
365 /* true if float/double/long double type */
366 static inline int is_float(int t)
368 int bt;
369 bt = t & VT_BTYPE;
370 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
373 #include "i386-gen.c"
375 #ifdef CONFIG_TCC_STATIC
377 #define RTLD_LAZY 0x001
378 #define RTLD_NOW 0x002
379 #define RTLD_GLOBAL 0x100
381 /* dummy function for profiling */
382 void *dlopen(const char *filename, int flag)
384 return NULL;
387 const char *dlerror(void)
389 return "error";
392 typedef struct TCCSyms {
393 char *str;
394 void *ptr;
395 } TCCSyms;
397 #define TCCSYM(a) { #a, &a, },
399 /* add the symbol you want here if no dynamic linking is done */
400 static TCCSyms tcc_syms[] = {
401 TCCSYM(printf)
402 TCCSYM(fprintf)
403 TCCSYM(fopen)
404 TCCSYM(fclose)
405 { NULL, NULL },
408 void *dlsym(void *handle, char *symbol)
410 TCCSyms *p;
411 p = tcc_syms;
412 while (p->str != NULL) {
413 if (!strcmp(p->str, symbol))
414 return p->ptr;
415 p++;
417 return NULL;
420 #endif
422 static inline int isid(int c)
424 return (c >= 'a' && c <= 'z') ||
425 (c >= 'A' && c <= 'Z') ||
426 c == '_';
429 static inline int isnum(int c)
431 return c >= '0' & c <= '9';
434 static inline int toup(int c)
436 if (ch >= 'a' && ch <= 'z')
437 return ch - 'a' + 'A';
438 else
439 return ch;
442 void printline(void)
444 IncludeFile *f;
445 for(f = include_stack; f < include_stack_ptr; f++)
446 fprintf(stderr, "In file included from %s:%d:\n",
447 f->filename, f->line_num);
448 fprintf(stderr, "%s:%d: ", filename, line_num);
451 void error(const char *fmt, ...)
453 va_list ap;
454 va_start(ap, fmt);
455 printline();
456 vfprintf(stderr, fmt, ap);
457 fprintf(stderr, "\n");
458 exit(1);
459 va_end(ap);
462 void expect(const char *msg)
464 error("%s expected", msg);
467 void warning(const char *msg)
469 printline();
470 fprintf(stderr, "warning: %s\n", msg);
473 void skip(int c)
475 if (tok != c)
476 error("'%c' expected", c);
477 next();
480 void test_lvalue(void)
482 if (!(vtop->t & VT_LVAL))
483 expect("lvalue");
486 TokenSym *tok_alloc(char *str, int len)
488 TokenSym *ts, **pts, **ptable;
489 int h, i;
491 if (len <= 0)
492 len = strlen(str);
493 h = 1;
494 for(i=0;i<len;i++)
495 h = ((h << 8) | (str[i] & 0xff)) % TOK_HASH_SIZE;
497 pts = &hash_ident[h];
498 while (1) {
499 ts = *pts;
500 if (!ts)
501 break;
502 if (ts->len == len && !memcmp(ts->str, str, len))
503 return ts;
504 pts = &(ts->hash_next);
507 if (tok_ident >= SYM_FIRST_ANOM)
508 error("memory full");
510 /* expand token table if needed */
511 i = tok_ident - TOK_IDENT;
512 if ((i % TOK_ALLOC_INCR) == 0) {
513 ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
514 if (!ptable)
515 error("memory full");
516 table_ident = ptable;
519 ts = malloc(sizeof(TokenSym) + len);
520 if (!ts)
521 error("memory full");
522 table_ident[i] = ts;
523 ts->tok = tok_ident++;
524 ts->len = len;
525 ts->hash_next = NULL;
526 memcpy(ts->str, str, len + 1);
527 *pts = ts;
528 return ts;
531 void add_char(char **pp, int c)
533 char *p;
534 p = *pp;
535 if (c == '\'' || c == '\"' || c == '\\') {
536 /* XXX: could be more precise if char or string */
537 *p++ = '\\';
539 if (c >= 32 && c <= 126) {
540 *p++ = c;
541 } else {
542 *p++ = '\\';
543 if (c == '\n') {
544 *p++ = 'n';
545 } else {
546 *p++ = '0' + ((c >> 6) & 7);
547 *p++ = '0' + ((c >> 3) & 7);
548 *p++ = '0' + (c & 7);
551 *pp = p;
554 /* XXX: buffer overflow */
555 char *get_tok_str(int v, CValue *cv)
557 static char buf[STRING_MAX_SIZE + 1];
558 TokenSym *ts;
559 char *p;
560 int i;
562 if (v == TOK_NUM) {
563 sprintf(buf, "%u", cv->ui);
564 return buf;
565 } else if (v == TOK_CCHAR || v == TOK_LCHAR) {
566 p = buf;
567 *p++ = '\'';
568 add_char(&p, cv->i);
569 *p++ = '\'';
570 *p = '\0';
571 return buf;
572 } else if (v == TOK_STR || v == TOK_LSTR) {
573 ts = cv->ts;
574 p = buf;
575 *p++ = '\"';
576 for(i=0;i<ts->len;i++)
577 add_char(&p, ts->str[i]);
578 *p++ = '\"';
579 *p = '\0';
580 return buf;
581 } else if (v < TOK_IDENT) {
582 p = buf;
583 *p++ = v;
584 *p = '\0';
585 return buf;
586 } else if (v < tok_ident) {
587 return table_ident[v - TOK_IDENT]->str;
588 } else {
589 /* should never happen */
590 return NULL;
594 /* push, without hashing */
595 Sym *sym_push2(Sym **ps, int v, int t, int c)
597 Sym *s;
598 s = malloc(sizeof(Sym));
599 if (!s)
600 error("memory full");
601 s->v = v;
602 s->t = t;
603 s->c = c;
604 s->next = NULL;
605 /* add in stack */
606 s->prev = *ps;
607 *ps = s;
608 return s;
611 /* find a symbol and return its associated structure. 's' is the top
612 of the symbol stack */
613 Sym *sym_find2(Sym *s, int v)
615 while (s) {
616 if (s->v == v)
617 return s;
618 s = s->prev;
620 return NULL;
623 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
625 /* find a symbol and return its associated structure. 'st' is the
626 symbol stack */
627 Sym *sym_find1(SymStack *st, int v)
629 Sym *s;
631 s = st->hash[HASH_SYM(v)];
632 while (s) {
633 if (s->v == v)
634 return s;
635 s = s->hash_next;
637 return 0;
640 Sym *sym_push1(SymStack *st, int v, int t, int c)
642 Sym *s, **ps;
643 s = sym_push2(&st->top, v, t, c);
644 /* add in hash table */
645 if (v) {
646 ps = &st->hash[HASH_SYM(v)];
647 s->hash_next = *ps;
648 *ps = s;
650 return s;
653 /* find a symbol in the right symbol space */
654 Sym *sym_find(int v)
656 Sym *s;
657 s = sym_find1(&local_stack, v);
658 if (!s)
659 s = sym_find1(&global_stack, v);
660 return s;
663 /* push a given symbol on the symbol stack */
664 Sym *sym_push(int v, int t, int c)
666 if (local_stack.top)
667 return sym_push1(&local_stack, v, t, c);
668 else
669 return sym_push1(&global_stack, v, t, c);
672 /* pop symbols until top reaches 'b' */
673 void sym_pop(SymStack *st, Sym *b)
675 Sym *s, *ss;
677 s = st->top;
678 while(s != b) {
679 ss = s->prev;
680 /* free hash table entry, except if symbol was freed (only
681 used for #undef symbols) */
682 if (s->v)
683 st->hash[HASH_SYM(s->v)] = s->hash_next;
684 free(s);
685 s = ss;
687 st->top = b;
690 /* undefined a hashed symbol (used for #undef). Its name is set to
691 zero */
692 void sym_undef(SymStack *st, Sym *s)
694 Sym **ss;
695 ss = &st->hash[HASH_SYM(s->v)];
696 while (*ss != NULL) {
697 if (*ss == s)
698 break;
699 ss = &(*ss)->hash_next;
701 *ss = s->hash_next;
702 s->v = 0;
705 /* no need to put that inline */
706 int handle_eof(void)
708 if (include_stack_ptr == include_stack)
709 return -1;
710 /* pop include stack */
711 fclose(file);
712 free(filename);
713 include_stack_ptr--;
714 file = include_stack_ptr->file;
715 filename = include_stack_ptr->filename;
716 line_num = include_stack_ptr->line_num;
717 return 0;
720 /* read next char from current input file */
721 static inline void inp(void)
723 redo:
724 /* faster than fgetc */
725 ch1 = getc_unlocked(file);
726 if (ch1 == -1) {
727 if (handle_eof() < 0)
728 return;
729 else
730 goto redo;
732 if (ch1 == '\n')
733 line_num++;
734 // printf("ch1=%c 0x%x\n", ch1, ch1);
737 /* input with '\\n' handling */
738 static inline void minp(void)
740 redo:
741 ch = ch1;
742 inp();
743 if (ch == '\\' && ch1 == '\n') {
744 inp();
745 goto redo;
747 //printf("ch=%c 0x%x\n", ch, ch);
751 /* same as minp, but also skip comments */
752 void cinp(void)
754 int c;
756 if (ch1 == '/') {
757 inp();
758 if (ch1 == '/') {
759 /* single line C++ comments */
760 inp();
761 while (ch1 != '\n' && ch1 != -1)
762 inp();
763 inp();
764 ch = ' '; /* return space */
765 } else if (ch1 == '*') {
766 /* C comments */
767 inp();
768 while (ch1 != -1) {
769 c = ch1;
770 inp();
771 if (c == '*' && ch1 == '/') {
772 inp();
773 ch = ' '; /* return space */
774 break;
777 } else {
778 ch = '/';
780 } else {
781 minp();
785 void skip_spaces(void)
787 while (ch == ' ' || ch == '\t')
788 cinp();
791 /* skip block of text until #else, #elif or #endif. skip also pairs of
792 #if/#endif */
793 void preprocess_skip()
795 int a;
796 a = 0;
797 while (1) {
798 while (ch != '\n') {
799 if (ch == -1)
800 expect("#endif");
801 cinp();
803 cinp();
804 skip_spaces();
805 if (ch == '#') {
806 cinp();
807 next_nomacro();
808 if (a == 0 &&
809 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
810 break;
811 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
812 a++;
813 else if (tok == TOK_ENDIF)
814 a--;
819 /* return the number of additionnal 'ints' necessary to store the
820 token */
821 static inline int tok_ext_size(int t)
823 switch(t) {
824 /* 4 bytes */
825 case TOK_NUM:
826 case TOK_CCHAR:
827 case TOK_LCHAR:
828 case TOK_STR:
829 case TOK_LSTR:
830 case TOK_CFLOAT:
831 return 1;
832 case TOK_CDOUBLE:
833 return 2;
834 case TOK_CLDOUBLE:
835 return LDOUBLE_SIZE / 4;
836 default:
837 return 0;
841 void tok_add(int **tok_str, int *tok_len, int t)
843 int len, *str;
844 len = *tok_len;
845 str = *tok_str;
846 if ((len & 63) == 0) {
847 str = realloc(str, (len + 64) * sizeof(int));
848 if (!str)
849 return;
850 *tok_str = str;
852 str[len++] = t;
853 *tok_len = len;
856 void tok_add2(int **tok_str, int *tok_len, int t, CValue *cv)
858 int n, i;
860 tok_add(tok_str, tok_len, t);
861 n = tok_ext_size(t);
862 for(i=0;i<n;i++)
863 tok_add(tok_str, tok_len, cv->tab[i]);
866 /* get a token from an integer array and increment pointer accordingly */
867 int tok_get(int **tok_str, CValue *cv)
869 int *p, t, n, i;
871 p = *tok_str;
872 t = *p++;
873 n = tok_ext_size(t);
874 for(i=0;i<n;i++)
875 cv->tab[i] = *p++;
876 *tok_str = p;
877 return t;
880 /* eval an expression for #if/#elif */
881 int expr_preprocess(void)
883 int *str, len, c, t;
885 str = NULL;
886 len = 0;
887 while (1) {
888 skip_spaces();
889 if (ch == '\n')
890 break;
891 next(); /* do macro subst */
892 if (tok == TOK_DEFINED) {
893 next_nomacro();
894 t = tok;
895 if (t == '(')
896 next_nomacro();
897 c = sym_find1(&define_stack, tok) != 0;
898 if (t == '(')
899 next_nomacro();
900 tok = TOK_NUM;
901 tokc.i = c;
902 } else if (tok >= TOK_IDENT) {
903 /* if undefined macro */
904 tok = TOK_NUM;
905 tokc.i = 0;
907 tok_add2(&str, &len, tok, &tokc);
909 tok_add(&str, &len, -1); /* simulate end of file */
910 tok_add(&str, &len, 0);
911 /* now evaluate C constant expression */
912 macro_ptr = str;
913 next();
914 c = expr_const();
915 macro_ptr = NULL;
916 free(str);
917 return c != 0;
920 #if defined(DEBUG)
921 void tok_print(int *str)
923 int t;
924 CValue cval;
926 while (1) {
927 t = tok_get(&str, &cval);
928 if (!t)
929 break;
930 printf(" %s", get_tok_str(t, &cval));
932 printf("\n");
934 #endif
936 /* XXX: should be more factorized */
937 void define_symbol(char *sym)
939 TokenSym *ts;
940 int *str, len;
941 CValue cval;
943 ts = tok_alloc(sym, 0);
944 str = NULL;
945 len = 0;
946 cval.i = 1;
947 tok_add2(&str, &len, TOK_NUM, &cval);
948 tok_add(&str, &len, 0);
949 sym_push1(&define_stack, ts->tok, MACRO_OBJ, (int)str);
952 void preprocess(void)
954 int size, i, c, v, t, *str, len;
955 char buf[1024], *q, *p;
956 char buf1[1024];
957 FILE *f;
958 Sym **ps, *first, *s;
960 cinp();
961 next_nomacro();
962 redo:
963 if (tok == TOK_DEFINE) {
964 next_nomacro();
965 v = tok;
966 /* XXX: should check if same macro (ANSI) */
967 first = NULL;
968 t = MACRO_OBJ;
969 /* '(' must be just after macro definition for MACRO_FUNC */
970 if (ch == '(') {
971 next_nomacro();
972 next_nomacro();
973 ps = &first;
974 while (tok != ')') {
975 if (tok == TOK_DOTS)
976 tok = TOK___VA_ARGS__;
977 s = sym_push1(&define_stack, tok | SYM_FIELD, 0, 0);
978 *ps = s;
979 ps = &s->next;
980 next_nomacro();
981 if (tok != ',')
982 break;
983 next_nomacro();
985 t = MACRO_FUNC;
987 str = NULL;
988 len = 0;
989 while (1) {
990 skip_spaces();
991 if (ch == '\n' || ch == -1)
992 break;
993 next_nomacro();
994 tok_add2(&str, &len, tok, &tokc);
996 tok_add(&str, &len, 0);
997 #ifdef PP_DEBUG
998 printf("define %s %d: ", get_tok_str(v, NULL), t);
999 tok_print(str);
1000 #endif
1001 s = sym_push1(&define_stack, v, t, (int)str);
1002 s->next = first;
1003 } else if (tok == TOK_UNDEF) {
1004 next_nomacro();
1005 s = sym_find1(&define_stack, tok);
1006 /* undefine symbol by putting an invalid name */
1007 if (s)
1008 sym_undef(&define_stack, s);
1009 } else if (tok == TOK_INCLUDE) {
1010 skip_spaces();
1011 if (ch == '<') {
1012 c = '>';
1013 goto read_name;
1014 } else if (ch == '\"') {
1015 c = ch;
1016 read_name:
1017 minp();
1018 q = buf;
1019 while (ch != c && ch != '\n' && ch != -1) {
1020 if ((q - buf) < sizeof(buf) - 1)
1021 *q++ = ch;
1022 minp();
1024 *q = '\0';
1025 } else {
1026 next();
1027 if (tok != TOK_STR)
1028 error("#include syntax error");
1029 /* XXX: buffer overflow */
1030 strcpy(buf, get_tok_str(tok, &tokc));
1031 c = '\"';
1033 /* eat all spaces and comments after include */
1034 /* XXX: slightly incorrect */
1035 while (ch1 != '\n' && ch1 != -1)
1036 inp();
1038 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1039 error("memory full");
1040 if (c == '\"') {
1041 /* first search in current dir if "header.h" */
1042 /* XXX: buffer overflow */
1043 size = 0;
1044 p = strrchr(filename, '/');
1045 if (p)
1046 size = p + 1 - filename;
1047 memcpy(buf1, filename, size);
1048 buf1[size] = '\0';
1049 strcat(buf1, buf);
1050 f = fopen(buf1, "r");
1051 if (f)
1052 goto found;
1054 /* now search in standard include path */
1055 for(i=nb_include_paths - 1;i>=0;i--) {
1056 strcpy(buf1, include_paths[i]);
1057 strcat(buf1, "/");
1058 strcat(buf1, buf);
1059 f = fopen(buf1, "r");
1060 if (f)
1061 goto found;
1063 error("include file '%s' not found", buf1);
1064 f = NULL;
1065 found:
1066 /* push current file in stack */
1067 /* XXX: fix current line init */
1068 include_stack_ptr->file = file;
1069 include_stack_ptr->filename = filename;
1070 include_stack_ptr->line_num = line_num;
1071 include_stack_ptr++;
1072 file = f;
1073 filename = strdup(buf1);
1074 line_num = 1;
1075 } else if (tok == TOK_IFNDEF) {
1076 c = 1;
1077 goto do_ifdef;
1078 } else if (tok == TOK_IF) {
1079 c = expr_preprocess();
1080 goto do_if;
1081 } else if (tok == TOK_IFDEF) {
1082 c = 0;
1083 do_ifdef:
1084 next_nomacro();
1085 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1086 do_if:
1087 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1088 error("memory full");
1089 *ifdef_stack_ptr++ = c;
1090 goto test_skip;
1091 } else if (tok == TOK_ELSE) {
1092 if (ifdef_stack_ptr == ifdef_stack ||
1093 (ifdef_stack_ptr[-1] & 2))
1094 error("#else after #else");
1095 c = (ifdef_stack_ptr[-1] ^= 3);
1096 goto test_skip;
1097 } else if (tok == TOK_ELIF) {
1098 if (ifdef_stack_ptr == ifdef_stack ||
1099 ifdef_stack_ptr[-1] > 1)
1100 error("#elif after #else");
1101 c = expr_preprocess();
1102 ifdef_stack_ptr[-1] = c;
1103 test_skip:
1104 if (!(c & 1)) {
1105 preprocess_skip();
1106 goto redo;
1108 } else if (tok == TOK_ENDIF) {
1109 if (ifdef_stack_ptr == ifdef_stack)
1110 expect("#if");
1111 ifdef_stack_ptr--;
1112 } else if (tok == TOK_LINE) {
1113 next();
1114 if (tok != TOK_NUM)
1115 error("#line");
1116 line_num = tokc.i;
1117 skip_spaces();
1118 if (ch != '\n') {
1119 next();
1120 if (tok != TOK_STR)
1121 error("#line");
1122 /* XXX: potential memory leak */
1123 filename = strdup(get_tok_str(tok, &tokc));
1125 } else if (tok == TOK_ERROR) {
1126 error("#error");
1128 /* ignore other preprocess commands or #! for C scripts */
1129 while (ch != '\n' && ch != -1)
1130 cinp();
1133 /* read a number in base b */
1134 int getn(b)
1136 int n, t;
1137 n = 0;
1138 while (1) {
1139 if (ch >= 'a' & ch <= 'f')
1140 t = ch - 'a' + 10;
1141 else if (ch >= 'A' & ch <= 'F')
1142 t = ch - 'A' + 10;
1143 else if (isnum(ch))
1144 t = ch - '0';
1145 else
1146 break;
1147 if (t < 0 | t >= b)
1148 break;
1149 n = n * b + t;
1150 cinp();
1152 return n;
1155 /* read a character for string or char constant and eval escape codes */
1156 int getq()
1158 int c;
1160 c = ch;
1161 minp();
1162 if (c == '\\') {
1163 if (isnum(ch)) {
1164 /* at most three octal digits */
1165 c = ch - '0';
1166 minp();
1167 if (isnum(ch)) {
1168 c = c * 8 + ch - '0';
1169 minp();
1170 if (isnum(ch)) {
1171 c = c * 8 + ch - '0';
1172 minp();
1175 return c;
1176 } else if (ch == 'x') {
1177 minp();
1178 return getn(16);
1179 } else {
1180 if (ch == 'a')
1181 c = '\a';
1182 else if (ch == 'b')
1183 c = '\b';
1184 else if (ch == 'f')
1185 c = '\f';
1186 else if (ch == 'n')
1187 c = '\n';
1188 else if (ch == 'r')
1189 c = '\r';
1190 else if (ch == 't')
1191 c = '\t';
1192 else if (ch == 'v')
1193 c = '\v';
1194 else if (ch == 'e' && gnu_ext)
1195 c = 27;
1196 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
1197 c = ch;
1198 else
1199 error("invalid escaped char");
1200 minp();
1203 return c;
1206 /* we use 64 bit numbers */
1207 #define BN_SIZE 2
1209 /* bn = (bn << shift) | or_val */
1210 void bn_lshift(unsigned int *bn, int shift, int or_val)
1212 int i;
1213 unsigned int v;
1214 for(i=0;i<BN_SIZE;i++) {
1215 v = bn[i];
1216 bn[i] = (v << shift) | or_val;
1217 or_val = v >> (32 - shift);
1221 void bn_zero(unsigned int *bn)
1223 int i;
1224 for(i=0;i<BN_SIZE;i++) {
1225 bn[i] = 0;
1229 void parse_number(void)
1231 int b, t, shift, frac_bits, s, exp_val;
1232 char *q;
1233 unsigned int n, n1;
1234 unsigned int bn[BN_SIZE];
1235 double d;
1237 /* number */
1238 q = token_buf;
1239 t = ch;
1240 cinp();
1241 *q++ = t;
1242 b = 10;
1243 if (t == '.') {
1244 /* special dot handling */
1245 if (ch >= '0' && ch <= '9') {
1246 goto float_frac_parse;
1247 } else if (ch == '.') {
1248 cinp();
1249 if (ch != '.')
1250 expect("'.'");
1251 cinp();
1252 tok = TOK_DOTS;
1253 } else {
1254 /* dots */
1255 tok = t;
1257 return;
1258 } else if (t == '0') {
1259 if (ch == 'x' || ch == 'X') {
1260 q--;
1261 cinp();
1262 b = 16;
1263 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
1264 q--;
1265 cinp();
1266 b = 2;
1269 /* parse all digits. cannot check octal numbers at this stage
1270 because of floating point constants */
1271 while (1) {
1272 if (ch >= 'a' & ch <= 'f')
1273 t = ch - 'a' + 10;
1274 else if (ch >= 'A' & ch <= 'F')
1275 t = ch - 'A' + 10;
1276 else if (isnum(ch))
1277 t = ch - '0';
1278 else
1279 break;
1280 if (t >= b)
1281 break;
1282 if (q >= token_buf + STRING_MAX_SIZE) {
1283 num_too_long:
1284 error("number too long");
1286 *q++ = ch;
1287 cinp();
1289 if (ch == '.' ||
1290 ((ch == 'e' || ch == 'E') && b == 10) ||
1291 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
1292 if (b != 10) {
1293 /* NOTE: strtox should support that for hexa numbers, but
1294 non ISOC99 libcs do not support it, so we prefer to do
1295 it by hand */
1296 /* hexadecimal or binary floats */
1297 /* XXX: handle overflows */
1298 *q = '\0';
1299 if (b == 16)
1300 shift = 4;
1301 else
1302 shift = 2;
1303 bn_zero(bn);
1304 q = token_buf;
1305 while (1) {
1306 t = *q++;
1307 if (t == '\0') {
1308 break;
1309 } else if (t >= 'a') {
1310 t = t - 'a' + 10;
1311 } else if (t >= 'A') {
1312 t = t - 'A' + 10;
1313 } else {
1314 t = t - '0';
1316 bn_lshift(bn, shift, t);
1318 frac_bits = 0;
1319 if (ch == '.') {
1320 cinp();
1321 while (1) {
1322 t = ch;
1323 if (t >= 'a' && t <= 'f') {
1324 t = t - 'a' + 10;
1325 } else if (t >= 'A' && t <= 'F') {
1326 t = t - 'A' + 10;
1327 } else if (t >= '0' && t <= '9') {
1328 t = t - '0';
1329 } else {
1330 break;
1332 if (t >= b)
1333 error("invalid digit");
1334 bn_lshift(bn, shift, t);
1335 frac_bits += shift;
1336 cinp();
1339 if (ch != 'p' && ch != 'P')
1340 error("exponent expected");
1341 cinp();
1342 s = 1;
1343 exp_val = 0;
1344 if (ch == '+') {
1345 cinp();
1346 } else if (ch == '-') {
1347 s = -1;
1348 cinp();
1350 if (ch < '0' || ch > '9')
1351 error("exponent digits expected");
1352 while (ch >= '0' && ch <= '9') {
1353 exp_val = exp_val * 10 + ch - '0';
1354 cinp();
1356 exp_val = exp_val * s;
1358 /* now we can generate the number */
1359 /* XXX: should patch directly float number */
1360 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
1361 d = ldexp(d, exp_val - frac_bits);
1362 t = toup(ch);
1363 if (t == 'F') {
1364 cinp();
1365 tok = TOK_CFLOAT;
1366 /* float : should handle overflow */
1367 tokc.f = (float)d;
1368 } else if (t == 'L') {
1369 cinp();
1370 tok = TOK_CLDOUBLE;
1371 /* XXX: not large enough */
1372 tokc.ld = (long double)d;
1373 } else {
1374 tok = TOK_CDOUBLE;
1375 tokc.d = d;
1377 } else {
1378 /* decimal floats */
1379 if (ch == '.') {
1380 if (q >= token_buf + STRING_MAX_SIZE)
1381 goto num_too_long;
1382 *q++ = ch;
1383 cinp();
1384 float_frac_parse:
1385 while (ch >= '0' && ch <= '9') {
1386 if (q >= token_buf + STRING_MAX_SIZE)
1387 goto num_too_long;
1388 *q++ = ch;
1389 cinp();
1392 if (ch == 'e' || ch == 'E') {
1393 if (q >= token_buf + STRING_MAX_SIZE)
1394 goto num_too_long;
1395 *q++ = ch;
1396 cinp();
1397 if (ch == '-' || ch == '+') {
1398 if (q >= token_buf + STRING_MAX_SIZE)
1399 goto num_too_long;
1400 *q++ = ch;
1401 cinp();
1403 if (ch < '0' || ch > '9')
1404 error("exponent digits expected");
1405 while (ch >= '0' && ch <= '9') {
1406 if (q >= token_buf + STRING_MAX_SIZE)
1407 goto num_too_long;
1408 *q++ = ch;
1409 cinp();
1412 *q = '\0';
1413 t = toup(ch);
1414 errno = 0;
1415 if (t == 'F') {
1416 cinp();
1417 tok = TOK_CFLOAT;
1418 tokc.f = strtof(token_buf, NULL);
1419 } else if (t == 'L') {
1420 cinp();
1421 tok = TOK_CLDOUBLE;
1422 tokc.ld = strtold(token_buf, NULL);
1423 } else {
1424 tok = TOK_CDOUBLE;
1425 tokc.d = strtod(token_buf, NULL);
1428 } else {
1429 /* integer number */
1430 *q = '\0';
1431 q = token_buf;
1432 if (b == 10 && *q == '0') {
1433 b = 8;
1434 q++;
1436 n = 0;
1437 while(1) {
1438 t = *q++;
1439 /* no need for checks except for base 10 / 8 errors */
1440 if (t == '\0') {
1441 break;
1442 } else if (t >= 'a') {
1443 t = t - 'a' + 10;
1444 } else if (t >= 'A') {
1445 t = t - 'A' + 10;
1446 } else {
1447 t = t - '0';
1448 if (t >= b)
1449 error("invalid digit");
1451 n1 = n;
1452 n = n * b + t;
1453 /* detect overflow */
1454 if (n < n1)
1455 error("integer constant overflow");
1457 tokc.ui = n;
1458 tok = TOK_NUM;
1459 /* XXX: add unsigned constant support (ANSI) */
1460 while (ch == 'L' || ch == 'l' || ch == 'U' || ch == 'u')
1461 cinp();
1466 /* return next token without macro substitution */
1467 void next_nomacro1(void)
1469 int b;
1470 char *q;
1471 TokenSym *ts;
1473 /* skip spaces */
1474 while(1) {
1475 while (ch == '\n') {
1476 cinp();
1477 while (ch == ' ' || ch == 9)
1478 cinp();
1479 if (ch == '#') {
1480 /* preprocessor command if # at start of line after
1481 spaces */
1482 preprocess();
1485 if (ch != ' ' && ch != '\t' && ch != '\f')
1486 break;
1487 cinp();
1489 if (isid(ch)) {
1490 q = token_buf;
1491 *q++ = ch;
1492 cinp();
1493 if (q[-1] == 'L') {
1494 if (ch == '\'') {
1495 tok = TOK_LCHAR;
1496 goto char_const;
1498 if (ch == '\"') {
1499 tok = TOK_LSTR;
1500 goto str_const;
1503 while (isid(ch) || isnum(ch)) {
1504 if (q >= token_buf + STRING_MAX_SIZE)
1505 error("ident too long");
1506 *q++ = ch;
1507 cinp();
1509 *q = '\0';
1510 ts = tok_alloc(token_buf, q - token_buf);
1511 tok = ts->tok;
1512 } else if (isnum(ch) || ch == '.') {
1513 parse_number();
1514 } else if (ch == '\'') {
1515 tok = TOK_CCHAR;
1516 char_const:
1517 minp();
1518 tokc.i = getq();
1519 if (ch != '\'')
1520 expect("\'");
1521 minp();
1522 } else if (ch == '\"') {
1523 tok = TOK_STR;
1524 str_const:
1525 minp();
1526 q = token_buf;
1527 while (ch != '\"') {
1528 b = getq();
1529 if (ch == -1)
1530 error("unterminated string");
1531 if (q >= token_buf + STRING_MAX_SIZE)
1532 error("string too long");
1533 *q++ = b;
1535 *q = '\0';
1536 tokc.ts = tok_alloc(token_buf, q - token_buf);
1537 minp();
1538 } else {
1539 q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\247..\250##\266";
1540 /* two chars */
1541 tok = ch;
1542 cinp();
1543 while (*q) {
1544 if (*q == tok && q[1] == ch) {
1545 cinp();
1546 tok = q[2] & 0xff;
1547 /* three chars tests */
1548 if (tok == TOK_SHL | tok == TOK_SAR) {
1549 if (ch == '=') {
1550 tok = tok | 0x80;
1551 cinp();
1553 } else if (tok == TOK_DOTS) {
1554 if (ch != '.')
1555 error("parse error");
1556 cinp();
1558 return;
1560 q = q + 3;
1562 /* single char substitutions */
1563 if (tok == '<')
1564 tok = TOK_LT;
1565 else if (tok == '>')
1566 tok = TOK_GT;
1570 /* return next token without macro substitution. Can read input from
1571 macro_ptr buffer */
1572 void next_nomacro()
1574 if (macro_ptr) {
1575 tok = *macro_ptr;
1576 if (tok)
1577 tok = tok_get(&macro_ptr, &tokc);
1578 } else {
1579 next_nomacro1();
1583 /* substitute args in macro_str and return allocated string */
1584 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
1586 int *st, last_tok, t, notfirst, *str, len;
1587 Sym *s;
1588 TokenSym *ts;
1589 CValue cval;
1591 str = NULL;
1592 len = 0;
1593 last_tok = 0;
1594 while(1) {
1595 t = tok_get(&macro_str, &cval);
1596 if (!t)
1597 break;
1598 if (t == '#') {
1599 /* stringize */
1600 t = tok_get(&macro_str, &cval);
1601 if (!t)
1602 break;
1603 s = sym_find2(args, t);
1604 if (s) {
1605 token_buf[0] = '\0';
1606 st = (int *)s->c;
1607 /* XXX: buffer overflow */
1608 notfirst = 0;
1609 while (*st) {
1610 if (notfirst)
1611 strcat(token_buf, " ");
1612 t = tok_get(&st, &cval);
1613 strcat(token_buf, get_tok_str(t, &cval));
1614 notfirst = 1;
1616 #ifdef PP_DEBUG
1617 printf("stringize: %s\n", token_buf);
1618 #endif
1619 /* add string */
1620 ts = tok_alloc(token_buf, 0);
1621 cval.ts = ts;
1622 tok_add2(&str, &len, TOK_STR, &cval);
1623 } else {
1624 tok_add2(&str, &len, t, &cval);
1626 } else if (t >= TOK_IDENT) {
1627 s = sym_find2(args, t);
1628 if (s) {
1629 st = (int *)s->c;
1630 /* if '##' is present before or after , no arg substitution */
1631 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
1632 while (*st)
1633 tok_add(&str, &len, *st++);
1634 } else {
1635 macro_subst(&str, &len, nested_list, st);
1637 } else {
1638 tok_add(&str, &len, t);
1640 } else {
1641 tok_add2(&str, &len, t, &cval);
1643 last_tok = t;
1645 tok_add(&str, &len, 0);
1646 return str;
1649 /* handle the '##' operator */
1650 int *macro_twosharps(int *macro_str)
1652 TokenSym *ts;
1653 int *macro_str1, macro_str1_len, *macro_ptr1;
1654 int t;
1655 char *p;
1656 CValue cval;
1658 macro_str1 = NULL;
1659 macro_str1_len = 0;
1660 tok = 0;
1661 while (1) {
1662 next_nomacro();
1663 if (tok == 0)
1664 break;
1665 while (*macro_ptr == TOK_TWOSHARPS) {
1666 macro_ptr++;
1667 macro_ptr1 = macro_ptr;
1668 t = *macro_ptr;
1669 if (t) {
1670 t = tok_get(&macro_ptr, &cval);
1671 /* XXX: we handle only most common cases:
1672 ident + ident or ident + number */
1673 if (tok >= TOK_IDENT &&
1674 (t >= TOK_IDENT || t == TOK_NUM)) {
1675 /* XXX: buffer overflow */
1676 p = get_tok_str(tok, &tokc);
1677 strcpy(token_buf, p);
1678 p = get_tok_str(t, &cval);
1679 strcat(token_buf, p);
1680 ts = tok_alloc(token_buf, 0);
1681 tok = ts->tok; /* modify current token */
1682 } else {
1683 /* cannot merge tokens: skip '##' */
1684 macro_ptr = macro_ptr1;
1685 break;
1689 tok_add2(&macro_str1, &macro_str1_len, tok, &tokc);
1691 tok_add(&macro_str1, &macro_str1_len, 0);
1692 return macro_str1;
1697 /* do macro substitution of macro_str and add result to
1698 (tok_str,tok_len). If macro_str is NULL, then input stream token is
1699 substituted. 'nested_list' is the list of all macros we got inside
1700 to avoid recursing. */
1701 void macro_subst(int **tok_str, int *tok_len,
1702 Sym **nested_list, int *macro_str)
1704 Sym *s, *args, *sa, *sa1;
1705 int *str, parlevel, len, *mstr, t, *saved_macro_ptr;
1706 int mstr_allocated, *macro_str1;
1707 CValue cval;
1709 saved_macro_ptr = macro_ptr;
1710 macro_ptr = macro_str;
1711 macro_str1 = NULL;
1712 if (macro_str) {
1713 /* first scan for '##' operator handling */
1714 macro_str1 = macro_twosharps(macro_str);
1715 macro_ptr = macro_str1;
1718 while (1) {
1719 next_nomacro();
1720 if (tok == 0)
1721 break;
1722 /* special macros */
1723 if (tok == TOK___LINE__) {
1724 cval.i = line_num;
1725 tok_add2(tok_str, tok_len, TOK_NUM, &cval);
1726 } else if (tok == TOK___FILE__) {
1727 cval.ts = tok_alloc(filename, 0);
1728 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1729 } else if (tok == TOK___DATE__) {
1730 cval.ts = tok_alloc("Jan 1 1970", 0);
1731 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1732 } else if (tok == TOK___TIME__) {
1733 cval.ts = tok_alloc("00:00:00", 0);
1734 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1735 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
1736 /* if symbol is a macro, prepare substitution */
1737 /* if nested substitution, do nothing */
1738 if (sym_find2(*nested_list, tok))
1739 goto no_subst;
1740 mstr = (int *)s->c;
1741 mstr_allocated = 0;
1742 if (s->t == MACRO_FUNC) {
1743 /* NOTE: we do not use next_nomacro to avoid eating the
1744 next token. XXX: find better solution */
1745 if (macro_ptr) {
1746 t = *macro_ptr;
1747 } else {
1748 while (ch == ' ' || ch == '\t' || ch == '\n')
1749 cinp();
1750 t = ch;
1752 if (t != '(') /* no macro subst */
1753 goto no_subst;
1755 /* argument macro */
1756 next_nomacro();
1757 next_nomacro();
1758 args = NULL;
1759 sa = s->next;
1760 while (tok != ')' && sa) {
1761 len = 0;
1762 str = NULL;
1763 parlevel = 0;
1764 while ((parlevel > 0 ||
1765 (tok != ')' &&
1766 (tok != ',' ||
1767 sa->v == (TOK___VA_ARGS__ | SYM_FIELD)))) &&
1768 tok != -1) {
1769 if (tok == '(')
1770 parlevel++;
1771 else if (tok == ')')
1772 parlevel--;
1773 tok_add2(&str, &len, tok, &tokc);
1774 next_nomacro();
1776 tok_add(&str, &len, 0);
1777 sym_push2(&args, sa->v & ~SYM_FIELD, 0, (int)str);
1778 if (tok != ',')
1779 break;
1780 next_nomacro();
1781 sa = sa->next;
1783 if (tok != ')')
1784 expect(")");
1785 /* now subst each arg */
1786 mstr = macro_arg_subst(nested_list, mstr, args);
1787 /* free memory */
1788 sa = args;
1789 while (sa) {
1790 sa1 = sa->prev;
1791 free((int *)sa->c);
1792 free(sa);
1793 sa = sa1;
1795 mstr_allocated = 1;
1797 sym_push2(nested_list, s->v, 0, 0);
1798 macro_subst(tok_str, tok_len, nested_list, mstr);
1799 /* pop nested defined symbol */
1800 sa1 = *nested_list;
1801 *nested_list = sa1->prev;
1802 free(sa1);
1803 if (mstr_allocated)
1804 free(mstr);
1805 } else {
1806 no_subst:
1807 /* no need to add if reading input stream */
1808 if (!macro_str)
1809 return;
1810 tok_add2(tok_str, tok_len, tok, &tokc);
1812 /* only replace one macro while parsing input stream */
1813 if (!macro_str)
1814 return;
1816 macro_ptr = saved_macro_ptr;
1817 if (macro_str1)
1818 free(macro_str1);
1821 /* return next token with macro substitution */
1822 void next(void)
1824 int len, *ptr;
1825 Sym *nested_list;
1827 /* special 'ungettok' case for label parsing */
1828 if (tok1) {
1829 tok = tok1;
1830 tokc = tok1c;
1831 tok1 = 0;
1832 } else {
1833 redo:
1834 if (!macro_ptr) {
1835 /* if not reading from macro substuted string, then try to substitute */
1836 len = 0;
1837 ptr = NULL;
1838 nested_list = NULL;
1839 macro_subst(&ptr, &len, &nested_list, NULL);
1840 if (ptr) {
1841 tok_add(&ptr, &len, 0);
1842 macro_ptr = ptr;
1843 macro_ptr_allocated = ptr;
1844 goto redo;
1846 if (tok == 0)
1847 goto redo;
1848 } else {
1849 next_nomacro();
1850 if (tok == 0) {
1851 /* end of macro string: free it */
1852 free(macro_ptr_allocated);
1853 macro_ptr = NULL;
1854 goto redo;
1858 #if defined(DEBUG)
1859 printf("token = %s\n", get_tok_str(tok, tokc));
1860 #endif
1863 void swap(int *p, int *q)
1865 int t;
1866 t = *p;
1867 *p = *q;
1868 *q = t;
1871 void vsetc(int t, CValue *vc)
1873 if (vtop >= vstack + VSTACK_SIZE)
1874 error("memory full");
1875 /* cannot let cpu flags if other instruction are generated */
1876 /* XXX: VT_JMP test too ? */
1877 if ((vtop->t & VT_VALMASK) == VT_CMP)
1878 gv();
1879 vtop++;
1880 vtop->t = t;
1881 vtop->c = *vc;
1884 void vset(int t, int v)
1886 CValue cval;
1888 cval.i = v;
1889 vsetc(t, &cval);
1892 void vswap(void)
1894 SValue tmp;
1896 tmp = vtop[0];
1897 vtop[0] = vtop[-1];
1898 vtop[-1] = tmp;
1901 void vdup(void)
1903 if (vtop >= vstack + VSTACK_SIZE)
1904 error("memory full");
1905 vtop++;
1906 *vtop = vtop[-1];
1909 int save_reg_forced(int r)
1911 int i, l, t;
1912 SValue *p;
1914 /* store register */
1915 loc = (loc - 4) & -3;
1916 store(r, VT_LOCAL, loc);
1917 l = loc;
1919 /* modify all stack values */
1920 for(p=vstack;p<=vtop;p++) {
1921 i = p->t & VT_VALMASK;
1922 if (i == r) {
1923 if (p->t & VT_LVAL)
1924 t = VT_LLOCAL;
1925 else
1926 t = VT_LOCAL;
1927 p->t = (p->t & VT_TYPE) | VT_LVAL | t;
1928 p->c.ul = l;
1931 return l;
1934 /* save r to memory. and mark it as being free */
1935 void save_reg(int r)
1937 int i;
1938 SValue *p;
1940 /* modify all stack values */
1941 for(p=vstack;p<=vtop;p++) {
1942 i = p->t & VT_VALMASK;
1943 if (i == r) {
1944 save_reg_forced(r);
1945 break;
1950 /* find a free register of class 'rc'. If none, save one register */
1951 int get_reg(int rc)
1953 int r, i;
1954 SValue *p;
1956 /* find a free register */
1957 for(r=0;r<NB_REGS;r++) {
1958 if (reg_classes[r] & rc) {
1959 for(p=vstack;p<=vtop;p++) {
1960 i = p->t & VT_VALMASK;
1961 if (i == r)
1962 goto notfound;
1964 return r;
1966 notfound: ;
1969 /* no register left : free the first one on the stack (very
1970 important to start from the bottom to ensure that we don't
1971 spill registers used in gen_op()) */
1972 for(p=vstack;p<=vtop;p++) {
1973 r = p->t & VT_VALMASK;
1974 if (r < VT_CONST && (reg_classes[r] & rc)) {
1975 save_reg(r);
1976 break;
1979 return r;
1982 void save_regs()
1984 int r;
1985 SValue *p;
1987 for(p=vstack;p<=vtop;p++) {
1988 r = p->t & VT_VALMASK;
1989 if (r < VT_CONST) {
1990 save_reg(r);
1995 /* move register 's' to 'r', and flush previous value of r to memory
1996 if needed */
1997 void move_reg(int r, int s)
1999 if (r != s) {
2000 save_reg(r);
2001 load(r, s, 0);
2005 /* convert a (vtop->t, vtop->c) in register. lvalues are converted as
2006 values. Cannot be used if cannot be converted to register value
2007 (such as structures). */
2008 int gv(void)
2010 int r, bit_pos, bit_size, rc, size, align, i;
2012 /* NOTE: get_reg can modify vstack[] */
2013 if (vtop->t & VT_BITFIELD) {
2014 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
2015 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2016 /* remove bit field info to avoid loops */
2017 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2018 /* generate shifts */
2019 vset(VT_CONST, 32 - (bit_pos + bit_size));
2020 gen_op(TOK_SHL);
2021 vset(VT_CONST, 32 - bit_size);
2022 /* NOTE: transformed to SHR if unsigned */
2023 gen_op(TOK_SAR);
2024 r = gv();
2025 } else {
2026 if (is_float(vtop->t) && (vtop->t & (VT_CONST | VT_LVAL)) == VT_CONST) {
2027 /* CPUs usually cannot use float constants, so we store them
2028 generically in data segment */
2029 size = type_size(vtop->t, &align);
2030 glo = (glo + align - 1) & -align;
2031 /* XXX: not portable yet */
2032 size = size >> 2;
2033 for(i=0;i<size;i++)
2034 ((int *)glo)[i] = vtop->c.tab[i];
2035 vtop->t |= VT_LVAL;
2036 vtop->c.ul = glo;
2037 glo += size << 2;
2039 r = vtop->t & VT_VALMASK;
2040 if (r >= VT_CONST || (vtop->t & VT_LVAL)) {
2041 if (is_float(vtop->t))
2042 rc = REG_CLASS_FLOAT;
2043 else
2044 rc = REG_CLASS_INT;
2045 r = get_reg(rc);
2047 load(r, vtop->t, vtop->c.ul);
2048 vtop->t = (vtop->t & VT_TYPE) | r;
2050 return r;
2053 /* handle constant optimizations and various machine independant opt */
2054 void gen_opc(int op)
2056 int fc, c1, c2, n;
2057 SValue *v1, *v2;
2059 v1 = vtop - 1;
2060 v2 = vtop;
2061 /* currently, we cannot do computations with forward symbols */
2062 c1 = (v1->t & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2063 c2 = (v2->t & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2064 if (c1 && c2) {
2065 fc = v2->c.i;
2066 switch(op) {
2067 case '+': v1->c.i += fc; break;
2068 case '-': v1->c.i -= fc; break;
2069 case '&': v1->c.i &= fc; break;
2070 case '^': v1->c.i ^= fc; break;
2071 case '|': v1->c.i |= fc; break;
2072 case '*': v1->c.i *= fc; break;
2073 case TOK_PDIV:
2074 case '/': v1->c.i /= fc; break; /* XXX: zero case ? */
2075 case '%': v1->c.i %= fc; break; /* XXX: zero case ? */
2076 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break; /* XXX: zero case ? */
2077 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break; /* XXX: zero case ? */
2078 case TOK_SHL: v1->c.i <<= fc; break;
2079 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
2080 case TOK_SAR: v1->c.i >>= fc; break;
2081 /* tests */
2082 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
2083 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
2084 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
2085 case TOK_NE: v1->c.i = v1->c.i != fc; break;
2086 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
2087 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
2088 case TOK_LT: v1->c.i = v1->c.i < fc; break;
2089 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
2090 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
2091 case TOK_GT: v1->c.i = v1->c.i > fc; break;
2092 /* logical */
2093 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
2094 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
2095 default:
2096 goto general_case;
2098 vtop--;
2099 } else {
2100 /* if commutative ops, put c2 as constant */
2101 if (c1 && (op == '+' || op == '&' || op == '^' ||
2102 op == '|' || op == '*')) {
2103 vswap();
2104 swap(&c1, &c2);
2106 fc = vtop->c.i;
2107 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2108 op == TOK_PDIV) &&
2109 fc == 1) ||
2110 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2111 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2112 fc == 0) ||
2113 (op == '&' &&
2114 fc == -1))) {
2115 /* nothing to do */
2116 vtop--;
2117 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2118 /* try to use shifts instead of muls or divs */
2119 if (fc > 0 && (fc & (fc - 1)) == 0) {
2120 n = -1;
2121 while (fc) {
2122 fc >>= 1;
2123 n++;
2125 vtop->c.i = n;
2126 if (op == '*')
2127 op = TOK_SHL;
2128 else if (op == TOK_PDIV)
2129 op = TOK_SAR;
2130 else
2131 op = TOK_SHR;
2133 goto general_case;
2134 } else {
2135 general_case:
2136 /* call low level op generator */
2137 /* XXX: remove explicit registers */
2138 gen_opi(op);
2143 int pointed_size(int t)
2145 return type_size(pointed_type(t), &t);
2148 /* generic gen_op: handles types problems */
2149 void gen_op(int op)
2151 int u, t1, t2, bt1, bt2, t;
2153 t1 = vtop[-1].t;
2154 t2 = vtop[0].t;
2155 bt1 = t1 & VT_BTYPE;
2156 bt2 = t2 & VT_BTYPE;
2158 if (is_float(bt1) || is_float(bt2)) {
2159 /* compute bigger type and do implicit casts */
2160 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
2161 t = VT_LDOUBLE;
2162 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
2163 t = VT_DOUBLE;
2164 } else {
2165 t = VT_FLOAT;
2167 if (op != '+' && op != '-' && op != '*' && op != '/' &&
2168 op < TOK_EQ || op > TOK_GT)
2169 error("invalid operands for binary operation");
2170 if (bt1 != t) {
2171 vswap();
2172 gen_cast(t);
2173 vswap();
2175 if (bt2 != t) {
2176 gen_cast(t);
2178 gen_opf(op);
2179 if (op >= TOK_EQ && op <= TOK_GT) {
2180 /* the result is an int */
2181 vtop->t = (vtop->t & ~VT_TYPE) | VT_INT;
2182 } else {
2183 vtop->t = (vtop->t & ~VT_TYPE) | t;
2185 } else if (op == '+' || op == '-') {
2186 if ((t1 & VT_BTYPE) == VT_PTR &&
2187 (t2 & VT_BTYPE) == VT_PTR) {
2188 if (op != '-')
2189 error("invalid type");
2190 /* XXX: check that types are compatible */
2191 u = pointed_size(t1);
2192 gen_opc(op);
2193 /* set to integer type */
2194 vtop->t = (vtop->t & ~VT_TYPE) | VT_INT;
2195 vset(VT_CONST, u);
2196 gen_op(TOK_PDIV);
2197 } else if ((t1 & VT_BTYPE) == VT_PTR ||
2198 (t2 & VT_BTYPE) == VT_PTR) {
2199 if ((t2 & VT_BTYPE) == VT_PTR) {
2200 vswap();
2201 swap(&t1, &t2);
2203 /* stack-4 contains pointer, stack-2 value to add */
2204 vset(VT_CONST, pointed_size(vtop[-1].t));
2205 gen_op('*');
2206 gen_opc(op);
2207 /* put again type if gen_opc() swaped operands */
2208 vtop->t = (vtop->t & ~VT_TYPE) | (t1 & VT_TYPE);
2209 } else {
2210 gen_opc(op);
2212 } else {
2213 /* XXX: test types and compute returned value */
2214 if ((t1 | t2) & VT_UNSIGNED ||
2215 (t1 & VT_BTYPE) == VT_PTR ||
2216 (t2 & VT_BTYPE) == VT_PTR) {
2217 if (op == TOK_SAR)
2218 op = TOK_SHR;
2219 else if (op == '/')
2220 op = TOK_UDIV;
2221 else if (op == '%')
2222 op = TOK_UMOD;
2223 else if (op == TOK_LT)
2224 op = TOK_ULT;
2225 else if (op == TOK_GT)
2226 op = TOK_UGT;
2227 else if (op == TOK_LE)
2228 op = TOK_ULE;
2229 else if (op == TOK_GE)
2230 op = TOK_UGE;
2232 gen_opc(op);
2236 /* cast 'vtop' to 't' type */
2237 void gen_cast(int t)
2239 int r, bits, sbt, dbt, sf, df, c, st1, dt1;
2241 r = vtop->t & VT_VALMASK;
2242 if (!(t & VT_LVAL)) {
2243 /* if not lvalue, then we convert now */
2244 dbt = t & VT_BTYPE;
2245 sbt = vtop->t & VT_BTYPE;
2246 if (sbt != dbt) {
2247 sf = is_float(sbt);
2248 df = is_float(dbt);
2249 c = (vtop->t & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2250 if (sf && df) {
2251 /* convert from fp to fp */
2252 if (c) {
2253 /* constant case: we can do it now */
2254 /* XXX: in ISOC, cannot do it if error in convert */
2255 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
2256 vtop->c.f = (float)vtop->c.d;
2257 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
2258 vtop->c.f = (float)vtop->c.ld;
2259 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
2260 vtop->c.d = (double)vtop->c.f;
2261 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
2262 vtop->c.d = (double)vtop->c.ld;
2263 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
2264 vtop->c.ld = (long double)vtop->c.f;
2265 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
2266 vtop->c.ld = (long double)vtop->c.d;
2267 } else {
2268 /* non constant case: generate code */
2269 gen_cvt_ftof(dbt);
2271 } else if (df) {
2272 /* convert int to fp */
2273 /* XXX: add const cases */
2274 st1 = vtop->t & (VT_BTYPE | VT_UNSIGNED);
2275 if (c) {
2276 switch(st1) {
2277 case VT_LLONG | VT_UNSIGNED:
2278 case VT_LLONG:
2279 /* well, currently not needed */
2280 goto do_itof;
2281 case VT_INT | VT_UNSIGNED:
2282 switch(dbt) {
2283 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
2284 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
2285 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
2287 break;
2288 default:
2289 switch(dbt) {
2290 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
2291 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
2292 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
2294 break;
2296 } else {
2297 do_itof:
2298 gen_cvt_itof(dbt);
2300 } else if (sf) {
2301 /* convert fp to int */
2302 dt1 = t & (VT_BTYPE | VT_UNSIGNED);
2303 /* we handle char/short/etc... with generic code */
2304 if (dt1 != VT_INT | VT_UNSIGNED &&
2305 dt1 != VT_LLONG | VT_UNSIGNED &&
2306 dt1 != VT_LLONG)
2307 dt1 = VT_INT;
2308 if (c) {
2309 switch(dt1) {
2310 case VT_LLONG | VT_UNSIGNED:
2311 case VT_LLONG:
2312 /* well, currently not needed */
2313 goto do_ftoi;
2314 case VT_INT | VT_UNSIGNED:
2315 switch(sbt) {
2316 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
2317 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
2318 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
2320 break;
2321 default:
2322 /* int case */
2323 switch(sbt) {
2324 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
2325 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
2326 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
2328 break;
2330 } else {
2331 do_ftoi:
2332 gen_cvt_ftoi(dt1);
2334 if (dt1 == VT_INT && (t & (VT_TYPE | VT_UNSIGNED)) != dt1) {
2335 /* additionnal cast for char/short/bool... */
2336 vtop->t = (vtop->t & ~VT_TYPE) | dt1;
2337 gen_cast(t);
2339 } else if (dbt == VT_BOOL) {
2340 vset(VT_CONST, 0);
2341 gen_op(TOK_NE);
2342 } else if (dbt == VT_BYTE || dbt == VT_SHORT) {
2343 if (dbt == VT_BYTE)
2344 bits = 8;
2345 else
2346 bits = 16;
2347 if (t & VT_UNSIGNED) {
2348 vset(VT_CONST, (1 << bits) - 1);
2349 gen_op('&');
2350 } else {
2351 bits = 32 - bits;
2352 vset(VT_CONST, bits);
2353 gen_op(TOK_SHL);
2354 vset(VT_CONST, bits);
2355 gen_op(TOK_SAR);
2360 vtop->t = (vtop->t & ~VT_TYPE) | t;
2363 /* return type size. Put alignment at 'a' */
2364 int type_size(int t, int *a)
2366 Sym *s;
2367 int bt;
2369 bt = t & VT_BTYPE;
2370 if (bt == VT_STRUCT) {
2371 /* struct/union */
2372 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
2373 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
2374 return s->c;
2375 } else if (bt == VT_PTR) {
2376 if (t & VT_ARRAY) {
2377 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
2378 return type_size(s->t, a) * s->c;
2379 } else {
2380 *a = PTR_SIZE;
2381 return PTR_SIZE;
2383 } else if (bt == VT_LDOUBLE) {
2384 *a = LDOUBLE_ALIGN;
2385 return LDOUBLE_SIZE;
2386 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2387 *a = 8;
2388 return 8;
2389 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2390 *a = 4;
2391 return 4;
2392 } else if (bt == VT_SHORT) {
2393 *a = 2;
2394 return 2;
2395 } else {
2396 /* char, void, function, _Bool */
2397 *a = 1;
2398 return 1;
2402 /* return the pointed type of t */
2403 int pointed_type(int t)
2405 Sym *s;
2406 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
2407 return s->t | (t & ~VT_TYPE);
2410 int mk_pointer(int t)
2412 int p;
2413 p = anon_sym++;
2414 sym_push(p, t, -1);
2415 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
2418 int is_compatible_types(int t1, int t2)
2420 Sym *s1, *s2;
2421 int bt1, bt2;
2423 t1 &= VT_TYPE;
2424 t2 &= VT_TYPE;
2425 bt1 = t1 & VT_BTYPE;
2426 bt2 = t2 & VT_BTYPE;
2427 if (bt1 == VT_PTR) {
2428 t1 = pointed_type(t1);
2429 /* if function, then convert implicitely to function pointer */
2430 if (bt2 != VT_FUNC) {
2431 if (bt2 != VT_PTR)
2432 return 0;
2433 t2 = pointed_type(t2);
2435 /* void matches everything */
2436 t1 &= VT_TYPE;
2437 t2 &= VT_TYPE;
2438 if (t1 == VT_VOID || t2 == VT_VOID)
2439 return 1;
2440 return is_compatible_types(t1, t2);
2441 } else if (bt1 == VT_STRUCT) {
2442 return (t2 == t1);
2443 } else if (bt1 == VT_FUNC) {
2444 if (bt2 != VT_FUNC)
2445 return 0;
2446 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
2447 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
2448 if (!is_compatible_types(s1->t, s2->t))
2449 return 0;
2450 /* XXX: not complete */
2451 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2452 return 1;
2453 if (s1->c != s2->c)
2454 return 0;
2455 while (s1 != NULL) {
2456 if (s2 == NULL)
2457 return 0;
2458 if (!is_compatible_types(s1->t, s2->t))
2459 return 0;
2460 s1 = s1->next;
2461 s2 = s2->next;
2463 if (s2)
2464 return 0;
2465 return 1;
2466 } else {
2467 /* XXX: not complete */
2468 return 1;
2472 int check_assign_types(int t1, int t2)
2474 t1 &= VT_TYPE;
2475 t2 &= VT_TYPE;
2476 if ((t1 & VT_BTYPE) == VT_PTR &&
2477 (t2 & VT_BTYPE) == VT_FUNC) {
2478 return is_compatible_types(pointed_type(t1), t2);
2479 } else {
2480 return is_compatible_types(t1, t2);
2484 /* print a type. If 'varstr' is not NULL, then the variable is also
2485 printed in the type */
2486 /* XXX: add array and function pointers */
2487 /* XXX: buffer overflows */
2488 void type_to_str(char *buf, int buf_size,
2489 int t, const char *varstr)
2491 int bt, v;
2492 Sym *s, *sa;
2493 char buf1[256];
2495 t = t & VT_TYPE;
2496 bt = t & VT_BTYPE;
2497 buf[0] = '\0';
2498 if (t & VT_UNSIGNED)
2499 strcat(buf, "unsigned ");
2500 switch(bt) {
2501 case VT_VOID:
2502 strcat(buf, "void");
2503 break;
2504 case VT_BOOL:
2505 strcat(buf, "_Bool");
2506 break;
2507 case VT_BYTE:
2508 strcat(buf, "char");
2509 break;
2510 case VT_SHORT:
2511 strcat(buf, "short");
2512 break;
2513 case VT_INT:
2514 strcat(buf, "int");
2515 break;
2516 case VT_LONG:
2517 strcat(buf, "long");
2518 break;
2519 case VT_LLONG:
2520 strcat(buf, "long long");
2521 break;
2522 case VT_FLOAT:
2523 strcat(buf, "float");
2524 break;
2525 case VT_DOUBLE:
2526 strcat(buf, "double");
2527 break;
2528 case VT_LDOUBLE:
2529 strcat(buf, "long double");
2530 break;
2531 case VT_ENUM:
2532 case VT_STRUCT:
2533 if (bt == VT_STRUCT)
2534 strcat(buf, "struct ");
2535 else
2536 strcat(buf, "enum ");
2537 v = (unsigned)t >> VT_STRUCT_SHIFT;
2538 if (v >= SYM_FIRST_ANOM)
2539 strcat(buf, "<anonymous>");
2540 else
2541 strcat(buf, get_tok_str(v, NULL));
2542 break;
2543 case VT_FUNC:
2544 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
2545 type_to_str(buf, buf_size, s->t, varstr);
2546 strcat(buf, "(");
2547 sa = s->next;
2548 while (sa != NULL) {
2549 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
2550 strcat(buf, buf1);
2551 sa = sa->next;
2552 if (sa)
2553 strcat(buf, ", ");
2555 strcat(buf, ")");
2556 goto no_var;
2557 case VT_PTR:
2558 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
2559 strcpy(buf1, "*");
2560 if (varstr)
2561 strcat(buf1, varstr);
2562 type_to_str(buf, buf_size, s->t, buf1);
2563 goto no_var;
2565 if (varstr) {
2566 strcat(buf, " ");
2567 strcat(buf, varstr);
2569 no_var: ;
2574 /* verify type compatibility to store vtop in 'st' type, and generate
2575 casts if needed */
2576 void gen_assign_cast(int dt)
2578 int st;
2579 char buf1[256], buf2[256];
2581 st = vtop->t; /* destination type */
2582 if (!check_assign_types(dt, st)) {
2583 type_to_str(buf1, sizeof(buf1), st, NULL);
2584 type_to_str(buf2, sizeof(buf2), dt, NULL);
2585 error("cannot cast '%s' to '%s'", buf1, buf2);
2587 if ((dt & VT_BTYPE) == VT_BOOL || is_float(dt)) {
2588 gen_cast(dt & VT_BTYPE);
2593 /* store vtop in lvalue pushed on stack */
2594 void vstore(void)
2596 int ft, fc, r, t, size, align, bit_size, bit_pos;
2597 GFuncContext gf;
2599 ft = vtop[-1].t;
2600 gen_assign_cast(ft & VT_TYPE);
2602 if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
2603 /* if structure, only generate pointer */
2604 /* structure assignment : generate memcpy */
2605 /* XXX: optimize if small size */
2607 vdup();
2608 gfunc_start(&gf);
2609 /* type size */
2610 size = type_size(vtop->t, &align);
2611 vset(VT_CONST, size);
2612 gfunc_param(&gf);
2613 /* source */
2614 vtop->t &= ~VT_LVAL;
2615 gfunc_param(&gf);
2616 /* destination */
2617 vswap();
2618 vtop->t &= ~VT_LVAL;
2619 gfunc_param(&gf);
2621 save_regs();
2622 vset(VT_CONST, (int)&memcpy);
2623 gfunc_call(&gf);
2624 /* leave source on stack */
2625 } else if (ft & VT_BITFIELD) {
2626 /* bitfield store handling */
2627 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2628 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2629 /* remove bit field info to avoid loops */
2630 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2632 /* duplicate destination */
2633 vdup();
2634 vtop[-1] = vtop[-2];
2636 /* mask and shift source */
2637 vset(VT_CONST, (1 << bit_size) - 1);
2638 gen_op('&');
2639 vset(VT_CONST, bit_pos);
2640 gen_op(TOK_SHL);
2641 /* load destination, mask and or with source */
2642 vswap();
2643 vset(VT_CONST, ~(((1 << bit_size) - 1) << bit_pos));
2644 gen_op('&');
2645 gen_op('|');
2646 /* store result */
2647 vstore();
2648 } else {
2649 r = gv(); /* generate value */
2650 ft = vtop[-1].t;
2651 fc = vtop[-1].c.i;
2652 /* if lvalue was saved on stack, must read it */
2653 if ((ft & VT_VALMASK) == VT_LLOCAL) {
2654 t = get_reg(REG_CLASS_INT);
2655 load(t, VT_LOCAL | VT_LVAL, fc);
2656 ft = (ft & ~VT_VALMASK) | t;
2658 store(r, ft, fc);
2659 vtop--;
2660 vtop->t = (ft & VT_TYPE) | r;
2661 vtop->c.i = 0;
2665 /* post defines POST/PRE add. c is the token ++ or -- */
2666 void inc(int post, int c)
2668 int r, r1;
2670 test_lvalue();
2671 if (post)
2672 vdup(); /* room for returned value */
2673 vdup(); /* save lvalue */
2674 r = gv();
2675 if (post) {
2676 /* duplicate value */
2677 /* XXX: handle floats */
2678 r1 = get_reg(REG_CLASS_INT);
2679 load(r1, r, 0); /* move r to r1 */
2680 /* duplicates value */
2681 vtop[-2].t = (vtop->t & VT_TYPE) | r1;
2682 vtop[-2].c.i = 0;
2684 /* add constant */
2685 vset(VT_CONST, c - TOK_MID);
2686 gen_op('+');
2687 vstore(); /* store value */
2688 if (post)
2689 vpop(); /* if post op, return saved value */
2692 /* enum/struct/union declaration */
2693 int struct_decl(int u)
2695 int a, t, b, v, size, align, maxalign, c, offset;
2696 int bit_size, bit_pos, bsize, bt, lbit_pos;
2697 Sym *s, *ss, **ps;
2699 a = tok; /* save decl type */
2700 next();
2701 if (tok != '{') {
2702 v = tok;
2703 next();
2704 /* struct already defined ? return it */
2705 /* XXX: check consistency */
2706 if (s = sym_find(v | SYM_STRUCT)) {
2707 if (s->t != a)
2708 error("invalid type");
2709 goto do_decl;
2711 } else {
2712 v = anon_sym++;
2714 s = sym_push(v | SYM_STRUCT, a, 0);
2715 /* put struct/union/enum name in type */
2716 do_decl:
2717 u = u | (v << VT_STRUCT_SHIFT);
2719 if (tok == '{') {
2720 next();
2721 if (s->c)
2722 error("struct/union/enum already defined");
2723 /* cannot be empty */
2724 c = 0;
2725 maxalign = 0;
2726 ps = &s->next;
2727 bit_pos = 0;
2728 offset = 0;
2729 while (1) {
2730 if (a == TOK_ENUM) {
2731 v = tok;
2732 next();
2733 if (tok == '=') {
2734 next();
2735 c = expr_const();
2737 /* enum symbols have static storage */
2738 sym_push(v, VT_CONST | VT_STATIC, c);
2739 if (tok == ',')
2740 next();
2741 c++;
2742 } else {
2743 b = ist();
2744 while (1) {
2745 bit_size = -1;
2746 v = 0;
2747 if (tok != ':') {
2748 t = type_decl(&v, b, TYPE_DIRECT);
2749 if ((t & VT_BTYPE) == VT_FUNC ||
2750 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
2751 error("invalid type for '%s'",
2752 get_tok_str(v, NULL));
2753 } else {
2754 t = b;
2756 if (tok == ':') {
2757 next();
2758 bit_size = expr_const();
2759 /* XXX: handle v = 0 case for messages */
2760 if (bit_size < 0)
2761 error("negative width in bit-field '%s'",
2762 get_tok_str(v, NULL));
2763 if (v && bit_size == 0)
2764 error("zero width for bit-field '%s'",
2765 get_tok_str(v, NULL));
2767 size = type_size(t, &align);
2768 lbit_pos = 0;
2769 if (bit_size >= 0) {
2770 bt = t & VT_BTYPE;
2771 if (bt != VT_INT &&
2772 bt != VT_BYTE &&
2773 bt != VT_SHORT)
2774 error("bitfields must have scalar type");
2775 bsize = size * 8;
2776 if (bit_size > bsize) {
2777 error("width of '%s' exceeds its type",
2778 get_tok_str(v, NULL));
2779 } else if (bit_size == bsize) {
2780 /* no need for bit fields */
2781 bit_pos = 0;
2782 } else if (bit_size == 0) {
2783 /* XXX: what to do if only padding in a
2784 structure ? */
2785 /* zero size: means to pad */
2786 if (bit_pos > 0)
2787 bit_pos = bsize;
2788 } else {
2789 /* we do not have enough room ? */
2790 if ((bit_pos + bit_size) > bsize)
2791 bit_pos = 0;
2792 lbit_pos = bit_pos;
2793 /* XXX: handle LSB first */
2794 t |= VT_BITFIELD |
2795 (bit_pos << VT_STRUCT_SHIFT) |
2796 (bit_size << (VT_STRUCT_SHIFT + 6));
2797 bit_pos += bit_size;
2799 } else {
2800 bit_pos = 0;
2802 if (v) {
2803 /* add new memory data only if starting
2804 bit field */
2805 if (lbit_pos == 0) {
2806 if (a == TOK_STRUCT) {
2807 c = (c + align - 1) & -align;
2808 offset = c;
2809 c += size;
2810 } else {
2811 offset = 0;
2812 if (size > c)
2813 c = size;
2815 if (align > maxalign)
2816 maxalign = align;
2818 #if 0
2819 printf("add field %s offset=%d",
2820 get_tok_str(v, NULL), offset);
2821 if (t & VT_BITFIELD) {
2822 printf(" pos=%d size=%d",
2823 (t >> VT_STRUCT_SHIFT) & 0x3f,
2824 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2826 printf("\n");
2827 #endif
2828 ss = sym_push(v | SYM_FIELD, t, offset);
2829 *ps = ss;
2830 ps = &ss->next;
2832 if (tok == ';' || tok == -1)
2833 break;
2834 skip(',');
2836 skip(';');
2838 if (tok == '}')
2839 break;
2841 skip('}');
2842 /* size for struct/union, dummy for enum */
2843 s->c = (c + maxalign - 1) & -maxalign;
2845 return u;
2848 /* return 0 if no type declaration. otherwise, return the basic type
2849 and skip it.
2850 XXX: A '2' is ored to ensure non zero return if int type.
2852 int ist(void)
2854 int t, u;
2855 Sym *s;
2857 t = 0;
2858 while(1) {
2859 switch(tok) {
2860 /* basic types */
2861 case TOK_CHAR:
2862 u = VT_BYTE;
2863 basic_type:
2864 next();
2865 basic_type1:
2866 if ((t & VT_BTYPE) != 0)
2867 error("too many basic types %x", t);
2868 t |= u;
2869 break;
2870 case TOK_VOID:
2871 u = VT_VOID;
2872 goto basic_type;
2873 case TOK_SHORT:
2874 u = VT_SHORT;
2875 goto basic_type;
2876 case TOK_INT:
2877 next();
2878 break;
2879 case TOK_LONG:
2880 next();
2881 if ((t & VT_BTYPE) == VT_DOUBLE) {
2882 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2883 } else if ((t & VT_BTYPE) == VT_LONG) {
2884 t = (t & ~VT_BTYPE) | VT_LLONG;
2885 } else {
2886 u = VT_LONG;
2887 goto basic_type1;
2889 break;
2890 case TOK_BOOL:
2891 u = VT_BOOL;
2892 goto basic_type;
2893 case TOK_FLOAT:
2894 u = VT_FLOAT;
2895 goto basic_type;
2896 case TOK_DOUBLE:
2897 next();
2898 if ((t & VT_BTYPE) == VT_LONG) {
2899 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2900 } else {
2901 u = VT_DOUBLE;
2902 goto basic_type1;
2904 break;
2905 case TOK_ENUM:
2906 u = struct_decl(VT_ENUM);
2907 goto basic_type1;
2908 case TOK_STRUCT:
2909 case TOK_UNION:
2910 u = struct_decl(VT_STRUCT);
2911 goto basic_type1;
2913 /* type modifiers */
2914 case TOK_CONST:
2915 case TOK_VOLATILE:
2916 case TOK_REGISTER:
2917 case TOK_SIGNED:
2918 case TOK_AUTO:
2919 case TOK_INLINE:
2920 case TOK_RESTRICT:
2921 next();
2922 break;
2923 case TOK_UNSIGNED:
2924 t |= VT_UNSIGNED;
2925 next();
2926 break;
2928 /* storage */
2929 case TOK_EXTERN:
2930 t |= VT_EXTERN;
2931 next();
2932 break;
2933 case TOK_STATIC:
2934 t |= VT_STATIC;
2935 next();
2936 break;
2937 case TOK_TYPEDEF:
2938 t |= VT_TYPEDEF;
2939 next();
2940 break;
2941 default:
2942 s = sym_find(tok);
2943 if (!s || !(s->t & VT_TYPEDEF))
2944 goto the_end;
2945 t |= (s->t & ~VT_TYPEDEF);
2946 next();
2947 break;
2949 t |= 2;
2951 the_end:
2952 /* long is never used as type */
2953 if ((t & VT_BTYPE) == VT_LONG)
2954 t = (t & ~VT_BTYPE) | VT_INT;
2955 return t;
2958 int post_type(int t)
2960 int p, n, pt, l, t1;
2961 Sym **plast, *s, *first;
2963 if (tok == '(') {
2964 /* function declaration */
2965 next();
2966 l = 0;
2967 first = NULL;
2968 plast = &first;
2969 while (tok != ')') {
2970 /* read param name and compute offset */
2971 if (l != FUNC_OLD) {
2972 if (!(pt = ist())) {
2973 if (l) {
2974 error("invalid type");
2975 } else {
2976 l = FUNC_OLD;
2977 goto old_proto;
2980 l = FUNC_NEW;
2981 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
2982 break;
2983 pt = type_decl(&n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
2984 if ((pt & VT_BTYPE) == VT_VOID)
2985 error("parameter declared as void");
2986 } else {
2987 old_proto:
2988 n = tok;
2989 pt = VT_INT;
2990 next();
2992 /* array must be transformed to pointer according to ANSI C */
2993 pt &= ~VT_ARRAY;
2994 s = sym_push(n | SYM_FIELD, pt, 0);
2995 *plast = s;
2996 plast = &s->next;
2997 if (tok == ',') {
2998 next();
2999 if (l == FUNC_NEW && tok == TOK_DOTS) {
3000 l = FUNC_ELLIPSIS;
3001 next();
3002 break;
3006 /* if no parameters, then old type prototype */
3007 if (l == 0)
3008 l = FUNC_OLD;
3009 skip(')');
3010 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
3011 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN));
3012 /* we push a anonymous symbol which will contain the function prototype */
3013 p = anon_sym++;
3014 s = sym_push(p, t, l);
3015 s->next = first;
3016 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
3017 } else if (tok == '[') {
3018 /* array definition */
3019 next();
3020 n = -1;
3021 if (tok != ']') {
3022 n = expr_const();
3023 if (n < 0)
3024 error("invalid array size");
3026 skip(']');
3027 /* parse next post type */
3028 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
3029 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN));
3031 /* we push a anonymous symbol which will contain the array
3032 element type */
3033 p = anon_sym++;
3034 sym_push(p, t, n);
3035 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
3037 return t;
3040 /* Read a type declaration (except basic type), and return the
3041 type. If v is true, then also put variable name in 'vtop->c' */
3042 int type_decl(int *v, int t, int td)
3044 int u, p;
3045 Sym *s;
3047 t = t & -3; /* suppress the ored '2' */
3048 while (tok == '*') {
3049 next();
3050 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
3051 next();
3052 t = mk_pointer(t);
3055 /* recursive type */
3056 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3057 if (tok == '(') {
3058 next();
3059 u = type_decl(v, 0, td);
3060 skip(')');
3061 } else {
3062 u = 0;
3063 /* type identifier */
3064 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3065 *v = tok;
3066 next();
3067 } else {
3068 if (!(td & TYPE_ABSTRACT))
3069 expect("identifier");
3070 *v = 0;
3073 /* append t at the end of u */
3074 t = post_type(t);
3075 if (!u)
3076 return t;
3077 p = u;
3078 while(1) {
3079 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
3080 p = s->t;
3081 if (!p) {
3082 s->t = t;
3083 break;
3086 return u;
3089 /* define a new external reference to a function 'v' of type 'u' */
3090 Sym *external_sym(int v, int u)
3092 Sym *s;
3093 s = sym_find(v);
3094 if (!s) {
3095 /* push forward reference */
3096 s = sym_push1(&global_stack,
3097 v, u | VT_CONST | VT_FORWARD, 0);
3099 return s;
3102 void indir(void)
3104 if (vtop->t & VT_LVAL)
3105 gv();
3106 if ((vtop->t & VT_BTYPE) != VT_PTR)
3107 expect("pointer");
3108 vtop->t = pointed_type(vtop->t);
3109 if (!(vtop->t & VT_ARRAY)) /* an array is never an lvalue */
3110 vtop->t |= VT_LVAL;
3113 /* pass a parameter to a function and do type checking and casting */
3114 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
3116 int func_type;
3117 func_type = func->c;
3118 if (func_type == FUNC_OLD ||
3119 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3120 /* default casting : only need to convert float to double */
3121 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
3122 gen_cast(VT_DOUBLE);
3123 } else if (arg == NULL) {
3124 error("too many arguments to function");
3125 } else {
3126 gen_assign_cast(arg->t);
3128 gfunc_param(gf);
3131 void unary(void)
3133 int n, t, ft, fc, p, align, size;
3134 Sym *s;
3135 GFuncContext gf;
3137 if (tok == TOK_NUM || tok == TOK_CCHAR || tok == TOK_LCHAR) {
3138 vset(VT_CONST | VT_INT, tokc.i);
3139 next();
3140 } else if (tok == TOK_CFLOAT) {
3141 vsetc(VT_CONST | VT_FLOAT, &tokc);
3142 next();
3143 } else if (tok == TOK_CDOUBLE) {
3144 vsetc(VT_CONST | VT_DOUBLE, &tokc);
3145 next();
3146 } else if (tok == TOK_CLDOUBLE) {
3147 vsetc(VT_CONST | VT_LDOUBLE, &tokc);
3148 next();
3149 } else if (tok == TOK___FUNC__) {
3150 /* special function name identifier */
3151 /* generate (char *) type */
3152 vset(VT_CONST | mk_pointer(VT_BYTE), glo);
3153 strcpy((void *)glo, funcname);
3154 glo += strlen(funcname) + 1;
3155 next();
3156 } else if (tok == TOK_LSTR) {
3157 t = VT_INT;
3158 goto str_init;
3159 } else if (tok == TOK_STR) {
3160 /* string parsing */
3161 t = VT_BYTE;
3162 str_init:
3163 type_size(t, &align);
3164 glo = (glo + align - 1) & -align;
3165 fc = glo;
3166 /* we must declare it as an array first to use initializer parser */
3167 t = VT_CONST | VT_ARRAY | mk_pointer(t);
3168 decl_initializer(t, glo, 1, 0);
3169 glo += type_size(t, &align);
3170 /* put it as pointer */
3171 vset(t & ~VT_ARRAY, fc);
3172 } else {
3173 t = tok;
3174 next();
3175 if (t == '(') {
3176 /* cast ? */
3177 if (t = ist()) {
3178 ft = type_decl(&n, t, TYPE_ABSTRACT);
3179 skip(')');
3180 /* check ISOC99 compound literal */
3181 if (tok == '{') {
3182 /* data is allocated locally by default */
3183 if (global_expr)
3184 ft |= VT_CONST;
3185 else
3186 ft |= VT_LOCAL;
3187 /* all except arrays are lvalues */
3188 if (!(ft & VT_ARRAY))
3189 ft |= VT_LVAL;
3190 fc = decl_initializer_alloc(ft, 1);
3191 vset(ft, fc);
3192 } else {
3193 unary();
3194 gen_cast(ft);
3196 } else {
3197 gexpr();
3198 skip(')');
3200 } else if (t == '*') {
3201 unary();
3202 indir();
3203 } else if (t == '&') {
3204 unary();
3205 /* functions names must be treated as function pointers,
3206 except for unary '&' and sizeof. Since we consider that
3207 functions are not lvalues, we only have to handle it
3208 there and in function calls. */
3209 if ((vtop->t & VT_BTYPE) != VT_FUNC)
3210 test_lvalue();
3211 vtop->t = mk_pointer(vtop->t & VT_LVALN);
3212 } else
3213 if (t == '!') {
3214 unary();
3215 if ((vtop->t & (VT_VALMASK | VT_LVAL)) == VT_CONST)
3216 vtop->c.i = !vtop->c.i;
3217 else if ((vtop->t & VT_VALMASK) == VT_CMP)
3218 vtop->c.i = vtop->c.i ^ 1;
3219 else
3220 vset(VT_JMP, gtst(1, 0));
3221 } else
3222 if (t == '~') {
3223 unary();
3224 vset(VT_CONST, -1);
3225 gen_op('^');
3226 } else
3227 if (t == '+') {
3228 unary();
3229 } else
3230 if (t == TOK_SIZEOF) {
3231 if (tok == '(') {
3232 next();
3233 if (t = ist())
3234 t = type_decl(&n, t, TYPE_ABSTRACT);
3235 else {
3236 /* XXX: some code could be generated: add eval
3237 flag */
3238 gexpr();
3239 t = vtop->t;
3240 vpop();
3242 skip(')');
3243 } else {
3244 unary();
3245 t = vtop->t;
3246 vpop();
3248 vset(VT_CONST, type_size(t, &t));
3249 } else
3250 if (t == TOK_INC || t == TOK_DEC) {
3251 unary();
3252 inc(0, t);
3253 } else if (t == '-') {
3254 vset(VT_CONST, 0);
3255 unary();
3256 gen_op('-');
3257 } else
3259 s = sym_find(t);
3260 if (!s) {
3261 if (tok != '(')
3262 error("'%s' undeclared", get_tok_str(t, NULL));
3263 /* for simple function calls, we tolerate undeclared
3264 external reference */
3265 p = anon_sym++;
3266 sym_push1(&global_stack, p, 0, FUNC_OLD);
3267 /* int() function */
3268 s = external_sym(t, VT_FUNC | (p << VT_STRUCT_SHIFT));
3270 vset(s->t, s->c);
3271 /* if forward reference, we must point to s */
3272 if (vtop->t & VT_FORWARD)
3273 vtop->c.sym = s;
3277 /* post operations */
3278 while (1) {
3279 if (tok == TOK_INC | tok == TOK_DEC) {
3280 inc(1, tok);
3281 next();
3282 } else if (tok == '.' | tok == TOK_ARROW) {
3283 /* field */
3284 if (tok == TOK_ARROW)
3285 indir();
3286 test_lvalue();
3287 vtop->t &= VT_LVALN;
3288 next();
3289 /* expect pointer on structure */
3290 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
3291 expect("struct or union");
3292 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3293 /* find field */
3294 tok |= SYM_FIELD;
3295 while (s = s->next) {
3296 if (s->v == tok)
3297 break;
3299 if (!s)
3300 error("field not found");
3301 /* add field offset to pointer */
3302 vtop->t = (vtop->t & ~VT_TYPE) | VT_INT; /* change type to int */
3303 vset(VT_CONST, s->c);
3304 gen_op('+');
3305 /* change type to field type, and set to lvalue */
3306 vtop->t = (vtop->t & ~VT_TYPE) | s->t;
3307 /* an array is never an lvalue */
3308 if (!(vtop->t & VT_ARRAY))
3309 vtop->t |= VT_LVAL;
3310 next();
3311 } else if (tok == '[') {
3312 next();
3313 gexpr();
3314 gen_op('+');
3315 indir();
3316 skip(']');
3317 } else if (tok == '(') {
3318 int rett;
3319 CValue retc;
3320 Sym *sa;
3322 /* function call */
3323 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
3324 /* pointer test (no array accepted) */
3325 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3326 vtop->t = pointed_type(vtop->t);
3327 if ((vtop->t & VT_BTYPE) != VT_FUNC)
3328 goto error_func;
3329 } else {
3330 error_func:
3331 expect("function pointer");
3333 } else {
3334 vtop->t &= ~VT_LVAL; /* no lvalue */
3336 /* get return type */
3337 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
3338 save_regs(); /* save used temporary registers */
3339 gfunc_start(&gf);
3340 next();
3341 sa = s->next; /* first parameter */
3342 #ifdef INVERT_FUNC_PARAMS
3344 int *str, len, parlevel, *saved_macro_ptr;
3345 Sym *args, *s1;
3347 /* read each argument and store it on a stack */
3348 /* XXX: merge it with macro args ? */
3349 args = NULL;
3350 while (tok != ')') {
3351 len = 0;
3352 str = NULL;
3353 parlevel = 0;
3354 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
3355 tok != -1) {
3356 if (tok == '(')
3357 parlevel++;
3358 else if (tok == ')')
3359 parlevel--;
3360 tok_add2(&str, &len, tok, &tokc);
3361 next();
3363 tok_add(&str, &len, -1); /* end of file added */
3364 tok_add(&str, &len, 0);
3365 s1 = sym_push2(&args, 0, 0, (int)str);
3366 s1->next = sa; /* add reference to argument */
3367 if (sa)
3368 sa = sa->next;
3369 if (tok != ',')
3370 break;
3371 next();
3373 if (tok != ')')
3374 expect(")");
3376 /* now generate code in reverse order by reading the stack */
3377 saved_macro_ptr = macro_ptr;
3378 while (args) {
3379 macro_ptr = (int *)args->c;
3380 next();
3381 expr_eq();
3382 if (tok != -1)
3383 expect("',' or ')'");
3384 gfunc_param_typed(&gf, s, args->next);
3385 s1 = args->prev;
3386 free((int *)args->c);
3387 free(args);
3388 args = s1;
3390 macro_ptr = saved_macro_ptr;
3391 /* restore token */
3392 tok = ')';
3394 #endif
3395 /* compute first implicit argument if a structure is returned */
3396 if ((s->t & VT_BTYPE) == VT_STRUCT) {
3397 /* get some space for the returned structure */
3398 size = type_size(s->t, &align);
3399 loc = (loc - size) & -align;
3400 rett = s->t | VT_LOCAL | VT_LVAL;
3401 /* pass it as 'int' to avoid structure arg passing
3402 problems */
3403 vset(VT_INT | VT_LOCAL, loc);
3404 retc = vtop->c;
3405 gfunc_param(&gf);
3406 } else {
3407 rett = s->t | FUNC_RET_REG; /* return in register */
3408 retc.i = 0;
3410 #ifndef INVERT_FUNC_PARAMS
3411 while (tok != ')') {
3412 expr_eq();
3413 gfunc_param_typed(&gf, s, sa);
3414 if (sa)
3415 sa = sa->next;
3416 if (tok == ',')
3417 next();
3419 #endif
3420 if (sa)
3421 error("too few arguments to function %x", sa->t);
3422 skip(')');
3423 gfunc_call(&gf);
3424 /* return value */
3425 vsetc(rett, &retc);
3426 } else {
3427 break;
3432 void uneq(void)
3434 int t;
3436 unary();
3437 if (tok == '=' ||
3438 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3439 tok == TOK_A_XOR || tok == TOK_A_OR ||
3440 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3441 test_lvalue();
3442 t = tok;
3443 next();
3444 if (t == '=') {
3445 expr_eq();
3446 } else {
3447 vdup();
3448 expr_eq();
3449 gen_op(t & 0x7f);
3451 vstore();
3455 void sum(int l)
3457 int t;
3459 if (l == 0)
3460 uneq();
3461 else {
3462 sum(--l);
3463 while ((l == 0 & (tok == '*' | tok == '/' | tok == '%')) |
3464 (l == 1 & (tok == '+' | tok == '-')) |
3465 (l == 2 & (tok == TOK_SHL | tok == TOK_SAR)) |
3466 (l == 3 & ((tok >= TOK_ULE & tok <= TOK_GT) |
3467 tok == TOK_ULT | tok == TOK_UGE)) |
3468 (l == 4 & (tok == TOK_EQ | tok == TOK_NE)) |
3469 (l == 5 & tok == '&') |
3470 (l == 6 & tok == '^') |
3471 (l == 7 & tok == '|') |
3472 (l == 8 & tok == TOK_LAND) |
3473 (l == 9 & tok == TOK_LOR)) {
3474 t = tok;
3475 next();
3476 sum(l);
3477 gen_op(t);
3482 /* only used if non constant */
3483 void eand(void)
3485 int t;
3487 sum(8);
3488 t = 0;
3489 while (1) {
3490 if (tok != TOK_LAND) {
3491 if (t) {
3492 t = gtst(1, t);
3493 vset(VT_JMPI, t);
3495 break;
3497 t = gtst(1, t);
3498 next();
3499 sum(8);
3503 void eor(void)
3505 int t;
3507 eand();
3508 t = 0;
3509 while (1) {
3510 if (tok != TOK_LOR) {
3511 if (t) {
3512 t = gtst(0, t);
3513 vset(VT_JMP, t);
3515 break;
3517 t = gtst(0, t);
3518 next();
3519 eand();
3523 /* XXX: better constant handling */
3524 void expr_eq(void)
3526 int t, u, c, r1, r2;
3528 if (const_wanted) {
3529 sum(10);
3530 if (tok == '?') {
3531 c = vtop->c.i;
3532 vpop();
3533 next();
3534 gexpr();
3535 t = vtop->c.i;
3536 vpop();
3537 skip(':');
3538 expr_eq();
3539 if (c)
3540 vtop->c.i = t;
3542 } else {
3543 eor();
3544 if (tok == '?') {
3545 next();
3546 t = gtst(1, 0);
3548 gexpr();
3549 r1 = gv();
3550 vpop();
3551 skip(':');
3552 u = gjmp(0);
3554 gsym(t);
3555 expr_eq();
3556 r2 = gv();
3557 move_reg(r1, r2);
3558 vtop->t = (vtop->t & VT_TYPE) | r1;
3559 gsym(u);
3564 void gexpr(void)
3566 while (1) {
3567 expr_eq();
3568 if (tok != ',')
3569 break;
3570 vpop();
3571 next();
3575 /* parse a constant expression and return value in vtop */
3576 void expr_const1(void)
3578 int a;
3579 a = const_wanted;
3580 const_wanted = 1;
3581 expr_eq();
3582 if ((vtop->t & (VT_CONST | VT_LVAL)) != VT_CONST)
3583 expect("constant");
3584 const_wanted = a;
3587 /* parse an integer constant and return its value */
3588 int expr_const(void)
3590 int c;
3591 expr_const1();
3592 c = vtop->c.i;
3593 vpop();
3594 return c;
3597 /* return the label token if current token is a label, otherwise
3598 return zero */
3599 int is_label(void)
3601 int t;
3602 CValue c;
3604 /* fast test first */
3605 if (tok < TOK_UIDENT)
3606 return 0;
3607 /* no need to save tokc since we expect an identifier */
3608 t = tok;
3609 c = tokc;
3610 next();
3611 if (tok == ':') {
3612 next();
3613 return t;
3614 } else {
3615 /* XXX: may not work in all cases (macros ?) */
3616 tok1 = tok;
3617 tok1c = tokc;
3618 tok = t;
3619 tokc = c;
3620 return 0;
3624 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
3626 int a, b, c, d;
3627 Sym *s;
3629 if (tok == TOK_IF) {
3630 /* if test */
3631 next();
3632 skip('(');
3633 gexpr();
3634 skip(')');
3635 a = gtst(1, 0);
3636 block(bsym, csym, case_sym, def_sym, case_reg);
3637 c = tok;
3638 if (c == TOK_ELSE) {
3639 next();
3640 d = gjmp(0);
3641 gsym(a);
3642 block(bsym, csym, case_sym, def_sym, case_reg);
3643 gsym(d); /* patch else jmp */
3644 } else
3645 gsym(a);
3646 } else if (tok == TOK_WHILE) {
3647 next();
3648 d = ind;
3649 skip('(');
3650 gexpr();
3651 skip(')');
3652 a = gtst(1, 0);
3653 b = 0;
3654 block(&a, &b, case_sym, def_sym, case_reg);
3655 oad(0xe9, d - ind - 5); /* jmp */
3656 gsym(a);
3657 gsym_addr(b, d);
3658 } else if (tok == '{') {
3659 next();
3660 /* declarations */
3661 s = local_stack.top;
3662 while (tok != '}') {
3663 decl(VT_LOCAL);
3664 if (tok != '}')
3665 block(bsym, csym, case_sym, def_sym, case_reg);
3667 /* pop locally defined symbols */
3668 sym_pop(&local_stack, s);
3669 next();
3670 } else if (tok == TOK_RETURN) {
3671 next();
3672 if (tok != ';') {
3673 gexpr();
3674 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
3675 /* if returning structure, must copy it to implicit
3676 first pointer arg location */
3677 vset(mk_pointer(func_vt) | VT_LOCAL | VT_LVAL, func_vc);
3678 indir();
3679 vswap();
3680 /* copy structure value to pointer */
3681 vstore();
3682 } else if (is_float(func_vt)) {
3683 /* move return value to float return register */
3684 move_reg(FUNC_RET_FREG, gv());
3685 } else {
3686 /* move return value to standard return register */
3687 move_reg(FUNC_RET_REG, gv());
3689 vpop();
3691 skip(';');
3692 rsym = gjmp(rsym); /* jmp */
3693 } else if (tok == TOK_BREAK) {
3694 /* compute jump */
3695 if (!bsym)
3696 error("cannot break");
3697 *bsym = gjmp(*bsym);
3698 next();
3699 skip(';');
3700 } else if (tok == TOK_CONTINUE) {
3701 /* compute jump */
3702 if (!csym)
3703 error("cannot continue");
3704 *csym = gjmp(*csym);
3705 next();
3706 skip(';');
3707 } else if (tok == TOK_FOR) {
3708 int e;
3709 next();
3710 skip('(');
3711 if (tok != ';') {
3712 gexpr();
3713 vpop();
3715 skip(';');
3716 d = ind;
3717 c = ind;
3718 a = 0;
3719 b = 0;
3720 if (tok != ';') {
3721 gexpr();
3722 a = gtst(1, 0);
3724 skip(';');
3725 if (tok != ')') {
3726 e = gjmp(0);
3727 c = ind;
3728 gexpr();
3729 vpop();
3730 oad(0xe9, d - ind - 5); /* jmp */
3731 gsym(e);
3733 skip(')');
3734 block(&a, &b, case_sym, def_sym, case_reg);
3735 oad(0xe9, c - ind - 5); /* jmp */
3736 gsym(a);
3737 gsym_addr(b, c);
3738 } else
3739 if (tok == TOK_DO) {
3740 next();
3741 a = 0;
3742 b = 0;
3743 d = ind;
3744 block(&a, &b, case_sym, def_sym, case_reg);
3745 skip(TOK_WHILE);
3746 skip('(');
3747 gsym(b);
3748 gexpr();
3749 c = gtst(0, 0);
3750 gsym_addr(c, d);
3751 skip(')');
3752 gsym(a);
3753 skip(';');
3754 } else
3755 if (tok == TOK_SWITCH) {
3756 next();
3757 skip('(');
3758 gexpr();
3759 case_reg = gv();
3760 vpop();
3761 skip(')');
3762 a = 0;
3763 b = gjmp(0); /* jump to first case */
3764 c = 0;
3765 block(&a, csym, &b, &c, case_reg);
3766 /* if no default, jmp after switch */
3767 if (c == 0)
3768 c = ind;
3769 /* default label */
3770 gsym_addr(b, c);
3771 /* break label */
3772 gsym(a);
3773 } else
3774 if (tok == TOK_CASE) {
3775 next();
3776 a = expr_const();
3777 if (!case_sym)
3778 expect("switch");
3779 /* since a case is like a label, we must skip it with a jmp */
3780 b = gjmp(0);
3781 gsym(*case_sym);
3782 vset(case_reg, 0);
3783 vset(VT_CONST, a);
3784 gen_op(TOK_EQ);
3785 *case_sym = gtst(1, 0);
3786 gsym(b);
3787 skip(':');
3788 block(bsym, csym, case_sym, def_sym, case_reg);
3789 } else
3790 if (tok == TOK_DEFAULT) {
3791 next();
3792 skip(':');
3793 if (!def_sym)
3794 expect("switch");
3795 if (*def_sym)
3796 error("too many 'default'");
3797 *def_sym = ind;
3798 block(bsym, csym, case_sym, def_sym, case_reg);
3799 } else
3800 if (tok == TOK_GOTO) {
3801 next();
3802 s = sym_find1(&label_stack, tok);
3803 /* put forward definition if needed */
3804 if (!s)
3805 s = sym_push1(&label_stack, tok, VT_FORWARD, 0);
3806 /* label already defined */
3807 if (s->t & VT_FORWARD)
3808 s->c = gjmp(s->c); /* jmp xxx */
3809 else
3810 oad(0xe9, s->c - ind - 5); /* jmp xxx */
3811 next();
3812 skip(';');
3813 } else {
3814 b = is_label();
3815 if (b) {
3816 /* label case */
3817 s = sym_find1(&label_stack, b);
3818 if (s) {
3819 if (!(s->t & VT_FORWARD))
3820 error("multiple defined label");
3821 gsym(s->c);
3822 s->c = ind;
3823 s->t = 0;
3824 } else {
3825 sym_push1(&label_stack, b, 0, ind);
3827 /* we accept this, but it is a mistake */
3828 if (tok == '}')
3829 warning("deprecated use of label at end of compound statement");
3830 else
3831 block(bsym, csym, case_sym, def_sym, case_reg);
3832 } else {
3833 /* expression case */
3834 if (tok != ';') {
3835 gexpr();
3836 vpop();
3838 skip(';');
3843 /* t is the array or struct type. c is the array or struct
3844 address. cur_index/cur_field is the pointer to the current
3845 value. 'size_only' is true if only size info is needed (only used
3846 in arrays) */
3847 void decl_designator(int t, int c,
3848 int *cur_index, Sym **cur_field,
3849 int size_only)
3851 Sym *s, *f;
3852 int notfirst, index, align, l;
3854 notfirst = 0;
3855 if (gnu_ext && (l = is_label()) != 0)
3856 goto struct_field;
3858 while (tok == '[' || tok == '.') {
3859 if (tok == '[') {
3860 if (!(t & VT_ARRAY))
3861 expect("array type");
3862 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3863 next();
3864 index = expr_const();
3865 if (index < 0 || (s->c >= 0 && index >= s->c))
3866 expect("invalid index");
3867 skip(']');
3868 if (!notfirst)
3869 *cur_index = index;
3870 t = pointed_type(t);
3871 c += index * type_size(t, &align);
3872 } else {
3873 next();
3874 l = tok;
3875 next();
3876 struct_field:
3877 if ((t & VT_BTYPE) != VT_STRUCT)
3878 expect("struct/union type");
3879 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3880 l |= SYM_FIELD;
3881 f = s->next;
3882 while (f) {
3883 if (f->v == l)
3884 break;
3885 f = f->next;
3887 if (!f)
3888 expect("field");
3889 if (!notfirst)
3890 *cur_field = f;
3891 t = f->t | (t & ~VT_TYPE);
3892 c += f->c;
3894 notfirst = 1;
3896 if (notfirst) {
3897 if (tok == '=') {
3898 next();
3899 } else {
3900 if (!gnu_ext)
3901 expect("=");
3903 } else {
3904 if (t & VT_ARRAY) {
3905 index = *cur_index;
3906 t = pointed_type(t);
3907 c += index * type_size(t, &align);
3908 } else {
3909 f = *cur_field;
3910 if (!f)
3911 error("too many field init");
3912 t = f->t | (t & ~VT_TYPE);
3913 c += f->c;
3916 decl_initializer(t, c, 0, size_only);
3919 /* store a value or an expression directly in global data or in local array */
3921 void init_putv(int t, int c, int v, int is_expr)
3923 int saved_global_expr, bt;
3925 if ((t & VT_VALMASK) == VT_CONST) {
3926 if (is_expr) {
3927 /* compound literals must be allocated globally in this case */
3928 saved_global_expr = global_expr;
3929 global_expr = 1;
3930 expr_const1();
3931 global_expr = saved_global_expr;
3932 } else {
3933 vset(VT_CONST | VT_INT, v);
3935 /* XXX: do casting */
3936 /* XXX: not portable */
3937 bt = vtop->t & VT_BTYPE;
3938 switch(bt) {
3939 case VT_BYTE:
3940 *(char *)c = vtop->c.i;
3941 break;
3942 case VT_SHORT:
3943 *(short *)c = vtop->c.i;
3944 break;
3945 case VT_DOUBLE:
3946 *(double *)c = vtop->c.d;
3947 break;
3948 case VT_LDOUBLE:
3949 *(long double *)c = vtop->c.ld;
3950 break;
3951 #if 0
3952 case VT_LLONG:
3953 *(long long *)c = vtop->c.ll;
3954 break;
3955 #endif
3956 default:
3957 *(int *)c = vtop->c.i;
3958 break;
3960 vpop();
3961 } else {
3962 vset(t, c);
3963 if (is_expr)
3964 expr_eq();
3965 else
3966 vset(VT_CONST | VT_INT, v);
3967 vstore();
3968 vpop();
3972 /* put zeros for variable based init */
3973 void init_putz(int t, int c, int size)
3975 GFuncContext gf;
3977 if ((t & VT_VALMASK) == VT_CONST) {
3978 /* nothing to do because global are already set to zero */
3979 } else {
3980 gfunc_start(&gf);
3981 vset(VT_CONST, size);
3982 gfunc_param(&gf);
3983 vset(VT_CONST, 0);
3984 gfunc_param(&gf);
3985 vset(VT_LOCAL, c);
3986 gfunc_param(&gf);
3987 vset(VT_CONST, (int)&memset);
3988 gfunc_call(&gf);
3992 /* 't' contains the type and storage info. c is the address of the
3993 object. 'first' is true if array '{' must be read (multi dimension
3994 implicit array init handling). 'size_only' is true if size only
3995 evaluation is wanted (only for arrays). */
3996 void decl_initializer(int t, int c, int first, int size_only)
3998 int index, array_length, n, no_oblock, nb, parlevel, i;
3999 int t1, size1, align1;
4000 Sym *s, *f;
4001 TokenSym *ts;
4003 if (t & VT_ARRAY) {
4004 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4005 n = s->c;
4006 array_length = 0;
4007 t1 = pointed_type(t);
4008 size1 = type_size(t1, &align1);
4010 no_oblock = 1;
4011 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4012 tok == '{') {
4013 skip('{');
4014 no_oblock = 0;
4017 /* only parse strings here if correct type (otherwise: handle
4018 them as ((w)char *) expressions */
4019 if ((tok == TOK_LSTR &&
4020 (t1 & VT_BTYPE) == VT_INT) ||
4021 (tok == TOK_STR &&
4022 (t1 & VT_BTYPE) == VT_BYTE)) {
4023 /* XXX: move multiple string parsing in parser ? */
4024 while (tok == TOK_STR || tok == TOK_LSTR) {
4025 ts = tokc.ts;
4026 /* compute maximum number of chars wanted */
4027 nb = ts->len;
4028 if (n >= 0 && nb > (n - array_length))
4029 nb = n - array_length;
4030 if (!size_only) {
4031 if (ts->len > nb)
4032 warning("initializer-string for array is too long");
4033 for(i=0;i<nb;i++) {
4034 init_putv(t1, c + (array_length + i) * size1,
4035 ts->str[i], 0);
4038 array_length += nb;
4039 next();
4041 /* only add trailing zero if enough storage (no
4042 warning in this case since it is standard) */
4043 if (n < 0 || array_length < n) {
4044 if (!size_only) {
4045 init_putv(t1, c + (array_length * size1), 0, 0);
4047 array_length++;
4049 } else {
4050 index = 0;
4051 while (tok != '}') {
4052 decl_designator(t, c, &index, NULL, size_only);
4053 if (n >= 0 && index >= n)
4054 error("index too large");
4055 /* must put zero in holes (note that doing it that way
4056 ensures that it even works with designators) */
4057 if (!size_only && array_length < index) {
4058 init_putz(t1, c + array_length * size1,
4059 (index - array_length) * size1);
4061 index++;
4062 if (index > array_length)
4063 array_length = index;
4064 /* special test for multi dimensional arrays (may not
4065 be strictly correct if designators are used at the
4066 same time) */
4067 if (index >= n && no_oblock)
4068 break;
4069 if (tok == '}')
4070 break;
4071 skip(',');
4074 if (!no_oblock)
4075 skip('}');
4076 /* put zeros at the end */
4077 if (!size_only && n >= 0 && array_length < n) {
4078 init_putz(t1, c + array_length * size1,
4079 (n - array_length) * size1);
4081 /* patch type size if needed */
4082 if (n < 0)
4083 s->c = array_length;
4084 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
4085 /* XXX: union needs only one init */
4086 next();
4087 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4088 f = s->next;
4089 array_length = 0;
4090 index = 0;
4091 n = s->c;
4092 while (tok != '}') {
4093 decl_designator(t, c, NULL, &f, size_only);
4094 /* fill with zero between fields */
4095 index = f->c;
4096 if (!size_only && array_length < index) {
4097 init_putz(t, c + array_length,
4098 index - array_length);
4100 index = index + type_size(f->t, &align1);
4101 if (index > array_length)
4102 array_length = index;
4103 if (tok == '}')
4104 break;
4105 skip(',');
4106 f = f->next;
4108 /* put zeros at the end */
4109 if (!size_only && array_length < n) {
4110 init_putz(t, c + array_length,
4111 n - array_length);
4113 skip('}');
4114 } else if (tok == '{') {
4115 next();
4116 decl_initializer(t, c, first, size_only);
4117 skip('}');
4118 } else if (size_only) {
4119 /* just skip expression */
4120 parlevel = 0;
4121 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4122 tok != -1) {
4123 if (tok == '(')
4124 parlevel++;
4125 else if (tok == ')')
4126 parlevel--;
4127 next();
4129 } else {
4130 init_putv(t, c, 0, 1);
4134 /* parse an initializer for type 't' if 'has_init' is true, and
4135 allocate space in local or global data space. The allocated address
4136 in returned */
4137 int decl_initializer_alloc(int t, int has_init)
4139 int size, align, addr, tok1;
4140 int *init_str, init_len, level, *saved_macro_ptr;
4142 size = type_size(t, &align);
4143 /* If unknown size, we must evaluate it before
4144 evaluating initializers because
4145 initializers can generate global data too
4146 (e.g. string pointers or ISOC99 compound
4147 literals). It also simplifies local
4148 initializers handling */
4149 init_len = 0;
4150 init_str = NULL;
4151 saved_macro_ptr = NULL; /* avoid warning */
4152 tok1 = 0;
4153 if (size < 0) {
4154 if (!has_init)
4155 error("unknown type size");
4156 /* get all init string */
4157 level = 0;
4158 while (level > 0 || (tok != ',' && tok != ';')) {
4159 if (tok < 0)
4160 error("unexpect end of file in initializer");
4161 tok_add2(&init_str, &init_len, tok, &tokc);
4162 if (tok == '{')
4163 level++;
4164 else if (tok == '}') {
4165 if (level == 0)
4166 break;
4167 level--;
4169 next();
4171 tok1 = tok;
4172 tok_add(&init_str, &init_len, -1);
4173 tok_add(&init_str, &init_len, 0);
4175 /* compute size */
4176 saved_macro_ptr = macro_ptr;
4177 macro_ptr = init_str;
4178 next();
4179 decl_initializer(t, 0, 1, 1);
4180 /* prepare second initializer parsing */
4181 macro_ptr = init_str;
4182 next();
4184 /* if still unknown size, error */
4185 size = type_size(t, &align);
4186 if (size < 0)
4187 error("unknown type size");
4189 if ((t & VT_VALMASK) == VT_LOCAL) {
4190 loc = (loc - size) & -align;
4191 addr = loc;
4192 } else {
4193 glo = (glo + align - 1) & -align;
4194 addr = glo;
4195 /* very important to increment global
4196 pointer at this time because
4197 initializers themselves can create new
4198 initializers */
4199 glo += size;
4201 if (has_init) {
4202 decl_initializer(t, addr, 1, 0);
4203 /* restore parse state if needed */
4204 if (init_str) {
4205 free(init_str);
4206 macro_ptr = saved_macro_ptr;
4207 tok = tok1;
4210 return addr;
4214 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
4215 void decl(int l)
4217 int *a, t, b, v, u, addr, has_init, size, align;
4218 Sym *sym;
4220 while (1) {
4221 b = ist();
4222 if (!b) {
4223 /* skip redundant ';' */
4224 /* XXX: find more elegant solution */
4225 if (tok == ';') {
4226 next();
4227 continue;
4229 /* special test for old K&R protos without explicit int
4230 type. Only accepted when defining global data */
4231 if (l == VT_LOCAL || tok < TOK_DEFINE)
4232 break;
4233 b = VT_INT;
4235 if (((b & VT_BTYPE) == VT_ENUM ||
4236 (b & VT_BTYPE) == VT_STRUCT) &&
4237 tok == ';') {
4238 /* we accept no variable after */
4239 next();
4240 continue;
4242 while (1) { /* iterate thru each declaration */
4243 t = type_decl(&v, b, TYPE_DIRECT);
4244 #if 0
4246 char buf[500];
4247 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
4248 printf("type = '%s'\n", buf);
4250 #endif
4251 if (tok == '{') {
4252 if (l == VT_LOCAL)
4253 error("cannot use local functions");
4254 if (!(t & VT_FUNC))
4255 expect("function definition");
4256 /* patch forward references */
4257 if ((sym = sym_find(v)) && (sym->t & VT_FORWARD)) {
4258 greloc_patch(sym, ind);
4259 sym->t = VT_CONST | t;
4260 } else {
4261 /* put function address */
4262 sym_push1(&global_stack, v, VT_CONST | t, ind);
4264 funcname = get_tok_str(v, NULL);
4265 /* push a dummy symbol to enable local sym storage */
4266 sym_push1(&local_stack, 0, 0, 0);
4267 /* define parameters */
4268 sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4269 /* XXX: the following is x86 dependant -> move it to
4270 x86 code gen */
4271 addr = 8;
4272 /* if the function returns a structure, then add an
4273 implicit pointer parameter */
4274 func_vt = sym->t;
4275 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
4276 func_vc = addr;
4277 addr += 4;
4279 while (sym = sym->next) {
4280 u = sym->t;
4281 sym_push(sym->v & ~SYM_FIELD,
4282 u | VT_LOCAL | VT_LVAL,
4283 addr);
4284 size = type_size(u, &align);
4285 size = (size + 3) & ~3;
4286 #ifdef FUNC_STRUCT_PARAM_AS_PTR
4287 /* structs are passed as pointer */
4288 if ((u & VT_BTYPE) == VT_STRUCT) {
4289 size = 4;
4291 #endif
4292 addr += size;
4294 loc = 0;
4295 o(0xe58955); /* push %ebp, mov %esp, %ebp */
4296 a = (int *)oad(0xec81, 0); /* sub $xxx, %esp */
4297 rsym = 0;
4298 block(NULL, NULL, NULL, NULL, 0);
4299 gsym(rsym);
4300 o(0xc3c9); /* leave, ret */
4301 *a = (-loc + 3) & -4; /* align local size to word &
4302 save local variables */
4303 sym_pop(&label_stack, NULL); /* reset label stack */
4304 sym_pop(&local_stack, NULL); /* reset local stack */
4305 funcname = ""; /* for safety */
4306 func_vt = VT_VOID; /* for safety */
4307 break;
4308 } else {
4309 if (b & VT_TYPEDEF) {
4310 /* save typedefed type */
4311 /* XXX: test storage specifiers ? */
4312 sym_push(v, t | VT_TYPEDEF, 0);
4313 } else if ((t & VT_BTYPE) == VT_FUNC) {
4314 /* external function definition */
4315 external_sym(v, t);
4316 } else {
4317 /* not lvalue if array */
4318 if (!(t & VT_ARRAY))
4319 t |= VT_LVAL;
4320 if (b & VT_EXTERN) {
4321 /* external variable */
4322 external_sym(v, t);
4323 } else {
4324 u = l;
4325 if (t & VT_STATIC)
4326 u = VT_CONST;
4327 u |= t;
4328 has_init = (tok == '=');
4329 if (has_init)
4330 next();
4331 addr = decl_initializer_alloc(u, has_init);
4332 if (l == VT_CONST) {
4333 /* global scope: see if already defined */
4334 sym = sym_find(v);
4335 if (!sym)
4336 goto do_def;
4337 if (!is_compatible_types(sym->t, u))
4338 error("incompatible types for redefinition of '%s'",
4339 get_tok_str(v, NULL));
4340 if (!(sym->t & VT_FORWARD))
4341 error("redefinition of '%s'", get_tok_str(v, NULL));
4342 greloc_patch(sym, addr);
4343 } else {
4344 do_def:
4345 sym_push(v, u, addr);
4349 if (tok != ',') {
4350 skip(';');
4351 break;
4353 next();
4359 /* put all global symbols in the extern stack and do all the
4360 resolving which can be done without using external symbols from DLLs */
4361 /* XXX: could try to verify types, but would not to save them in
4362 extern_stack too */
4363 void resolve_global_syms(void)
4365 Sym *s, *s1, *ext_sym;
4366 Reloc **p;
4368 s = global_stack.top;
4369 while (s != NULL) {
4370 s1 = s->prev;
4371 /* do not save static or typedefed symbols or types */
4372 if (!(s->t & (VT_STATIC | VT_TYPEDEF)) &&
4373 !(s->v & (SYM_FIELD | SYM_STRUCT)) &&
4374 (s->v < SYM_FIRST_ANOM)) {
4375 ext_sym = sym_find1(&extern_stack, s->v);
4376 if (!ext_sym) {
4377 /* if the symbol do not exist, we simply save it */
4378 sym_push1(&extern_stack, s->v, s->t, s->c);
4379 } else if (ext_sym->t & VT_FORWARD) {
4380 /* external symbol already exists, but only as forward
4381 definition */
4382 if (!(s->t & VT_FORWARD)) {
4383 /* s is not forward, so we can relocate all symbols */
4384 greloc_patch(ext_sym, s->c);
4385 } else {
4386 /* the two symbols are forward: merge them */
4387 p = (Reloc **)&ext_sym->c;
4388 while (*p != NULL)
4389 p = &(*p)->next;
4390 *p = (Reloc *)s->c;
4392 } else {
4393 /* external symbol already exists and is defined :
4394 patch all references to it */
4395 if (!(s->t & VT_FORWARD))
4396 error("'%s' defined twice", get_tok_str(s->v, NULL));
4397 greloc_patch(s, ext_sym->c);
4400 s = s1;
4404 /* compile a C file. Return non zero if errors. */
4405 int tcc_compile_file(const char *filename1)
4407 Sym *define_start;
4409 filename = (char *)filename1;
4411 line_num = 1;
4412 funcname = "";
4413 file = fopen(filename, "r");
4414 if (!file)
4415 error("file '%s' not found", filename);
4416 include_stack_ptr = include_stack;
4417 ifdef_stack_ptr = ifdef_stack;
4419 vtop = vstack - 1;
4420 anon_sym = SYM_FIRST_ANOM;
4422 define_start = define_stack.top;
4423 inp();
4424 ch = '\n'; /* needed to parse correctly first preprocessor command */
4425 next();
4426 decl(VT_CONST);
4427 if (tok != -1)
4428 expect("declaration");
4429 fclose(file);
4431 /* reset define stack, but leave -Dsymbols (may be incorrect if
4432 they are undefined) */
4433 sym_pop(&define_stack, define_start);
4435 resolve_global_syms();
4437 sym_pop(&global_stack, NULL);
4439 return 0;
4442 /* open a dynamic library so that its symbol are available for
4443 compiled programs */
4444 void open_dll(char *libname)
4446 char buf[1024];
4447 void *h;
4449 snprintf(buf, sizeof(buf), "lib%s.so", libname);
4450 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
4451 if (!h)
4452 error((char *)dlerror());
4455 void resolve_extern_syms(void)
4457 Sym *s, *s1;
4458 char *str;
4459 int addr;
4461 s = extern_stack.top;
4462 while (s != NULL) {
4463 s1 = s->prev;
4464 if (s->t & VT_FORWARD) {
4465 /* if there is at least one relocation to do, then find it
4466 and patch it */
4467 if (s->c) {
4468 str = get_tok_str(s->v, NULL);
4469 addr = (int)dlsym(NULL, str);
4470 if (!addr)
4471 error("unresolved external reference '%s'", str);
4472 greloc_patch(s, addr);
4475 s = s1;
4479 /* output a binary file (for testing) */
4480 void build_exe(char *filename)
4482 FILE *f;
4483 f = fopen(filename, "w");
4484 fwrite((void *)prog, 1, ind - prog, f);
4485 fclose(f);
4488 int main(int argc, char **argv)
4490 Sym *s;
4491 int (*t)();
4492 char *p, *r, *outfile;
4493 int optind;
4495 include_paths[0] = "/usr/include";
4496 include_paths[1] = "/usr/lib/tcc";
4497 include_paths[2] = "/usr/local/lib/tcc";
4498 nb_include_paths = 3;
4500 /* add all tokens */
4501 tok_ident = TOK_IDENT;
4502 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";
4503 while (*p) {
4504 r = p;
4505 while (*r++);
4506 tok_alloc(p, r - p - 1);
4507 p = r;
4510 /* standard defines */
4511 define_symbol("__STDC__");
4512 #ifdef __i386__
4513 define_symbol("__i386__");
4514 #endif
4515 /* tiny C specific defines */
4516 define_symbol("__TINYC__");
4518 glo = (int)malloc(DATA_SIZE);
4519 memset((void *)glo, 0, DATA_SIZE);
4520 prog = (int)malloc(TEXT_SIZE);
4521 ind = prog;
4523 optind = 1;
4524 outfile = NULL;
4525 while (1) {
4526 if (optind >= argc) {
4527 show_help:
4528 printf("tcc version 0.9.2 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n"
4529 "usage: tcc [-Idir] [-Dsym] [-llib] [-i infile] infile [infile_args...]\n");
4530 return 1;
4532 r = argv[optind];
4533 if (r[0] != '-')
4534 break;
4535 optind++;
4536 if (r[1] == 'I') {
4537 if (nb_include_paths >= INCLUDE_PATHS_MAX)
4538 error("too many include paths");
4539 include_paths[nb_include_paths++] = r + 2;
4540 } else if (r[1] == 'D') {
4541 define_symbol(r + 2);
4542 } else if (r[1] == 'l') {
4543 open_dll(r + 2);
4544 } else if (r[1] == 'i') {
4545 if (optind >= argc)
4546 goto show_help;
4547 tcc_compile_file(argv[optind++]);
4548 } else if (r[1] == 'o') {
4549 /* currently, only for testing, so not documented */
4550 if (optind >= argc)
4551 goto show_help;
4552 outfile = argv[optind++];
4553 } else {
4554 fprintf(stderr, "invalid option -- '%s'\n", r);
4555 exit(1);
4559 tcc_compile_file(argv[optind]);
4561 resolve_extern_syms();
4563 if (outfile) {
4564 build_exe(outfile);
4565 return 0;
4566 } else {
4567 s = sym_find1(&extern_stack, TOK_MAIN);
4568 if (!s || (s->t & VT_FORWARD))
4569 error("main() not defined");
4570 t = (int (*)())s->c;
4571 return (*t)(argc - optind, argv + optind);