last patches to separate type and value handling
[tinycc.git] / tcc.c
blob855e8e9eabcb9b607da3c6dbba7b4ac561fdfd14
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <math.h>
25 #ifndef CONFIG_TCC_STATIC
26 #include <dlfcn.h>
27 #endif
29 //#define DEBUG
30 /* preprocessor debug */
31 //#define PP_DEBUG
33 /* these sizes are dummy for unix, because malloc() does not use
34 memory when the pages are not used */
35 #define TEXT_SIZE (4*1024*1024)
36 #define DATA_SIZE (4*1024*1024)
38 #define INCLUDE_STACK_SIZE 32
39 #define IFDEF_STACK_SIZE 64
40 #define VSTACK_SIZE 64
41 #define STRING_MAX_SIZE 1024
42 #define INCLUDE_PATHS_MAX 32
44 #define TOK_HASH_SIZE 521
45 #define TOK_ALLOC_INCR 256 /* must be a power of two */
46 #define SYM_HASH_SIZE 263
48 /* token symbol management */
49 typedef struct TokenSym {
50 struct TokenSym *hash_next;
51 int tok; /* token number */
52 int len;
53 char str[1];
54 } TokenSym;
56 /* constant value */
57 typedef union CValue {
58 long double ld;
59 double d;
60 float f;
61 int i;
62 unsigned int ui;
63 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
64 long long ll;
65 unsigned long long ull;
66 struct TokenSym *ts;
67 struct Sym *sym;
68 int tab[1];
69 } CValue;
71 /* value on stack */
72 typedef struct SValue {
73 int t; /* type */
74 int r; /* register + flags */
75 CValue c; /* constant */
76 } SValue;
78 /* symbol management */
79 typedef struct Sym {
80 int v; /* symbol token */
81 int t; /* associated type */
82 int r; /* associated register */
83 int c; /* associated number */
84 struct Sym *next; /* next related symbol */
85 struct Sym *prev; /* prev symbol in stack */
86 struct Sym *hash_next; /* next symbol in hash table */
87 } Sym;
89 typedef struct SymStack {
90 struct Sym *top;
91 struct Sym *hash[SYM_HASH_SIZE];
92 } SymStack;
94 /* relocation entry (currently only used for functions or variables */
95 typedef struct Reloc {
96 int type; /* type of relocation */
97 int addr; /* address of relocation */
98 struct Reloc *next; /* next relocation */
99 } Reloc;
101 #define RELOC_ADDR32 1 /* 32 bits relocation */
102 #define RELOC_REL32 2 /* 32 bits relative relocation */
105 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
106 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
107 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
109 #define FUNC_NEW 1 /* ansi function prototype */
110 #define FUNC_OLD 2 /* old function prototype */
111 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
113 /* field 'Sym.t' for macros */
114 #define MACRO_OBJ 0 /* object like macro */
115 #define MACRO_FUNC 1 /* function like macro */
117 /* type_decl() types */
118 #define TYPE_ABSTRACT 1 /* type without variable */
119 #define TYPE_DIRECT 2 /* type with variable */
121 typedef struct {
122 FILE *file;
123 char *filename;
124 int line_num;
125 } IncludeFile;
127 /* parser */
128 FILE *file;
129 int line_num;
130 int ch, ch1, tok, tok1;
131 CValue tokc, tok1c;
133 /* loc : local variable index
134 glo : global variable index
135 ind : output code ptr
136 rsym: return symbol
137 prog: output code
138 anon_sym: anonymous symbol index
140 int rsym, anon_sym,
141 prog, ind, loc, glo, const_wanted;
142 int global_expr; /* true if compound literals must be allocated
143 globally (used during initializers parsing */
144 int func_vt, func_vc; /* current function return type (used by
145 return instruction) */
146 int tok_ident;
147 TokenSym **table_ident;
148 TokenSym *hash_ident[TOK_HASH_SIZE];
149 char token_buf[STRING_MAX_SIZE + 1];
150 char *filename, *funcname;
151 /* contains global symbols which remain between each translation unit */
152 SymStack extern_stack;
153 SymStack define_stack, global_stack, local_stack, label_stack;
155 SValue vstack[VSTACK_SIZE], *vtop;
156 int *macro_ptr, *macro_ptr_allocated;
157 IncludeFile include_stack[INCLUDE_STACK_SIZE], *include_stack_ptr;
158 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
159 char *include_paths[INCLUDE_PATHS_MAX];
160 int nb_include_paths;
162 /* use GNU C extensions */
163 int gnu_ext = 1;
165 /* use Tiny C extensions */
166 int tcc_ext = 1;
168 /* The current value can be: */
169 #define VT_VALMASK 0x00ff
170 #define VT_CONST 0x00f0 /* constant in vc
171 (must be first non register value) */
172 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
173 #define VT_LOCAL 0x00f2 /* offset on stack */
174 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
175 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
176 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
177 #define VT_LVAL 0x0100 /* var is an lvalue */
178 #define VT_FORWARD 0x0200 /* value is forward reference */
180 /* types */
181 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
183 #define VT_INT 0 /* integer type */
184 #define VT_BYTE 1 /* signed byte type */
185 #define VT_SHORT 2 /* short type */
186 #define VT_VOID 3 /* void type */
187 #define VT_PTR 4 /* pointer increment */
188 #define VT_ENUM 5 /* enum definition */
189 #define VT_FUNC 6 /* function type */
190 #define VT_STRUCT 7 /* struct/union definition */
191 #define VT_FLOAT 8 /* IEEE float */
192 #define VT_DOUBLE 9 /* IEEE double */
193 #define VT_LDOUBLE 10 /* IEEE long double */
194 #define VT_BOOL 11 /* ISOC99 boolean type */
195 #define VT_LLONG 12 /* 64 bit integer */
196 #define VT_LONG 13 /* long integer (NEVER USED as type, only
197 during parsing) */
198 #define VT_BTYPE 0x000f /* mask for basic type */
199 #define VT_UNSIGNED 0x0010 /* unsigned type */
200 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
201 #define VT_BITFIELD 0x0040 /* bitfield modifier */
203 /* storage */
204 #define VT_EXTERN 0x00000080 /* extern definition */
205 #define VT_STATIC 0x00000100 /* static variable */
206 #define VT_TYPEDEF 0x00000200 /* typedef definition */
208 /* type mask (except storage) */
209 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
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 r, int c, int first, int size_only);
342 int decl_initializer_alloc(int t, int sec, 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 parse_btype(int *type_ptr);
361 int type_decl(int *v, int t, int td);
362 void error(const char *fmt, ...);
363 void vset(int t, int r, 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 *fmt, ...)
469 va_list ap;
471 va_start(ap, fmt);
472 printline();
473 fprintf(stderr, "warning: ");
474 vfprintf(stderr, fmt, ap);
475 fprintf(stderr, "\n");
476 va_end(ap);
479 void skip(int c)
481 if (tok != c)
482 error("'%c' expected", c);
483 next();
486 void test_lvalue(void)
488 if (!(vtop->r & VT_LVAL))
489 expect("lvalue");
492 TokenSym *tok_alloc(char *str, int len)
494 TokenSym *ts, **pts, **ptable;
495 int h, i;
497 if (len <= 0)
498 len = strlen(str);
499 h = 1;
500 for(i=0;i<len;i++)
501 h = ((h << 8) | (str[i] & 0xff)) % TOK_HASH_SIZE;
503 pts = &hash_ident[h];
504 while (1) {
505 ts = *pts;
506 if (!ts)
507 break;
508 if (ts->len == len && !memcmp(ts->str, str, len))
509 return ts;
510 pts = &(ts->hash_next);
513 if (tok_ident >= SYM_FIRST_ANOM)
514 error("memory full");
516 /* expand token table if needed */
517 i = tok_ident - TOK_IDENT;
518 if ((i % TOK_ALLOC_INCR) == 0) {
519 ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
520 if (!ptable)
521 error("memory full");
522 table_ident = ptable;
525 ts = malloc(sizeof(TokenSym) + len);
526 if (!ts)
527 error("memory full");
528 table_ident[i] = ts;
529 ts->tok = tok_ident++;
530 ts->len = len;
531 ts->hash_next = NULL;
532 memcpy(ts->str, str, len + 1);
533 *pts = ts;
534 return ts;
537 void add_char(char **pp, int c)
539 char *p;
540 p = *pp;
541 if (c == '\'' || c == '\"' || c == '\\') {
542 /* XXX: could be more precise if char or string */
543 *p++ = '\\';
545 if (c >= 32 && c <= 126) {
546 *p++ = c;
547 } else {
548 *p++ = '\\';
549 if (c == '\n') {
550 *p++ = 'n';
551 } else {
552 *p++ = '0' + ((c >> 6) & 7);
553 *p++ = '0' + ((c >> 3) & 7);
554 *p++ = '0' + (c & 7);
557 *pp = p;
560 /* XXX: buffer overflow */
561 char *get_tok_str(int v, CValue *cv)
563 static char buf[STRING_MAX_SIZE + 1];
564 TokenSym *ts;
565 char *p;
566 int i;
568 if (v == TOK_NUM) {
569 sprintf(buf, "%u", cv->ui);
570 return buf;
571 } else if (v == TOK_CCHAR || v == TOK_LCHAR) {
572 p = buf;
573 *p++ = '\'';
574 add_char(&p, cv->i);
575 *p++ = '\'';
576 *p = '\0';
577 return buf;
578 } else if (v == TOK_STR || v == TOK_LSTR) {
579 ts = cv->ts;
580 p = buf;
581 *p++ = '\"';
582 for(i=0;i<ts->len;i++)
583 add_char(&p, ts->str[i]);
584 *p++ = '\"';
585 *p = '\0';
586 return buf;
587 } else if (v < TOK_IDENT) {
588 p = buf;
589 *p++ = v;
590 *p = '\0';
591 return buf;
592 } else if (v < tok_ident) {
593 return table_ident[v - TOK_IDENT]->str;
594 } else {
595 /* should never happen */
596 return NULL;
600 /* push, without hashing */
601 Sym *sym_push2(Sym **ps, int v, int t, int c)
603 Sym *s;
604 s = malloc(sizeof(Sym));
605 if (!s)
606 error("memory full");
607 s->v = v;
608 s->t = t;
609 s->c = c;
610 s->next = NULL;
611 /* add in stack */
612 s->prev = *ps;
613 *ps = s;
614 return s;
617 /* find a symbol and return its associated structure. 's' is the top
618 of the symbol stack */
619 Sym *sym_find2(Sym *s, int v)
621 while (s) {
622 if (s->v == v)
623 return s;
624 s = s->prev;
626 return NULL;
629 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
631 /* find a symbol and return its associated structure. 'st' is the
632 symbol stack */
633 Sym *sym_find1(SymStack *st, int v)
635 Sym *s;
637 s = st->hash[HASH_SYM(v)];
638 while (s) {
639 if (s->v == v)
640 return s;
641 s = s->hash_next;
643 return 0;
646 Sym *sym_push1(SymStack *st, int v, int t, int c)
648 Sym *s, **ps;
649 s = sym_push2(&st->top, v, t, c);
650 /* add in hash table */
651 if (v) {
652 ps = &st->hash[HASH_SYM(v)];
653 s->hash_next = *ps;
654 *ps = s;
656 return s;
659 /* find a symbol in the right symbol space */
660 Sym *sym_find(int v)
662 Sym *s;
663 s = sym_find1(&local_stack, v);
664 if (!s)
665 s = sym_find1(&global_stack, v);
666 return s;
669 /* push a given symbol on the symbol stack */
670 Sym *sym_push(int v, int t, int r, int c)
672 Sym *s;
673 if (local_stack.top)
674 s = sym_push1(&local_stack, v, t, c);
675 else
676 s = sym_push1(&global_stack, v, t, c);
677 s->r = r;
678 return s;
681 /* pop symbols until top reaches 'b' */
682 void sym_pop(SymStack *st, Sym *b)
684 Sym *s, *ss;
686 s = st->top;
687 while(s != b) {
688 ss = s->prev;
689 /* free hash table entry, except if symbol was freed (only
690 used for #undef symbols) */
691 if (s->v)
692 st->hash[HASH_SYM(s->v)] = s->hash_next;
693 free(s);
694 s = ss;
696 st->top = b;
699 /* undefined a hashed symbol (used for #undef). Its name is set to
700 zero */
701 void sym_undef(SymStack *st, Sym *s)
703 Sym **ss;
704 ss = &st->hash[HASH_SYM(s->v)];
705 while (*ss != NULL) {
706 if (*ss == s)
707 break;
708 ss = &(*ss)->hash_next;
710 *ss = s->hash_next;
711 s->v = 0;
714 /* no need to put that inline */
715 int handle_eof(void)
717 if (include_stack_ptr == include_stack)
718 return -1;
719 /* pop include stack */
720 fclose(file);
721 free(filename);
722 include_stack_ptr--;
723 file = include_stack_ptr->file;
724 filename = include_stack_ptr->filename;
725 line_num = include_stack_ptr->line_num;
726 return 0;
729 /* read next char from current input file */
730 static inline void inp(void)
732 redo:
733 /* faster than fgetc */
734 ch1 = getc_unlocked(file);
735 if (ch1 == -1) {
736 if (handle_eof() < 0)
737 return;
738 else
739 goto redo;
741 if (ch1 == '\n')
742 line_num++;
743 // printf("ch1=%c 0x%x\n", ch1, ch1);
746 /* input with '\\n' handling */
747 static inline void minp(void)
749 redo:
750 ch = ch1;
751 inp();
752 if (ch == '\\' && ch1 == '\n') {
753 inp();
754 goto redo;
756 //printf("ch=%c 0x%x\n", ch, ch);
760 /* same as minp, but also skip comments */
761 void cinp(void)
763 int c;
765 if (ch1 == '/') {
766 inp();
767 if (ch1 == '/') {
768 /* single line C++ comments */
769 inp();
770 while (ch1 != '\n' && ch1 != -1)
771 inp();
772 inp();
773 ch = ' '; /* return space */
774 } else if (ch1 == '*') {
775 /* C comments */
776 inp();
777 while (ch1 != -1) {
778 c = ch1;
779 inp();
780 if (c == '*' && ch1 == '/') {
781 inp();
782 ch = ' '; /* return space */
783 break;
786 } else {
787 ch = '/';
789 } else {
790 minp();
794 void skip_spaces(void)
796 while (ch == ' ' || ch == '\t')
797 cinp();
800 /* skip block of text until #else, #elif or #endif. skip also pairs of
801 #if/#endif */
802 void preprocess_skip()
804 int a;
805 a = 0;
806 while (1) {
807 while (ch != '\n') {
808 if (ch == -1)
809 expect("#endif");
810 cinp();
812 cinp();
813 skip_spaces();
814 if (ch == '#') {
815 cinp();
816 next_nomacro();
817 if (a == 0 &&
818 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
819 break;
820 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
821 a++;
822 else if (tok == TOK_ENDIF)
823 a--;
828 /* return the number of additionnal 'ints' necessary to store the
829 token */
830 static inline int tok_ext_size(int t)
832 switch(t) {
833 /* 4 bytes */
834 case TOK_NUM:
835 case TOK_CCHAR:
836 case TOK_LCHAR:
837 case TOK_STR:
838 case TOK_LSTR:
839 case TOK_CFLOAT:
840 return 1;
841 case TOK_CDOUBLE:
842 return 2;
843 case TOK_CLDOUBLE:
844 return LDOUBLE_SIZE / 4;
845 default:
846 return 0;
850 void tok_add(int **tok_str, int *tok_len, int t)
852 int len, *str;
853 len = *tok_len;
854 str = *tok_str;
855 if ((len & 63) == 0) {
856 str = realloc(str, (len + 64) * sizeof(int));
857 if (!str)
858 return;
859 *tok_str = str;
861 str[len++] = t;
862 *tok_len = len;
865 void tok_add2(int **tok_str, int *tok_len, int t, CValue *cv)
867 int n, i;
869 tok_add(tok_str, tok_len, t);
870 n = tok_ext_size(t);
871 for(i=0;i<n;i++)
872 tok_add(tok_str, tok_len, cv->tab[i]);
875 /* get a token from an integer array and increment pointer accordingly */
876 int tok_get(int **tok_str, CValue *cv)
878 int *p, t, n, i;
880 p = *tok_str;
881 t = *p++;
882 n = tok_ext_size(t);
883 for(i=0;i<n;i++)
884 cv->tab[i] = *p++;
885 *tok_str = p;
886 return t;
889 /* eval an expression for #if/#elif */
890 int expr_preprocess(void)
892 int *str, len, c, t;
894 str = NULL;
895 len = 0;
896 while (1) {
897 skip_spaces();
898 if (ch == '\n')
899 break;
900 next(); /* do macro subst */
901 if (tok == TOK_DEFINED) {
902 next_nomacro();
903 t = tok;
904 if (t == '(')
905 next_nomacro();
906 c = sym_find1(&define_stack, tok) != 0;
907 if (t == '(')
908 next_nomacro();
909 tok = TOK_NUM;
910 tokc.i = c;
911 } else if (tok >= TOK_IDENT) {
912 /* if undefined macro */
913 tok = TOK_NUM;
914 tokc.i = 0;
916 tok_add2(&str, &len, tok, &tokc);
918 tok_add(&str, &len, -1); /* simulate end of file */
919 tok_add(&str, &len, 0);
920 /* now evaluate C constant expression */
921 macro_ptr = str;
922 next();
923 c = expr_const();
924 macro_ptr = NULL;
925 free(str);
926 return c != 0;
929 #if defined(DEBUG)
930 void tok_print(int *str)
932 int t;
933 CValue cval;
935 while (1) {
936 t = tok_get(&str, &cval);
937 if (!t)
938 break;
939 printf(" %s", get_tok_str(t, &cval));
941 printf("\n");
943 #endif
945 /* XXX: should be more factorized */
946 void define_symbol(char *sym)
948 TokenSym *ts;
949 int *str, len;
950 CValue cval;
952 ts = tok_alloc(sym, 0);
953 str = NULL;
954 len = 0;
955 cval.i = 1;
956 tok_add2(&str, &len, TOK_NUM, &cval);
957 tok_add(&str, &len, 0);
958 sym_push1(&define_stack, ts->tok, MACRO_OBJ, (int)str);
961 void preprocess(void)
963 int size, i, c, v, t, *str, len;
964 char buf[1024], *q, *p;
965 char buf1[1024];
966 FILE *f;
967 Sym **ps, *first, *s;
969 cinp();
970 next_nomacro();
971 redo:
972 if (tok == TOK_DEFINE) {
973 next_nomacro();
974 v = tok;
975 /* XXX: should check if same macro (ANSI) */
976 first = NULL;
977 t = MACRO_OBJ;
978 /* '(' must be just after macro definition for MACRO_FUNC */
979 if (ch == '(') {
980 next_nomacro();
981 next_nomacro();
982 ps = &first;
983 while (tok != ')') {
984 if (tok == TOK_DOTS)
985 tok = TOK___VA_ARGS__;
986 s = sym_push1(&define_stack, tok | SYM_FIELD, 0, 0);
987 *ps = s;
988 ps = &s->next;
989 next_nomacro();
990 if (tok != ',')
991 break;
992 next_nomacro();
994 t = MACRO_FUNC;
996 str = NULL;
997 len = 0;
998 while (1) {
999 skip_spaces();
1000 if (ch == '\n' || ch == -1)
1001 break;
1002 next_nomacro();
1003 tok_add2(&str, &len, tok, &tokc);
1005 tok_add(&str, &len, 0);
1006 #ifdef PP_DEBUG
1007 printf("define %s %d: ", get_tok_str(v, NULL), t);
1008 tok_print(str);
1009 #endif
1010 s = sym_push1(&define_stack, v, t, (int)str);
1011 s->next = first;
1012 } else if (tok == TOK_UNDEF) {
1013 next_nomacro();
1014 s = sym_find1(&define_stack, tok);
1015 /* undefine symbol by putting an invalid name */
1016 if (s)
1017 sym_undef(&define_stack, s);
1018 } else if (tok == TOK_INCLUDE) {
1019 skip_spaces();
1020 if (ch == '<') {
1021 c = '>';
1022 goto read_name;
1023 } else if (ch == '\"') {
1024 c = ch;
1025 read_name:
1026 minp();
1027 q = buf;
1028 while (ch != c && ch != '\n' && ch != -1) {
1029 if ((q - buf) < sizeof(buf) - 1)
1030 *q++ = ch;
1031 minp();
1033 *q = '\0';
1034 } else {
1035 next();
1036 if (tok != TOK_STR)
1037 error("#include syntax error");
1038 /* XXX: buffer overflow */
1039 strcpy(buf, get_tok_str(tok, &tokc));
1040 c = '\"';
1042 /* eat all spaces and comments after include */
1043 /* XXX: slightly incorrect */
1044 while (ch1 != '\n' && ch1 != -1)
1045 inp();
1047 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1048 error("memory full");
1049 if (c == '\"') {
1050 /* first search in current dir if "header.h" */
1051 /* XXX: buffer overflow */
1052 size = 0;
1053 p = strrchr(filename, '/');
1054 if (p)
1055 size = p + 1 - filename;
1056 memcpy(buf1, filename, size);
1057 buf1[size] = '\0';
1058 strcat(buf1, buf);
1059 f = fopen(buf1, "r");
1060 if (f)
1061 goto found;
1063 /* now search in standard include path */
1064 for(i=nb_include_paths - 1;i>=0;i--) {
1065 strcpy(buf1, include_paths[i]);
1066 strcat(buf1, "/");
1067 strcat(buf1, buf);
1068 f = fopen(buf1, "r");
1069 if (f)
1070 goto found;
1072 error("include file '%s' not found", buf1);
1073 f = NULL;
1074 found:
1075 /* push current file in stack */
1076 /* XXX: fix current line init */
1077 include_stack_ptr->file = file;
1078 include_stack_ptr->filename = filename;
1079 include_stack_ptr->line_num = line_num;
1080 include_stack_ptr++;
1081 file = f;
1082 filename = strdup(buf1);
1083 line_num = 1;
1084 } else if (tok == TOK_IFNDEF) {
1085 c = 1;
1086 goto do_ifdef;
1087 } else if (tok == TOK_IF) {
1088 c = expr_preprocess();
1089 goto do_if;
1090 } else if (tok == TOK_IFDEF) {
1091 c = 0;
1092 do_ifdef:
1093 next_nomacro();
1094 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1095 do_if:
1096 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1097 error("memory full");
1098 *ifdef_stack_ptr++ = c;
1099 goto test_skip;
1100 } else if (tok == TOK_ELSE) {
1101 if (ifdef_stack_ptr == ifdef_stack ||
1102 (ifdef_stack_ptr[-1] & 2))
1103 error("#else after #else");
1104 c = (ifdef_stack_ptr[-1] ^= 3);
1105 goto test_skip;
1106 } else if (tok == TOK_ELIF) {
1107 if (ifdef_stack_ptr == ifdef_stack ||
1108 ifdef_stack_ptr[-1] > 1)
1109 error("#elif after #else");
1110 c = expr_preprocess();
1111 ifdef_stack_ptr[-1] = c;
1112 test_skip:
1113 if (!(c & 1)) {
1114 preprocess_skip();
1115 goto redo;
1117 } else if (tok == TOK_ENDIF) {
1118 if (ifdef_stack_ptr == ifdef_stack)
1119 expect("#if");
1120 ifdef_stack_ptr--;
1121 } else if (tok == TOK_LINE) {
1122 next();
1123 if (tok != TOK_NUM)
1124 error("#line");
1125 line_num = tokc.i;
1126 skip_spaces();
1127 if (ch != '\n') {
1128 next();
1129 if (tok != TOK_STR)
1130 error("#line");
1131 /* XXX: potential memory leak */
1132 filename = strdup(get_tok_str(tok, &tokc));
1134 } else if (tok == TOK_ERROR) {
1135 error("#error");
1137 /* ignore other preprocess commands or #! for C scripts */
1138 while (ch != '\n' && ch != -1)
1139 cinp();
1142 /* read a number in base b */
1143 int getn(b)
1145 int n, t;
1146 n = 0;
1147 while (1) {
1148 if (ch >= 'a' & ch <= 'f')
1149 t = ch - 'a' + 10;
1150 else if (ch >= 'A' & ch <= 'F')
1151 t = ch - 'A' + 10;
1152 else if (isnum(ch))
1153 t = ch - '0';
1154 else
1155 break;
1156 if (t < 0 | t >= b)
1157 break;
1158 n = n * b + t;
1159 cinp();
1161 return n;
1164 /* read a character for string or char constant and eval escape codes */
1165 int getq()
1167 int c;
1169 c = ch;
1170 minp();
1171 if (c == '\\') {
1172 if (isnum(ch)) {
1173 /* at most three octal digits */
1174 c = ch - '0';
1175 minp();
1176 if (isnum(ch)) {
1177 c = c * 8 + ch - '0';
1178 minp();
1179 if (isnum(ch)) {
1180 c = c * 8 + ch - '0';
1181 minp();
1184 return c;
1185 } else if (ch == 'x') {
1186 minp();
1187 return getn(16);
1188 } else {
1189 if (ch == 'a')
1190 c = '\a';
1191 else if (ch == 'b')
1192 c = '\b';
1193 else if (ch == 'f')
1194 c = '\f';
1195 else if (ch == 'n')
1196 c = '\n';
1197 else if (ch == 'r')
1198 c = '\r';
1199 else if (ch == 't')
1200 c = '\t';
1201 else if (ch == 'v')
1202 c = '\v';
1203 else if (ch == 'e' && gnu_ext)
1204 c = 27;
1205 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
1206 c = ch;
1207 else
1208 error("invalid escaped char");
1209 minp();
1212 return c;
1215 /* we use 64 bit numbers */
1216 #define BN_SIZE 2
1218 /* bn = (bn << shift) | or_val */
1219 void bn_lshift(unsigned int *bn, int shift, int or_val)
1221 int i;
1222 unsigned int v;
1223 for(i=0;i<BN_SIZE;i++) {
1224 v = bn[i];
1225 bn[i] = (v << shift) | or_val;
1226 or_val = v >> (32 - shift);
1230 void bn_zero(unsigned int *bn)
1232 int i;
1233 for(i=0;i<BN_SIZE;i++) {
1234 bn[i] = 0;
1238 void parse_number(void)
1240 int b, t, shift, frac_bits, s, exp_val;
1241 char *q;
1242 unsigned int n, n1;
1243 unsigned int bn[BN_SIZE];
1244 double d;
1246 /* number */
1247 q = token_buf;
1248 t = ch;
1249 cinp();
1250 *q++ = t;
1251 b = 10;
1252 if (t == '.') {
1253 /* special dot handling */
1254 if (ch >= '0' && ch <= '9') {
1255 goto float_frac_parse;
1256 } else if (ch == '.') {
1257 cinp();
1258 if (ch != '.')
1259 expect("'.'");
1260 cinp();
1261 tok = TOK_DOTS;
1262 } else {
1263 /* dots */
1264 tok = t;
1266 return;
1267 } else if (t == '0') {
1268 if (ch == 'x' || ch == 'X') {
1269 q--;
1270 cinp();
1271 b = 16;
1272 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
1273 q--;
1274 cinp();
1275 b = 2;
1278 /* parse all digits. cannot check octal numbers at this stage
1279 because of floating point constants */
1280 while (1) {
1281 if (ch >= 'a' & ch <= 'f')
1282 t = ch - 'a' + 10;
1283 else if (ch >= 'A' & ch <= 'F')
1284 t = ch - 'A' + 10;
1285 else if (isnum(ch))
1286 t = ch - '0';
1287 else
1288 break;
1289 if (t >= b)
1290 break;
1291 if (q >= token_buf + STRING_MAX_SIZE) {
1292 num_too_long:
1293 error("number too long");
1295 *q++ = ch;
1296 cinp();
1298 if (ch == '.' ||
1299 ((ch == 'e' || ch == 'E') && b == 10) ||
1300 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
1301 if (b != 10) {
1302 /* NOTE: strtox should support that for hexa numbers, but
1303 non ISOC99 libcs do not support it, so we prefer to do
1304 it by hand */
1305 /* hexadecimal or binary floats */
1306 /* XXX: handle overflows */
1307 *q = '\0';
1308 if (b == 16)
1309 shift = 4;
1310 else
1311 shift = 2;
1312 bn_zero(bn);
1313 q = token_buf;
1314 while (1) {
1315 t = *q++;
1316 if (t == '\0') {
1317 break;
1318 } else if (t >= 'a') {
1319 t = t - 'a' + 10;
1320 } else if (t >= 'A') {
1321 t = t - 'A' + 10;
1322 } else {
1323 t = t - '0';
1325 bn_lshift(bn, shift, t);
1327 frac_bits = 0;
1328 if (ch == '.') {
1329 cinp();
1330 while (1) {
1331 t = ch;
1332 if (t >= 'a' && t <= 'f') {
1333 t = t - 'a' + 10;
1334 } else if (t >= 'A' && t <= 'F') {
1335 t = t - 'A' + 10;
1336 } else if (t >= '0' && t <= '9') {
1337 t = t - '0';
1338 } else {
1339 break;
1341 if (t >= b)
1342 error("invalid digit");
1343 bn_lshift(bn, shift, t);
1344 frac_bits += shift;
1345 cinp();
1348 if (ch != 'p' && ch != 'P')
1349 error("exponent expected");
1350 cinp();
1351 s = 1;
1352 exp_val = 0;
1353 if (ch == '+') {
1354 cinp();
1355 } else if (ch == '-') {
1356 s = -1;
1357 cinp();
1359 if (ch < '0' || ch > '9')
1360 error("exponent digits expected");
1361 while (ch >= '0' && ch <= '9') {
1362 exp_val = exp_val * 10 + ch - '0';
1363 cinp();
1365 exp_val = exp_val * s;
1367 /* now we can generate the number */
1368 /* XXX: should patch directly float number */
1369 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
1370 d = ldexp(d, exp_val - frac_bits);
1371 t = toup(ch);
1372 if (t == 'F') {
1373 cinp();
1374 tok = TOK_CFLOAT;
1375 /* float : should handle overflow */
1376 tokc.f = (float)d;
1377 } else if (t == 'L') {
1378 cinp();
1379 tok = TOK_CLDOUBLE;
1380 /* XXX: not large enough */
1381 tokc.ld = (long double)d;
1382 } else {
1383 tok = TOK_CDOUBLE;
1384 tokc.d = d;
1386 } else {
1387 /* decimal floats */
1388 if (ch == '.') {
1389 if (q >= token_buf + STRING_MAX_SIZE)
1390 goto num_too_long;
1391 *q++ = ch;
1392 cinp();
1393 float_frac_parse:
1394 while (ch >= '0' && ch <= '9') {
1395 if (q >= token_buf + STRING_MAX_SIZE)
1396 goto num_too_long;
1397 *q++ = ch;
1398 cinp();
1401 if (ch == 'e' || ch == 'E') {
1402 if (q >= token_buf + STRING_MAX_SIZE)
1403 goto num_too_long;
1404 *q++ = ch;
1405 cinp();
1406 if (ch == '-' || ch == '+') {
1407 if (q >= token_buf + STRING_MAX_SIZE)
1408 goto num_too_long;
1409 *q++ = ch;
1410 cinp();
1412 if (ch < '0' || ch > '9')
1413 error("exponent digits expected");
1414 while (ch >= '0' && ch <= '9') {
1415 if (q >= token_buf + STRING_MAX_SIZE)
1416 goto num_too_long;
1417 *q++ = ch;
1418 cinp();
1421 *q = '\0';
1422 t = toup(ch);
1423 errno = 0;
1424 if (t == 'F') {
1425 cinp();
1426 tok = TOK_CFLOAT;
1427 tokc.f = strtof(token_buf, NULL);
1428 } else if (t == 'L') {
1429 cinp();
1430 tok = TOK_CLDOUBLE;
1431 tokc.ld = strtold(token_buf, NULL);
1432 } else {
1433 tok = TOK_CDOUBLE;
1434 tokc.d = strtod(token_buf, NULL);
1437 } else {
1438 /* integer number */
1439 *q = '\0';
1440 q = token_buf;
1441 if (b == 10 && *q == '0') {
1442 b = 8;
1443 q++;
1445 n = 0;
1446 while(1) {
1447 t = *q++;
1448 /* no need for checks except for base 10 / 8 errors */
1449 if (t == '\0') {
1450 break;
1451 } else if (t >= 'a') {
1452 t = t - 'a' + 10;
1453 } else if (t >= 'A') {
1454 t = t - 'A' + 10;
1455 } else {
1456 t = t - '0';
1457 if (t >= b)
1458 error("invalid digit");
1460 n1 = n;
1461 n = n * b + t;
1462 /* detect overflow */
1463 if (n < n1)
1464 error("integer constant overflow");
1466 tokc.ui = n;
1467 tok = TOK_NUM;
1468 /* XXX: add unsigned constant support (ANSI) */
1469 while (ch == 'L' || ch == 'l' || ch == 'U' || ch == 'u')
1470 cinp();
1475 /* return next token without macro substitution */
1476 void next_nomacro1(void)
1478 int b;
1479 char *q;
1480 TokenSym *ts;
1482 /* skip spaces */
1483 while(1) {
1484 while (ch == '\n') {
1485 cinp();
1486 while (ch == ' ' || ch == 9)
1487 cinp();
1488 if (ch == '#') {
1489 /* preprocessor command if # at start of line after
1490 spaces */
1491 preprocess();
1494 if (ch != ' ' && ch != '\t' && ch != '\f')
1495 break;
1496 cinp();
1498 if (isid(ch)) {
1499 q = token_buf;
1500 *q++ = ch;
1501 cinp();
1502 if (q[-1] == 'L') {
1503 if (ch == '\'') {
1504 tok = TOK_LCHAR;
1505 goto char_const;
1507 if (ch == '\"') {
1508 tok = TOK_LSTR;
1509 goto str_const;
1512 while (isid(ch) || isnum(ch)) {
1513 if (q >= token_buf + STRING_MAX_SIZE)
1514 error("ident too long");
1515 *q++ = ch;
1516 cinp();
1518 *q = '\0';
1519 ts = tok_alloc(token_buf, q - token_buf);
1520 tok = ts->tok;
1521 } else if (isnum(ch) || ch == '.') {
1522 parse_number();
1523 } else if (ch == '\'') {
1524 tok = TOK_CCHAR;
1525 char_const:
1526 minp();
1527 tokc.i = getq();
1528 if (ch != '\'')
1529 expect("\'");
1530 minp();
1531 } else if (ch == '\"') {
1532 tok = TOK_STR;
1533 str_const:
1534 minp();
1535 q = token_buf;
1536 while (ch != '\"') {
1537 b = getq();
1538 if (ch == -1)
1539 error("unterminated string");
1540 if (q >= token_buf + STRING_MAX_SIZE)
1541 error("string too long");
1542 *q++ = b;
1544 *q = '\0';
1545 tokc.ts = tok_alloc(token_buf, q - token_buf);
1546 minp();
1547 } else {
1548 q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\247..\250##\266";
1549 /* two chars */
1550 tok = ch;
1551 cinp();
1552 while (*q) {
1553 if (*q == tok && q[1] == ch) {
1554 cinp();
1555 tok = q[2] & 0xff;
1556 /* three chars tests */
1557 if (tok == TOK_SHL | tok == TOK_SAR) {
1558 if (ch == '=') {
1559 tok = tok | 0x80;
1560 cinp();
1562 } else if (tok == TOK_DOTS) {
1563 if (ch != '.')
1564 error("parse error");
1565 cinp();
1567 return;
1569 q = q + 3;
1571 /* single char substitutions */
1572 if (tok == '<')
1573 tok = TOK_LT;
1574 else if (tok == '>')
1575 tok = TOK_GT;
1579 /* return next token without macro substitution. Can read input from
1580 macro_ptr buffer */
1581 void next_nomacro()
1583 if (macro_ptr) {
1584 tok = *macro_ptr;
1585 if (tok)
1586 tok = tok_get(&macro_ptr, &tokc);
1587 } else {
1588 next_nomacro1();
1592 /* substitute args in macro_str and return allocated string */
1593 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
1595 int *st, last_tok, t, notfirst, *str, len;
1596 Sym *s;
1597 TokenSym *ts;
1598 CValue cval;
1600 str = NULL;
1601 len = 0;
1602 last_tok = 0;
1603 while(1) {
1604 t = tok_get(&macro_str, &cval);
1605 if (!t)
1606 break;
1607 if (t == '#') {
1608 /* stringize */
1609 t = tok_get(&macro_str, &cval);
1610 if (!t)
1611 break;
1612 s = sym_find2(args, t);
1613 if (s) {
1614 token_buf[0] = '\0';
1615 st = (int *)s->c;
1616 /* XXX: buffer overflow */
1617 notfirst = 0;
1618 while (*st) {
1619 if (notfirst)
1620 strcat(token_buf, " ");
1621 t = tok_get(&st, &cval);
1622 strcat(token_buf, get_tok_str(t, &cval));
1623 notfirst = 1;
1625 #ifdef PP_DEBUG
1626 printf("stringize: %s\n", token_buf);
1627 #endif
1628 /* add string */
1629 ts = tok_alloc(token_buf, 0);
1630 cval.ts = ts;
1631 tok_add2(&str, &len, TOK_STR, &cval);
1632 } else {
1633 tok_add2(&str, &len, t, &cval);
1635 } else if (t >= TOK_IDENT) {
1636 s = sym_find2(args, t);
1637 if (s) {
1638 st = (int *)s->c;
1639 /* if '##' is present before or after , no arg substitution */
1640 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
1641 while (*st)
1642 tok_add(&str, &len, *st++);
1643 } else {
1644 macro_subst(&str, &len, nested_list, st);
1646 } else {
1647 tok_add(&str, &len, t);
1649 } else {
1650 tok_add2(&str, &len, t, &cval);
1652 last_tok = t;
1654 tok_add(&str, &len, 0);
1655 return str;
1658 /* handle the '##' operator */
1659 int *macro_twosharps(int *macro_str)
1661 TokenSym *ts;
1662 int *macro_str1, macro_str1_len, *macro_ptr1;
1663 int t;
1664 char *p;
1665 CValue cval;
1667 macro_str1 = NULL;
1668 macro_str1_len = 0;
1669 tok = 0;
1670 while (1) {
1671 next_nomacro();
1672 if (tok == 0)
1673 break;
1674 while (*macro_ptr == TOK_TWOSHARPS) {
1675 macro_ptr++;
1676 macro_ptr1 = macro_ptr;
1677 t = *macro_ptr;
1678 if (t) {
1679 t = tok_get(&macro_ptr, &cval);
1680 /* XXX: we handle only most common cases:
1681 ident + ident or ident + number */
1682 if (tok >= TOK_IDENT &&
1683 (t >= TOK_IDENT || t == TOK_NUM)) {
1684 /* XXX: buffer overflow */
1685 p = get_tok_str(tok, &tokc);
1686 strcpy(token_buf, p);
1687 p = get_tok_str(t, &cval);
1688 strcat(token_buf, p);
1689 ts = tok_alloc(token_buf, 0);
1690 tok = ts->tok; /* modify current token */
1691 } else {
1692 /* cannot merge tokens: skip '##' */
1693 macro_ptr = macro_ptr1;
1694 break;
1698 tok_add2(&macro_str1, &macro_str1_len, tok, &tokc);
1700 tok_add(&macro_str1, &macro_str1_len, 0);
1701 return macro_str1;
1706 /* do macro substitution of macro_str and add result to
1707 (tok_str,tok_len). If macro_str is NULL, then input stream token is
1708 substituted. 'nested_list' is the list of all macros we got inside
1709 to avoid recursing. */
1710 void macro_subst(int **tok_str, int *tok_len,
1711 Sym **nested_list, int *macro_str)
1713 Sym *s, *args, *sa, *sa1;
1714 int *str, parlevel, len, *mstr, t, *saved_macro_ptr;
1715 int mstr_allocated, *macro_str1;
1716 CValue cval;
1718 saved_macro_ptr = macro_ptr;
1719 macro_ptr = macro_str;
1720 macro_str1 = NULL;
1721 if (macro_str) {
1722 /* first scan for '##' operator handling */
1723 macro_str1 = macro_twosharps(macro_str);
1724 macro_ptr = macro_str1;
1727 while (1) {
1728 next_nomacro();
1729 if (tok == 0)
1730 break;
1731 /* special macros */
1732 if (tok == TOK___LINE__) {
1733 cval.i = line_num;
1734 tok_add2(tok_str, tok_len, TOK_NUM, &cval);
1735 } else if (tok == TOK___FILE__) {
1736 cval.ts = tok_alloc(filename, 0);
1737 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1738 } else if (tok == TOK___DATE__) {
1739 cval.ts = tok_alloc("Jan 1 1970", 0);
1740 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1741 } else if (tok == TOK___TIME__) {
1742 cval.ts = tok_alloc("00:00:00", 0);
1743 tok_add2(tok_str, tok_len, TOK_STR, &cval);
1744 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
1745 /* if symbol is a macro, prepare substitution */
1746 /* if nested substitution, do nothing */
1747 if (sym_find2(*nested_list, tok))
1748 goto no_subst;
1749 mstr = (int *)s->c;
1750 mstr_allocated = 0;
1751 if (s->t == MACRO_FUNC) {
1752 /* NOTE: we do not use next_nomacro to avoid eating the
1753 next token. XXX: find better solution */
1754 if (macro_ptr) {
1755 t = *macro_ptr;
1756 } else {
1757 while (ch == ' ' || ch == '\t' || ch == '\n')
1758 cinp();
1759 t = ch;
1761 if (t != '(') /* no macro subst */
1762 goto no_subst;
1764 /* argument macro */
1765 next_nomacro();
1766 next_nomacro();
1767 args = NULL;
1768 sa = s->next;
1769 while (tok != ')' && sa) {
1770 len = 0;
1771 str = NULL;
1772 parlevel = 0;
1773 while ((parlevel > 0 ||
1774 (tok != ')' &&
1775 (tok != ',' ||
1776 sa->v == (TOK___VA_ARGS__ | SYM_FIELD)))) &&
1777 tok != -1) {
1778 if (tok == '(')
1779 parlevel++;
1780 else if (tok == ')')
1781 parlevel--;
1782 tok_add2(&str, &len, tok, &tokc);
1783 next_nomacro();
1785 tok_add(&str, &len, 0);
1786 sym_push2(&args, sa->v & ~SYM_FIELD, 0, (int)str);
1787 if (tok != ',')
1788 break;
1789 next_nomacro();
1790 sa = sa->next;
1792 if (tok != ')')
1793 expect(")");
1794 /* now subst each arg */
1795 mstr = macro_arg_subst(nested_list, mstr, args);
1796 /* free memory */
1797 sa = args;
1798 while (sa) {
1799 sa1 = sa->prev;
1800 free((int *)sa->c);
1801 free(sa);
1802 sa = sa1;
1804 mstr_allocated = 1;
1806 sym_push2(nested_list, s->v, 0, 0);
1807 macro_subst(tok_str, tok_len, nested_list, mstr);
1808 /* pop nested defined symbol */
1809 sa1 = *nested_list;
1810 *nested_list = sa1->prev;
1811 free(sa1);
1812 if (mstr_allocated)
1813 free(mstr);
1814 } else {
1815 no_subst:
1816 /* no need to add if reading input stream */
1817 if (!macro_str)
1818 return;
1819 tok_add2(tok_str, tok_len, tok, &tokc);
1821 /* only replace one macro while parsing input stream */
1822 if (!macro_str)
1823 return;
1825 macro_ptr = saved_macro_ptr;
1826 if (macro_str1)
1827 free(macro_str1);
1830 /* return next token with macro substitution */
1831 void next(void)
1833 int len, *ptr;
1834 Sym *nested_list;
1836 /* special 'ungettok' case for label parsing */
1837 if (tok1) {
1838 tok = tok1;
1839 tokc = tok1c;
1840 tok1 = 0;
1841 } else {
1842 redo:
1843 if (!macro_ptr) {
1844 /* if not reading from macro substuted string, then try to substitute */
1845 len = 0;
1846 ptr = NULL;
1847 nested_list = NULL;
1848 macro_subst(&ptr, &len, &nested_list, NULL);
1849 if (ptr) {
1850 tok_add(&ptr, &len, 0);
1851 macro_ptr = ptr;
1852 macro_ptr_allocated = ptr;
1853 goto redo;
1855 if (tok == 0)
1856 goto redo;
1857 } else {
1858 next_nomacro();
1859 if (tok == 0) {
1860 /* end of macro string: free it */
1861 free(macro_ptr_allocated);
1862 macro_ptr = NULL;
1863 goto redo;
1867 #if defined(DEBUG)
1868 printf("token = %s\n", get_tok_str(tok, tokc));
1869 #endif
1872 void swap(int *p, int *q)
1874 int t;
1875 t = *p;
1876 *p = *q;
1877 *q = t;
1880 void vsetc(int t, int r, CValue *vc)
1882 if (vtop >= vstack + VSTACK_SIZE)
1883 error("memory full");
1884 /* cannot let cpu flags if other instruction are generated */
1885 /* XXX: VT_JMP test too ? */
1886 if ((vtop->r & VT_VALMASK) == VT_CMP)
1887 gv();
1888 vtop++;
1889 vtop->t = t;
1890 vtop->r = r;
1891 vtop->c = *vc;
1894 /* push integer constant */
1895 void vpushi(int v)
1897 CValue cval;
1898 cval.i = v;
1899 vsetc(VT_INT, VT_CONST, &cval);
1902 void vset(int t, int r, int v)
1904 CValue cval;
1906 cval.i = v;
1907 vsetc(t, r, &cval);
1910 void vswap(void)
1912 SValue tmp;
1914 tmp = vtop[0];
1915 vtop[0] = vtop[-1];
1916 vtop[-1] = tmp;
1919 void vdup(void)
1921 if (vtop >= vstack + VSTACK_SIZE)
1922 error("memory full");
1923 vtop++;
1924 *vtop = vtop[-1];
1927 int save_reg_forced(int r)
1929 int i, l, t;
1930 SValue *p, sv;
1932 /* store register */
1933 loc = (loc - 4) & -3;
1934 sv.t = VT_INT;
1935 sv.r = VT_LOCAL | VT_LVAL;
1936 sv.c.ul = loc;
1937 store(r, &sv);
1938 l = loc;
1940 /* modify all stack values */
1941 for(p=vstack;p<=vtop;p++) {
1942 i = p->r & VT_VALMASK;
1943 if (i == r) {
1944 if (p->r & VT_LVAL)
1945 t = VT_LLOCAL;
1946 else
1947 t = VT_LOCAL;
1948 p->r = VT_LVAL | t;
1949 p->c.ul = l;
1952 return l;
1955 /* save r to memory. and mark it as being free */
1956 void save_reg(int r)
1958 int i;
1959 SValue *p;
1961 /* modify all stack values */
1962 for(p=vstack;p<=vtop;p++) {
1963 i = p->r & VT_VALMASK;
1964 if (i == r) {
1965 save_reg_forced(r);
1966 break;
1971 /* find a free register of class 'rc'. If none, save one register */
1972 int get_reg(int rc)
1974 int r, i;
1975 SValue *p;
1977 /* find a free register */
1978 for(r=0;r<NB_REGS;r++) {
1979 if (reg_classes[r] & rc) {
1980 for(p=vstack;p<=vtop;p++) {
1981 i = p->r & VT_VALMASK;
1982 if (i == r)
1983 goto notfound;
1985 return r;
1987 notfound: ;
1990 /* no register left : free the first one on the stack (very
1991 important to start from the bottom to ensure that we don't
1992 spill registers used in gen_op()) */
1993 for(p=vstack;p<=vtop;p++) {
1994 r = p->r & VT_VALMASK;
1995 if (r < VT_CONST && (reg_classes[r] & rc)) {
1996 save_reg(r);
1997 break;
2000 return r;
2003 void save_regs(void)
2005 int r;
2006 SValue *p;
2008 for(p=vstack;p<=vtop;p++) {
2009 r = p->r & VT_VALMASK;
2010 if (r < VT_CONST) {
2011 save_reg(r);
2016 /* move register 's' to 'r', and flush previous value of r to memory
2017 if needed */
2018 void move_reg(int r, int s)
2020 SValue sv;
2022 if (r != s) {
2023 save_reg(r);
2024 sv.t = VT_INT;
2025 sv.r = s;
2026 sv.c.ul = 0;
2027 load(r, &sv);
2031 /* convert a (vtop->t, vtop->c) in register. lvalues are converted as
2032 values. Cannot be used if cannot be converted to register value
2033 (such as structures). */
2034 int gv(void)
2036 int r, bit_pos, bit_size, rc, size, align, i;
2038 /* NOTE: get_reg can modify vstack[] */
2039 if (vtop->t & VT_BITFIELD) {
2040 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
2041 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2042 /* remove bit field info to avoid loops */
2043 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2044 /* generate shifts */
2045 vpushi(32 - (bit_pos + bit_size));
2046 gen_op(TOK_SHL);
2047 vpushi(32 - bit_size);
2048 /* NOTE: transformed to SHR if unsigned */
2049 gen_op(TOK_SAR);
2050 r = gv();
2051 } else {
2052 if (is_float(vtop->t) &&
2053 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2054 /* CPUs usually cannot use float constants, so we store them
2055 generically in data segment */
2056 size = type_size(vtop->t, &align);
2057 glo = (glo + align - 1) & -align;
2058 /* XXX: not portable yet */
2059 size = size >> 2;
2060 for(i=0;i<size;i++)
2061 ((int *)glo)[i] = vtop->c.tab[i];
2062 vtop->r |= VT_LVAL;
2063 vtop->c.ul = glo;
2064 glo += size << 2;
2066 r = vtop->r & VT_VALMASK;
2067 if (r >= VT_CONST || (vtop->r & VT_LVAL)) {
2068 if (is_float(vtop->t))
2069 rc = REG_CLASS_FLOAT;
2070 else
2071 rc = REG_CLASS_INT;
2072 r = get_reg(rc);
2074 load(r, vtop);
2075 vtop->r = r;
2077 return r;
2080 /* handle constant optimizations and various machine independant opt */
2081 void gen_opc(int op)
2083 int fc, c1, c2, n;
2084 SValue *v1, *v2;
2086 v1 = vtop - 1;
2087 v2 = vtop;
2088 /* currently, we cannot do computations with forward symbols */
2089 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2090 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2091 if (c1 && c2) {
2092 fc = v2->c.i;
2093 switch(op) {
2094 case '+': v1->c.i += fc; break;
2095 case '-': v1->c.i -= fc; break;
2096 case '&': v1->c.i &= fc; break;
2097 case '^': v1->c.i ^= fc; break;
2098 case '|': v1->c.i |= fc; break;
2099 case '*': v1->c.i *= fc; break;
2100 case TOK_PDIV:
2101 case '/': v1->c.i /= fc; break; /* XXX: zero case ? */
2102 case '%': v1->c.i %= fc; break; /* XXX: zero case ? */
2103 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break; /* XXX: zero case ? */
2104 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break; /* XXX: zero case ? */
2105 case TOK_SHL: v1->c.i <<= fc; break;
2106 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
2107 case TOK_SAR: v1->c.i >>= fc; break;
2108 /* tests */
2109 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
2110 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
2111 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
2112 case TOK_NE: v1->c.i = v1->c.i != fc; break;
2113 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
2114 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
2115 case TOK_LT: v1->c.i = v1->c.i < fc; break;
2116 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
2117 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
2118 case TOK_GT: v1->c.i = v1->c.i > fc; break;
2119 /* logical */
2120 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
2121 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
2122 default:
2123 goto general_case;
2125 vtop--;
2126 } else {
2127 /* if commutative ops, put c2 as constant */
2128 if (c1 && (op == '+' || op == '&' || op == '^' ||
2129 op == '|' || op == '*')) {
2130 vswap();
2131 swap(&c1, &c2);
2133 fc = vtop->c.i;
2134 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2135 op == TOK_PDIV) &&
2136 fc == 1) ||
2137 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2138 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2139 fc == 0) ||
2140 (op == '&' &&
2141 fc == -1))) {
2142 /* nothing to do */
2143 vtop--;
2144 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2145 /* try to use shifts instead of muls or divs */
2146 if (fc > 0 && (fc & (fc - 1)) == 0) {
2147 n = -1;
2148 while (fc) {
2149 fc >>= 1;
2150 n++;
2152 vtop->c.i = n;
2153 if (op == '*')
2154 op = TOK_SHL;
2155 else if (op == TOK_PDIV)
2156 op = TOK_SAR;
2157 else
2158 op = TOK_SHR;
2160 goto general_case;
2161 } else {
2162 general_case:
2163 /* call low level op generator */
2164 /* XXX: remove explicit registers */
2165 gen_opi(op);
2170 int pointed_size(int t)
2172 return type_size(pointed_type(t), &t);
2175 /* generic gen_op: handles types problems */
2176 void gen_op(int op)
2178 int u, t1, t2, bt1, bt2, t;
2180 t1 = vtop[-1].t;
2181 t2 = vtop[0].t;
2182 bt1 = t1 & VT_BTYPE;
2183 bt2 = t2 & VT_BTYPE;
2185 if (is_float(bt1) || is_float(bt2)) {
2186 /* compute bigger type and do implicit casts */
2187 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
2188 t = VT_LDOUBLE;
2189 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
2190 t = VT_DOUBLE;
2191 } else {
2192 t = VT_FLOAT;
2194 if (op != '+' && op != '-' && op != '*' && op != '/' &&
2195 op < TOK_EQ || op > TOK_GT)
2196 error("invalid operands for binary operation");
2197 if (bt1 != t) {
2198 vswap();
2199 gen_cast(t);
2200 vswap();
2202 if (bt2 != t) {
2203 gen_cast(t);
2205 gen_opf(op);
2206 if (op >= TOK_EQ && op <= TOK_GT) {
2207 /* the result is an int */
2208 vtop->t = VT_INT;
2209 } else {
2210 vtop->t = t;
2212 } else if (op == '+' || op == '-') {
2213 if ((t1 & VT_BTYPE) == VT_PTR &&
2214 (t2 & VT_BTYPE) == VT_PTR) {
2215 if (op != '-')
2216 error("invalid type");
2217 /* XXX: check that types are compatible */
2218 u = pointed_size(t1);
2219 gen_opc(op);
2220 /* set to integer type */
2221 vtop->t = VT_INT;
2222 vpushi(u);
2223 gen_op(TOK_PDIV);
2224 } else if ((t1 & VT_BTYPE) == VT_PTR ||
2225 (t2 & VT_BTYPE) == VT_PTR) {
2226 if ((t2 & VT_BTYPE) == VT_PTR) {
2227 vswap();
2228 swap(&t1, &t2);
2230 /* stack-4 contains pointer, stack-2 value to add */
2231 vpushi(pointed_size(vtop[-1].t));
2232 gen_op('*');
2233 gen_opc(op);
2234 /* put again type if gen_opc() swaped operands */
2235 vtop->t = t1;
2236 } else {
2237 gen_opc(op);
2239 } else {
2240 /* XXX: test types and compute returned value */
2241 if ((t1 | t2) & VT_UNSIGNED ||
2242 (t1 & VT_BTYPE) == VT_PTR ||
2243 (t2 & VT_BTYPE) == VT_PTR) {
2244 if (op == TOK_SAR)
2245 op = TOK_SHR;
2246 else if (op == '/')
2247 op = TOK_UDIV;
2248 else if (op == '%')
2249 op = TOK_UMOD;
2250 else if (op == TOK_LT)
2251 op = TOK_ULT;
2252 else if (op == TOK_GT)
2253 op = TOK_UGT;
2254 else if (op == TOK_LE)
2255 op = TOK_ULE;
2256 else if (op == TOK_GE)
2257 op = TOK_UGE;
2259 gen_opc(op);
2263 /* cast 'vtop' to 't' type */
2264 void gen_cast(int t)
2266 int bits, sbt, dbt, sf, df, c, st1, dt1;
2268 /* if not lvalue, then we convert now */
2269 dbt = t & VT_BTYPE;
2270 sbt = vtop->t & VT_BTYPE;
2271 if (sbt != dbt) {
2272 sf = is_float(sbt);
2273 df = is_float(dbt);
2274 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST;
2275 if (sf && df) {
2276 /* convert from fp to fp */
2277 if (c) {
2278 /* constant case: we can do it now */
2279 /* XXX: in ISOC, cannot do it if error in convert */
2280 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
2281 vtop->c.f = (float)vtop->c.d;
2282 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
2283 vtop->c.f = (float)vtop->c.ld;
2284 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
2285 vtop->c.d = (double)vtop->c.f;
2286 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
2287 vtop->c.d = (double)vtop->c.ld;
2288 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
2289 vtop->c.ld = (long double)vtop->c.f;
2290 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
2291 vtop->c.ld = (long double)vtop->c.d;
2292 } else {
2293 /* non constant case: generate code */
2294 gen_cvt_ftof(dbt);
2296 } else if (df) {
2297 /* convert int to fp */
2298 /* XXX: add const cases */
2299 st1 = vtop->t & (VT_BTYPE | VT_UNSIGNED);
2300 if (c) {
2301 switch(st1) {
2302 case VT_LLONG | VT_UNSIGNED:
2303 case VT_LLONG:
2304 /* well, currently not needed */
2305 goto do_itof;
2306 case VT_INT | VT_UNSIGNED:
2307 switch(dbt) {
2308 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
2309 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
2310 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
2312 break;
2313 default:
2314 switch(dbt) {
2315 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
2316 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
2317 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
2319 break;
2321 } else {
2322 do_itof:
2323 gen_cvt_itof(dbt);
2325 } else if (sf) {
2326 /* convert fp to int */
2327 dt1 = t & (VT_BTYPE | VT_UNSIGNED);
2328 /* we handle char/short/etc... with generic code */
2329 if (dt1 != VT_INT | VT_UNSIGNED &&
2330 dt1 != VT_LLONG | VT_UNSIGNED &&
2331 dt1 != VT_LLONG)
2332 dt1 = VT_INT;
2333 if (c) {
2334 switch(dt1) {
2335 case VT_LLONG | VT_UNSIGNED:
2336 case VT_LLONG:
2337 /* well, currently not needed */
2338 goto do_ftoi;
2339 case VT_INT | VT_UNSIGNED:
2340 switch(sbt) {
2341 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
2342 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
2343 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
2345 break;
2346 default:
2347 /* int case */
2348 switch(sbt) {
2349 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
2350 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
2351 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
2353 break;
2355 } else {
2356 do_ftoi:
2357 gen_cvt_ftoi(dt1);
2359 if (dt1 == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dt1) {
2360 /* additionnal cast for char/short/bool... */
2361 vtop->t = dt1;
2362 gen_cast(t);
2364 } else if (dbt == VT_BOOL) {
2365 vpushi(0);
2366 gen_op(TOK_NE);
2367 } else if ((dbt == VT_BYTE || dbt == VT_SHORT) &&
2368 !(vtop->r & VT_LVAL)) {
2369 /* no need to apply if lvalue because we do it while
2370 loading the value */
2371 if (dbt == VT_BYTE)
2372 bits = 8;
2373 else
2374 bits = 16;
2375 if (t & VT_UNSIGNED) {
2376 vpushi((1 << bits) - 1);
2377 gen_op('&');
2378 } else {
2379 bits = 32 - bits;
2380 vpushi(bits);
2381 gen_op(TOK_SHL);
2382 vpushi(bits);
2383 gen_op(TOK_SAR);
2387 vtop->t = t;
2390 /* return type size. Put alignment at 'a' */
2391 int type_size(int t, int *a)
2393 Sym *s;
2394 int bt;
2396 bt = t & VT_BTYPE;
2397 if (bt == VT_STRUCT) {
2398 /* struct/union */
2399 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
2400 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
2401 return s->c;
2402 } else if (bt == VT_PTR) {
2403 if (t & VT_ARRAY) {
2404 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
2405 return type_size(s->t, a) * s->c;
2406 } else {
2407 *a = PTR_SIZE;
2408 return PTR_SIZE;
2410 } else if (bt == VT_LDOUBLE) {
2411 *a = LDOUBLE_ALIGN;
2412 return LDOUBLE_SIZE;
2413 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2414 *a = 8;
2415 return 8;
2416 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2417 *a = 4;
2418 return 4;
2419 } else if (bt == VT_SHORT) {
2420 *a = 2;
2421 return 2;
2422 } else {
2423 /* char, void, function, _Bool */
2424 *a = 1;
2425 return 1;
2429 /* return the pointed type of t */
2430 int pointed_type(int t)
2432 Sym *s;
2433 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
2434 return s->t | (t & ~VT_TYPE);
2437 int mk_pointer(int t)
2439 int p;
2440 p = anon_sym++;
2441 sym_push(p, t, 0, -1);
2442 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
2445 int is_compatible_types(int t1, int t2)
2447 Sym *s1, *s2;
2448 int bt1, bt2;
2450 t1 &= VT_TYPE;
2451 t2 &= VT_TYPE;
2452 bt1 = t1 & VT_BTYPE;
2453 bt2 = t2 & VT_BTYPE;
2454 if (bt1 == VT_PTR) {
2455 t1 = pointed_type(t1);
2456 /* if function, then convert implicitely to function pointer */
2457 if (bt2 != VT_FUNC) {
2458 if (bt2 != VT_PTR)
2459 return 0;
2460 t2 = pointed_type(t2);
2462 /* void matches everything */
2463 t1 &= VT_TYPE;
2464 t2 &= VT_TYPE;
2465 if (t1 == VT_VOID || t2 == VT_VOID)
2466 return 1;
2467 return is_compatible_types(t1, t2);
2468 } else if (bt1 == VT_STRUCT) {
2469 return (t2 == t1);
2470 } else if (bt1 == VT_FUNC) {
2471 if (bt2 != VT_FUNC)
2472 return 0;
2473 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
2474 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
2475 if (!is_compatible_types(s1->t, s2->t))
2476 return 0;
2477 /* XXX: not complete */
2478 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2479 return 1;
2480 if (s1->c != s2->c)
2481 return 0;
2482 while (s1 != NULL) {
2483 if (s2 == NULL)
2484 return 0;
2485 if (!is_compatible_types(s1->t, s2->t))
2486 return 0;
2487 s1 = s1->next;
2488 s2 = s2->next;
2490 if (s2)
2491 return 0;
2492 return 1;
2493 } else {
2494 /* XXX: not complete */
2495 return 1;
2499 int check_assign_types(int t1, int t2)
2501 t1 &= VT_TYPE;
2502 t2 &= VT_TYPE;
2503 if ((t1 & VT_BTYPE) == VT_PTR &&
2504 (t2 & VT_BTYPE) == VT_FUNC) {
2505 return is_compatible_types(pointed_type(t1), t2);
2506 } else {
2507 return is_compatible_types(t1, t2);
2511 /* print a type. If 'varstr' is not NULL, then the variable is also
2512 printed in the type */
2513 /* XXX: add array and function pointers */
2514 /* XXX: buffer overflows */
2515 void type_to_str(char *buf, int buf_size,
2516 int t, const char *varstr)
2518 int bt, v;
2519 Sym *s, *sa;
2520 char buf1[256];
2522 t = t & VT_TYPE;
2523 bt = t & VT_BTYPE;
2524 buf[0] = '\0';
2525 if (t & VT_UNSIGNED)
2526 strcat(buf, "unsigned ");
2527 switch(bt) {
2528 case VT_VOID:
2529 strcat(buf, "void");
2530 break;
2531 case VT_BOOL:
2532 strcat(buf, "_Bool");
2533 break;
2534 case VT_BYTE:
2535 strcat(buf, "char");
2536 break;
2537 case VT_SHORT:
2538 strcat(buf, "short");
2539 break;
2540 case VT_INT:
2541 strcat(buf, "int");
2542 break;
2543 case VT_LONG:
2544 strcat(buf, "long");
2545 break;
2546 case VT_LLONG:
2547 strcat(buf, "long long");
2548 break;
2549 case VT_FLOAT:
2550 strcat(buf, "float");
2551 break;
2552 case VT_DOUBLE:
2553 strcat(buf, "double");
2554 break;
2555 case VT_LDOUBLE:
2556 strcat(buf, "long double");
2557 break;
2558 case VT_ENUM:
2559 case VT_STRUCT:
2560 if (bt == VT_STRUCT)
2561 strcat(buf, "struct ");
2562 else
2563 strcat(buf, "enum ");
2564 v = (unsigned)t >> VT_STRUCT_SHIFT;
2565 if (v >= SYM_FIRST_ANOM)
2566 strcat(buf, "<anonymous>");
2567 else
2568 strcat(buf, get_tok_str(v, NULL));
2569 break;
2570 case VT_FUNC:
2571 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
2572 type_to_str(buf, buf_size, s->t, varstr);
2573 strcat(buf, "(");
2574 sa = s->next;
2575 while (sa != NULL) {
2576 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
2577 strcat(buf, buf1);
2578 sa = sa->next;
2579 if (sa)
2580 strcat(buf, ", ");
2582 strcat(buf, ")");
2583 goto no_var;
2584 case VT_PTR:
2585 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
2586 strcpy(buf1, "*");
2587 if (varstr)
2588 strcat(buf1, varstr);
2589 type_to_str(buf, buf_size, s->t, buf1);
2590 goto no_var;
2592 if (varstr) {
2593 strcat(buf, " ");
2594 strcat(buf, varstr);
2596 no_var: ;
2601 /* verify type compatibility to store vtop in 'st' type, and generate
2602 casts if needed */
2603 void gen_assign_cast(int dt)
2605 int st;
2606 char buf1[256], buf2[256];
2608 st = vtop->t; /* destination type */
2609 if (!check_assign_types(dt, st)) {
2610 type_to_str(buf1, sizeof(buf1), st, NULL);
2611 type_to_str(buf2, sizeof(buf2), dt, NULL);
2612 error("cannot cast '%s' to '%s'", buf1, buf2);
2614 if ((dt & VT_BTYPE) == VT_BOOL || is_float(dt)) {
2615 gen_cast(dt & VT_BTYPE);
2620 /* store vtop in lvalue pushed on stack */
2621 void vstore(void)
2623 int ft, r, t, size, align, bit_size, bit_pos;
2624 GFuncContext gf;
2626 ft = vtop[-1].t;
2627 gen_assign_cast(ft & VT_TYPE);
2629 if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
2630 /* if structure, only generate pointer */
2631 /* structure assignment : generate memcpy */
2632 /* XXX: optimize if small size */
2634 vdup();
2635 gfunc_start(&gf);
2636 /* type size */
2637 size = type_size(vtop->t, &align);
2638 vpushi(size);
2639 gfunc_param(&gf);
2640 /* source */
2641 vtop->t = VT_INT;
2642 vtop->r &= ~VT_LVAL;
2643 gfunc_param(&gf);
2644 /* destination */
2645 vswap();
2646 vtop->t = VT_INT;
2647 vtop->r &= ~VT_LVAL;
2648 gfunc_param(&gf);
2650 save_regs();
2651 vpushi((int)&memcpy);
2652 gfunc_call(&gf);
2653 /* leave source on stack */
2654 } else if (ft & VT_BITFIELD) {
2655 /* bitfield store handling */
2656 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2657 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2658 /* remove bit field info to avoid loops */
2659 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2661 /* duplicate destination */
2662 vdup();
2663 vtop[-1] = vtop[-2];
2665 /* mask and shift source */
2666 vpushi((1 << bit_size) - 1);
2667 gen_op('&');
2668 vpushi(bit_pos);
2669 gen_op(TOK_SHL);
2670 /* load destination, mask and or with source */
2671 vswap();
2672 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2673 gen_op('&');
2674 gen_op('|');
2675 /* store result */
2676 vstore();
2677 } else {
2678 r = gv(); /* generate value */
2679 /* if lvalue was saved on stack, must read it */
2680 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2681 SValue sv;
2682 t = get_reg(REG_CLASS_INT);
2683 sv.t = VT_INT;
2684 sv.r = VT_LOCAL | VT_LVAL;
2685 sv.c.ul = vtop[-1].c.ul;
2686 load(t, &sv);
2687 vtop[-1].r = t | VT_LVAL;
2689 store(r, vtop - 1);
2690 vtop--;
2691 vtop->r = r;
2692 vtop->c.i = 0;
2696 /* post defines POST/PRE add. c is the token ++ or -- */
2697 void inc(int post, int c)
2699 int r, r1;
2700 SValue sv;
2702 test_lvalue();
2703 if (post)
2704 vdup(); /* room for returned value */
2705 vdup(); /* save lvalue */
2706 r = gv();
2707 if (post) {
2708 /* duplicate value */
2709 /* XXX: handle floats */
2710 r1 = get_reg(REG_CLASS_INT);
2711 sv.t = VT_INT;
2712 sv.r = r;
2713 sv.c.ul = 0;
2714 load(r1, &sv); /* move r to r1 */
2715 /* duplicates value */
2716 vtop[-2].r = r1;
2717 vtop[-2].c.i = 0;
2719 /* add constant */
2720 vpushi(c - TOK_MID);
2721 gen_op('+');
2722 vstore(); /* store value */
2723 if (post)
2724 vpop(); /* if post op, return saved value */
2727 /* enum/struct/union declaration */
2728 int struct_decl(int u)
2730 int a, t, b, v, size, align, maxalign, c, offset;
2731 int bit_size, bit_pos, bsize, bt, lbit_pos;
2732 Sym *s, *ss, **ps;
2734 a = tok; /* save decl type */
2735 next();
2736 if (tok != '{') {
2737 v = tok;
2738 next();
2739 /* struct already defined ? return it */
2740 /* XXX: check consistency */
2741 if (s = sym_find(v | SYM_STRUCT)) {
2742 if (s->t != a)
2743 error("invalid type");
2744 goto do_decl;
2746 } else {
2747 v = anon_sym++;
2749 s = sym_push(v | SYM_STRUCT, a, 0, 0);
2750 /* put struct/union/enum name in type */
2751 do_decl:
2752 u = u | (v << VT_STRUCT_SHIFT);
2754 if (tok == '{') {
2755 next();
2756 if (s->c)
2757 error("struct/union/enum already defined");
2758 /* cannot be empty */
2759 c = 0;
2760 maxalign = 0;
2761 ps = &s->next;
2762 bit_pos = 0;
2763 offset = 0;
2764 while (1) {
2765 if (a == TOK_ENUM) {
2766 v = tok;
2767 next();
2768 if (tok == '=') {
2769 next();
2770 c = expr_const();
2772 /* enum symbols have static storage */
2773 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
2774 if (tok == ',')
2775 next();
2776 c++;
2777 } else {
2778 parse_btype(&b);
2779 while (1) {
2780 bit_size = -1;
2781 v = 0;
2782 if (tok != ':') {
2783 t = type_decl(&v, b, TYPE_DIRECT);
2784 if ((t & VT_BTYPE) == VT_FUNC ||
2785 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
2786 error("invalid type for '%s'",
2787 get_tok_str(v, NULL));
2788 } else {
2789 t = b;
2791 if (tok == ':') {
2792 next();
2793 bit_size = expr_const();
2794 /* XXX: handle v = 0 case for messages */
2795 if (bit_size < 0)
2796 error("negative width in bit-field '%s'",
2797 get_tok_str(v, NULL));
2798 if (v && bit_size == 0)
2799 error("zero width for bit-field '%s'",
2800 get_tok_str(v, NULL));
2802 size = type_size(t, &align);
2803 lbit_pos = 0;
2804 if (bit_size >= 0) {
2805 bt = t & VT_BTYPE;
2806 if (bt != VT_INT &&
2807 bt != VT_BYTE &&
2808 bt != VT_SHORT)
2809 error("bitfields must have scalar type");
2810 bsize = size * 8;
2811 if (bit_size > bsize) {
2812 error("width of '%s' exceeds its type",
2813 get_tok_str(v, NULL));
2814 } else if (bit_size == bsize) {
2815 /* no need for bit fields */
2816 bit_pos = 0;
2817 } else if (bit_size == 0) {
2818 /* XXX: what to do if only padding in a
2819 structure ? */
2820 /* zero size: means to pad */
2821 if (bit_pos > 0)
2822 bit_pos = bsize;
2823 } else {
2824 /* we do not have enough room ? */
2825 if ((bit_pos + bit_size) > bsize)
2826 bit_pos = 0;
2827 lbit_pos = bit_pos;
2828 /* XXX: handle LSB first */
2829 t |= VT_BITFIELD |
2830 (bit_pos << VT_STRUCT_SHIFT) |
2831 (bit_size << (VT_STRUCT_SHIFT + 6));
2832 bit_pos += bit_size;
2834 } else {
2835 bit_pos = 0;
2837 if (v) {
2838 /* add new memory data only if starting
2839 bit field */
2840 if (lbit_pos == 0) {
2841 if (a == TOK_STRUCT) {
2842 c = (c + align - 1) & -align;
2843 offset = c;
2844 c += size;
2845 } else {
2846 offset = 0;
2847 if (size > c)
2848 c = size;
2850 if (align > maxalign)
2851 maxalign = align;
2853 #if 0
2854 printf("add field %s offset=%d",
2855 get_tok_str(v, NULL), offset);
2856 if (t & VT_BITFIELD) {
2857 printf(" pos=%d size=%d",
2858 (t >> VT_STRUCT_SHIFT) & 0x3f,
2859 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2861 printf("\n");
2862 #endif
2863 ss = sym_push(v | SYM_FIELD, t, 0, offset);
2864 *ps = ss;
2865 ps = &ss->next;
2867 if (tok == ';' || tok == -1)
2868 break;
2869 skip(',');
2871 skip(';');
2873 if (tok == '}')
2874 break;
2876 skip('}');
2877 /* size for struct/union, dummy for enum */
2878 s->c = (c + maxalign - 1) & -maxalign;
2880 return u;
2883 /* return 0 if no type declaration. otherwise, return the basic type
2884 and skip it.
2886 int parse_btype(int *type_ptr)
2888 int t, u, type_found;
2889 Sym *s;
2891 type_found = 0;
2892 t = 0;
2893 while(1) {
2894 switch(tok) {
2895 /* basic types */
2896 case TOK_CHAR:
2897 u = VT_BYTE;
2898 basic_type:
2899 next();
2900 basic_type1:
2901 if ((t & VT_BTYPE) != 0)
2902 error("too many basic types");
2903 t |= u;
2904 break;
2905 case TOK_VOID:
2906 u = VT_VOID;
2907 goto basic_type;
2908 case TOK_SHORT:
2909 u = VT_SHORT;
2910 goto basic_type;
2911 case TOK_INT:
2912 next();
2913 break;
2914 case TOK_LONG:
2915 next();
2916 if ((t & VT_BTYPE) == VT_DOUBLE) {
2917 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2918 } else if ((t & VT_BTYPE) == VT_LONG) {
2919 t = (t & ~VT_BTYPE) | VT_LLONG;
2920 } else {
2921 u = VT_LONG;
2922 goto basic_type1;
2924 break;
2925 case TOK_BOOL:
2926 u = VT_BOOL;
2927 goto basic_type;
2928 case TOK_FLOAT:
2929 u = VT_FLOAT;
2930 goto basic_type;
2931 case TOK_DOUBLE:
2932 next();
2933 if ((t & VT_BTYPE) == VT_LONG) {
2934 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2935 } else {
2936 u = VT_DOUBLE;
2937 goto basic_type1;
2939 break;
2940 case TOK_ENUM:
2941 u = struct_decl(VT_ENUM);
2942 goto basic_type1;
2943 case TOK_STRUCT:
2944 case TOK_UNION:
2945 u = struct_decl(VT_STRUCT);
2946 goto basic_type1;
2948 /* type modifiers */
2949 case TOK_CONST:
2950 case TOK_VOLATILE:
2951 case TOK_REGISTER:
2952 case TOK_SIGNED:
2953 case TOK_AUTO:
2954 case TOK_INLINE:
2955 case TOK_RESTRICT:
2956 next();
2957 break;
2958 case TOK_UNSIGNED:
2959 t |= VT_UNSIGNED;
2960 next();
2961 break;
2963 /* storage */
2964 case TOK_EXTERN:
2965 t |= VT_EXTERN;
2966 next();
2967 break;
2968 case TOK_STATIC:
2969 t |= VT_STATIC;
2970 next();
2971 break;
2972 case TOK_TYPEDEF:
2973 t |= VT_TYPEDEF;
2974 next();
2975 break;
2976 default:
2977 s = sym_find(tok);
2978 if (!s || !(s->t & VT_TYPEDEF))
2979 goto the_end;
2980 t |= (s->t & ~VT_TYPEDEF);
2981 next();
2982 break;
2984 type_found = 1;
2986 the_end:
2987 /* long is never used as type */
2988 if ((t & VT_BTYPE) == VT_LONG)
2989 t = (t & ~VT_BTYPE) | VT_INT;
2990 *type_ptr = t;
2991 return type_found;
2994 int post_type(int t)
2996 int p, n, pt, l, t1;
2997 Sym **plast, *s, *first;
2999 if (tok == '(') {
3000 /* function declaration */
3001 next();
3002 l = 0;
3003 first = NULL;
3004 plast = &first;
3005 while (tok != ')') {
3006 /* read param name and compute offset */
3007 if (l != FUNC_OLD) {
3008 if (!parse_btype(&pt)) {
3009 if (l) {
3010 error("invalid type");
3011 } else {
3012 l = FUNC_OLD;
3013 goto old_proto;
3016 l = FUNC_NEW;
3017 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
3018 break;
3019 pt = type_decl(&n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
3020 if ((pt & VT_BTYPE) == VT_VOID)
3021 error("parameter declared as void");
3022 } else {
3023 old_proto:
3024 n = tok;
3025 pt = VT_INT;
3026 next();
3028 /* array must be transformed to pointer according to ANSI C */
3029 pt &= ~VT_ARRAY;
3030 s = sym_push(n | SYM_FIELD, pt, 0, 0);
3031 *plast = s;
3032 plast = &s->next;
3033 if (tok == ',') {
3034 next();
3035 if (l == FUNC_NEW && tok == TOK_DOTS) {
3036 l = FUNC_ELLIPSIS;
3037 next();
3038 break;
3042 /* if no parameters, then old type prototype */
3043 if (l == 0)
3044 l = FUNC_OLD;
3045 skip(')');
3046 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
3047 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN));
3048 /* we push a anonymous symbol which will contain the function prototype */
3049 p = anon_sym++;
3050 s = sym_push(p, t, 0, l);
3051 s->next = first;
3052 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
3053 } else if (tok == '[') {
3054 /* array definition */
3055 next();
3056 n = -1;
3057 if (tok != ']') {
3058 n = expr_const();
3059 if (n < 0)
3060 error("invalid array size");
3062 skip(']');
3063 /* parse next post type */
3064 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
3065 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN));
3067 /* we push a anonymous symbol which will contain the array
3068 element type */
3069 p = anon_sym++;
3070 sym_push(p, t, 0, n);
3071 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
3073 return t;
3076 /* Read a type declaration (except basic type), and return the
3077 type. If v is true, then also put variable name in 'vtop->c' */
3078 int type_decl(int *v, int t, int td)
3080 int u, p;
3081 Sym *s;
3083 while (tok == '*') {
3084 next();
3085 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
3086 next();
3087 t = mk_pointer(t);
3090 /* recursive type */
3091 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3092 if (tok == '(') {
3093 next();
3094 u = type_decl(v, 0, td);
3095 skip(')');
3096 } else {
3097 u = 0;
3098 /* type identifier */
3099 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3100 *v = tok;
3101 next();
3102 } else {
3103 if (!(td & TYPE_ABSTRACT))
3104 expect("identifier");
3105 *v = 0;
3108 /* append t at the end of u */
3109 t = post_type(t);
3110 if (!u)
3111 return t;
3112 p = u;
3113 while(1) {
3114 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
3115 p = s->t;
3116 if (!p) {
3117 s->t = t;
3118 break;
3121 return u;
3124 /* define a new external reference to a function 'v' of type 'u' */
3125 Sym *external_sym(int v, int u, int r)
3127 Sym *s;
3128 s = sym_find(v);
3129 if (!s) {
3130 /* push forward reference */
3131 s = sym_push1(&global_stack,
3132 v, u, 0);
3133 s->r = r | VT_CONST | VT_FORWARD;
3135 return s;
3138 void indir(void)
3140 if (vtop->r & VT_LVAL)
3141 gv();
3142 if ((vtop->t & VT_BTYPE) != VT_PTR)
3143 expect("pointer");
3144 vtop->t = pointed_type(vtop->t);
3145 if (!(vtop->t & VT_ARRAY)) /* an array is never an lvalue */
3146 vtop->r |= VT_LVAL;
3149 /* pass a parameter to a function and do type checking and casting */
3150 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
3152 int func_type;
3153 func_type = func->c;
3154 if (func_type == FUNC_OLD ||
3155 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3156 /* default casting : only need to convert float to double */
3157 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
3158 gen_cast(VT_DOUBLE);
3159 } else if (arg == NULL) {
3160 error("too many arguments to function");
3161 } else {
3162 gen_assign_cast(arg->t);
3164 gfunc_param(gf);
3167 void unary(void)
3169 int n, t, ft, fc, p, align, size, r;
3170 Sym *s;
3171 GFuncContext gf;
3173 if (tok == TOK_NUM || tok == TOK_CCHAR || tok == TOK_LCHAR) {
3174 vpushi(tokc.i);
3175 next();
3176 } else if (tok == TOK_CFLOAT) {
3177 vsetc(VT_FLOAT, VT_CONST, &tokc);
3178 next();
3179 } else if (tok == TOK_CDOUBLE) {
3180 vsetc(VT_DOUBLE, VT_CONST, &tokc);
3181 next();
3182 } else if (tok == TOK_CLDOUBLE) {
3183 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
3184 next();
3185 } else if (tok == TOK___FUNC__) {
3186 /* special function name identifier */
3187 /* generate (char *) type */
3188 vset(mk_pointer(VT_BYTE), VT_CONST, glo);
3189 strcpy((void *)glo, funcname);
3190 glo += strlen(funcname) + 1;
3191 next();
3192 } else if (tok == TOK_LSTR) {
3193 t = VT_INT;
3194 goto str_init;
3195 } else if (tok == TOK_STR) {
3196 /* string parsing */
3197 t = VT_BYTE;
3198 str_init:
3199 type_size(t, &align);
3200 glo = (glo + align - 1) & -align;
3201 fc = glo;
3202 /* we must declare it as an array first to use initializer parser */
3203 t = VT_ARRAY | mk_pointer(t);
3204 decl_initializer(t, VT_CONST, glo, 1, 0);
3205 glo += type_size(t, &align);
3206 /* put it as pointer */
3207 vset(t & ~VT_ARRAY, VT_CONST, fc);
3208 } else {
3209 t = tok;
3210 next();
3211 if (t == '(') {
3212 /* cast ? */
3213 if (parse_btype(&t)) {
3214 ft = type_decl(&n, t, TYPE_ABSTRACT);
3215 skip(')');
3216 /* check ISOC99 compound literal */
3217 if (tok == '{') {
3218 /* data is allocated locally by default */
3219 if (global_expr)
3220 r = VT_CONST;
3221 else
3222 r = VT_LOCAL;
3223 /* all except arrays are lvalues */
3224 if (!(ft & VT_ARRAY))
3225 r |= VT_LVAL;
3226 fc = decl_initializer_alloc(ft, r, 1);
3227 vset(ft, r, fc);
3228 } else {
3229 unary();
3230 gen_cast(ft);
3232 } else {
3233 gexpr();
3234 skip(')');
3236 } else if (t == '*') {
3237 unary();
3238 indir();
3239 } else if (t == '&') {
3240 unary();
3241 /* functions names must be treated as function pointers,
3242 except for unary '&' and sizeof. Since we consider that
3243 functions are not lvalues, we only have to handle it
3244 there and in function calls. */
3245 if ((vtop->t & VT_BTYPE) != VT_FUNC)
3246 test_lvalue();
3247 vtop->t = mk_pointer(vtop->t);
3248 vtop->r &= ~VT_LVAL;
3249 } else
3250 if (t == '!') {
3251 unary();
3252 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
3253 vtop->c.i = !vtop->c.i;
3254 else if ((vtop->r & VT_VALMASK) == VT_CMP)
3255 vtop->c.i = vtop->c.i ^ 1;
3256 else
3257 vset(VT_INT, VT_JMP, gtst(1, 0));
3258 } else
3259 if (t == '~') {
3260 unary();
3261 vpushi(-1);
3262 gen_op('^');
3263 } else
3264 if (t == '+') {
3265 unary();
3266 } else
3267 if (t == TOK_SIZEOF) {
3268 if (tok == '(') {
3269 next();
3270 if (parse_btype(&t)) {
3271 t = type_decl(&n, t, TYPE_ABSTRACT);
3272 } else {
3273 /* XXX: some code could be generated: add eval
3274 flag */
3275 gexpr();
3276 t = vtop->t;
3277 vpop();
3279 skip(')');
3280 } else {
3281 unary();
3282 t = vtop->t;
3283 vpop();
3285 vpushi(type_size(t, &t));
3286 } else
3287 if (t == TOK_INC || t == TOK_DEC) {
3288 unary();
3289 inc(0, t);
3290 } else if (t == '-') {
3291 vpushi(0);
3292 unary();
3293 gen_op('-');
3294 } else
3296 s = sym_find(t);
3297 if (!s) {
3298 if (tok != '(')
3299 error("'%s' undeclared", get_tok_str(t, NULL));
3300 /* for simple function calls, we tolerate undeclared
3301 external reference */
3302 p = anon_sym++;
3303 sym_push1(&global_stack, p, 0, FUNC_OLD);
3304 /* int() function */
3305 s = external_sym(t, VT_FUNC | (p << VT_STRUCT_SHIFT), 0);
3307 vset(s->t, s->r, s->c);
3308 /* if forward reference, we must point to s */
3309 if (vtop->r & VT_FORWARD)
3310 vtop->c.sym = s;
3314 /* post operations */
3315 while (1) {
3316 if (tok == TOK_INC | tok == TOK_DEC) {
3317 inc(1, tok);
3318 next();
3319 } else if (tok == '.' | tok == TOK_ARROW) {
3320 /* field */
3321 if (tok == TOK_ARROW)
3322 indir();
3323 test_lvalue();
3324 vtop->r &= ~VT_LVAL;
3325 next();
3326 /* expect pointer on structure */
3327 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
3328 expect("struct or union");
3329 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3330 /* find field */
3331 tok |= SYM_FIELD;
3332 while (s = s->next) {
3333 if (s->v == tok)
3334 break;
3336 if (!s)
3337 error("field not found");
3338 /* add field offset to pointer */
3339 vtop->t = VT_INT; /* change type to int */
3340 vpushi(s->c);
3341 gen_op('+');
3342 /* change type to field type, and set to lvalue */
3343 vtop->t = s->t;
3344 /* an array is never an lvalue */
3345 if (!(vtop->t & VT_ARRAY))
3346 vtop->r |= VT_LVAL;
3347 next();
3348 } else if (tok == '[') {
3349 next();
3350 gexpr();
3351 gen_op('+');
3352 indir();
3353 skip(']');
3354 } else if (tok == '(') {
3355 SValue ret;
3356 Sym *sa;
3358 /* function call */
3359 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
3360 /* pointer test (no array accepted) */
3361 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3362 vtop->t = pointed_type(vtop->t);
3363 if ((vtop->t & VT_BTYPE) != VT_FUNC)
3364 goto error_func;
3365 } else {
3366 error_func:
3367 expect("function pointer");
3369 } else {
3370 vtop->r &= ~VT_LVAL; /* no lvalue */
3372 /* get return type */
3373 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
3374 save_regs(); /* save used temporary registers */
3375 gfunc_start(&gf);
3376 next();
3377 sa = s->next; /* first parameter */
3378 #ifdef INVERT_FUNC_PARAMS
3380 int *str, len, parlevel, *saved_macro_ptr;
3381 Sym *args, *s1;
3383 /* read each argument and store it on a stack */
3384 /* XXX: merge it with macro args ? */
3385 args = NULL;
3386 while (tok != ')') {
3387 len = 0;
3388 str = NULL;
3389 parlevel = 0;
3390 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
3391 tok != -1) {
3392 if (tok == '(')
3393 parlevel++;
3394 else if (tok == ')')
3395 parlevel--;
3396 tok_add2(&str, &len, tok, &tokc);
3397 next();
3399 tok_add(&str, &len, -1); /* end of file added */
3400 tok_add(&str, &len, 0);
3401 s1 = sym_push2(&args, 0, 0, (int)str);
3402 s1->next = sa; /* add reference to argument */
3403 if (sa)
3404 sa = sa->next;
3405 if (tok != ',')
3406 break;
3407 next();
3409 if (tok != ')')
3410 expect(")");
3412 /* now generate code in reverse order by reading the stack */
3413 saved_macro_ptr = macro_ptr;
3414 while (args) {
3415 macro_ptr = (int *)args->c;
3416 next();
3417 expr_eq();
3418 if (tok != -1)
3419 expect("',' or ')'");
3420 gfunc_param_typed(&gf, s, args->next);
3421 s1 = args->prev;
3422 free((int *)args->c);
3423 free(args);
3424 args = s1;
3426 macro_ptr = saved_macro_ptr;
3427 /* restore token */
3428 tok = ')';
3430 #endif
3431 /* compute first implicit argument if a structure is returned */
3432 if ((s->t & VT_BTYPE) == VT_STRUCT) {
3433 /* get some space for the returned structure */
3434 size = type_size(s->t, &align);
3435 loc = (loc - size) & -align;
3436 ret.t = s->t;
3437 ret.r = VT_LOCAL | VT_LVAL;
3438 /* pass it as 'int' to avoid structure arg passing
3439 problems */
3440 vset(VT_INT, VT_LOCAL, loc);
3441 ret.c = vtop->c;
3442 gfunc_param(&gf);
3443 } else {
3444 ret.t = s->t;
3445 ret.r = FUNC_RET_REG; /* return in register */
3446 ret.c.i = 0;
3448 #ifndef INVERT_FUNC_PARAMS
3449 while (tok != ')') {
3450 expr_eq();
3451 gfunc_param_typed(&gf, s, sa);
3452 if (sa)
3453 sa = sa->next;
3454 if (tok == ',')
3455 next();
3457 #endif
3458 if (sa)
3459 error("too few arguments to function");
3460 skip(')');
3461 gfunc_call(&gf);
3462 /* return value */
3463 vsetc(ret.t, ret.r, &ret.c);
3464 } else {
3465 break;
3470 void uneq(void)
3472 int t;
3474 unary();
3475 if (tok == '=' ||
3476 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3477 tok == TOK_A_XOR || tok == TOK_A_OR ||
3478 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3479 test_lvalue();
3480 t = tok;
3481 next();
3482 if (t == '=') {
3483 expr_eq();
3484 } else {
3485 vdup();
3486 expr_eq();
3487 gen_op(t & 0x7f);
3489 vstore();
3493 void sum(int l)
3495 int t;
3497 if (l == 0)
3498 uneq();
3499 else {
3500 sum(--l);
3501 while ((l == 0 & (tok == '*' | tok == '/' | tok == '%')) |
3502 (l == 1 & (tok == '+' | tok == '-')) |
3503 (l == 2 & (tok == TOK_SHL | tok == TOK_SAR)) |
3504 (l == 3 & ((tok >= TOK_ULE & tok <= TOK_GT) |
3505 tok == TOK_ULT | tok == TOK_UGE)) |
3506 (l == 4 & (tok == TOK_EQ | tok == TOK_NE)) |
3507 (l == 5 & tok == '&') |
3508 (l == 6 & tok == '^') |
3509 (l == 7 & tok == '|') |
3510 (l == 8 & tok == TOK_LAND) |
3511 (l == 9 & tok == TOK_LOR)) {
3512 t = tok;
3513 next();
3514 sum(l);
3515 gen_op(t);
3520 /* only used if non constant */
3521 void eand(void)
3523 int t;
3525 sum(8);
3526 t = 0;
3527 while (1) {
3528 if (tok != TOK_LAND) {
3529 if (t) {
3530 t = gtst(1, t);
3531 vset(VT_INT, VT_JMPI, t);
3533 break;
3535 t = gtst(1, t);
3536 next();
3537 sum(8);
3541 void eor(void)
3543 int t;
3545 eand();
3546 t = 0;
3547 while (1) {
3548 if (tok != TOK_LOR) {
3549 if (t) {
3550 t = gtst(0, t);
3551 vset(VT_INT, VT_JMP, t);
3553 break;
3555 t = gtst(0, t);
3556 next();
3557 eand();
3561 /* XXX: better constant handling */
3562 void expr_eq(void)
3564 int t, u, c, r1, r2;
3566 if (const_wanted) {
3567 sum(10);
3568 if (tok == '?') {
3569 c = vtop->c.i;
3570 vpop();
3571 next();
3572 gexpr();
3573 t = vtop->c.i;
3574 vpop();
3575 skip(':');
3576 expr_eq();
3577 if (c)
3578 vtop->c.i = t;
3580 } else {
3581 eor();
3582 if (tok == '?') {
3583 next();
3584 t = gtst(1, 0);
3586 gexpr();
3587 r1 = gv();
3588 vpop();
3589 skip(':');
3590 u = gjmp(0);
3592 gsym(t);
3593 expr_eq();
3594 r2 = gv();
3595 move_reg(r1, r2);
3596 vtop->r = r1;
3597 gsym(u);
3602 void gexpr(void)
3604 while (1) {
3605 expr_eq();
3606 if (tok != ',')
3607 break;
3608 vpop();
3609 next();
3613 /* parse a constant expression and return value in vtop */
3614 void expr_const1(void)
3616 int a;
3617 a = const_wanted;
3618 const_wanted = 1;
3619 expr_eq();
3620 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
3621 expect("constant");
3622 const_wanted = a;
3625 /* parse an integer constant and return its value */
3626 int expr_const(void)
3628 int c;
3629 expr_const1();
3630 c = vtop->c.i;
3631 vpop();
3632 return c;
3635 /* return the label token if current token is a label, otherwise
3636 return zero */
3637 int is_label(void)
3639 int t;
3640 CValue c;
3642 /* fast test first */
3643 if (tok < TOK_UIDENT)
3644 return 0;
3645 /* no need to save tokc since we expect an identifier */
3646 t = tok;
3647 c = tokc;
3648 next();
3649 if (tok == ':') {
3650 next();
3651 return t;
3652 } else {
3653 /* XXX: may not work in all cases (macros ?) */
3654 tok1 = tok;
3655 tok1c = tokc;
3656 tok = t;
3657 tokc = c;
3658 return 0;
3662 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
3664 int a, b, c, d;
3665 Sym *s;
3667 if (tok == TOK_IF) {
3668 /* if test */
3669 next();
3670 skip('(');
3671 gexpr();
3672 skip(')');
3673 a = gtst(1, 0);
3674 block(bsym, csym, case_sym, def_sym, case_reg);
3675 c = tok;
3676 if (c == TOK_ELSE) {
3677 next();
3678 d = gjmp(0);
3679 gsym(a);
3680 block(bsym, csym, case_sym, def_sym, case_reg);
3681 gsym(d); /* patch else jmp */
3682 } else
3683 gsym(a);
3684 } else if (tok == TOK_WHILE) {
3685 next();
3686 d = ind;
3687 skip('(');
3688 gexpr();
3689 skip(')');
3690 a = gtst(1, 0);
3691 b = 0;
3692 block(&a, &b, case_sym, def_sym, case_reg);
3693 oad(0xe9, d - ind - 5); /* jmp */
3694 gsym(a);
3695 gsym_addr(b, d);
3696 } else if (tok == '{') {
3697 next();
3698 /* declarations */
3699 s = local_stack.top;
3700 while (tok != '}') {
3701 decl(VT_LOCAL);
3702 if (tok != '}')
3703 block(bsym, csym, case_sym, def_sym, case_reg);
3705 /* pop locally defined symbols */
3706 sym_pop(&local_stack, s);
3707 next();
3708 } else if (tok == TOK_RETURN) {
3709 next();
3710 if (tok != ';') {
3711 gexpr();
3712 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
3713 /* if returning structure, must copy it to implicit
3714 first pointer arg location */
3715 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
3716 indir();
3717 vswap();
3718 /* copy structure value to pointer */
3719 vstore();
3720 } else if (is_float(func_vt)) {
3721 /* move return value to float return register */
3722 move_reg(FUNC_RET_FREG, gv());
3723 } else {
3724 /* move return value to standard return register */
3725 move_reg(FUNC_RET_REG, gv());
3727 vpop();
3729 skip(';');
3730 rsym = gjmp(rsym); /* jmp */
3731 } else if (tok == TOK_BREAK) {
3732 /* compute jump */
3733 if (!bsym)
3734 error("cannot break");
3735 *bsym = gjmp(*bsym);
3736 next();
3737 skip(';');
3738 } else if (tok == TOK_CONTINUE) {
3739 /* compute jump */
3740 if (!csym)
3741 error("cannot continue");
3742 *csym = gjmp(*csym);
3743 next();
3744 skip(';');
3745 } else if (tok == TOK_FOR) {
3746 int e;
3747 next();
3748 skip('(');
3749 if (tok != ';') {
3750 gexpr();
3751 vpop();
3753 skip(';');
3754 d = ind;
3755 c = ind;
3756 a = 0;
3757 b = 0;
3758 if (tok != ';') {
3759 gexpr();
3760 a = gtst(1, 0);
3762 skip(';');
3763 if (tok != ')') {
3764 e = gjmp(0);
3765 c = ind;
3766 gexpr();
3767 vpop();
3768 oad(0xe9, d - ind - 5); /* jmp */
3769 gsym(e);
3771 skip(')');
3772 block(&a, &b, case_sym, def_sym, case_reg);
3773 oad(0xe9, c - ind - 5); /* jmp */
3774 gsym(a);
3775 gsym_addr(b, c);
3776 } else
3777 if (tok == TOK_DO) {
3778 next();
3779 a = 0;
3780 b = 0;
3781 d = ind;
3782 block(&a, &b, case_sym, def_sym, case_reg);
3783 skip(TOK_WHILE);
3784 skip('(');
3785 gsym(b);
3786 gexpr();
3787 c = gtst(0, 0);
3788 gsym_addr(c, d);
3789 skip(')');
3790 gsym(a);
3791 skip(';');
3792 } else
3793 if (tok == TOK_SWITCH) {
3794 next();
3795 skip('(');
3796 gexpr();
3797 case_reg = gv();
3798 vpop();
3799 skip(')');
3800 a = 0;
3801 b = gjmp(0); /* jump to first case */
3802 c = 0;
3803 block(&a, csym, &b, &c, case_reg);
3804 /* if no default, jmp after switch */
3805 if (c == 0)
3806 c = ind;
3807 /* default label */
3808 gsym_addr(b, c);
3809 /* break label */
3810 gsym(a);
3811 } else
3812 if (tok == TOK_CASE) {
3813 next();
3814 a = expr_const();
3815 if (!case_sym)
3816 expect("switch");
3817 /* since a case is like a label, we must skip it with a jmp */
3818 b = gjmp(0);
3819 gsym(*case_sym);
3820 vset(VT_INT, case_reg, 0);
3821 vpushi(a);
3822 gen_op(TOK_EQ);
3823 *case_sym = gtst(1, 0);
3824 gsym(b);
3825 skip(':');
3826 block(bsym, csym, case_sym, def_sym, case_reg);
3827 } else
3828 if (tok == TOK_DEFAULT) {
3829 next();
3830 skip(':');
3831 if (!def_sym)
3832 expect("switch");
3833 if (*def_sym)
3834 error("too many 'default'");
3835 *def_sym = ind;
3836 block(bsym, csym, case_sym, def_sym, case_reg);
3837 } else
3838 if (tok == TOK_GOTO) {
3839 next();
3840 s = sym_find1(&label_stack, tok);
3841 /* put forward definition if needed */
3842 if (!s)
3843 s = sym_push1(&label_stack, tok, VT_FORWARD, 0);
3844 /* label already defined */
3845 if (s->t & VT_FORWARD)
3846 s->c = gjmp(s->c); /* jmp xxx */
3847 else
3848 oad(0xe9, s->c - ind - 5); /* jmp xxx */
3849 next();
3850 skip(';');
3851 } else {
3852 b = is_label();
3853 if (b) {
3854 /* label case */
3855 s = sym_find1(&label_stack, b);
3856 if (s) {
3857 if (!(s->t & VT_FORWARD))
3858 error("multiple defined label");
3859 gsym(s->c);
3860 s->c = ind;
3861 s->t = 0;
3862 } else {
3863 sym_push1(&label_stack, b, 0, ind);
3865 /* we accept this, but it is a mistake */
3866 if (tok == '}')
3867 warning("deprecated use of label at end of compound statement");
3868 else
3869 block(bsym, csym, case_sym, def_sym, case_reg);
3870 } else {
3871 /* expression case */
3872 if (tok != ';') {
3873 gexpr();
3874 vpop();
3876 skip(';');
3881 /* t is the array or struct type. c is the array or struct
3882 address. cur_index/cur_field is the pointer to the current
3883 value. 'size_only' is true if only size info is needed (only used
3884 in arrays) */
3885 void decl_designator(int t, int r, int c,
3886 int *cur_index, Sym **cur_field,
3887 int size_only)
3889 Sym *s, *f;
3890 int notfirst, index, align, l;
3892 notfirst = 0;
3893 if (gnu_ext && (l = is_label()) != 0)
3894 goto struct_field;
3896 while (tok == '[' || tok == '.') {
3897 if (tok == '[') {
3898 if (!(t & VT_ARRAY))
3899 expect("array type");
3900 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3901 next();
3902 index = expr_const();
3903 if (index < 0 || (s->c >= 0 && index >= s->c))
3904 expect("invalid index");
3905 skip(']');
3906 if (!notfirst)
3907 *cur_index = index;
3908 t = pointed_type(t);
3909 c += index * type_size(t, &align);
3910 } else {
3911 next();
3912 l = tok;
3913 next();
3914 struct_field:
3915 if ((t & VT_BTYPE) != VT_STRUCT)
3916 expect("struct/union type");
3917 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3918 l |= SYM_FIELD;
3919 f = s->next;
3920 while (f) {
3921 if (f->v == l)
3922 break;
3923 f = f->next;
3925 if (!f)
3926 expect("field");
3927 if (!notfirst)
3928 *cur_field = f;
3929 t = f->t | (t & ~VT_TYPE);
3930 c += f->c;
3932 notfirst = 1;
3934 if (notfirst) {
3935 if (tok == '=') {
3936 next();
3937 } else {
3938 if (!gnu_ext)
3939 expect("=");
3941 } else {
3942 if (t & VT_ARRAY) {
3943 index = *cur_index;
3944 t = pointed_type(t);
3945 c += index * type_size(t, &align);
3946 } else {
3947 f = *cur_field;
3948 if (!f)
3949 error("too many field init");
3950 t = f->t | (t & ~VT_TYPE);
3951 c += f->c;
3954 decl_initializer(t, r, c, 0, size_only);
3957 #define EXPR_VAL 0
3958 #define EXPR_CONST 1
3959 #define EXPR_ANY 2
3961 /* store a value or an expression directly in global data or in local array */
3962 void init_putv(int t, int r, int c,
3963 int v, int expr_type)
3965 int saved_global_expr, bt;
3967 switch(expr_type) {
3968 case EXPR_VAL:
3969 vpushi(v);
3970 break;
3971 case EXPR_CONST:
3972 /* compound literals must be allocated globally in this case */
3973 saved_global_expr = global_expr;
3974 global_expr = 1;
3975 expr_const1();
3976 global_expr = saved_global_expr;
3977 break;
3978 case EXPR_ANY:
3979 expr_eq();
3980 break;
3983 if ((r & VT_VALMASK) == VT_CONST) {
3984 /* XXX: do casting */
3985 /* XXX: not portable */
3986 bt = vtop->t & VT_BTYPE;
3987 switch(bt) {
3988 case VT_BYTE:
3989 *(char *)c = vtop->c.i;
3990 break;
3991 case VT_SHORT:
3992 *(short *)c = vtop->c.i;
3993 break;
3994 case VT_DOUBLE:
3995 *(double *)c = vtop->c.d;
3996 break;
3997 case VT_LDOUBLE:
3998 *(long double *)c = vtop->c.ld;
3999 break;
4000 #if 0
4001 case VT_LLONG:
4002 *(long long *)c = vtop->c.ll;
4003 break;
4004 #endif
4005 default:
4006 *(int *)c = vtop->c.i;
4007 break;
4009 vpop();
4010 } else {
4011 vset(t, r, c);
4012 vswap();
4013 vstore();
4014 vpop();
4018 /* put zeros for variable based init */
4019 void init_putz(int t, int r, int c, int size)
4021 GFuncContext gf;
4023 if ((r & VT_VALMASK) == VT_CONST) {
4024 /* nothing to do because global are already set to zero */
4025 } else {
4026 gfunc_start(&gf);
4027 vpushi(size);
4028 gfunc_param(&gf);
4029 vpushi(0);
4030 gfunc_param(&gf);
4031 vset(VT_INT, VT_LOCAL, c);
4032 gfunc_param(&gf);
4033 vpushi((int)&memset);
4034 gfunc_call(&gf);
4038 /* 't' contains the type and storage info. c is the address of the
4039 object. 'first' is true if array '{' must be read (multi dimension
4040 implicit array init handling). 'size_only' is true if size only
4041 evaluation is wanted (only for arrays). */
4042 void decl_initializer(int t, int r, int c, int first, int size_only)
4044 int index, array_length, n, no_oblock, nb, parlevel, i;
4045 int t1, size1, align1, expr_type;
4046 Sym *s, *f;
4047 TokenSym *ts;
4049 if (t & VT_ARRAY) {
4050 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4051 n = s->c;
4052 array_length = 0;
4053 t1 = pointed_type(t);
4054 size1 = type_size(t1, &align1);
4056 no_oblock = 1;
4057 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4058 tok == '{') {
4059 skip('{');
4060 no_oblock = 0;
4063 /* only parse strings here if correct type (otherwise: handle
4064 them as ((w)char *) expressions */
4065 if ((tok == TOK_LSTR &&
4066 (t1 & VT_BTYPE) == VT_INT) ||
4067 (tok == TOK_STR &&
4068 (t1 & VT_BTYPE) == VT_BYTE)) {
4069 /* XXX: move multiple string parsing in parser ? */
4070 while (tok == TOK_STR || tok == TOK_LSTR) {
4071 ts = tokc.ts;
4072 /* compute maximum number of chars wanted */
4073 nb = ts->len;
4074 if (n >= 0 && nb > (n - array_length))
4075 nb = n - array_length;
4076 if (!size_only) {
4077 if (ts->len > nb)
4078 warning("initializer-string for array is too long");
4079 for(i=0;i<nb;i++) {
4080 init_putv(t1, r, c + (array_length + i) * size1,
4081 ts->str[i], EXPR_VAL);
4084 array_length += nb;
4085 next();
4087 /* only add trailing zero if enough storage (no
4088 warning in this case since it is standard) */
4089 if (n < 0 || array_length < n) {
4090 if (!size_only) {
4091 init_putv(t1, r, c + (array_length * size1), 0, EXPR_VAL);
4093 array_length++;
4095 } else {
4096 index = 0;
4097 while (tok != '}') {
4098 decl_designator(t, r, c, &index, NULL, size_only);
4099 if (n >= 0 && index >= n)
4100 error("index too large");
4101 /* must put zero in holes (note that doing it that way
4102 ensures that it even works with designators) */
4103 if (!size_only && array_length < index) {
4104 init_putz(t1, r, c + array_length * size1,
4105 (index - array_length) * size1);
4107 index++;
4108 if (index > array_length)
4109 array_length = index;
4110 /* special test for multi dimensional arrays (may not
4111 be strictly correct if designators are used at the
4112 same time) */
4113 if (index >= n && no_oblock)
4114 break;
4115 if (tok == '}')
4116 break;
4117 skip(',');
4120 if (!no_oblock)
4121 skip('}');
4122 /* put zeros at the end */
4123 if (!size_only && n >= 0 && array_length < n) {
4124 init_putz(t1, r, c + array_length * size1,
4125 (n - array_length) * size1);
4127 /* patch type size if needed */
4128 if (n < 0)
4129 s->c = array_length;
4130 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
4131 /* XXX: union needs only one init */
4132 next();
4133 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4134 f = s->next;
4135 array_length = 0;
4136 index = 0;
4137 n = s->c;
4138 while (tok != '}') {
4139 decl_designator(t, r, c, NULL, &f, size_only);
4140 /* fill with zero between fields */
4141 index = f->c;
4142 if (!size_only && array_length < index) {
4143 init_putz(t, r, c + array_length,
4144 index - array_length);
4146 index = index + type_size(f->t, &align1);
4147 if (index > array_length)
4148 array_length = index;
4149 if (tok == '}')
4150 break;
4151 skip(',');
4152 f = f->next;
4154 /* put zeros at the end */
4155 if (!size_only && array_length < n) {
4156 init_putz(t, r, c + array_length,
4157 n - array_length);
4159 skip('}');
4160 } else if (tok == '{') {
4161 next();
4162 decl_initializer(t, r, c, first, size_only);
4163 skip('}');
4164 } else if (size_only) {
4165 /* just skip expression */
4166 parlevel = 0;
4167 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4168 tok != -1) {
4169 if (tok == '(')
4170 parlevel++;
4171 else if (tok == ')')
4172 parlevel--;
4173 next();
4175 } else {
4176 /* currently, we always use constant expression for globals
4177 (may change for scripting case) */
4178 expr_type = EXPR_CONST;
4179 if ((r & VT_VALMASK) == VT_LOCAL)
4180 expr_type = EXPR_ANY;
4181 init_putv(t, r, c, 0, expr_type);
4185 /* parse an initializer for type 't' if 'has_init' is true, and
4186 allocate space in local or global data space ('r' is either
4187 VT_LOCAL or VT_CONST). The allocated address in returned */
4188 int decl_initializer_alloc(int t, int r, int has_init)
4190 int size, align, addr, tok1;
4191 int *init_str, init_len, level, *saved_macro_ptr;
4193 size = type_size(t, &align);
4194 /* If unknown size, we must evaluate it before
4195 evaluating initializers because
4196 initializers can generate global data too
4197 (e.g. string pointers or ISOC99 compound
4198 literals). It also simplifies local
4199 initializers handling */
4200 init_len = 0;
4201 init_str = NULL;
4202 saved_macro_ptr = NULL; /* avoid warning */
4203 tok1 = 0;
4204 if (size < 0) {
4205 if (!has_init)
4206 error("unknown type size");
4207 /* get all init string */
4208 level = 0;
4209 while (level > 0 || (tok != ',' && tok != ';')) {
4210 if (tok < 0)
4211 error("unexpected end of file in initializer");
4212 tok_add2(&init_str, &init_len, tok, &tokc);
4213 if (tok == '{')
4214 level++;
4215 else if (tok == '}') {
4216 if (level == 0)
4217 break;
4218 level--;
4220 next();
4222 tok1 = tok;
4223 tok_add(&init_str, &init_len, -1);
4224 tok_add(&init_str, &init_len, 0);
4226 /* compute size */
4227 saved_macro_ptr = macro_ptr;
4228 macro_ptr = init_str;
4229 next();
4230 decl_initializer(t, r, 0, 1, 1);
4231 /* prepare second initializer parsing */
4232 macro_ptr = init_str;
4233 next();
4235 /* if still unknown size, error */
4236 size = type_size(t, &align);
4237 if (size < 0)
4238 error("unknown type size");
4240 if ((r & VT_VALMASK) == VT_LOCAL) {
4241 loc = (loc - size) & -align;
4242 addr = loc;
4243 } else {
4244 glo = (glo + align - 1) & -align;
4245 addr = glo;
4246 /* very important to increment global
4247 pointer at this time because
4248 initializers themselves can create new
4249 initializers */
4250 glo += size;
4252 if (has_init) {
4253 decl_initializer(t, r, addr, 1, 0);
4254 /* restore parse state if needed */
4255 if (init_str) {
4256 free(init_str);
4257 macro_ptr = saved_macro_ptr;
4258 tok = tok1;
4261 return addr;
4265 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
4266 void decl(int l)
4268 int *a, t, b, v, addr, has_init, size, align, r, u;
4269 Sym *sym;
4271 while (1) {
4272 if (!parse_btype(&b)) {
4273 /* skip redundant ';' */
4274 /* XXX: find more elegant solution */
4275 if (tok == ';') {
4276 next();
4277 continue;
4279 /* special test for old K&R protos without explicit int
4280 type. Only accepted when defining global data */
4281 if (l == VT_LOCAL || tok < TOK_DEFINE)
4282 break;
4283 b = VT_INT;
4285 if (((b & VT_BTYPE) == VT_ENUM ||
4286 (b & VT_BTYPE) == VT_STRUCT) &&
4287 tok == ';') {
4288 /* we accept no variable after */
4289 next();
4290 continue;
4292 while (1) { /* iterate thru each declaration */
4293 t = type_decl(&v, b, TYPE_DIRECT);
4294 #if 0
4296 char buf[500];
4297 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
4298 printf("type = '%s'\n", buf);
4300 #endif
4301 if (tok == '{') {
4302 if (l == VT_LOCAL)
4303 error("cannot use local functions");
4304 if (!(t & VT_FUNC))
4305 expect("function definition");
4306 /* patch forward references */
4307 if ((sym = sym_find(v)) && (sym->r & VT_FORWARD)) {
4308 greloc_patch(sym, ind);
4309 sym->t = t;
4310 } else {
4311 /* put function address */
4312 sym = sym_push1(&global_stack, v, t, ind);
4314 sym->r = VT_CONST;
4315 funcname = get_tok_str(v, NULL);
4316 /* push a dummy symbol to enable local sym storage */
4317 sym_push1(&local_stack, 0, 0, 0);
4318 /* define parameters */
4319 sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4320 /* XXX: the following is x86 dependant -> move it to
4321 x86 code gen */
4322 addr = 8;
4323 /* if the function returns a structure, then add an
4324 implicit pointer parameter */
4325 func_vt = sym->t;
4326 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
4327 func_vc = addr;
4328 addr += 4;
4330 while (sym = sym->next) {
4331 u = sym->t;
4332 sym_push(sym->v & ~SYM_FIELD, u,
4333 VT_LOCAL | VT_LVAL, addr);
4334 size = type_size(u, &align);
4335 size = (size + 3) & ~3;
4336 #ifdef FUNC_STRUCT_PARAM_AS_PTR
4337 /* structs are passed as pointer */
4338 if ((u & VT_BTYPE) == VT_STRUCT) {
4339 size = 4;
4341 #endif
4342 addr += size;
4344 loc = 0;
4345 o(0xe58955); /* push %ebp, mov %esp, %ebp */
4346 a = (int *)oad(0xec81, 0); /* sub $xxx, %esp */
4347 rsym = 0;
4348 block(NULL, NULL, NULL, NULL, 0);
4349 gsym(rsym);
4350 o(0xc3c9); /* leave, ret */
4351 *a = (-loc + 3) & -4; /* align local size to word &
4352 save local variables */
4353 sym_pop(&label_stack, NULL); /* reset label stack */
4354 sym_pop(&local_stack, NULL); /* reset local stack */
4355 funcname = ""; /* for safety */
4356 func_vt = VT_VOID; /* for safety */
4357 break;
4358 } else {
4359 if (b & VT_TYPEDEF) {
4360 /* save typedefed type */
4361 /* XXX: test storage specifiers ? */
4362 sym_push(v, t | VT_TYPEDEF, 0, 0);
4363 } else if ((t & VT_BTYPE) == VT_FUNC) {
4364 /* external function definition */
4365 external_sym(v, t, 0);
4366 } else {
4367 /* not lvalue if array */
4368 r = 0;
4369 if (!(t & VT_ARRAY))
4370 r |= VT_LVAL;
4371 if (b & VT_EXTERN) {
4372 /* external variable */
4373 external_sym(v, t, r);
4374 } else {
4375 if (t & VT_STATIC)
4376 r |= VT_CONST;
4377 else
4378 r |= l;
4379 has_init = (tok == '=');
4380 if (has_init)
4381 next();
4382 addr = decl_initializer_alloc(t, r,
4383 has_init);
4384 if (l == VT_CONST) {
4385 /* global scope: see if already defined */
4386 sym = sym_find(v);
4387 if (!sym)
4388 goto do_def;
4389 if (!is_compatible_types(sym->t, t))
4390 error("incompatible types for redefinition of '%s'",
4391 get_tok_str(v, NULL));
4392 if (!(sym->r & VT_FORWARD))
4393 error("redefinition of '%s'", get_tok_str(v, NULL));
4394 greloc_patch(sym, addr);
4395 } else {
4396 do_def:
4397 sym_push(v, t, r, addr);
4401 if (tok != ',') {
4402 skip(';');
4403 break;
4405 next();
4411 /* put all global symbols in the extern stack and do all the
4412 resolving which can be done without using external symbols from DLLs */
4413 /* XXX: could try to verify types, but would not to save them in
4414 extern_stack too */
4415 void resolve_global_syms(void)
4417 Sym *s, *s1, *ext_sym;
4418 Reloc **p;
4420 s = global_stack.top;
4421 while (s != NULL) {
4422 s1 = s->prev;
4423 /* do not save static or typedefed symbols or types */
4424 if (!(s->t & (VT_STATIC | VT_TYPEDEF)) &&
4425 !(s->v & (SYM_FIELD | SYM_STRUCT)) &&
4426 (s->v < SYM_FIRST_ANOM)) {
4427 ext_sym = sym_find1(&extern_stack, s->v);
4428 if (!ext_sym) {
4429 /* if the symbol do not exist, we simply save it */
4430 ext_sym = sym_push1(&extern_stack, s->v, s->t, s->c);
4431 ext_sym->r = s->r;
4432 } else if (ext_sym->r & VT_FORWARD) {
4433 /* external symbol already exists, but only as forward
4434 definition */
4435 if (!(s->r & VT_FORWARD)) {
4436 /* s is not forward, so we can relocate all symbols */
4437 greloc_patch(ext_sym, s->c);
4438 } else {
4439 /* the two symbols are forward: merge them */
4440 p = (Reloc **)&ext_sym->c;
4441 while (*p != NULL)
4442 p = &(*p)->next;
4443 *p = (Reloc *)s->c;
4445 } else {
4446 /* external symbol already exists and is defined :
4447 patch all references to it */
4448 if (!(s->r & VT_FORWARD))
4449 error("'%s' defined twice", get_tok_str(s->v, NULL));
4450 greloc_patch(s, ext_sym->c);
4453 s = s1;
4457 /* compile a C file. Return non zero if errors. */
4458 int tcc_compile_file(const char *filename1)
4460 Sym *define_start;
4462 filename = (char *)filename1;
4464 line_num = 1;
4465 funcname = "";
4466 file = fopen(filename, "r");
4467 if (!file)
4468 error("file '%s' not found", filename);
4469 include_stack_ptr = include_stack;
4470 ifdef_stack_ptr = ifdef_stack;
4472 vtop = vstack - 1;
4473 anon_sym = SYM_FIRST_ANOM;
4475 define_start = define_stack.top;
4476 inp();
4477 ch = '\n'; /* needed to parse correctly first preprocessor command */
4478 next();
4479 decl(VT_CONST);
4480 if (tok != -1)
4481 expect("declaration");
4482 fclose(file);
4484 /* reset define stack, but leave -Dsymbols (may be incorrect if
4485 they are undefined) */
4486 sym_pop(&define_stack, define_start);
4488 resolve_global_syms();
4490 sym_pop(&global_stack, NULL);
4492 return 0;
4495 /* open a dynamic library so that its symbol are available for
4496 compiled programs */
4497 void open_dll(char *libname)
4499 char buf[1024];
4500 void *h;
4502 snprintf(buf, sizeof(buf), "lib%s.so", libname);
4503 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
4504 if (!h)
4505 error((char *)dlerror());
4508 void resolve_extern_syms(void)
4510 Sym *s, *s1;
4511 char *str;
4512 int addr;
4514 s = extern_stack.top;
4515 while (s != NULL) {
4516 s1 = s->prev;
4517 if (s->r & VT_FORWARD) {
4518 /* if there is at least one relocation to do, then find it
4519 and patch it */
4520 if (s->c) {
4521 str = get_tok_str(s->v, NULL);
4522 addr = (int)dlsym(NULL, str);
4523 if (!addr)
4524 error("unresolved external reference '%s'", str);
4525 greloc_patch(s, addr);
4528 s = s1;
4532 /* output a binary file (for testing) */
4533 void build_exe(char *filename)
4535 FILE *f;
4536 f = fopen(filename, "w");
4537 fwrite((void *)prog, 1, ind - prog, f);
4538 fclose(f);
4541 int main(int argc, char **argv)
4543 Sym *s;
4544 int (*t)();
4545 char *p, *r, *outfile;
4546 int optind;
4548 include_paths[0] = "/usr/include";
4549 include_paths[1] = "/usr/lib/tcc";
4550 include_paths[2] = "/usr/local/lib/tcc";
4551 nb_include_paths = 3;
4553 /* add all tokens */
4554 tok_ident = TOK_IDENT;
4555 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";
4556 while (*p) {
4557 r = p;
4558 while (*r++);
4559 tok_alloc(p, r - p - 1);
4560 p = r;
4563 /* standard defines */
4564 define_symbol("__STDC__");
4565 #ifdef __i386__
4566 define_symbol("__i386__");
4567 #endif
4568 /* tiny C specific defines */
4569 define_symbol("__TINYC__");
4571 glo = (int)malloc(DATA_SIZE);
4572 memset((void *)glo, 0, DATA_SIZE);
4573 prog = (int)malloc(TEXT_SIZE);
4574 ind = prog;
4576 optind = 1;
4577 outfile = NULL;
4578 while (1) {
4579 if (optind >= argc) {
4580 show_help:
4581 printf("tcc version 0.9.2 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n"
4582 "usage: tcc [-Idir] [-Dsym] [-llib] [-i infile] infile [infile_args...]\n");
4583 return 1;
4585 r = argv[optind];
4586 if (r[0] != '-')
4587 break;
4588 optind++;
4589 if (r[1] == 'I') {
4590 if (nb_include_paths >= INCLUDE_PATHS_MAX)
4591 error("too many include paths");
4592 include_paths[nb_include_paths++] = r + 2;
4593 } else if (r[1] == 'D') {
4594 define_symbol(r + 2);
4595 } else if (r[1] == 'l') {
4596 open_dll(r + 2);
4597 } else if (r[1] == 'i') {
4598 if (optind >= argc)
4599 goto show_help;
4600 tcc_compile_file(argv[optind++]);
4601 } else if (r[1] == 'o') {
4602 /* currently, only for testing, so not documented */
4603 if (optind >= argc)
4604 goto show_help;
4605 outfile = argv[optind++];
4606 } else {
4607 fprintf(stderr, "invalid option -- '%s'\n", r);
4608 exit(1);
4612 tcc_compile_file(argv[optind]);
4614 resolve_extern_syms();
4616 if (outfile) {
4617 build_exe(outfile);
4618 return 0;
4619 } else {
4620 s = sym_find1(&extern_stack, TOK_MAIN);
4621 if (!s || (s->r & VT_FORWARD))
4622 error("main() not defined");
4623 t = (int (*)())s->c;
4624 return (*t)(argc - optind, argv + optind);