further parse optimizations
[tinycc/miki.git] / tcc.c
bloba4a5abb98b54f7ee9d9243c40f39ac1379eab829
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 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 <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <setjmp.h>
31 #ifdef WIN32
32 #include <sys/timeb.h>
33 #endif
34 #ifndef WIN32
35 #include <sys/time.h>
36 #include <sys/ucontext.h>
37 #endif
38 #include "elf.h"
39 #include "stab.h"
40 #ifndef CONFIG_TCC_STATIC
41 #include <dlfcn.h>
42 #endif
44 #include "libtcc.h"
46 //#define DEBUG
47 /* preprocessor debug */
48 //#define PP_DEBUG
49 /* include file debug */
50 //#define INC_DEBUG
52 //#define MEM_DEBUG
54 /* target selection */
55 //#define TCC_TARGET_I386 /* i386 code generator */
56 //#define TCC_TARGET_IL /* .NET CLI generator */
58 /* default target is I386 */
59 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
60 #define TCC_TARGET_I386
61 #endif
63 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
64 #define CONFIG_TCC_BCHECK /* enable bound checking code */
65 #endif
67 #ifndef CONFIG_TCC_PREFIX
68 #define CONFIG_TCC_PREFIX "/usr/local"
69 #endif
71 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
72 executables or dlls */
73 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
75 #define INCLUDE_STACK_SIZE 32
76 #define IFDEF_STACK_SIZE 64
77 #define VSTACK_SIZE 64
78 #define STRING_MAX_SIZE 1024
80 #define TOK_HASH_SIZE 2048 /* must be a power of two */
81 #define TOK_ALLOC_INCR 512 /* must be a power of two */
83 /* token symbol management */
84 typedef struct TokenSym {
85 struct TokenSym *hash_next;
86 struct Sym *sym_define; /* direct pointer to define */
87 struct Sym *sym_label; /* direct pointer to label */
88 struct Sym *sym_struct; /* direct pointer to structure */
89 struct Sym *sym_identifier; /* direct pointer to identifier */
90 int tok; /* token number */
91 int len;
92 char str[1];
93 } TokenSym;
95 typedef struct CString {
96 int size; /* size in bytes */
97 void *data; /* either 'char *' or 'int *' */
98 int size_allocated;
99 void *data_allocated; /* if non NULL, data has been malloced */
100 } CString;
102 /* type definition */
103 typedef struct CType {
104 int t;
105 struct Sym *ref;
106 } CType;
108 /* constant value */
109 typedef union CValue {
110 long double ld;
111 double d;
112 float f;
113 int i;
114 unsigned int ui;
115 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
116 long long ll;
117 unsigned long long ull;
118 struct CString *cstr;
119 void *ptr;
120 int tab[1];
121 } CValue;
123 /* value on stack */
124 typedef struct SValue {
125 CType type; /* type */
126 unsigned short r; /* register + flags */
127 unsigned short r2; /* second register, used for 'long long'
128 type. If not used, set to VT_CONST */
129 CValue c; /* constant, if VT_CONST */
130 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
131 } SValue;
133 /* symbol management */
134 typedef struct Sym {
135 int v; /* symbol token */
136 int r; /* associated register */
137 int c; /* associated number */
138 CType type; /* associated type */
139 struct Sym *next; /* next related symbol */
140 struct Sym *prev; /* prev symbol in stack */
141 struct Sym *prev_tok; /* previous symbol for this token */
142 } Sym;
144 /* section definition */
145 /* XXX: use directly ELF structure for parameters ? */
146 /* special flag to indicate that the section should not be linked to
147 the other ones */
148 #define SHF_PRIVATE 0x80000000
150 typedef struct Section {
151 unsigned long data_offset; /* current data offset */
152 unsigned char *data; /* section data */
153 unsigned long data_allocated; /* used for realloc() handling */
154 int sh_name; /* elf section name (only used during output) */
155 int sh_num; /* elf section number */
156 int sh_type; /* elf section type */
157 int sh_flags; /* elf section flags */
158 int sh_info; /* elf section info */
159 int sh_addralign; /* elf section alignment */
160 int sh_entsize; /* elf entry size */
161 unsigned long sh_size; /* section size (only used during output) */
162 unsigned long sh_addr; /* address at which the section is relocated */
163 unsigned long sh_offset; /* address at which the section is relocated */
164 int nb_hashed_syms; /* used to resize the hash table */
165 struct Section *link; /* link to another section */
166 struct Section *reloc; /* corresponding section for relocation, if any */
167 struct Section *hash; /* hash table for symbols */
168 struct Section *next;
169 char name[64]; /* section name */
170 } Section;
172 typedef struct DLLReference {
173 int level;
174 char name[1];
175 } DLLReference;
177 /* GNUC attribute definition */
178 typedef struct AttributeDef {
179 int aligned;
180 Section *section;
181 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
182 } AttributeDef;
184 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
185 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
186 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
188 /* stored in 'Sym.c' field */
189 #define FUNC_NEW 1 /* ansi function prototype */
190 #define FUNC_OLD 2 /* old function prototype */
191 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
193 /* stored in 'Sym.r' field */
194 #define FUNC_CDECL 0 /* standard c call */
195 #define FUNC_STDCALL 1 /* pascal c call */
197 /* field 'Sym.t' for macros */
198 #define MACRO_OBJ 0 /* object like macro */
199 #define MACRO_FUNC 1 /* function like macro */
201 /* field 'Sym.r' for labels */
202 #define LABEL_FORWARD 1 /* label is forward defined */
204 /* type_decl() types */
205 #define TYPE_ABSTRACT 1 /* type without variable */
206 #define TYPE_DIRECT 2 /* type with variable */
208 #define IO_BUF_SIZE 8192
210 typedef struct BufferedFile {
211 unsigned char *buf_ptr;
212 unsigned char *buf_end;
213 int fd;
214 int line_num; /* current line number - here to simply code */
215 int ifndef_macro; /*'#ifndef macro \n #define macro' search */
216 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
217 char inc_type; /* type of include */
218 char inc_filename[512]; /* filename specified by the user */
219 char filename[1024]; /* current filename - here to simplify code */
220 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
221 } BufferedFile;
223 #define CH_EOB 0 /* end of buffer or '\0' char in file */
224 #define CH_EOF (-1) /* end of file */
226 /* parsing state (used to save parser state to reparse part of the
227 source several times) */
228 typedef struct ParseState {
229 int *macro_ptr;
230 int line_num;
231 int tok;
232 CValue tokc;
233 } ParseState;
235 /* used to record tokens */
236 typedef struct TokenString {
237 int *str;
238 int len;
239 int last_line_num;
240 } TokenString;
242 /* include file cache, used to find files faster and also to eliminate
243 inclusion if the include file is protected by #ifndef ... #endif */
244 typedef struct CachedInclude {
245 int ifndef_macro;
246 char type; /* '"' or '>' to give include type */
247 char filename[1]; /* path specified in #include */
248 } CachedInclude;
250 /* parser */
251 struct BufferedFile *file;
252 int ch, ch1, tok, tok1;
253 CValue tokc, tok1c;
254 CString tokcstr; /* current parsed string, if any */
255 /* if true, line feed is returned as a token. line feed is also
256 returned at eof */
257 int return_linefeed;
258 /* set to TRUE if eof was reached */
259 int eof_seen;
260 Section *text_section, *data_section, *bss_section; /* predefined sections */
261 Section *cur_text_section; /* current section where function code is
262 generated */
263 /* bound check related sections */
264 Section *bounds_section; /* contains global data bound description */
265 Section *lbounds_section; /* contains local data bound description */
266 /* symbol sections */
267 Section *symtab_section, *strtab_section;
269 /* debug sections */
270 Section *stab_section, *stabstr_section;
272 /* loc : local variable index
273 ind : output code index
274 rsym: return symbol
275 anon_sym: anonymous symbol index
277 int rsym, anon_sym,
278 prog, ind, loc;
279 /* expression generation modifiers */
280 int const_wanted; /* true if constant wanted */
281 int nocode_wanted; /* true if no code generation wanted for an expression */
282 int global_expr; /* true if compound literals must be allocated
283 globally (used during initializers parsing */
284 CType func_vt; /* current function return type (used by return
285 instruction) */
286 int func_vc;
287 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
288 int tok_ident;
289 TokenSym **table_ident;
290 TokenSym *hash_ident[TOK_HASH_SIZE];
291 char token_buf[STRING_MAX_SIZE + 1];
292 char *funcname;
293 Sym *global_stack, *local_stack;
294 Sym *define_stack;
295 Sym *label_stack;
297 SValue vstack[VSTACK_SIZE], *vtop;
298 int *macro_ptr, *macro_ptr_allocated;
299 /* some predefined types */
300 CType char_pointer_type, func_old_type, int_type;
302 /* compile with debug symbol (and use them if error during execution) */
303 int do_debug = 0;
305 /* compile with built-in memory and bounds checker */
306 int do_bounds_check = 0;
308 /* display benchmark infos */
309 int do_bench = 0;
310 int total_lines;
311 int total_bytes;
313 /* use GNU C extensions */
314 int gnu_ext = 1;
316 /* use Tiny C extensions */
317 int tcc_ext = 1;
319 /* max number of callers shown if error */
320 static int num_callers = 6;
321 static const char **rt_bound_error_msg;
323 /* XXX: suppress that ASAP */
324 static struct TCCState *tcc_state;
326 /* give the path of the tcc libraries */
327 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
329 struct TCCState {
330 int output_type;
332 BufferedFile **include_stack_ptr;
333 int *ifdef_stack_ptr;
335 /* include file handling */
336 char **include_paths;
337 int nb_include_paths;
338 char **sysinclude_paths;
339 int nb_sysinclude_paths;
340 CachedInclude **cached_includes;
341 int nb_cached_includes;
343 char **library_paths;
344 int nb_library_paths;
346 /* array of all loaded dlls (including those referenced by loaded
347 dlls) */
348 DLLReference **loaded_dlls;
349 int nb_loaded_dlls;
351 /* sections */
352 Section **sections;
353 int nb_sections; /* number of sections, including first dummy section */
355 /* got handling */
356 Section *got;
357 unsigned long *got_offsets;
358 int nb_got_offsets;
359 int nb_plt_entries;
360 /* give the correspondance from symtab indexes to dynsym indexes */
361 int *symtab_to_dynsym;
363 /* temporary dynamic symbol sections (for dll loading) */
364 Section *dynsymtab_section;
365 /* exported dynamic symbol section */
366 Section *dynsym;
368 /* if true, static linking is performed */
369 int static_link;
371 /* error handling */
372 void *error_opaque;
373 void (*error_func)(void *opaque, const char *msg);
374 int error_set_jmp_enabled;
375 jmp_buf error_jmp_buf;
376 int nb_errors;
378 /* see include_stack_ptr */
379 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
381 /* see ifdef_stack_ptr */
382 int ifdef_stack[IFDEF_STACK_SIZE];
385 /* The current value can be: */
386 #define VT_VALMASK 0x00ff
387 #define VT_CONST 0x00f0 /* constant in vc
388 (must be first non register value) */
389 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
390 #define VT_LOCAL 0x00f2 /* offset on stack */
391 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
392 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
393 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
394 #define VT_LVAL 0x0100 /* var is an lvalue */
395 #define VT_SYM 0x0200 /* a symbol value is added */
396 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
397 char/short stored in integer registers) */
398 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
399 dereferencing value */
400 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
401 bounding function call point is in vc */
402 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
403 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
404 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
405 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
407 /* types */
408 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
410 #define VT_INT 0 /* integer type */
411 #define VT_BYTE 1 /* signed byte type */
412 #define VT_SHORT 2 /* short type */
413 #define VT_VOID 3 /* void type */
414 #define VT_PTR 4 /* pointer */
415 #define VT_ENUM 5 /* enum definition */
416 #define VT_FUNC 6 /* function type */
417 #define VT_STRUCT 7 /* struct/union definition */
418 #define VT_FLOAT 8 /* IEEE float */
419 #define VT_DOUBLE 9 /* IEEE double */
420 #define VT_LDOUBLE 10 /* IEEE long double */
421 #define VT_BOOL 11 /* ISOC99 boolean type */
422 #define VT_LLONG 12 /* 64 bit integer */
423 #define VT_LONG 13 /* long integer (NEVER USED as type, only
424 during parsing) */
425 #define VT_BTYPE 0x000f /* mask for basic type */
426 #define VT_UNSIGNED 0x0010 /* unsigned type */
427 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
428 #define VT_BITFIELD 0x0040 /* bitfield modifier */
430 /* storage */
431 #define VT_EXTERN 0x00000080 /* extern definition */
432 #define VT_STATIC 0x00000100 /* static variable */
433 #define VT_TYPEDEF 0x00000200 /* typedef definition */
435 /* type mask (except storage) */
436 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
438 /* token values */
440 /* warning: the following compare tokens depend on i386 asm code */
441 #define TOK_ULT 0x92
442 #define TOK_UGE 0x93
443 #define TOK_EQ 0x94
444 #define TOK_NE 0x95
445 #define TOK_ULE 0x96
446 #define TOK_UGT 0x97
447 #define TOK_LT 0x9c
448 #define TOK_GE 0x9d
449 #define TOK_LE 0x9e
450 #define TOK_GT 0x9f
452 #define TOK_LAND 0xa0
453 #define TOK_LOR 0xa1
455 #define TOK_DEC 0xa2
456 #define TOK_MID 0xa3 /* inc/dec, to void constant */
457 #define TOK_INC 0xa4
458 #define TOK_UDIV 0xb0 /* unsigned division */
459 #define TOK_UMOD 0xb1 /* unsigned modulo */
460 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
461 #define TOK_CINT 0xb3 /* number in tokc */
462 #define TOK_CCHAR 0xb4 /* char constant in tokc */
463 #define TOK_STR 0xb5 /* pointer to string in tokc */
464 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
465 #define TOK_LCHAR 0xb7
466 #define TOK_LSTR 0xb8
467 #define TOK_CFLOAT 0xb9 /* float constant */
468 #define TOK_LINENUM 0xba /* line number info */
469 #define TOK_CDOUBLE 0xc0 /* double constant */
470 #define TOK_CLDOUBLE 0xc1 /* long double constant */
471 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
472 #define TOK_ADDC1 0xc3 /* add with carry generation */
473 #define TOK_ADDC2 0xc4 /* add with carry use */
474 #define TOK_SUBC1 0xc5 /* add with carry generation */
475 #define TOK_SUBC2 0xc6 /* add with carry use */
476 #define TOK_CUINT 0xc8 /* unsigned int constant */
477 #define TOK_CLLONG 0xc9 /* long long constant */
478 #define TOK_CULLONG 0xca /* unsigned long long constant */
479 #define TOK_ARROW 0xcb
480 #define TOK_DOTS 0xcc /* three dots */
481 #define TOK_SHR 0xcd /* unsigned shift right */
482 #define TOK_PPNUM 0xce /* preprocessor number */
484 #define TOK_SHL 0x01 /* shift left */
485 #define TOK_SAR 0x02 /* signed shift right */
487 /* assignement operators : normal operator or 0x80 */
488 #define TOK_A_MOD 0xa5
489 #define TOK_A_AND 0xa6
490 #define TOK_A_MUL 0xaa
491 #define TOK_A_ADD 0xab
492 #define TOK_A_SUB 0xad
493 #define TOK_A_DIV 0xaf
494 #define TOK_A_XOR 0xde
495 #define TOK_A_OR 0xfc
496 #define TOK_A_SHL 0x81
497 #define TOK_A_SAR 0x82
499 /* WARNING: the content of this string encodes token numbers */
500 static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
502 #define TOK_EOF (-1) /* end of file */
503 #define TOK_LINEFEED 10 /* line feed */
505 /* all identificators and strings have token above that */
506 #define TOK_IDENT 256
508 enum {
509 TOK_LAST = TOK_IDENT - 1,
510 #define DEF(id, str) id,
511 #include "tcctok.h"
512 #undef DEF
515 static const char *tcc_keywords =
516 #define DEF(id, str) str "\0"
517 #include "tcctok.h"
518 #undef DEF
521 #define TOK_UIDENT TOK_DEFINE
523 #ifdef WIN32
524 #define snprintf _snprintf
525 #define vsnprintf _vsnprintf
526 #endif
528 #if defined(WIN32) || defined(TCC_UCLIBC)
529 /* currently incorrect */
530 long double strtold(const char *nptr, char **endptr)
532 return (long double)strtod(nptr, endptr);
534 float strtof(const char *nptr, char **endptr)
536 return (float)strtod(nptr, endptr);
538 #else
539 /* XXX: need to define this to use them in non ISOC99 context */
540 extern float strtof (const char *__nptr, char **__endptr);
541 extern long double strtold (const char *__nptr, char **__endptr);
542 #endif
544 static char *pstrcpy(char *buf, int buf_size, const char *s);
545 static char *pstrcat(char *buf, int buf_size, const char *s);
547 static void sum(int l);
548 static void next(void);
549 static void next_nomacro(void);
550 static void parse_expr_type(CType *type);
551 static void expr_type(CType *type);
552 static void unary_type(CType *type);
553 static int expr_const(void);
554 static void expr_eq(void);
555 static void gexpr(void);
556 static void decl(int l);
557 static void decl_initializer(CType *type, Section *sec, unsigned long c,
558 int first, int size_only);
559 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
560 int has_init, int v, int scope);
561 int gv(int rc);
562 void gv2(int rc1, int rc2);
563 void move_reg(int r, int s);
564 void save_regs(int n);
565 void save_reg(int r);
566 void vpop(void);
567 void vswap(void);
568 void vdup(void);
569 int get_reg(int rc);
571 static void macro_subst(TokenString *tok_str,
572 Sym **nested_list, int *macro_str);
573 int save_reg_forced(int r);
574 void gen_op(int op);
575 void force_charshort_cast(int t);
576 static void gen_cast(CType *type);
577 void vstore(void);
578 static Sym *sym_find(int v);
579 static Sym *sym_push(int v, CType *type, int r, int c);
581 /* type handling */
582 int type_size(CType *type, int *a);
583 static inline CType *pointed_type(CType *type);
584 static int pointed_size(CType *type);
585 static int lvalue_type(int t);
586 static int is_compatible_types(CType *type1, CType *type2);
587 static int parse_btype(CType *type, AttributeDef *ad);
588 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
590 void error(const char *fmt, ...);
591 void vpushi(int v);
592 void vset(CType *type, int r, int v);
593 void type_to_str(char *buf, int buf_size,
594 CType *type, const char *varstr);
595 char *get_tok_str(int v, CValue *cv);
596 static Sym *get_sym_ref(CType *type, Section *sec,
597 unsigned long offset, unsigned long size);
598 static Sym *external_global_sym(int v, CType *type, int r);
600 /* section generation */
601 static void section_realloc(Section *sec, unsigned long new_size);
602 static void *section_ptr_add(Section *sec, unsigned long size);
603 static void put_extern_sym(Sym *sym, Section *section,
604 unsigned long value, unsigned long size);
605 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
606 static int put_elf_str(Section *s, const char *sym);
607 static int put_elf_sym(Section *s,
608 unsigned long value, unsigned long size,
609 int info, int other, int shndx, const char *name);
610 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
611 int info, int sh_num, const char *name);
612 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
613 int type, int symbol);
614 static void put_stabs(const char *str, int type, int other, int desc,
615 unsigned long value);
616 static void put_stabs_r(const char *str, int type, int other, int desc,
617 unsigned long value, Section *sec, int sym_index);
618 static void put_stabn(int type, int other, int desc, int value);
619 static void put_stabd(int type, int other, int desc);
620 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
622 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
623 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
624 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
626 /* true if float/double/long double type */
627 static inline int is_float(int t)
629 int bt;
630 bt = t & VT_BTYPE;
631 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
634 #ifdef TCC_TARGET_I386
635 #include "i386-gen.c"
636 #endif
637 #ifdef TCC_TARGET_IL
638 #include "il-gen.c"
639 #endif
641 #ifdef CONFIG_TCC_STATIC
643 #define RTLD_LAZY 0x001
644 #define RTLD_NOW 0x002
645 #define RTLD_GLOBAL 0x100
646 #define RTLD_DEFAULT NULL
648 /* dummy function for profiling */
649 void *dlopen(const char *filename, int flag)
651 return NULL;
654 const char *dlerror(void)
656 return "error";
659 typedef struct TCCSyms {
660 char *str;
661 void *ptr;
662 } TCCSyms;
664 #define TCCSYM(a) { #a, &a, },
666 /* add the symbol you want here if no dynamic linking is done */
667 static TCCSyms tcc_syms[] = {
668 TCCSYM(printf)
669 TCCSYM(fprintf)
670 TCCSYM(fopen)
671 TCCSYM(fclose)
672 { NULL, NULL },
675 void *dlsym(void *handle, const char *symbol)
677 TCCSyms *p;
678 p = tcc_syms;
679 while (p->str != NULL) {
680 if (!strcmp(p->str, symbol))
681 return p->ptr;
682 p++;
684 return NULL;
687 #endif
689 /********************************************************/
691 /* we use our own 'finite' function to avoid potential problems with
692 non standard math libs */
693 /* XXX: endianness dependant */
694 int ieee_finite(double d)
696 int *p = (int *)&d;
697 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
700 /* copy a string and truncate it. */
701 static char *pstrcpy(char *buf, int buf_size, const char *s)
703 char *q, *q_end;
704 int c;
706 if (buf_size > 0) {
707 q = buf;
708 q_end = buf + buf_size - 1;
709 while (q < q_end) {
710 c = *s++;
711 if (c == '\0')
712 break;
713 *q++ = c;
715 *q = '\0';
717 return buf;
720 /* strcat and truncate. */
721 static char *pstrcat(char *buf, int buf_size, const char *s)
723 int len;
724 len = strlen(buf);
725 if (len < buf_size)
726 pstrcpy(buf + len, buf_size - len, s);
727 return buf;
730 /* memory management */
731 #ifdef MEM_DEBUG
732 int mem_cur_size;
733 int mem_max_size;
734 #endif
736 static inline void tcc_free(void *ptr)
738 #ifdef MEM_DEBUG
739 mem_cur_size -= malloc_usable_size(ptr);
740 #endif
741 free(ptr);
744 static void *tcc_malloc(unsigned long size)
746 void *ptr;
747 ptr = malloc(size);
748 if (!ptr && size)
749 error("memory full");
750 #ifdef MEM_DEBUG
751 mem_cur_size += malloc_usable_size(ptr);
752 if (mem_cur_size > mem_max_size)
753 mem_max_size = mem_cur_size;
754 #endif
755 return ptr;
758 static void *tcc_mallocz(unsigned long size)
760 void *ptr;
761 ptr = tcc_malloc(size);
762 memset(ptr, 0, size);
763 return ptr;
766 static inline void *tcc_realloc(void *ptr, unsigned long size)
768 void *ptr1;
769 #ifdef MEM_DEBUG
770 mem_cur_size -= malloc_usable_size(ptr);
771 #endif
772 ptr1 = realloc(ptr, size);
773 #ifdef MEM_DEBUG
774 /* NOTE: count not correct if alloc error, but not critical */
775 mem_cur_size += malloc_usable_size(ptr1);
776 if (mem_cur_size > mem_max_size)
777 mem_max_size = mem_cur_size;
778 #endif
779 return ptr1;
782 static char *tcc_strdup(const char *str)
784 char *ptr;
785 ptr = tcc_malloc(strlen(str) + 1);
786 strcpy(ptr, str);
787 return ptr;
790 #define free(p) use_tcc_free(p)
791 #define malloc(s) use_tcc_malloc(s)
792 #define realloc(p, s) use_tcc_realloc(p, s)
794 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
796 int nb, nb_alloc;
797 void **pp;
799 nb = *nb_ptr;
800 pp = *ptab;
801 /* every power of two we double array size */
802 if ((nb & (nb - 1)) == 0) {
803 if (!nb)
804 nb_alloc = 1;
805 else
806 nb_alloc = nb * 2;
807 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
808 if (!pp)
809 error("memory full");
810 *ptab = pp;
812 pp[nb++] = data;
813 *nb_ptr = nb;
816 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
818 Section *sec;
820 sec = tcc_mallocz(sizeof(Section));
821 pstrcpy(sec->name, sizeof(sec->name), name);
822 sec->sh_type = sh_type;
823 sec->sh_flags = sh_flags;
824 switch(sh_type) {
825 case SHT_HASH:
826 case SHT_REL:
827 case SHT_DYNSYM:
828 case SHT_SYMTAB:
829 case SHT_DYNAMIC:
830 sec->sh_addralign = 4;
831 break;
832 case SHT_STRTAB:
833 sec->sh_addralign = 1;
834 break;
835 default:
836 sec->sh_addralign = 32; /* default conservative alignment */
837 break;
840 /* only add section if not private */
841 if (!(sh_flags & SHF_PRIVATE)) {
842 sec->sh_num = s1->nb_sections;
843 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
845 return sec;
848 static void free_section(Section *s)
850 tcc_free(s->data);
851 tcc_free(s);
854 /* realloc section and set its content to zero */
855 static void section_realloc(Section *sec, unsigned long new_size)
857 unsigned long size;
858 unsigned char *data;
860 size = sec->data_allocated;
861 if (size == 0)
862 size = 1;
863 while (size < new_size)
864 size = size * 2;
865 data = tcc_realloc(sec->data, size);
866 if (!data)
867 error("memory full");
868 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
869 sec->data = data;
870 sec->data_allocated = size;
873 /* reserve at least 'size' bytes in section 'sec' from
874 sec->data_offset. */
875 static void *section_ptr_add(Section *sec, unsigned long size)
877 unsigned long offset, offset1;
879 offset = sec->data_offset;
880 offset1 = offset + size;
881 if (offset1 > sec->data_allocated)
882 section_realloc(sec, offset1);
883 sec->data_offset = offset1;
884 return sec->data + offset;
887 /* return a reference to a section, and create it if it does not
888 exists */
889 Section *find_section(TCCState *s1, const char *name)
891 Section *sec;
892 int i;
893 for(i = 1; i < s1->nb_sections; i++) {
894 sec = s1->sections[i];
895 if (!strcmp(name, sec->name))
896 return sec;
898 /* sections are created as PROGBITS */
899 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
902 /* update sym->c so that it points to an external symbol in section
903 'section' with value 'value' */
904 static void put_extern_sym(Sym *sym, Section *section,
905 unsigned long value, unsigned long size)
907 int sym_type, sym_bind, sh_num, info;
908 Elf32_Sym *esym;
909 const char *name;
911 if (section)
912 sh_num = section->sh_num;
913 else
914 sh_num = SHN_UNDEF;
915 if (!sym->c) {
916 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
917 sym_type = STT_FUNC;
918 else
919 sym_type = STT_OBJECT;
920 if (sym->type.t & VT_STATIC)
921 sym_bind = STB_LOCAL;
922 else
923 sym_bind = STB_GLOBAL;
925 name = get_tok_str(sym->v, NULL);
926 #ifdef CONFIG_TCC_BCHECK
927 if (do_bounds_check) {
928 char buf[32];
930 /* XXX: avoid doing that for statics ? */
931 /* if bound checking is activated, we change some function
932 names by adding the "__bound" prefix */
933 switch(sym->v) {
934 #if 0
935 /* XXX: we rely only on malloc hooks */
936 case TOK_malloc:
937 case TOK_free:
938 case TOK_realloc:
939 case TOK_memalign:
940 case TOK_calloc:
941 #endif
942 case TOK_memcpy:
943 case TOK_memmove:
944 case TOK_memset:
945 case TOK_strlen:
946 case TOK_strcpy:
947 strcpy(buf, "__bound_");
948 strcat(buf, name);
949 name = buf;
950 break;
953 #endif
954 info = ELF32_ST_INFO(sym_bind, sym_type);
955 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
956 } else {
957 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
958 esym->st_value = value;
959 esym->st_size = size;
960 esym->st_shndx = sh_num;
964 /* add a new relocation entry to symbol 'sym' in section 's' */
965 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
967 if (!sym->c)
968 put_extern_sym(sym, NULL, 0, 0);
969 /* now we can add ELF relocation info */
970 put_elf_reloc(symtab_section, s, offset, type, sym->c);
973 static inline int isid(int c)
975 return (c >= 'a' && c <= 'z') ||
976 (c >= 'A' && c <= 'Z') ||
977 c == '_';
980 static inline int isnum(int c)
982 return c >= '0' && c <= '9';
985 static inline int isoct(int c)
987 return c >= '0' && c <= '7';
990 static inline int toup(int c)
992 if (c >= 'a' && c <= 'z')
993 return c - 'a' + 'A';
994 else
995 return c;
998 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1000 int len;
1001 len = strlen(buf);
1002 vsnprintf(buf + len, buf_size - len, fmt, ap);
1005 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1007 va_list ap;
1008 va_start(ap, fmt);
1009 strcat_vprintf(buf, buf_size, fmt, ap);
1010 va_end(ap);
1013 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1015 char buf[2048];
1016 BufferedFile **f;
1018 buf[0] = '\0';
1019 if (file) {
1020 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1021 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1022 (*f)->filename, (*f)->line_num);
1023 if (file->line_num > 0) {
1024 strcat_printf(buf, sizeof(buf),
1025 "%s:%d: ", file->filename, file->line_num);
1026 } else {
1027 strcat_printf(buf, sizeof(buf),
1028 "%s: ", file->filename);
1030 } else {
1031 strcat_printf(buf, sizeof(buf),
1032 "tcc: ");
1034 if (is_warning)
1035 strcat_printf(buf, sizeof(buf), "warning: ");
1036 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1038 if (!s1->error_func) {
1039 /* default case: stderr */
1040 fprintf(stderr, "%s\n", buf);
1041 } else {
1042 s1->error_func(s1->error_opaque, buf);
1044 if (!is_warning)
1045 s1->nb_errors++;
1048 #ifdef LIBTCC
1049 void tcc_set_error_func(TCCState *s, void *error_opaque,
1050 void (*error_func)(void *opaque, const char *msg))
1052 s->error_opaque = error_opaque;
1053 s->error_func = error_func;
1055 #endif
1057 /* error without aborting current compilation */
1058 void error_noabort(const char *fmt, ...)
1060 TCCState *s1 = tcc_state;
1061 va_list ap;
1063 va_start(ap, fmt);
1064 error1(s1, 0, fmt, ap);
1065 va_end(ap);
1068 void error(const char *fmt, ...)
1070 TCCState *s1 = tcc_state;
1071 va_list ap;
1073 va_start(ap, fmt);
1074 error1(s1, 0, fmt, ap);
1075 va_end(ap);
1076 /* better than nothing: in some cases, we accept to handle errors */
1077 if (s1->error_set_jmp_enabled) {
1078 longjmp(s1->error_jmp_buf, 1);
1079 } else {
1080 /* XXX: suppress it someday */
1081 exit(1);
1085 void expect(const char *msg)
1087 error("%s expected", msg);
1090 void warning(const char *fmt, ...)
1092 TCCState *s1 = tcc_state;
1093 va_list ap;
1095 va_start(ap, fmt);
1096 error1(s1, 1, fmt, ap);
1097 va_end(ap);
1100 void skip(int c)
1102 if (tok != c)
1103 error("'%c' expected", c);
1104 next();
1107 void test_lvalue(void)
1109 if (!(vtop->r & VT_LVAL))
1110 expect("lvalue");
1113 TokenSym *tok_alloc(const char *str, int len)
1115 TokenSym *ts, **pts, **ptable;
1116 int h, i;
1118 h = 1;
1119 for(i=0;i<len;i++)
1120 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1122 pts = &hash_ident[h];
1123 while (1) {
1124 ts = *pts;
1125 if (!ts)
1126 break;
1127 if (ts->len == len && !memcmp(ts->str, str, len))
1128 return ts;
1129 pts = &(ts->hash_next);
1132 if (tok_ident >= SYM_FIRST_ANOM)
1133 error("memory full");
1135 /* expand token table if needed */
1136 i = tok_ident - TOK_IDENT;
1137 if ((i % TOK_ALLOC_INCR) == 0) {
1138 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1139 if (!ptable)
1140 error("memory full");
1141 table_ident = ptable;
1144 ts = tcc_malloc(sizeof(TokenSym) + len);
1145 table_ident[i] = ts;
1146 ts->tok = tok_ident++;
1147 ts->sym_define = NULL;
1148 ts->sym_label = NULL;
1149 ts->sym_struct = NULL;
1150 ts->sym_identifier = NULL;
1151 ts->len = len;
1152 ts->hash_next = NULL;
1153 memcpy(ts->str, str, len + 1);
1154 *pts = ts;
1155 return ts;
1158 /* CString handling */
1160 static void cstr_realloc(CString *cstr, int new_size)
1162 int size;
1163 void *data;
1165 size = cstr->size_allocated;
1166 if (size == 0)
1167 size = 8; /* no need to allocate a too small first string */
1168 while (size < new_size)
1169 size = size * 2;
1170 data = tcc_realloc(cstr->data_allocated, size);
1171 if (!data)
1172 error("memory full");
1173 cstr->data_allocated = data;
1174 cstr->size_allocated = size;
1175 cstr->data = data;
1178 /* add a byte */
1179 static void cstr_ccat(CString *cstr, int ch)
1181 int size;
1182 size = cstr->size + 1;
1183 if (size > cstr->size_allocated)
1184 cstr_realloc(cstr, size);
1185 ((unsigned char *)cstr->data)[size - 1] = ch;
1186 cstr->size = size;
1189 static void cstr_cat(CString *cstr, const char *str)
1191 int c;
1192 for(;;) {
1193 c = *str;
1194 if (c == '\0')
1195 break;
1196 cstr_ccat(cstr, c);
1197 str++;
1201 /* add a wide char */
1202 static void cstr_wccat(CString *cstr, int ch)
1204 int size;
1205 size = cstr->size + sizeof(int);
1206 if (size > cstr->size_allocated)
1207 cstr_realloc(cstr, size);
1208 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1209 cstr->size = size;
1212 static void cstr_new(CString *cstr)
1214 memset(cstr, 0, sizeof(CString));
1217 /* free string and reset it to NULL */
1218 static void cstr_free(CString *cstr)
1220 tcc_free(cstr->data_allocated);
1221 cstr_new(cstr);
1224 #define cstr_reset(cstr) cstr_free(cstr)
1226 /* XXX: unicode ? */
1227 static void add_char(CString *cstr, int c)
1229 if (c == '\'' || c == '\"' || c == '\\') {
1230 /* XXX: could be more precise if char or string */
1231 cstr_ccat(cstr, '\\');
1233 if (c >= 32 && c <= 126) {
1234 cstr_ccat(cstr, c);
1235 } else {
1236 cstr_ccat(cstr, '\\');
1237 if (c == '\n') {
1238 cstr_ccat(cstr, 'n');
1239 } else {
1240 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1241 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1242 cstr_ccat(cstr, '0' + (c & 7));
1247 /* XXX: buffer overflow */
1248 /* XXX: float tokens */
1249 char *get_tok_str(int v, CValue *cv)
1251 static char buf[STRING_MAX_SIZE + 1];
1252 static CString cstr_buf;
1253 CString *cstr;
1254 unsigned char *q;
1255 char *p;
1256 int i, len;
1258 /* NOTE: to go faster, we give a fixed buffer for small strings */
1259 cstr_reset(&cstr_buf);
1260 cstr_buf.data = buf;
1261 cstr_buf.size_allocated = sizeof(buf);
1262 p = buf;
1264 switch(v) {
1265 case TOK_CINT:
1266 case TOK_CUINT:
1267 /* XXX: not quite exact, but only useful for testing */
1268 sprintf(p, "%u", cv->ui);
1269 break;
1270 case TOK_CLLONG:
1271 case TOK_CULLONG:
1272 /* XXX: not quite exact, but only useful for testing */
1273 sprintf(p, "%Lu", cv->ull);
1274 break;
1275 case TOK_CCHAR:
1276 case TOK_LCHAR:
1277 cstr_ccat(&cstr_buf, '\'');
1278 add_char(&cstr_buf, cv->i);
1279 cstr_ccat(&cstr_buf, '\'');
1280 cstr_ccat(&cstr_buf, '\0');
1281 break;
1282 case TOK_PPNUM:
1283 cstr = cv->cstr;
1284 len = cstr->size - 1;
1285 for(i=0;i<len;i++)
1286 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1287 cstr_ccat(&cstr_buf, '\0');
1288 break;
1289 case TOK_STR:
1290 case TOK_LSTR:
1291 cstr = cv->cstr;
1292 cstr_ccat(&cstr_buf, '\"');
1293 if (v == TOK_STR) {
1294 len = cstr->size - 1;
1295 for(i=0;i<len;i++)
1296 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1297 } else {
1298 len = (cstr->size / sizeof(int)) - 1;
1299 for(i=0;i<len;i++)
1300 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1302 cstr_ccat(&cstr_buf, '\"');
1303 cstr_ccat(&cstr_buf, '\0');
1304 break;
1305 case TOK_LT:
1306 v = '<';
1307 goto addv;
1308 case TOK_GT:
1309 v = '>';
1310 goto addv;
1311 case TOK_A_SHL:
1312 return strcpy(p, "<<=");
1313 case TOK_A_SAR:
1314 return strcpy(p, ">>=");
1315 default:
1316 if (v < TOK_IDENT) {
1317 /* search in two bytes table */
1318 q = tok_two_chars;
1319 while (*q) {
1320 if (q[2] == v) {
1321 *p++ = q[0];
1322 *p++ = q[1];
1323 *p = '\0';
1324 return buf;
1326 q += 3;
1328 addv:
1329 *p++ = v;
1330 *p = '\0';
1331 } else if (v < tok_ident) {
1332 return table_ident[v - TOK_IDENT]->str;
1333 } else if (v >= SYM_FIRST_ANOM) {
1334 /* special name for anonymous symbol */
1335 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1336 } else {
1337 /* should never happen */
1338 return NULL;
1340 break;
1342 return cstr_buf.data;
1345 /* push, without hashing */
1346 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1348 Sym *s;
1349 s = tcc_malloc(sizeof(Sym));
1350 s->v = v;
1351 s->type.t = t;
1352 s->c = c;
1353 s->next = NULL;
1354 /* add in stack */
1355 s->prev = *ps;
1356 *ps = s;
1357 return s;
1360 /* find a symbol and return its associated structure. 's' is the top
1361 of the symbol stack */
1362 static Sym *sym_find2(Sym *s, int v)
1364 while (s) {
1365 if (s->v == v)
1366 return s;
1367 s = s->prev;
1369 return NULL;
1372 /* structure lookup */
1373 static Sym *struct_find(int v)
1375 v -= TOK_IDENT;
1376 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1377 return NULL;
1378 return table_ident[v]->sym_struct;
1381 /* find an identifier */
1382 static inline Sym *sym_find(int v)
1384 v -= TOK_IDENT;
1385 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1386 return NULL;
1387 return table_ident[v]->sym_identifier;
1390 /* push a given symbol on the symbol stack */
1391 static Sym *sym_push(int v, CType *type, int r, int c)
1393 Sym *s, **ps;
1394 TokenSym *ts;
1396 if (local_stack)
1397 ps = &local_stack;
1398 else
1399 ps = &global_stack;
1400 s = sym_push2(ps, v, type->t, c);
1401 s->type.ref = type->ref;
1402 s->r = r;
1403 /* don't record fields or anonymous symbols */
1404 /* XXX: simplify */
1405 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1406 /* record symbol in token array */
1407 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1408 if (v & SYM_STRUCT)
1409 ps = &ts->sym_struct;
1410 else
1411 ps = &ts->sym_identifier;
1412 s->prev_tok = *ps;
1413 *ps = s;
1415 return s;
1418 /* push a global identifier */
1419 static Sym *global_identifier_push(int v, int t, int c)
1421 Sym *s, **ps;
1422 s = sym_push2(&global_stack, v, t, c);
1423 /* don't record anonymous symbol */
1424 if (v < SYM_FIRST_ANOM) {
1425 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1426 /* modify the top most local identifier, so that
1427 sym_identifier will point to 's' when popped */
1428 while (*ps != NULL)
1429 ps = &(*ps)->prev_tok;
1430 s->prev_tok = NULL;
1431 *ps = s;
1433 return s;
1436 /* pop symbols until top reaches 'b' */
1437 static void sym_pop(Sym **ptop, Sym *b)
1439 Sym *s, *ss, **ps;
1440 TokenSym *ts;
1441 int v;
1443 s = *ptop;
1444 while(s != b) {
1445 ss = s->prev;
1446 v = s->v;
1447 /* remove symbol in token array */
1448 /* XXX: simplify */
1449 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1450 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1451 if (v & SYM_STRUCT)
1452 ps = &ts->sym_struct;
1453 else
1454 ps = &ts->sym_identifier;
1455 *ps = s->prev_tok;
1457 tcc_free(s);
1458 s = ss;
1460 *ptop = b;
1463 /* I/O layer */
1465 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1467 int fd;
1468 BufferedFile *bf;
1470 fd = open(filename, O_RDONLY);
1471 if (fd < 0)
1472 return NULL;
1473 bf = tcc_malloc(sizeof(BufferedFile));
1474 if (!bf) {
1475 close(fd);
1476 return NULL;
1478 bf->fd = fd;
1479 bf->buf_ptr = bf->buffer;
1480 bf->buf_end = bf->buffer;
1481 bf->buffer[0] = CH_EOB; /* put eob symbol */
1482 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1483 bf->line_num = 1;
1484 bf->ifndef_macro = 0;
1485 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1486 // printf("opening '%s'\n", filename);
1487 return bf;
1490 void tcc_close(BufferedFile *bf)
1492 total_lines += bf->line_num;
1493 close(bf->fd);
1494 tcc_free(bf);
1497 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1498 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1500 /* fill input buffer and return next char */
1501 int tcc_getc_slow(BufferedFile *bf)
1503 int len;
1504 /* only tries to read if really end of buffer */
1505 if (bf->buf_ptr >= bf->buf_end) {
1506 if (bf->fd != -1) {
1507 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1508 if (len < 0)
1509 len = 0;
1510 } else {
1511 len = 0;
1513 total_bytes += len;
1514 bf->buf_ptr = bf->buffer;
1515 bf->buf_end = bf->buffer + len;
1516 *bf->buf_end = CH_EOB;
1518 if (bf->buf_ptr < bf->buf_end) {
1519 return *bf->buf_ptr++;
1520 } else {
1521 bf->buf_ptr = bf->buf_end;
1522 return CH_EOF;
1526 /* no need to put that inline */
1527 void handle_eob(void)
1529 TCCState *s1 = tcc_state;
1530 for(;;) {
1531 ch1 = tcc_getc_slow(file);
1532 if (ch1 != CH_EOF)
1533 return;
1534 eof_seen = 1;
1535 if (return_linefeed) {
1536 ch1 = '\n';
1537 return;
1539 if (s1->include_stack_ptr == s1->include_stack)
1540 return;
1541 /* add end of include file debug info */
1542 if (do_debug) {
1543 put_stabd(N_EINCL, 0, 0);
1545 /* pop include stack */
1546 tcc_close(file);
1547 s1->include_stack_ptr--;
1548 file = *s1->include_stack_ptr;
1552 /* read next char from current input file */
1553 static inline void inp(void)
1555 ch1 = TCC_GETC(file);
1556 /* end of buffer/file handling */
1557 if (ch1 == CH_EOB)
1558 handle_eob();
1559 if (ch1 == '\n')
1560 file->line_num++;
1561 // printf("ch1=%c 0x%x\n", ch1, ch1);
1564 /* handle '\\n' and '\\r\n' */
1565 static void handle_stray(void)
1567 do {
1568 if (ch1 == '\n') {
1569 inp();
1570 } else if (ch1 == '\r') {
1571 inp();
1572 if (ch1 != '\n')
1573 error("invalid character after '\\'");
1574 inp();
1575 } else {
1576 break;
1578 ch = ch1;
1579 inp();
1580 } while (ch == '\\');
1583 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1584 case */
1585 static inline void minp(void)
1587 ch = ch1;
1588 inp();
1589 if (ch == '\\')
1590 handle_stray();
1594 /* same as minp, but also skip comments */
1595 static void cinp(void)
1597 int c;
1599 if (ch1 == '/') {
1600 inp();
1601 if (ch1 == '/') {
1602 /* single line C++ comments */
1603 inp();
1604 while (ch1 != '\n' && ch1 != CH_EOF)
1605 inp();
1606 ch = ' '; /* return space */
1607 } else if (ch1 == '*') {
1608 /* C comments */
1609 inp();
1610 while (ch1 != CH_EOF) {
1611 c = ch1;
1612 inp();
1613 if (c == '*' && ch1 == '/') {
1614 inp();
1615 ch = ' '; /* return space */
1616 break;
1619 } else {
1620 ch = '/';
1622 } else {
1623 minp();
1627 /* space exlcuding newline */
1628 static inline int is_space(int ch)
1630 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1633 static inline void skip_spaces(void)
1635 while (is_space(ch))
1636 cinp();
1639 /* skip block of text until #else, #elif or #endif. skip also pairs of
1640 #if/#endif */
1641 void preprocess_skip(void)
1643 int a;
1644 a = 0;
1645 while (1) {
1646 while (ch != '\n') {
1647 if (ch == CH_EOF)
1648 expect("#endif");
1649 cinp();
1651 cinp();
1652 skip_spaces();
1653 if (ch == '#') {
1654 cinp();
1655 next_nomacro();
1656 if (a == 0 &&
1657 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1658 break;
1659 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1660 a++;
1661 else if (tok == TOK_ENDIF)
1662 a--;
1667 /* ParseState handling */
1669 /* XXX: currently, no include file info is stored. Thus, we cannot display
1670 accurate messages if the function or data definition spans multiple
1671 files */
1673 /* save current parse state in 's' */
1674 void save_parse_state(ParseState *s)
1676 s->line_num = file->line_num;
1677 s->macro_ptr = macro_ptr;
1678 s->tok = tok;
1679 s->tokc = tokc;
1682 /* restore parse state from 's' */
1683 void restore_parse_state(ParseState *s)
1685 file->line_num = s->line_num;
1686 macro_ptr = s->macro_ptr;
1687 tok = s->tok;
1688 tokc = s->tokc;
1691 /* return the number of additionnal 'ints' necessary to store the
1692 token */
1693 static inline int tok_ext_size(int t)
1695 switch(t) {
1696 /* 4 bytes */
1697 case TOK_CINT:
1698 case TOK_CUINT:
1699 case TOK_CCHAR:
1700 case TOK_LCHAR:
1701 case TOK_STR:
1702 case TOK_LSTR:
1703 case TOK_CFLOAT:
1704 case TOK_LINENUM:
1705 case TOK_PPNUM:
1706 return 1;
1707 case TOK_CDOUBLE:
1708 case TOK_CLLONG:
1709 case TOK_CULLONG:
1710 return 2;
1711 case TOK_CLDOUBLE:
1712 return LDOUBLE_SIZE / 4;
1713 default:
1714 return 0;
1718 /* token string handling */
1720 static inline void tok_str_new(TokenString *s)
1722 s->str = NULL;
1723 s->len = 0;
1724 s->last_line_num = -1;
1727 static void tok_str_free(int *str)
1729 const int *p;
1730 CString *cstr;
1731 int t;
1733 p = str;
1734 for(;;) {
1735 t = *p++;
1736 if (t == 0)
1737 break;
1738 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1739 /* XXX: use a macro to be portable on 64 bit ? */
1740 cstr = (CString *)(*p++);
1741 cstr_free(cstr);
1742 tcc_free(cstr);
1743 } else {
1744 p += tok_ext_size(t);
1747 tcc_free(str);
1750 static void tok_str_add(TokenString *s, int t)
1752 int len, *str;
1754 len = s->len;
1755 str = s->str;
1756 if ((len & 63) == 0) {
1757 str = tcc_realloc(str, (len + 64) * sizeof(int));
1758 if (!str)
1759 return;
1760 s->str = str;
1762 str[len++] = t;
1763 s->len = len;
1766 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1768 int n, i, size;
1769 CString *cstr, *cstr1;
1770 CValue cv1;
1772 tok_str_add(s, t);
1773 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1774 /* special case: need to duplicate string */
1775 cstr1 = cv->cstr;
1776 cstr = tcc_malloc(sizeof(CString));
1777 size = cstr1->size;
1778 cstr->size = size;
1779 cstr->size_allocated = size;
1780 cstr->data_allocated = tcc_malloc(size);
1781 cstr->data = cstr->data_allocated;
1782 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1783 cv1.cstr = cstr;
1784 tok_str_add(s, cv1.tab[0]);
1785 } else {
1786 n = tok_ext_size(t);
1787 for(i=0;i<n;i++)
1788 tok_str_add(s, cv->tab[i]);
1792 /* add the current parse token in token string 's' */
1793 static void tok_str_add_tok(TokenString *s)
1795 CValue cval;
1797 /* save line number info */
1798 if (file->line_num != s->last_line_num) {
1799 s->last_line_num = file->line_num;
1800 cval.i = s->last_line_num;
1801 tok_str_add2(s, TOK_LINENUM, &cval);
1803 tok_str_add2(s, tok, &tokc);
1806 /* get a token from an integer array and increment pointer accordingly */
1807 static int tok_get(int **tok_str, CValue *cv)
1809 int *p, t, n, i;
1811 p = *tok_str;
1812 t = *p++;
1813 n = tok_ext_size(t);
1814 for(i=0;i<n;i++)
1815 cv->tab[i] = *p++;
1816 *tok_str = p;
1817 return t;
1820 /* defines handling */
1821 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
1823 Sym *s;
1825 s = sym_push2(&define_stack, v, macro_type, (int)str);
1826 s->next = first_arg;
1827 table_ident[v - TOK_IDENT]->sym_define = s;
1830 /* undefined a define symbol. Its name is just set to zero */
1831 static void define_undef(Sym *s)
1833 int v;
1834 v = s->v;
1835 if (v >= TOK_IDENT && v < tok_ident)
1836 table_ident[v - TOK_IDENT]->sym_define = NULL;
1837 s->v = 0;
1840 static inline Sym *define_find(int v)
1842 v -= TOK_IDENT;
1843 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1844 return NULL;
1845 return table_ident[v]->sym_define;
1848 /* free define stack until top reaches 'b' */
1849 static void free_defines(Sym *b)
1851 Sym *top, *top1;
1852 int v;
1854 top = define_stack;
1855 while (top != b) {
1856 top1 = top->prev;
1857 /* do not free args or predefined defines */
1858 if (top->c)
1859 tok_str_free((int *)top->c);
1860 v = top->v;
1861 if (v >= TOK_IDENT && v < tok_ident)
1862 table_ident[v - TOK_IDENT]->sym_define = NULL;
1863 tcc_free(top);
1864 top = top1;
1866 define_stack = b;
1869 /* label lookup */
1870 static Sym *label_find(int v)
1872 v -= TOK_IDENT;
1873 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1874 return NULL;
1875 return table_ident[v]->sym_label;
1878 static Sym *label_push(int v, int flags)
1880 Sym *s;
1881 s = sym_push2(&label_stack, v, 0, 0);
1882 s->r = flags;
1883 table_ident[v - TOK_IDENT]->sym_label = s;
1884 return s;
1887 /* eval an expression for #if/#elif */
1888 int expr_preprocess(void)
1890 int c, t;
1891 TokenString str;
1893 tok_str_new(&str);
1894 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1895 next(); /* do macro subst */
1896 if (tok == TOK_DEFINED) {
1897 next_nomacro();
1898 t = tok;
1899 if (t == '(')
1900 next_nomacro();
1901 c = define_find(tok) != 0;
1902 if (t == '(')
1903 next_nomacro();
1904 tok = TOK_CINT;
1905 tokc.i = c;
1906 } else if (tok >= TOK_IDENT) {
1907 /* if undefined macro */
1908 tok = TOK_CINT;
1909 tokc.i = 0;
1911 tok_str_add_tok(&str);
1913 tok_str_add(&str, -1); /* simulate end of file */
1914 tok_str_add(&str, 0);
1915 /* now evaluate C constant expression */
1916 macro_ptr = str.str;
1917 next();
1918 c = expr_const();
1919 macro_ptr = NULL;
1920 tok_str_free(str.str);
1921 return c != 0;
1924 #if defined(DEBUG) || defined(PP_DEBUG)
1925 void tok_print(int *str)
1927 int t;
1928 CValue cval;
1930 while (1) {
1931 t = tok_get(&str, &cval);
1932 if (!t)
1933 break;
1934 printf(" %s", get_tok_str(t, &cval));
1936 printf("\n");
1938 #endif
1940 /* parse after #define */
1941 void parse_define(void)
1943 Sym *s, *first, **ps;
1944 int v, t, varg, is_vaargs;
1945 TokenString str;
1947 v = tok;
1948 if (v < TOK_IDENT)
1949 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
1950 /* XXX: should check if same macro (ANSI) */
1951 first = NULL;
1952 t = MACRO_OBJ;
1953 /* '(' must be just after macro definition for MACRO_FUNC */
1954 if (ch == '(') {
1955 next_nomacro();
1956 next_nomacro();
1957 ps = &first;
1958 while (tok != ')') {
1959 varg = tok;
1960 next_nomacro();
1961 is_vaargs = 0;
1962 if (varg == TOK_DOTS) {
1963 varg = TOK___VA_ARGS__;
1964 is_vaargs = 1;
1965 } else if (tok == TOK_DOTS && gnu_ext) {
1966 is_vaargs = 1;
1967 next_nomacro();
1969 if (varg < TOK_IDENT)
1970 error("badly punctuated parameter list");
1971 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1972 *ps = s;
1973 ps = &s->next;
1974 if (tok != ',')
1975 break;
1976 next_nomacro();
1978 t = MACRO_FUNC;
1980 tok_str_new(&str);
1981 next_nomacro();
1982 /* EOF testing necessary for '-D' handling */
1983 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1984 tok_str_add2(&str, tok, &tokc);
1985 next_nomacro();
1987 tok_str_add(&str, 0);
1988 #ifdef PP_DEBUG
1989 printf("define %s %d: ", get_tok_str(v, NULL), t);
1990 tok_print(str.str);
1991 #endif
1992 define_push(v, t, str.str, first);
1995 /* XXX: use a token or a hash table to accelerate matching ? */
1996 static CachedInclude *search_cached_include(TCCState *s1,
1997 int type, const char *filename)
1999 CachedInclude *e;
2000 int i;
2002 for(i = 0;i < s1->nb_cached_includes; i++) {
2003 e = s1->cached_includes[i];
2004 if (e->type == type && !strcmp(e->filename, filename))
2005 return e;
2007 return NULL;
2010 static inline void add_cached_include(TCCState *s1, int type,
2011 const char *filename, int ifndef_macro)
2013 CachedInclude *e;
2015 if (search_cached_include(s1, type, filename))
2016 return;
2017 #ifdef INC_DEBUG
2018 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2019 #endif
2020 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2021 if (!e)
2022 return;
2023 e->type = type;
2024 strcpy(e->filename, filename);
2025 e->ifndef_macro = ifndef_macro;
2026 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2030 enum IncludeState {
2031 INCLUDE_STATE_NONE = 0,
2032 INCLUDE_STATE_SEEK_IFNDEF,
2035 void preprocess(void)
2037 TCCState *s1 = tcc_state;
2038 int size, i, c, n, line_num;
2039 enum IncludeState state;
2040 char buf[1024], *q, *p;
2041 char buf1[1024];
2042 BufferedFile *f;
2043 Sym *s;
2044 CachedInclude *e;
2046 return_linefeed = 1; /* linefeed will be returned as a
2047 token. EOF is also returned as line feed */
2048 state = INCLUDE_STATE_NONE;
2049 eof_seen = 0;
2050 redo1:
2051 cinp();
2052 next_nomacro();
2053 redo:
2054 switch(tok) {
2055 case TOK_DEFINE:
2056 next_nomacro();
2057 parse_define();
2058 break;
2059 case TOK_UNDEF:
2060 next_nomacro();
2061 s = define_find(tok);
2062 /* undefine symbol by putting an invalid name */
2063 if (s)
2064 define_undef(s);
2065 break;
2066 case TOK_INCLUDE:
2067 skip_spaces();
2068 if (ch == '<') {
2069 c = '>';
2070 goto read_name;
2071 } else if (ch == '\"') {
2072 c = ch;
2073 read_name:
2074 minp();
2075 q = buf;
2076 while (ch != c && ch != '\n' && ch != CH_EOF) {
2077 if ((q - buf) < sizeof(buf) - 1)
2078 *q++ = ch;
2079 minp();
2081 *q = '\0';
2082 /* eat all spaces and comments after include */
2083 /* XXX: slightly incorrect */
2084 while (ch1 != '\n' && ch1 != CH_EOF)
2085 inp();
2086 } else {
2087 /* computed #include : either we have only strings or
2088 we have anything enclosed in '<>' */
2089 next();
2090 buf[0] = '\0';
2091 if (tok == TOK_STR) {
2092 while (tok != TOK_LINEFEED) {
2093 if (tok != TOK_STR) {
2094 include_syntax:
2095 error("'#include' expects \"FILENAME\" or <FILENAME>");
2097 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2098 next();
2100 c = '\"';
2101 } else {
2102 int len;
2103 while (tok != TOK_LINEFEED) {
2104 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2105 next();
2107 len = strlen(buf);
2108 /* check syntax and remove '<>' */
2109 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2110 goto include_syntax;
2111 memmove(buf, buf + 1, len - 2);
2112 buf[len - 2] = '\0';
2113 c = '>';
2117 ch = '\n';
2118 e = search_cached_include(s1, c, buf);
2119 if (e && define_find(e->ifndef_macro)) {
2120 /* no need to parse the include because the 'ifndef macro'
2121 is defined */
2122 #ifdef INC_DEBUG
2123 printf("%s: skipping %s\n", file->filename, buf);
2124 #endif
2125 } else {
2126 if (c == '\"') {
2127 /* first search in current dir if "header.h" */
2128 size = 0;
2129 p = strrchr(file->filename, '/');
2130 if (p)
2131 size = p + 1 - file->filename;
2132 if (size > sizeof(buf1) - 1)
2133 size = sizeof(buf1) - 1;
2134 memcpy(buf1, file->filename, size);
2135 buf1[size] = '\0';
2136 pstrcat(buf1, sizeof(buf1), buf);
2137 f = tcc_open(s1, buf1);
2138 if (f)
2139 goto found;
2141 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2142 error("#include recursion too deep");
2143 /* now search in all the include paths */
2144 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2145 for(i = 0; i < n; i++) {
2146 const char *path;
2147 if (i < s1->nb_include_paths)
2148 path = s1->include_paths[i];
2149 else
2150 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2151 pstrcpy(buf1, sizeof(buf1), path);
2152 pstrcat(buf1, sizeof(buf1), "/");
2153 pstrcat(buf1, sizeof(buf1), buf);
2154 f = tcc_open(s1, buf1);
2155 if (f)
2156 goto found;
2158 error("include file '%s' not found", buf);
2159 f = NULL;
2160 found:
2161 #ifdef INC_DEBUG
2162 printf("%s: including %s\n", file->filename, buf1);
2163 #endif
2164 f->inc_type = c;
2165 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2166 /* push current file in stack */
2167 /* XXX: fix current line init */
2168 *s1->include_stack_ptr++ = file;
2169 file = f;
2170 /* add include file debug info */
2171 if (do_debug) {
2172 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2174 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2175 inp();
2176 /* get first non space char */
2177 while (is_space(ch) || ch == '\n')
2178 cinp();
2179 if (ch != '#')
2180 goto the_end;
2181 state = INCLUDE_STATE_SEEK_IFNDEF;
2182 goto redo1;
2184 break;
2185 case TOK_IFNDEF:
2186 c = 1;
2187 goto do_ifdef;
2188 case TOK_IF:
2189 c = expr_preprocess();
2190 goto do_if;
2191 case TOK_IFDEF:
2192 c = 0;
2193 do_ifdef:
2194 next_nomacro();
2195 if (tok < TOK_IDENT)
2196 error("invalid argument for '#if%sdef'", c ? "n" : "");
2197 if (state == INCLUDE_STATE_SEEK_IFNDEF) {
2198 if (c) {
2199 file->ifndef_macro = tok;
2201 state = INCLUDE_STATE_NONE;
2203 c = (define_find(tok) != 0) ^ c;
2204 do_if:
2205 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2206 error("memory full");
2207 *s1->ifdef_stack_ptr++ = c;
2208 goto test_skip;
2209 case TOK_ELSE:
2210 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2211 error("#else without matching #if");
2212 if (s1->ifdef_stack_ptr[-1] & 2)
2213 error("#else after #else");
2214 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2215 goto test_skip;
2216 case TOK_ELIF:
2217 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2218 error("#elif without matching #if");
2219 c = s1->ifdef_stack_ptr[-1];
2220 if (c > 1)
2221 error("#elif after #else");
2222 /* last #if/#elif expression was true: we skip */
2223 if (c == 1)
2224 goto skip;
2225 c = expr_preprocess();
2226 s1->ifdef_stack_ptr[-1] = c;
2227 test_skip:
2228 if (!(c & 1)) {
2229 skip:
2230 preprocess_skip();
2231 state = INCLUDE_STATE_NONE;
2232 goto redo;
2234 break;
2235 case TOK_ENDIF:
2236 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2237 error("#endif without matching #if");
2238 if (file->ifndef_macro &&
2239 s1->ifdef_stack_ptr == (file->ifdef_stack_ptr + 1)) {
2240 /* '#ifndef macro \n #define macro' was at the start of
2241 file. Now we check if an '#endif' is exactly at the end
2242 of file */
2243 while (tok != TOK_LINEFEED)
2244 next_nomacro();
2245 /* XXX: should also skip comments, but it is more complicated */
2246 if (eof_seen) {
2247 add_cached_include(s1, file->inc_type, file->inc_filename,
2248 file->ifndef_macro);
2249 } else {
2250 /* if not end of file, we must desactivate the ifndef
2251 macro search */
2252 file->ifndef_macro = 0;
2255 s1->ifdef_stack_ptr--;
2256 break;
2257 case TOK_LINE:
2258 next();
2259 if (tok != TOK_CINT)
2260 error("#line");
2261 line_num = tokc.i;
2262 next();
2263 if (tok != TOK_LINEFEED) {
2264 if (tok != TOK_STR)
2265 error("#line");
2266 pstrcpy(file->filename, sizeof(file->filename),
2267 (char *)tokc.cstr->data);
2269 /* NOTE: we do it there to avoid problems with linefeed */
2270 file->line_num = line_num;
2271 break;
2272 case TOK_ERROR:
2273 case TOK_WARNING:
2274 c = tok;
2275 skip_spaces();
2276 q = buf;
2277 while (ch != '\n' && ch != CH_EOF) {
2278 if ((q - buf) < sizeof(buf) - 1)
2279 *q++ = ch;
2280 minp();
2282 *q = '\0';
2283 if (c == TOK_ERROR)
2284 error("#error %s", buf);
2285 else
2286 warning("#warning %s", buf);
2287 break;
2288 default:
2289 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2290 /* '!' is ignored to allow C scripts. numbers are ignored
2291 to emulate cpp behaviour */
2292 } else {
2293 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2295 break;
2297 /* ignore other preprocess commands or #! for C scripts */
2298 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2299 next_nomacro();
2300 the_end:
2301 return_linefeed = 0;
2304 /* read a number in base b */
2305 static int getn(int b)
2307 int n, t;
2308 n = 0;
2309 while (1) {
2310 if (ch >= 'a' && ch <= 'f')
2311 t = ch - 'a' + 10;
2312 else if (ch >= 'A' && ch <= 'F')
2313 t = ch - 'A' + 10;
2314 else if (isnum(ch))
2315 t = ch - '0';
2316 else
2317 break;
2318 if (t < 0 || t >= b)
2319 break;
2320 n = n * b + t;
2321 cinp();
2323 return n;
2326 /* read a character for string or char constant and eval escape codes */
2327 static int getq(void)
2329 int c;
2331 c = ch;
2332 minp();
2333 if (c == '\\') {
2334 if (isoct(ch)) {
2335 /* at most three octal digits */
2336 c = ch - '0';
2337 minp();
2338 if (isoct(ch)) {
2339 c = c * 8 + ch - '0';
2340 minp();
2341 if (isoct(ch)) {
2342 c = c * 8 + ch - '0';
2343 minp();
2346 return c;
2347 } else if (ch == 'x') {
2348 minp();
2349 return getn(16);
2350 } else {
2351 if (ch == 'a')
2352 c = '\a';
2353 else if (ch == 'b')
2354 c = '\b';
2355 else if (ch == 'f')
2356 c = '\f';
2357 else if (ch == 'n')
2358 c = '\n';
2359 else if (ch == 'r')
2360 c = '\r';
2361 else if (ch == 't')
2362 c = '\t';
2363 else if (ch == 'v')
2364 c = '\v';
2365 else if (ch == 'e' && gnu_ext)
2366 c = 27;
2367 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2368 c = ch;
2369 else
2370 error("invalid escaped char");
2371 minp();
2373 } else if (c == '\r' && ch == '\n') {
2374 minp();
2375 c = '\n';
2377 return c;
2380 /* we use 64 bit numbers */
2381 #define BN_SIZE 2
2383 /* bn = (bn << shift) | or_val */
2384 void bn_lshift(unsigned int *bn, int shift, int or_val)
2386 int i;
2387 unsigned int v;
2388 for(i=0;i<BN_SIZE;i++) {
2389 v = bn[i];
2390 bn[i] = (v << shift) | or_val;
2391 or_val = v >> (32 - shift);
2395 void bn_zero(unsigned int *bn)
2397 int i;
2398 for(i=0;i<BN_SIZE;i++) {
2399 bn[i] = 0;
2403 /* parse number in null terminated string 'p' and return it in the
2404 current token */
2405 void parse_number(const char *p)
2407 int b, t, shift, frac_bits, s, exp_val, ch;
2408 char *q;
2409 unsigned int bn[BN_SIZE];
2410 double d;
2412 /* number */
2413 q = token_buf;
2414 ch = *p++;
2415 t = ch;
2416 ch = *p++;
2417 *q++ = t;
2418 b = 10;
2419 if (t == '.') {
2420 goto float_frac_parse;
2421 } else if (t == '0') {
2422 if (ch == 'x' || ch == 'X') {
2423 q--;
2424 ch = *p++;
2425 b = 16;
2426 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2427 q--;
2428 ch = *p++;
2429 b = 2;
2432 /* parse all digits. cannot check octal numbers at this stage
2433 because of floating point constants */
2434 while (1) {
2435 if (ch >= 'a' && ch <= 'f')
2436 t = ch - 'a' + 10;
2437 else if (ch >= 'A' && ch <= 'F')
2438 t = ch - 'A' + 10;
2439 else if (isnum(ch))
2440 t = ch - '0';
2441 else
2442 break;
2443 if (t >= b)
2444 break;
2445 if (q >= token_buf + STRING_MAX_SIZE) {
2446 num_too_long:
2447 error("number too long");
2449 *q++ = ch;
2450 ch = *p++;
2452 if (ch == '.' ||
2453 ((ch == 'e' || ch == 'E') && b == 10) ||
2454 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2455 if (b != 10) {
2456 /* NOTE: strtox should support that for hexa numbers, but
2457 non ISOC99 libcs do not support it, so we prefer to do
2458 it by hand */
2459 /* hexadecimal or binary floats */
2460 /* XXX: handle overflows */
2461 *q = '\0';
2462 if (b == 16)
2463 shift = 4;
2464 else
2465 shift = 2;
2466 bn_zero(bn);
2467 q = token_buf;
2468 while (1) {
2469 t = *q++;
2470 if (t == '\0') {
2471 break;
2472 } else if (t >= 'a') {
2473 t = t - 'a' + 10;
2474 } else if (t >= 'A') {
2475 t = t - 'A' + 10;
2476 } else {
2477 t = t - '0';
2479 bn_lshift(bn, shift, t);
2481 frac_bits = 0;
2482 if (ch == '.') {
2483 ch = *p++;
2484 while (1) {
2485 t = ch;
2486 if (t >= 'a' && t <= 'f') {
2487 t = t - 'a' + 10;
2488 } else if (t >= 'A' && t <= 'F') {
2489 t = t - 'A' + 10;
2490 } else if (t >= '0' && t <= '9') {
2491 t = t - '0';
2492 } else {
2493 break;
2495 if (t >= b)
2496 error("invalid digit");
2497 bn_lshift(bn, shift, t);
2498 frac_bits += shift;
2499 ch = *p++;
2502 if (ch != 'p' && ch != 'P')
2503 error("exponent expected");
2504 ch = *p++;
2505 s = 1;
2506 exp_val = 0;
2507 if (ch == '+') {
2508 ch = *p++;
2509 } else if (ch == '-') {
2510 s = -1;
2511 ch = *p++;
2513 if (ch < '0' || ch > '9')
2514 error("exponent digits expected");
2515 while (ch >= '0' && ch <= '9') {
2516 exp_val = exp_val * 10 + ch - '0';
2517 ch = *p++;
2519 exp_val = exp_val * s;
2521 /* now we can generate the number */
2522 /* XXX: should patch directly float number */
2523 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2524 d = ldexp(d, exp_val - frac_bits);
2525 t = toup(ch);
2526 if (t == 'F') {
2527 ch = *p++;
2528 tok = TOK_CFLOAT;
2529 /* float : should handle overflow */
2530 tokc.f = (float)d;
2531 } else if (t == 'L') {
2532 ch = *p++;
2533 tok = TOK_CLDOUBLE;
2534 /* XXX: not large enough */
2535 tokc.ld = (long double)d;
2536 } else {
2537 tok = TOK_CDOUBLE;
2538 tokc.d = d;
2540 } else {
2541 /* decimal floats */
2542 if (ch == '.') {
2543 if (q >= token_buf + STRING_MAX_SIZE)
2544 goto num_too_long;
2545 *q++ = ch;
2546 ch = *p++;
2547 float_frac_parse:
2548 while (ch >= '0' && ch <= '9') {
2549 if (q >= token_buf + STRING_MAX_SIZE)
2550 goto num_too_long;
2551 *q++ = ch;
2552 ch = *p++;
2555 if (ch == 'e' || ch == 'E') {
2556 if (q >= token_buf + STRING_MAX_SIZE)
2557 goto num_too_long;
2558 *q++ = ch;
2559 ch = *p++;
2560 if (ch == '-' || ch == '+') {
2561 if (q >= token_buf + STRING_MAX_SIZE)
2562 goto num_too_long;
2563 *q++ = ch;
2564 ch = *p++;
2566 if (ch < '0' || ch > '9')
2567 error("exponent digits expected");
2568 while (ch >= '0' && ch <= '9') {
2569 if (q >= token_buf + STRING_MAX_SIZE)
2570 goto num_too_long;
2571 *q++ = ch;
2572 ch = *p++;
2575 *q = '\0';
2576 t = toup(ch);
2577 errno = 0;
2578 if (t == 'F') {
2579 ch = *p++;
2580 tok = TOK_CFLOAT;
2581 tokc.f = strtof(token_buf, NULL);
2582 } else if (t == 'L') {
2583 ch = *p++;
2584 tok = TOK_CLDOUBLE;
2585 tokc.ld = strtold(token_buf, NULL);
2586 } else {
2587 tok = TOK_CDOUBLE;
2588 tokc.d = strtod(token_buf, NULL);
2591 } else {
2592 unsigned long long n, n1;
2593 int lcount, ucount;
2595 /* integer number */
2596 *q = '\0';
2597 q = token_buf;
2598 if (b == 10 && *q == '0') {
2599 b = 8;
2600 q++;
2602 n = 0;
2603 while(1) {
2604 t = *q++;
2605 /* no need for checks except for base 10 / 8 errors */
2606 if (t == '\0') {
2607 break;
2608 } else if (t >= 'a') {
2609 t = t - 'a' + 10;
2610 } else if (t >= 'A') {
2611 t = t - 'A' + 10;
2612 } else {
2613 t = t - '0';
2614 if (t >= b)
2615 error("invalid digit");
2617 n1 = n;
2618 n = n * b + t;
2619 /* detect overflow */
2620 /* XXX: this test is not reliable */
2621 if (n < n1)
2622 error("integer constant overflow");
2625 /* XXX: not exactly ANSI compliant */
2626 if ((n & 0xffffffff00000000LL) != 0) {
2627 if ((n >> 63) != 0)
2628 tok = TOK_CULLONG;
2629 else
2630 tok = TOK_CLLONG;
2631 } else if (n > 0x7fffffff) {
2632 tok = TOK_CUINT;
2633 } else {
2634 tok = TOK_CINT;
2636 lcount = 0;
2637 ucount = 0;
2638 for(;;) {
2639 t = toup(ch);
2640 if (t == 'L') {
2641 if (lcount >= 2)
2642 error("three 'l's in integer constant");
2643 lcount++;
2644 if (lcount == 2) {
2645 if (tok == TOK_CINT)
2646 tok = TOK_CLLONG;
2647 else if (tok == TOK_CUINT)
2648 tok = TOK_CULLONG;
2650 ch = *p++;
2651 } else if (t == 'U') {
2652 if (ucount >= 1)
2653 error("two 'u's in integer constant");
2654 ucount++;
2655 if (tok == TOK_CINT)
2656 tok = TOK_CUINT;
2657 else if (tok == TOK_CLLONG)
2658 tok = TOK_CULLONG;
2659 ch = *p++;
2660 } else {
2661 break;
2664 if (tok == TOK_CINT || tok == TOK_CUINT)
2665 tokc.ui = n;
2666 else
2667 tokc.ull = n;
2671 /* return next token without macro substitution */
2672 static inline void next_nomacro1(void)
2674 int b, t;
2675 char *q;
2676 TokenSym *ts;
2678 redo_no_start:
2679 switch(ch) {
2680 case ' ':
2681 case '\t':
2682 case '\f':
2683 case '\v':
2684 case '\r':
2685 cinp();
2686 goto redo_no_start;
2688 case '\n':
2689 if (return_linefeed) {
2690 /* XXX: should eat token ? */
2691 tok = TOK_LINEFEED;
2692 } else {
2693 cinp();
2694 skip_spaces();
2695 if (ch == '#') {
2696 /* preprocessor command if # at start of line after
2697 spaces */
2698 preprocess();
2700 goto redo_no_start;
2702 break;
2704 case '#':
2705 tok = ch;
2706 cinp();
2707 #if 0
2708 if (start_of_line) {
2709 preprocess();
2710 goto redo_no_start;
2711 } else
2712 #endif
2714 if (ch == '#') {
2715 cinp();
2716 tok = TOK_TWOSHARPS;
2719 break;
2721 case 'a': case 'b': case 'c': case 'd':
2722 case 'e': case 'f': case 'g': case 'h':
2723 case 'i': case 'j': case 'k': case 'l':
2724 case 'm': case 'n': case 'o': case 'p':
2725 case 'q': case 'r': case 's': case 't':
2726 case 'u': case 'v': case 'w': case 'x':
2727 case 'y': case 'z':
2728 case 'A': case 'B': case 'C': case 'D':
2729 case 'E': case 'F': case 'G': case 'H':
2730 case 'I': case 'J': case 'K':
2731 case 'M': case 'N': case 'O': case 'P':
2732 case 'Q': case 'R': case 'S': case 'T':
2733 case 'U': case 'V': case 'W': case 'X':
2734 case 'Y': case 'Z':
2735 case '_':
2736 q = token_buf;
2737 *q++ = ch;
2738 cinp();
2739 parse_ident:
2740 while (isid(ch) || isnum(ch)) {
2741 if (q >= token_buf + STRING_MAX_SIZE)
2742 error("ident too long");
2743 *q++ = ch;
2744 cinp();
2746 *q = '\0';
2747 ts = tok_alloc(token_buf, q - token_buf);
2748 tok = ts->tok;
2749 break;
2750 case 'L':
2751 cinp();
2752 if (ch == '\'') {
2753 tok = TOK_LCHAR;
2754 goto char_const;
2756 if (ch == '\"') {
2757 tok = TOK_LSTR;
2758 goto str_const;
2760 q = token_buf;
2761 *q++ = 'L';
2762 goto parse_ident;
2764 case '0': case '1': case '2': case '3':
2765 case '4': case '5': case '6': case '7':
2766 case '8': case '9':
2768 cstr_reset(&tokcstr);
2769 /* after the first digit, accept digits, alpha, '.' or sign if
2770 prefixed by 'eEpP' */
2771 parse_num:
2772 for(;;) {
2773 t = ch;
2774 cstr_ccat(&tokcstr, ch);
2775 cinp();
2776 if (!(isnum(ch) || isid(ch) || ch == '.' ||
2777 ((ch == '+' || ch == '-') &&
2778 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
2779 break;
2781 /* We add a trailing '\0' to ease parsing */
2782 cstr_ccat(&tokcstr, '\0');
2783 tokc.cstr = &tokcstr;
2784 tok = TOK_PPNUM;
2785 break;
2786 case '.':
2787 /* special dot handling because it can also start a number */
2788 cinp();
2789 if (isnum(ch)) {
2790 cstr_reset(&tokcstr);
2791 cstr_ccat(&tokcstr, '.');
2792 goto parse_num;
2794 if (ch == '.') {
2795 cinp();
2796 if (ch != '.')
2797 expect("'.'");
2798 cinp();
2799 tok = TOK_DOTS;
2800 } else {
2801 tok = '.';
2803 break;
2804 case '\'':
2805 tok = TOK_CCHAR;
2806 char_const:
2807 minp();
2808 b = getq();
2809 /* this cast is needed if >= 128 */
2810 if (tok == TOK_CCHAR)
2811 b = (char)b;
2812 tokc.i = b;
2813 if (ch != '\'')
2814 expect("\'");
2815 minp();
2816 break;
2817 case '\"':
2818 tok = TOK_STR;
2819 str_const:
2820 minp();
2821 cstr_reset(&tokcstr);
2822 while (ch != '\"') {
2823 b = getq();
2824 if (ch == CH_EOF)
2825 error("unterminated string");
2826 if (tok == TOK_STR)
2827 cstr_ccat(&tokcstr, b);
2828 else
2829 cstr_wccat(&tokcstr, b);
2831 if (tok == TOK_STR)
2832 cstr_ccat(&tokcstr, '\0');
2833 else
2834 cstr_wccat(&tokcstr, '\0');
2835 tokc.cstr = &tokcstr;
2836 minp();
2837 break;
2839 case '<':
2840 cinp();
2841 if (ch == '=') {
2842 cinp();
2843 tok = TOK_LE;
2844 } else if (ch == '<') {
2845 cinp();
2846 if (ch == '=') {
2847 cinp();
2848 tok = TOK_A_SHL;
2849 } else {
2850 tok = TOK_SHL;
2852 } else {
2853 tok = TOK_LT;
2855 break;
2857 case '>':
2858 cinp();
2859 if (ch == '=') {
2860 cinp();
2861 tok = TOK_GE;
2862 } else if (ch == '>') {
2863 cinp();
2864 if (ch == '=') {
2865 cinp();
2866 tok = TOK_A_SAR;
2867 } else {
2868 tok = TOK_SAR;
2870 } else {
2871 tok = TOK_GT;
2873 break;
2875 case '!':
2876 tok = ch;
2877 cinp();
2878 if (ch == '=') {
2879 cinp();
2880 tok = TOK_NE;
2882 break;
2884 case '=':
2885 tok = ch;
2886 cinp();
2887 if (ch == '=') {
2888 cinp();
2889 tok = TOK_EQ;
2891 break;
2893 case '&':
2894 tok = ch;
2895 cinp();
2896 if (ch == '&') {
2897 cinp();
2898 tok = TOK_LAND;
2899 } else if (ch == '=') {
2900 cinp();
2901 tok = TOK_A_AND;
2903 break;
2905 case '|':
2906 tok = ch;
2907 cinp();
2908 if (ch == '|') {
2909 cinp();
2910 tok = TOK_LOR;
2911 } else if (ch == '=') {
2912 cinp();
2913 tok = TOK_A_OR;
2915 break;
2917 case '+':
2918 tok = ch;
2919 cinp();
2920 if (ch == '+') {
2921 cinp();
2922 tok = TOK_INC;
2923 } else if (ch == '=') {
2924 cinp();
2925 tok = TOK_A_ADD;
2927 break;
2929 case '-':
2930 tok = ch;
2931 cinp();
2932 if (ch == '-') {
2933 cinp();
2934 tok = TOK_DEC;
2935 } else if (ch == '=') {
2936 cinp();
2937 tok = TOK_A_SUB;
2938 } else if (ch == '>') {
2939 cinp();
2940 tok = TOK_ARROW;
2942 break;
2944 case '*':
2945 tok = ch;
2946 cinp();
2947 if (ch == '=') {
2948 cinp();
2949 tok = TOK_A_MUL;
2951 break;
2953 case '%':
2954 tok = ch;
2955 cinp();
2956 if (ch == '=') {
2957 cinp();
2958 tok = TOK_A_MOD;
2960 break;
2962 case '^':
2963 tok = ch;
2964 cinp();
2965 if (ch == '=') {
2966 cinp();
2967 tok = TOK_A_XOR;
2969 break;
2971 /* comments or operator */
2972 case '/':
2973 tok = ch;
2974 cinp();
2975 if (ch == '=') {
2976 cinp();
2977 tok = TOK_A_DIV;
2979 #if 0
2980 else if (ch == '/' || ch == '*') {
2981 parse_comments();
2982 goto redo_no_start;
2984 #endif
2985 break;
2987 /* simple tokens */
2988 case '(':
2989 case ')':
2990 case '[':
2991 case ']':
2992 case '{':
2993 case '}':
2994 case ',':
2995 case ';':
2996 case ':':
2997 case '?':
2998 case '~':
2999 tok = ch;
3000 cinp();
3001 break;
3002 case CH_EOF:
3003 tok = TOK_EOF;
3004 break;
3005 default:
3006 error("unrecognized character \\x%02x", ch);
3007 break;
3011 /* return next token without macro substitution. Can read input from
3012 macro_ptr buffer */
3013 static void next_nomacro(void)
3015 if (macro_ptr) {
3016 redo:
3017 tok = *macro_ptr;
3018 if (tok) {
3019 tok = tok_get(&macro_ptr, &tokc);
3020 if (tok == TOK_LINENUM) {
3021 file->line_num = tokc.i;
3022 goto redo;
3025 } else {
3026 next_nomacro1();
3030 /* substitute args in macro_str and return allocated string */
3031 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3033 int *st, last_tok, t, notfirst;
3034 Sym *s;
3035 CValue cval;
3036 TokenString str;
3037 CString cstr;
3039 tok_str_new(&str);
3040 last_tok = 0;
3041 while(1) {
3042 t = tok_get(&macro_str, &cval);
3043 if (!t)
3044 break;
3045 if (t == '#') {
3046 /* stringize */
3047 t = tok_get(&macro_str, &cval);
3048 if (!t)
3049 break;
3050 s = sym_find2(args, t);
3051 if (s) {
3052 cstr_new(&cstr);
3053 st = (int *)s->c;
3054 notfirst = 0;
3055 while (*st) {
3056 if (notfirst)
3057 cstr_ccat(&cstr, ' ');
3058 t = tok_get(&st, &cval);
3059 cstr_cat(&cstr, get_tok_str(t, &cval));
3060 notfirst = 1;
3062 cstr_ccat(&cstr, '\0');
3063 #ifdef PP_DEBUG
3064 printf("stringize: %s\n", (char *)cstr.data);
3065 #endif
3066 /* add string */
3067 cval.cstr = &cstr;
3068 tok_str_add2(&str, TOK_STR, &cval);
3069 cstr_free(&cstr);
3070 } else {
3071 tok_str_add2(&str, t, &cval);
3073 } else if (t >= TOK_IDENT) {
3074 s = sym_find2(args, t);
3075 if (s) {
3076 st = (int *)s->c;
3077 /* if '##' is present before or after, no arg substitution */
3078 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3079 /* special case for var arg macros : ## eats the
3080 ',' if empty VA_ARGS variable. */
3081 /* XXX: test of the ',' is not 100%
3082 reliable. should fix it to avoid security
3083 problems */
3084 if (gnu_ext && s->type.t &&
3085 last_tok == TOK_TWOSHARPS &&
3086 str.len >= 2 && str.str[str.len - 2] == ',') {
3087 if (*st == 0) {
3088 /* suppress ',' '##' */
3089 str.len -= 2;
3090 } else {
3091 /* suppress '##' and add variable */
3092 str.len--;
3093 goto add_var;
3095 } else {
3096 int t1;
3097 add_var:
3098 for(;;) {
3099 t1 = tok_get(&st, &cval);
3100 if (!t1)
3101 break;
3102 tok_str_add2(&str, t1, &cval);
3105 } else {
3106 macro_subst(&str, nested_list, st);
3108 } else {
3109 tok_str_add(&str, t);
3111 } else {
3112 tok_str_add2(&str, t, &cval);
3114 last_tok = t;
3116 tok_str_add(&str, 0);
3117 return str.str;
3120 /* handle the '##' operator */
3121 static int *macro_twosharps(void)
3123 TokenSym *ts;
3124 int *macro_ptr1;
3125 int t;
3126 const char *p1, *p2;
3127 CValue cval;
3128 TokenString macro_str1;
3129 CString cstr;
3131 cstr_new(&cstr);
3132 tok_str_new(&macro_str1);
3133 tok = 0;
3134 while (1) {
3135 next_nomacro();
3136 if (tok == 0)
3137 break;
3138 while (*macro_ptr == TOK_TWOSHARPS) {
3139 macro_ptr++;
3140 macro_ptr1 = macro_ptr;
3141 t = *macro_ptr;
3142 if (t) {
3143 t = tok_get(&macro_ptr, &cval);
3145 /* We concatenate the two tokens if we have an
3146 identifier or a preprocessing number */
3147 cstr_reset(&cstr);
3148 p1 = get_tok_str(tok, &tokc);
3149 cstr_cat(&cstr, p1);
3150 p2 = get_tok_str(t, &cval);
3151 cstr_cat(&cstr, p2);
3152 cstr_ccat(&cstr, '\0');
3154 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3155 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3156 if (tok == TOK_PPNUM) {
3157 /* if number, then create a number token */
3158 /* NOTE: no need to allocate because
3159 tok_str_add2() does it */
3160 tokc.cstr = &cstr;
3161 } else {
3162 /* if identifier, we must do a test to
3163 validate we have a correct identifier */
3164 if (t == TOK_PPNUM) {
3165 const char *p;
3166 int c;
3168 p = p2;
3169 for(;;) {
3170 c = *p;
3171 if (c == '\0')
3172 break;
3173 p++;
3174 if (!isnum(c) && !isid(c))
3175 goto error_pasting;
3178 ts = tok_alloc(cstr.data, strlen(cstr.data));
3179 tok = ts->tok; /* modify current token */
3181 } else {
3182 const char *str = cstr.data;
3183 const unsigned char *q;
3185 /* we look for a valid token */
3186 /* XXX: do more extensive checks */
3187 if (!strcmp(str, ">>=")) {
3188 tok = TOK_A_SAR;
3189 } else if (!strcmp(str, "<<=")) {
3190 tok = TOK_A_SHL;
3191 } else if (strlen(str) == 2) {
3192 /* search in two bytes table */
3193 q = tok_two_chars;
3194 for(;;) {
3195 if (!*q)
3196 goto error_pasting;
3197 if (q[0] == str[0] && q[1] == str[1])
3198 break;
3199 q += 3;
3201 tok = q[2];
3202 } else {
3203 error_pasting:
3204 /* NOTE: because get_tok_str use a static buffer,
3205 we must save it */
3206 cstr_reset(&cstr);
3207 p1 = get_tok_str(tok, &tokc);
3208 cstr_cat(&cstr, p1);
3209 cstr_ccat(&cstr, '\0');
3210 p2 = get_tok_str(t, &cval);
3211 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3212 /* cannot merge tokens: just add them separately */
3213 tok_str_add2(&macro_str1, tok, &tokc);
3214 /* XXX: free associated memory ? */
3215 tok = t;
3216 tokc = cval;
3221 tok_str_add2(&macro_str1, tok, &tokc);
3223 cstr_free(&cstr);
3224 tok_str_add(&macro_str1, 0);
3225 return macro_str1.str;
3229 /* do macro substitution of current token with macro 's' and add
3230 result to (tok_str,tok_len). 'nested_list' is the list of all
3231 macros we got inside to avoid recursing. Return non zero if no
3232 substitution needs to be done */
3233 static int macro_subst_tok(TokenString *tok_str,
3234 Sym **nested_list, Sym *s)
3236 Sym *args, *sa, *sa1;
3237 int mstr_allocated, parlevel, *mstr, t;
3238 TokenString str;
3239 char *cstrval;
3240 CValue cval;
3241 CString cstr;
3243 /* if symbol is a macro, prepare substitution */
3244 /* if nested substitution, do nothing */
3245 if (sym_find2(*nested_list, tok))
3246 return -1;
3248 /* special macros */
3249 if (tok == TOK___LINE__) {
3250 cval.i = file->line_num;
3251 tok_str_add2(tok_str, TOK_CINT, &cval);
3252 } else if (tok == TOK___FILE__) {
3253 cstrval = file->filename;
3254 goto add_cstr;
3255 tok_str_add2(tok_str, TOK_STR, &cval);
3256 } else if (tok == TOK___DATE__) {
3257 cstrval = "Jan 1 2002";
3258 goto add_cstr;
3259 } else if (tok == TOK___TIME__) {
3260 cstrval = "00:00:00";
3261 add_cstr:
3262 cstr_new(&cstr);
3263 cstr_cat(&cstr, cstrval);
3264 cstr_ccat(&cstr, '\0');
3265 cval.cstr = &cstr;
3266 tok_str_add2(tok_str, TOK_STR, &cval);
3267 cstr_free(&cstr);
3268 } else {
3269 mstr = (int *)s->c;
3270 mstr_allocated = 0;
3271 if (s->type.t == MACRO_FUNC) {
3272 /* NOTE: we do not use next_nomacro to avoid eating the
3273 next token. XXX: find better solution */
3274 if (macro_ptr) {
3275 t = *macro_ptr;
3276 } else {
3277 while (is_space(ch) || ch == '\n')
3278 cinp();
3279 t = ch;
3281 if (t != '(') /* no macro subst */
3282 return -1;
3284 /* argument macro */
3285 next_nomacro();
3286 next_nomacro();
3287 args = NULL;
3288 sa = s->next;
3289 /* NOTE: empty args are allowed, except if no args */
3290 for(;;) {
3291 /* handle '()' case */
3292 if (!args && tok == ')')
3293 break;
3294 if (!sa)
3295 error("macro '%s' used with too many args",
3296 get_tok_str(s->v, 0));
3297 tok_str_new(&str);
3298 parlevel = 0;
3299 /* NOTE: non zero sa->t indicates VA_ARGS */
3300 while ((parlevel > 0 ||
3301 (tok != ')' &&
3302 (tok != ',' || sa->type.t))) &&
3303 tok != -1) {
3304 if (tok == '(')
3305 parlevel++;
3306 else if (tok == ')')
3307 parlevel--;
3308 tok_str_add2(&str, tok, &tokc);
3309 next_nomacro();
3311 tok_str_add(&str, 0);
3312 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3313 sa = sa->next;
3314 if (tok == ')') {
3315 /* special case for gcc var args: add an empty
3316 var arg argument if it is omitted */
3317 if (sa && sa->type.t && gnu_ext)
3318 continue;
3319 else
3320 break;
3322 if (tok != ',')
3323 expect(",");
3324 next_nomacro();
3326 if (sa) {
3327 error("macro '%s' used with too few args",
3328 get_tok_str(s->v, 0));
3331 /* now subst each arg */
3332 mstr = macro_arg_subst(nested_list, mstr, args);
3333 /* free memory */
3334 sa = args;
3335 while (sa) {
3336 sa1 = sa->prev;
3337 tok_str_free((int *)sa->c);
3338 tcc_free(sa);
3339 sa = sa1;
3341 mstr_allocated = 1;
3343 sym_push2(nested_list, s->v, 0, 0);
3344 macro_subst(tok_str, nested_list, mstr);
3345 /* pop nested defined symbol */
3346 sa1 = *nested_list;
3347 *nested_list = sa1->prev;
3348 tcc_free(sa1);
3349 if (mstr_allocated)
3350 tok_str_free(mstr);
3352 return 0;
3355 /* do macro substitution of macro_str and add result to
3356 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3357 inside to avoid recursing. */
3358 static void macro_subst(TokenString *tok_str,
3359 Sym **nested_list, int *macro_str)
3361 Sym *s;
3362 int *saved_macro_ptr;
3363 int *macro_str1;
3365 saved_macro_ptr = macro_ptr;
3366 macro_ptr = macro_str;
3367 /* first scan for '##' operator handling */
3368 macro_str1 = macro_twosharps();
3369 macro_ptr = macro_str1;
3371 while (1) {
3372 next_nomacro();
3373 if (tok == 0)
3374 break;
3375 s = define_find(tok);
3376 if (s != NULL) {
3377 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3378 goto no_subst;
3379 } else {
3380 no_subst:
3381 tok_str_add2(tok_str, tok, &tokc);
3384 macro_ptr = saved_macro_ptr;
3385 tok_str_free(macro_str1);
3388 /* return next token with macro substitution */
3389 static void next(void)
3391 Sym *nested_list, *s;
3392 TokenString str;
3394 /* special 'ungettok' case for label parsing */
3395 if (tok1) {
3396 tok = tok1;
3397 tokc = tok1c;
3398 tok1 = 0;
3399 } else {
3400 redo:
3401 next_nomacro();
3402 if (!macro_ptr) {
3403 /* if not reading from macro substituted string, then try
3404 to substitute macros */
3405 if (tok >= TOK_IDENT) {
3406 s = define_find(tok);
3407 if (s) {
3408 /* we have a macro: we try to substitute */
3409 tok_str_new(&str);
3410 nested_list = NULL;
3411 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3412 /* substitution done, NOTE: maybe empty */
3413 tok_str_add(&str, 0);
3414 macro_ptr = str.str;
3415 macro_ptr_allocated = str.str;
3416 goto redo;
3420 } else {
3421 if (tok == 0) {
3422 /* end of macro string: free it */
3423 tok_str_free(macro_ptr_allocated);
3424 macro_ptr = NULL;
3425 goto redo;
3429 /* convert preprocessor tokens into C tokens */
3430 if (tok == TOK_PPNUM) {
3431 parse_number((char *)tokc.cstr->data);
3434 #if defined(DEBUG)
3435 printf("token = %s\n", get_tok_str(tok, &tokc));
3436 #endif
3439 void swap(int *p, int *q)
3441 int t;
3442 t = *p;
3443 *p = *q;
3444 *q = t;
3447 void vsetc(CType *type, int r, CValue *vc)
3449 int v;
3451 if (vtop >= vstack + VSTACK_SIZE)
3452 error("memory full");
3453 /* cannot let cpu flags if other instruction are generated. Also
3454 avoid leaving VT_JMP anywhere except on the top of the stack
3455 because it would complicate the code generator. */
3456 if (vtop >= vstack) {
3457 v = vtop->r & VT_VALMASK;
3458 if (v == VT_CMP || (v & ~1) == VT_JMP)
3459 gv(RC_INT);
3461 vtop++;
3462 vtop->type = *type;
3463 vtop->r = r;
3464 vtop->r2 = VT_CONST;
3465 vtop->c = *vc;
3468 /* push integer constant */
3469 void vpushi(int v)
3471 CValue cval;
3472 cval.i = v;
3473 vsetc(&int_type, VT_CONST, &cval);
3476 /* Return a static symbol pointing to a section */
3477 static Sym *get_sym_ref(CType *type, Section *sec,
3478 unsigned long offset, unsigned long size)
3480 int v;
3481 Sym *sym;
3483 v = anon_sym++;
3484 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
3485 sym->type.ref = type->ref;
3486 sym->r = VT_CONST | VT_SYM;
3487 put_extern_sym(sym, sec, offset, size);
3488 return sym;
3491 /* push a reference to a section offset by adding a dummy symbol */
3492 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
3494 CValue cval;
3496 cval.ul = 0;
3497 vsetc(type, VT_CONST | VT_SYM, &cval);
3498 vtop->sym = get_sym_ref(type, sec, offset, size);
3501 /* define a new external reference to a symbol 'v' of type 'u' */
3502 static Sym *external_global_sym(int v, CType *type, int r)
3504 Sym *s;
3506 s = sym_find(v);
3507 if (!s) {
3508 /* push forward reference */
3509 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
3510 s->type.ref = type->ref;
3511 s->r = r | VT_CONST | VT_SYM;
3513 return s;
3516 /* define a new external reference to a symbol 'v' of type 'u' */
3517 static Sym *external_sym(int v, CType *type, int r)
3519 Sym *s;
3521 s = sym_find(v);
3522 if (!s) {
3523 /* push forward reference */
3524 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
3525 s->type.t |= VT_EXTERN;
3527 return s;
3530 /* push a reference to global symbol v */
3531 static void vpush_global_sym(CType *type, int v)
3533 Sym *sym;
3534 CValue cval;
3536 sym = external_global_sym(v, type, 0);
3537 cval.ul = 0;
3538 vsetc(type, VT_CONST | VT_SYM, &cval);
3539 vtop->sym = sym;
3542 void vset(CType *type, int r, int v)
3544 CValue cval;
3546 cval.i = v;
3547 vsetc(type, r, &cval);
3550 void vseti(int r, int v)
3552 CType type;
3553 type.t = VT_INT;
3554 vset(&type, r, v);
3557 void vswap(void)
3559 SValue tmp;
3561 tmp = vtop[0];
3562 vtop[0] = vtop[-1];
3563 vtop[-1] = tmp;
3566 void vpushv(SValue *v)
3568 if (vtop >= vstack + VSTACK_SIZE)
3569 error("memory full");
3570 vtop++;
3571 *vtop = *v;
3574 void vdup(void)
3576 vpushv(vtop);
3579 /* save r to the memory stack, and mark it as being free */
3580 void save_reg(int r)
3582 int l, saved, size, align;
3583 SValue *p, sv;
3584 CType *type;
3586 /* modify all stack values */
3587 saved = 0;
3588 l = 0;
3589 for(p=vstack;p<=vtop;p++) {
3590 if ((p->r & VT_VALMASK) == r ||
3591 (p->r2 & VT_VALMASK) == r) {
3592 /* must save value on stack if not already done */
3593 if (!saved) {
3594 /* NOTE: must reload 'r' because r might be equal to r2 */
3595 r = p->r & VT_VALMASK;
3596 /* store register in the stack */
3597 type = &p->type;
3598 if ((p->r & VT_LVAL) ||
3599 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
3600 type = &int_type;
3601 size = type_size(type, &align);
3602 loc = (loc - size) & -align;
3603 sv.type.t = type->t;
3604 sv.r = VT_LOCAL | VT_LVAL;
3605 sv.c.ul = loc;
3606 store(r, &sv);
3607 #ifdef TCC_TARGET_I386
3608 /* x86 specific: need to pop fp register ST0 if saved */
3609 if (r == REG_ST0) {
3610 o(0xd9dd); /* fstp %st(1) */
3612 #endif
3613 /* special long long case */
3614 if ((type->t & VT_BTYPE) == VT_LLONG) {
3615 sv.c.ul += 4;
3616 store(p->r2, &sv);
3618 l = loc;
3619 saved = 1;
3621 /* mark that stack entry as being saved on the stack */
3622 if (p->r & VT_LVAL) {
3623 /* also suppress the bounded flag because the
3624 relocation address of the function was stored in
3625 p->c.ul */
3626 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
3627 } else {
3628 p->r = lvalue_type(p->type.t) | VT_LOCAL;
3630 p->r2 = VT_CONST;
3631 p->c.ul = l;
3636 /* find a free register of class 'rc'. If none, save one register */
3637 int get_reg(int rc)
3639 int r;
3640 SValue *p;
3642 /* find a free register */
3643 for(r=0;r<NB_REGS;r++) {
3644 if (reg_classes[r] & rc) {
3645 for(p=vstack;p<=vtop;p++) {
3646 if ((p->r & VT_VALMASK) == r ||
3647 (p->r2 & VT_VALMASK) == r)
3648 goto notfound;
3650 return r;
3652 notfound: ;
3655 /* no register left : free the first one on the stack (VERY
3656 IMPORTANT to start from the bottom to ensure that we don't
3657 spill registers used in gen_opi()) */
3658 for(p=vstack;p<=vtop;p++) {
3659 r = p->r & VT_VALMASK;
3660 if (r < VT_CONST && (reg_classes[r] & rc))
3661 goto save_found;
3662 /* also look at second register (if long long) */
3663 r = p->r2 & VT_VALMASK;
3664 if (r < VT_CONST && (reg_classes[r] & rc)) {
3665 save_found:
3666 save_reg(r);
3667 return r;
3670 /* Should never comes here */
3671 return -1;
3674 /* save registers up to (vtop - n) stack entry */
3675 void save_regs(int n)
3677 int r;
3678 SValue *p, *p1;
3679 p1 = vtop - n;
3680 for(p = vstack;p <= p1; p++) {
3681 r = p->r & VT_VALMASK;
3682 if (r < VT_CONST) {
3683 save_reg(r);
3688 /* move register 's' to 'r', and flush previous value of r to memory
3689 if needed */
3690 void move_reg(int r, int s)
3692 SValue sv;
3694 if (r != s) {
3695 save_reg(r);
3696 sv.type.t = VT_INT;
3697 sv.r = s;
3698 sv.c.ul = 0;
3699 load(r, &sv);
3703 /* get address of vtop (vtop MUST BE an lvalue) */
3704 void gaddrof(void)
3706 vtop->r &= ~VT_LVAL;
3707 /* tricky: if saved lvalue, then we can go back to lvalue */
3708 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3709 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3712 #ifdef CONFIG_TCC_BCHECK
3713 /* generate lvalue bound code */
3714 void gbound(void)
3716 int lval_type;
3717 CType type1;
3719 vtop->r &= ~VT_MUSTBOUND;
3720 /* if lvalue, then use checking code before dereferencing */
3721 if (vtop->r & VT_LVAL) {
3722 /* if not VT_BOUNDED value, then make one */
3723 if (!(vtop->r & VT_BOUNDED)) {
3724 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3725 /* must save type because we must set it to int to get pointer */
3726 type1 = vtop->type;
3727 vtop->type.t = VT_INT;
3728 gaddrof();
3729 vpushi(0);
3730 gen_bounded_ptr_add();
3731 vtop->r |= lval_type;
3732 vtop->type = type1;
3734 /* then check for dereferencing */
3735 gen_bounded_ptr_deref();
3738 #endif
3740 /* store vtop a register belonging to class 'rc'. lvalues are
3741 converted to values. Cannot be used if cannot be converted to
3742 register value (such as structures). */
3743 int gv(int rc)
3745 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3746 unsigned long long ll;
3748 /* NOTE: get_reg can modify vstack[] */
3749 if (vtop->type.t & VT_BITFIELD) {
3750 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
3751 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3752 /* remove bit field info to avoid loops */
3753 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3754 /* generate shifts */
3755 vpushi(32 - (bit_pos + bit_size));
3756 gen_op(TOK_SHL);
3757 vpushi(32 - bit_size);
3758 /* NOTE: transformed to SHR if unsigned */
3759 gen_op(TOK_SAR);
3760 r = gv(rc);
3761 } else {
3762 if (is_float(vtop->type.t) &&
3763 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3764 Sym *sym;
3765 int *ptr;
3766 unsigned long offset;
3768 /* XXX: unify with initializers handling ? */
3769 /* CPUs usually cannot use float constants, so we store them
3770 generically in data segment */
3771 size = type_size(&vtop->type, &align);
3772 offset = (data_section->data_offset + align - 1) & -align;
3773 data_section->data_offset = offset;
3774 /* XXX: not portable yet */
3775 ptr = section_ptr_add(data_section, size);
3776 size = size >> 2;
3777 for(i=0;i<size;i++)
3778 ptr[i] = vtop->c.tab[i];
3779 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
3780 vtop->r |= VT_LVAL | VT_SYM;
3781 vtop->sym = sym;
3782 vtop->c.ul = 0;
3784 #ifdef CONFIG_TCC_BCHECK
3785 if (vtop->r & VT_MUSTBOUND)
3786 gbound();
3787 #endif
3789 r = vtop->r & VT_VALMASK;
3790 /* need to reload if:
3791 - constant
3792 - lvalue (need to dereference pointer)
3793 - already a register, but not in the right class */
3794 if (r >= VT_CONST ||
3795 (vtop->r & VT_LVAL) ||
3796 !(reg_classes[r] & rc) ||
3797 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
3798 !(reg_classes[vtop->r2] & rc))) {
3799 r = get_reg(rc);
3800 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
3801 /* two register type load : expand to two words
3802 temporarily */
3803 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3804 /* load constant */
3805 ll = vtop->c.ull;
3806 vtop->c.ui = ll; /* first word */
3807 load(r, vtop);
3808 vtop->r = r; /* save register value */
3809 vpushi(ll >> 32); /* second word */
3810 } else if (r >= VT_CONST ||
3811 (vtop->r & VT_LVAL)) {
3812 /* load from memory */
3813 load(r, vtop);
3814 vdup();
3815 vtop[-1].r = r; /* save register value */
3816 /* increment pointer to get second word */
3817 vtop->type.t = VT_INT;
3818 gaddrof();
3819 vpushi(4);
3820 gen_op('+');
3821 vtop->r |= VT_LVAL;
3822 } else {
3823 /* move registers */
3824 load(r, vtop);
3825 vdup();
3826 vtop[-1].r = r; /* save register value */
3827 vtop->r = vtop[-1].r2;
3829 /* allocate second register */
3830 rc2 = RC_INT;
3831 if (rc == RC_IRET)
3832 rc2 = RC_LRET;
3833 r2 = get_reg(rc2);
3834 load(r2, vtop);
3835 vpop();
3836 /* write second register */
3837 vtop->r2 = r2;
3838 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
3839 int t1, t;
3840 /* lvalue of scalar type : need to use lvalue type
3841 because of possible cast */
3842 t = vtop->type.t;
3843 t1 = t;
3844 /* compute memory access type */
3845 if (vtop->r & VT_LVAL_BYTE)
3846 t = VT_BYTE;
3847 else if (vtop->r & VT_LVAL_SHORT)
3848 t = VT_SHORT;
3849 if (vtop->r & VT_LVAL_UNSIGNED)
3850 t |= VT_UNSIGNED;
3851 vtop->type.t = t;
3852 load(r, vtop);
3853 /* restore wanted type */
3854 vtop->type.t = t1;
3855 } else {
3856 /* one register type load */
3857 load(r, vtop);
3860 vtop->r = r;
3862 return r;
3865 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3866 void gv2(int rc1, int rc2)
3868 int v;
3870 /* generate more generic register first. But VT_JMP or VT_CMP
3871 values must be generated first in all cases to avoid possible
3872 reload errors */
3873 v = vtop[0].r & VT_VALMASK;
3874 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
3875 vswap();
3876 gv(rc1);
3877 vswap();
3878 gv(rc2);
3879 /* test if reload is needed for first register */
3880 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3881 vswap();
3882 gv(rc1);
3883 vswap();
3885 } else {
3886 gv(rc2);
3887 vswap();
3888 gv(rc1);
3889 vswap();
3890 /* test if reload is needed for first register */
3891 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3892 gv(rc2);
3897 /* expand long long on stack in two int registers */
3898 void lexpand(void)
3900 int u;
3902 u = vtop->type.t & VT_UNSIGNED;
3903 gv(RC_INT);
3904 vdup();
3905 vtop[0].r = vtop[-1].r2;
3906 vtop[0].r2 = VT_CONST;
3907 vtop[-1].r2 = VT_CONST;
3908 vtop[0].type.t = VT_INT | u;
3909 vtop[-1].type.t = VT_INT | u;
3912 /* build a long long from two ints */
3913 void lbuild(int t)
3915 gv2(RC_INT, RC_INT);
3916 vtop[-1].r2 = vtop[0].r;
3917 vtop[-1].type.t = t;
3918 vpop();
3921 /* rotate n first stack elements to the bottom */
3922 void vrotb(int n)
3924 int i;
3925 SValue tmp;
3927 tmp = vtop[-n + 1];
3928 for(i=-n+1;i!=0;i++)
3929 vtop[i] = vtop[i+1];
3930 vtop[0] = tmp;
3933 /* pop stack value */
3934 void vpop(void)
3936 int v;
3937 v = vtop->r & VT_VALMASK;
3938 #ifdef TCC_TARGET_I386
3939 /* for x86, we need to pop the FP stack */
3940 if (v == REG_ST0 && !nocode_wanted) {
3941 o(0xd9dd); /* fstp %st(1) */
3942 } else
3943 #endif
3944 if (v == VT_JMP || v == VT_JMPI) {
3945 /* need to put correct jump if && or || without test */
3946 gsym(vtop->c.ul);
3948 vtop--;
3951 /* convert stack entry to register and duplicate its value in another
3952 register */
3953 void gv_dup(void)
3955 int rc, t, r, r1;
3956 SValue sv;
3958 t = vtop->type.t;
3959 if ((t & VT_BTYPE) == VT_LLONG) {
3960 lexpand();
3961 gv_dup();
3962 vswap();
3963 vrotb(3);
3964 gv_dup();
3965 vrotb(4);
3966 /* stack: H L L1 H1 */
3967 lbuild(t);
3968 vrotb(3);
3969 vrotb(3);
3970 vswap();
3971 lbuild(t);
3972 vswap();
3973 } else {
3974 /* duplicate value */
3975 rc = RC_INT;
3976 sv.type.t = VT_INT;
3977 if (is_float(t)) {
3978 rc = RC_FLOAT;
3979 sv.type.t = t;
3981 r = gv(rc);
3982 r1 = get_reg(rc);
3983 sv.r = r;
3984 sv.c.ul = 0;
3985 load(r1, &sv); /* move r to r1 */
3986 vdup();
3987 /* duplicates value */
3988 vtop->r = r1;
3992 /* generate CPU independent (unsigned) long long operations */
3993 void gen_opl(int op)
3995 int t, a, b, op1, c, i;
3996 int func;
3997 GFuncContext gf;
3998 SValue tmp;
4000 switch(op) {
4001 case '/':
4002 case TOK_PDIV:
4003 func = TOK___divdi3;
4004 goto gen_func;
4005 case TOK_UDIV:
4006 func = TOK___udivdi3;
4007 goto gen_func;
4008 case '%':
4009 func = TOK___moddi3;
4010 goto gen_func;
4011 case TOK_UMOD:
4012 func = TOK___umoddi3;
4013 gen_func:
4014 /* call generic long long function */
4015 gfunc_start(&gf, FUNC_CDECL);
4016 gfunc_param(&gf);
4017 gfunc_param(&gf);
4018 vpush_global_sym(&func_old_type, func);
4019 gfunc_call(&gf);
4020 vpushi(0);
4021 vtop->r = REG_IRET;
4022 vtop->r2 = REG_LRET;
4023 break;
4024 case '^':
4025 case '&':
4026 case '|':
4027 case '*':
4028 case '+':
4029 case '-':
4030 t = vtop->type.t;
4031 vswap();
4032 lexpand();
4033 vrotb(3);
4034 lexpand();
4035 /* stack: L1 H1 L2 H2 */
4036 tmp = vtop[0];
4037 vtop[0] = vtop[-3];
4038 vtop[-3] = tmp;
4039 tmp = vtop[-2];
4040 vtop[-2] = vtop[-3];
4041 vtop[-3] = tmp;
4042 vswap();
4043 /* stack: H1 H2 L1 L2 */
4044 if (op == '*') {
4045 vpushv(vtop - 1);
4046 vpushv(vtop - 1);
4047 gen_op(TOK_UMULL);
4048 lexpand();
4049 /* stack: H1 H2 L1 L2 ML MH */
4050 for(i=0;i<4;i++)
4051 vrotb(6);
4052 /* stack: ML MH H1 H2 L1 L2 */
4053 tmp = vtop[0];
4054 vtop[0] = vtop[-2];
4055 vtop[-2] = tmp;
4056 /* stack: ML MH H1 L2 H2 L1 */
4057 gen_op('*');
4058 vrotb(3);
4059 vrotb(3);
4060 gen_op('*');
4061 /* stack: ML MH M1 M2 */
4062 gen_op('+');
4063 gen_op('+');
4064 } else if (op == '+' || op == '-') {
4065 /* XXX: add non carry method too (for MIPS or alpha) */
4066 if (op == '+')
4067 op1 = TOK_ADDC1;
4068 else
4069 op1 = TOK_SUBC1;
4070 gen_op(op1);
4071 /* stack: H1 H2 (L1 op L2) */
4072 vrotb(3);
4073 vrotb(3);
4074 gen_op(op1 + 1); /* TOK_xxxC2 */
4075 } else {
4076 gen_op(op);
4077 /* stack: H1 H2 (L1 op L2) */
4078 vrotb(3);
4079 vrotb(3);
4080 /* stack: (L1 op L2) H1 H2 */
4081 gen_op(op);
4082 /* stack: (L1 op L2) (H1 op H2) */
4084 /* stack: L H */
4085 lbuild(t);
4086 break;
4087 case TOK_SAR:
4088 case TOK_SHR:
4089 case TOK_SHL:
4090 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4091 t = vtop[-1].type.t;
4092 vswap();
4093 lexpand();
4094 vrotb(3);
4095 /* stack: L H shift */
4096 c = (int)vtop->c.i;
4097 /* constant: simpler */
4098 /* NOTE: all comments are for SHL. the other cases are
4099 done by swaping words */
4100 vpop();
4101 if (op != TOK_SHL)
4102 vswap();
4103 if (c >= 32) {
4104 /* stack: L H */
4105 vpop();
4106 if (c > 32) {
4107 vpushi(c - 32);
4108 gen_op(op);
4110 if (op != TOK_SAR) {
4111 vpushi(0);
4112 } else {
4113 gv_dup();
4114 vpushi(31);
4115 gen_op(TOK_SAR);
4117 vswap();
4118 } else {
4119 vswap();
4120 gv_dup();
4121 /* stack: H L L */
4122 vpushi(c);
4123 gen_op(op);
4124 vswap();
4125 vpushi(32 - c);
4126 if (op == TOK_SHL)
4127 gen_op(TOK_SHR);
4128 else
4129 gen_op(TOK_SHL);
4130 vrotb(3);
4131 /* stack: L L H */
4132 vpushi(c);
4133 if (op == TOK_SHL)
4134 gen_op(TOK_SHL);
4135 else
4136 gen_op(TOK_SHR);
4137 gen_op('|');
4139 if (op != TOK_SHL)
4140 vswap();
4141 lbuild(t);
4142 } else {
4143 /* XXX: should provide a faster fallback on x86 ? */
4144 switch(op) {
4145 case TOK_SAR:
4146 func = TOK___sardi3;
4147 goto gen_func;
4148 case TOK_SHR:
4149 func = TOK___shrdi3;
4150 goto gen_func;
4151 case TOK_SHL:
4152 func = TOK___shldi3;
4153 goto gen_func;
4156 break;
4157 default:
4158 /* compare operations */
4159 t = vtop->type.t;
4160 vswap();
4161 lexpand();
4162 vrotb(3);
4163 lexpand();
4164 /* stack: L1 H1 L2 H2 */
4165 tmp = vtop[-1];
4166 vtop[-1] = vtop[-2];
4167 vtop[-2] = tmp;
4168 /* stack: L1 L2 H1 H2 */
4169 /* compare high */
4170 op1 = op;
4171 /* when values are equal, we need to compare low words. since
4172 the jump is inverted, we invert the test too. */
4173 if (op1 == TOK_LT)
4174 op1 = TOK_LE;
4175 else if (op1 == TOK_GT)
4176 op1 = TOK_GE;
4177 else if (op1 == TOK_ULT)
4178 op1 = TOK_ULE;
4179 else if (op1 == TOK_UGT)
4180 op1 = TOK_UGE;
4181 a = 0;
4182 b = 0;
4183 gen_op(op1);
4184 if (op1 != TOK_NE) {
4185 a = gtst(1, 0);
4187 if (op != TOK_EQ) {
4188 /* generate non equal test */
4189 /* XXX: NOT PORTABLE yet */
4190 if (a == 0) {
4191 b = gtst(0, 0);
4192 } else {
4193 #ifdef TCC_TARGET_I386
4194 b = psym(0x850f, 0);
4195 #else
4196 error("not implemented");
4197 #endif
4200 /* compare low */
4201 gen_op(op);
4202 a = gtst(1, a);
4203 gsym(b);
4204 vseti(VT_JMPI, a);
4205 break;
4209 /* handle integer constant optimizations and various machine
4210 independant opt */
4211 void gen_opic(int op)
4213 int fc, c1, c2, n;
4214 SValue *v1, *v2;
4216 v1 = vtop - 1;
4217 v2 = vtop;
4218 /* currently, we cannot do computations with forward symbols */
4219 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4220 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4221 if (c1 && c2) {
4222 fc = v2->c.i;
4223 switch(op) {
4224 case '+': v1->c.i += fc; break;
4225 case '-': v1->c.i -= fc; break;
4226 case '&': v1->c.i &= fc; break;
4227 case '^': v1->c.i ^= fc; break;
4228 case '|': v1->c.i |= fc; break;
4229 case '*': v1->c.i *= fc; break;
4231 case TOK_PDIV:
4232 case '/':
4233 case '%':
4234 case TOK_UDIV:
4235 case TOK_UMOD:
4236 /* if division by zero, generate explicit division */
4237 if (fc == 0) {
4238 if (const_wanted)
4239 error("division by zero in constant");
4240 goto general_case;
4242 switch(op) {
4243 default: v1->c.i /= fc; break;
4244 case '%': v1->c.i %= fc; break;
4245 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4246 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4248 break;
4249 case TOK_SHL: v1->c.i <<= fc; break;
4250 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4251 case TOK_SAR: v1->c.i >>= fc; break;
4252 /* tests */
4253 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4254 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4255 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4256 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4257 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4258 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4259 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4260 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4261 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4262 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4263 /* logical */
4264 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4265 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4266 default:
4267 goto general_case;
4269 vtop--;
4270 } else {
4271 /* if commutative ops, put c2 as constant */
4272 if (c1 && (op == '+' || op == '&' || op == '^' ||
4273 op == '|' || op == '*')) {
4274 vswap();
4275 swap(&c1, &c2);
4277 fc = vtop->c.i;
4278 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4279 op == TOK_PDIV) &&
4280 fc == 1) ||
4281 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4282 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4283 fc == 0) ||
4284 (op == '&' &&
4285 fc == -1))) {
4286 /* nothing to do */
4287 vtop--;
4288 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4289 /* try to use shifts instead of muls or divs */
4290 if (fc > 0 && (fc & (fc - 1)) == 0) {
4291 n = -1;
4292 while (fc) {
4293 fc >>= 1;
4294 n++;
4296 vtop->c.i = n;
4297 if (op == '*')
4298 op = TOK_SHL;
4299 else if (op == TOK_PDIV)
4300 op = TOK_SAR;
4301 else
4302 op = TOK_SHR;
4304 goto general_case;
4305 } else if (c2 && (op == '+' || op == '-') &&
4306 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4307 (VT_CONST | VT_SYM)) {
4308 /* symbol + constant case */
4309 if (op == '-')
4310 fc = -fc;
4311 vtop--;
4312 vtop->c.i += fc;
4313 } else {
4314 general_case:
4315 if (!nocode_wanted) {
4316 /* call low level op generator */
4317 gen_opi(op);
4318 } else {
4319 vtop--;
4325 /* generate a floating point operation with constant propagation */
4326 void gen_opif(int op)
4328 int c1, c2;
4329 SValue *v1, *v2;
4330 long double f1, f2;
4332 v1 = vtop - 1;
4333 v2 = vtop;
4334 /* currently, we cannot do computations with forward symbols */
4335 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4336 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4337 if (c1 && c2) {
4338 if (v1->type.t == VT_FLOAT) {
4339 f1 = v1->c.f;
4340 f2 = v2->c.f;
4341 } else if (v1->type.t == VT_DOUBLE) {
4342 f1 = v1->c.d;
4343 f2 = v2->c.d;
4344 } else {
4345 f1 = v1->c.ld;
4346 f2 = v2->c.ld;
4349 /* NOTE: we only do constant propagation if finite number (not
4350 NaN or infinity) (ANSI spec) */
4351 if (!ieee_finite(f1) || !ieee_finite(f2))
4352 goto general_case;
4354 switch(op) {
4355 case '+': f1 += f2; break;
4356 case '-': f1 -= f2; break;
4357 case '*': f1 *= f2; break;
4358 case '/':
4359 if (f2 == 0.0) {
4360 if (const_wanted)
4361 error("division by zero in constant");
4362 goto general_case;
4364 f1 /= f2;
4365 break;
4366 /* XXX: also handles tests ? */
4367 default:
4368 goto general_case;
4370 /* XXX: overflow test ? */
4371 if (v1->type.t == VT_FLOAT) {
4372 v1->c.f = f1;
4373 } else if (v1->type.t == VT_DOUBLE) {
4374 v1->c.d = f1;
4375 } else {
4376 v1->c.ld = f1;
4378 vtop--;
4379 } else {
4380 general_case:
4381 if (!nocode_wanted) {
4382 gen_opf(op);
4383 } else {
4384 vtop--;
4389 static int pointed_size(CType *type)
4391 int align;
4392 return type_size(pointed_type(type), &align);
4395 #if 0
4396 void check_pointer_types(SValue *p1, SValue *p2)
4398 char buf1[256], buf2[256];
4399 int t1, t2;
4400 t1 = p1->t;
4401 t2 = p2->t;
4402 if (!is_compatible_types(t1, t2)) {
4403 type_to_str(buf1, sizeof(buf1), t1, NULL);
4404 type_to_str(buf2, sizeof(buf2), t2, NULL);
4405 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4408 #endif
4410 /* generic gen_op: handles types problems */
4411 void gen_op(int op)
4413 int u, t1, t2, bt1, bt2, t;
4414 CType type1;
4416 t1 = vtop[-1].type.t;
4417 t2 = vtop[0].type.t;
4418 bt1 = t1 & VT_BTYPE;
4419 bt2 = t2 & VT_BTYPE;
4421 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4422 /* at least one operand is a pointer */
4423 /* relationnal op: must be both pointers */
4424 if (op >= TOK_ULT && op <= TOK_GT) {
4425 // check_pointer_types(vtop, vtop - 1);
4426 /* pointers are handled are unsigned */
4427 t = VT_INT | VT_UNSIGNED;
4428 goto std_op;
4430 /* if both pointers, then it must be the '-' op */
4431 if (bt1 == VT_PTR && bt2 == VT_PTR) {
4432 if (op != '-')
4433 error("cannot use pointers here");
4434 // check_pointer_types(vtop - 1, vtop);
4435 /* XXX: check that types are compatible */
4436 u = pointed_size(&vtop[-1].type);
4437 gen_opic(op);
4438 /* set to integer type */
4439 vtop->type.t = VT_INT;
4440 vpushi(u);
4441 gen_op(TOK_PDIV);
4442 } else {
4443 /* exactly one pointer : must be '+' or '-'. */
4444 if (op != '-' && op != '+')
4445 error("cannot use pointers here");
4446 /* Put pointer as first operand */
4447 if (bt2 == VT_PTR) {
4448 vswap();
4449 swap(&t1, &t2);
4451 type1 = vtop[-1].type;
4452 /* XXX: cast to int ? (long long case) */
4453 vpushi(pointed_size(&vtop[-1].type));
4454 gen_op('*');
4455 #ifdef CONFIG_TCC_BCHECK
4456 /* if evaluating constant expression, no code should be
4457 generated, so no bound check */
4458 if (do_bounds_check && !const_wanted) {
4459 /* if bounded pointers, we generate a special code to
4460 test bounds */
4461 if (op == '-') {
4462 vpushi(0);
4463 vswap();
4464 gen_op('-');
4466 gen_bounded_ptr_add();
4467 } else
4468 #endif
4470 gen_opic(op);
4472 /* put again type if gen_opic() swaped operands */
4473 vtop->type = type1;
4475 } else if (is_float(bt1) || is_float(bt2)) {
4476 /* compute bigger type and do implicit casts */
4477 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4478 t = VT_LDOUBLE;
4479 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4480 t = VT_DOUBLE;
4481 } else {
4482 t = VT_FLOAT;
4484 /* floats can only be used for a few operations */
4485 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4486 (op < TOK_ULT || op > TOK_GT))
4487 error("invalid operands for binary operation");
4488 goto std_op;
4489 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4490 /* cast to biggest op */
4491 t = VT_LLONG;
4492 /* convert to unsigned if it does not fit in a long long */
4493 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4494 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4495 t |= VT_UNSIGNED;
4496 goto std_op;
4497 } else {
4498 /* integer operations */
4499 t = VT_INT;
4500 /* convert to unsigned if it does not fit in an integer */
4501 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4502 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4503 t |= VT_UNSIGNED;
4504 std_op:
4505 /* XXX: currently, some unsigned operations are explicit, so
4506 we modify them here */
4507 if (t & VT_UNSIGNED) {
4508 if (op == TOK_SAR)
4509 op = TOK_SHR;
4510 else if (op == '/')
4511 op = TOK_UDIV;
4512 else if (op == '%')
4513 op = TOK_UMOD;
4514 else if (op == TOK_LT)
4515 op = TOK_ULT;
4516 else if (op == TOK_GT)
4517 op = TOK_UGT;
4518 else if (op == TOK_LE)
4519 op = TOK_ULE;
4520 else if (op == TOK_GE)
4521 op = TOK_UGE;
4523 vswap();
4524 type1.t = t;
4525 gen_cast(&type1);
4526 vswap();
4527 /* special case for shifts and long long: we keep the shift as
4528 an integer */
4529 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4530 type1.t = VT_INT;
4531 gen_cast(&type1);
4532 if (is_float(t))
4533 gen_opif(op);
4534 else if ((t & VT_BTYPE) == VT_LLONG)
4535 gen_opl(op);
4536 else
4537 gen_opic(op);
4538 if (op >= TOK_ULT && op <= TOK_GT) {
4539 /* relationnal op: the result is an int */
4540 vtop->type.t = VT_INT;
4541 } else {
4542 vtop->type.t = t;
4547 /* generic itof for unsigned long long case */
4548 void gen_cvt_itof1(int t)
4550 GFuncContext gf;
4552 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
4553 (VT_LLONG | VT_UNSIGNED)) {
4555 gfunc_start(&gf, FUNC_CDECL);
4556 gfunc_param(&gf);
4557 if (t == VT_FLOAT)
4558 vpush_global_sym(&func_old_type, TOK___ulltof);
4559 else if (t == VT_DOUBLE)
4560 vpush_global_sym(&func_old_type, TOK___ulltod);
4561 else
4562 vpush_global_sym(&func_old_type, TOK___ulltold);
4563 gfunc_call(&gf);
4564 vpushi(0);
4565 vtop->r = REG_FRET;
4566 } else {
4567 gen_cvt_itof(t);
4571 /* generic ftoi for unsigned long long case */
4572 void gen_cvt_ftoi1(int t)
4574 GFuncContext gf;
4575 int st;
4577 if (t == (VT_LLONG | VT_UNSIGNED)) {
4578 /* not handled natively */
4579 gfunc_start(&gf, FUNC_CDECL);
4580 st = vtop->type.t & VT_BTYPE;
4581 gfunc_param(&gf);
4582 if (st == VT_FLOAT)
4583 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
4584 else if (st == VT_DOUBLE)
4585 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
4586 else
4587 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
4588 gfunc_call(&gf);
4589 vpushi(0);
4590 vtop->r = REG_IRET;
4591 vtop->r2 = REG_LRET;
4592 } else {
4593 gen_cvt_ftoi(t);
4597 /* force char or short cast */
4598 void force_charshort_cast(int t)
4600 int bits, dbt;
4601 dbt = t & VT_BTYPE;
4602 /* XXX: add optimization if lvalue : just change type and offset */
4603 if (dbt == VT_BYTE)
4604 bits = 8;
4605 else
4606 bits = 16;
4607 if (t & VT_UNSIGNED) {
4608 vpushi((1 << bits) - 1);
4609 gen_op('&');
4610 } else {
4611 bits = 32 - bits;
4612 vpushi(bits);
4613 gen_op(TOK_SHL);
4614 vpushi(bits);
4615 gen_op(TOK_SAR);
4619 /* cast 'vtop' to 'type' */
4620 static void gen_cast(CType *type)
4622 int sbt, dbt, sf, df, c;
4624 /* special delayed cast for char/short */
4625 /* XXX: in some cases (multiple cascaded casts), it may still
4626 be incorrect */
4627 if (vtop->r & VT_MUSTCAST) {
4628 vtop->r &= ~VT_MUSTCAST;
4629 force_charshort_cast(vtop->type.t);
4632 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
4633 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
4635 if (sbt != dbt && !nocode_wanted) {
4636 sf = is_float(sbt);
4637 df = is_float(dbt);
4638 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4639 if (sf && df) {
4640 /* convert from fp to fp */
4641 if (c) {
4642 /* constant case: we can do it now */
4643 /* XXX: in ISOC, cannot do it if error in convert */
4644 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
4645 vtop->c.f = (float)vtop->c.d;
4646 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
4647 vtop->c.f = (float)vtop->c.ld;
4648 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
4649 vtop->c.d = (double)vtop->c.f;
4650 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
4651 vtop->c.d = (double)vtop->c.ld;
4652 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
4653 vtop->c.ld = (long double)vtop->c.f;
4654 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
4655 vtop->c.ld = (long double)vtop->c.d;
4656 } else {
4657 /* non constant case: generate code */
4658 gen_cvt_ftof(dbt);
4660 } else if (df) {
4661 /* convert int to fp */
4662 if (c) {
4663 switch(sbt) {
4664 case VT_LLONG | VT_UNSIGNED:
4665 case VT_LLONG:
4666 /* XXX: add const cases for long long */
4667 goto do_itof;
4668 case VT_INT | VT_UNSIGNED:
4669 switch(dbt) {
4670 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
4671 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
4672 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
4674 break;
4675 default:
4676 switch(dbt) {
4677 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
4678 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
4679 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4681 break;
4683 } else {
4684 do_itof:
4685 gen_cvt_itof1(dbt);
4687 } else if (sf) {
4688 /* convert fp to int */
4689 /* we handle char/short/etc... with generic code */
4690 if (dbt != (VT_INT | VT_UNSIGNED) &&
4691 dbt != (VT_LLONG | VT_UNSIGNED) &&
4692 dbt != VT_LLONG)
4693 dbt = VT_INT;
4694 if (c) {
4695 switch(dbt) {
4696 case VT_LLONG | VT_UNSIGNED:
4697 case VT_LLONG:
4698 /* XXX: add const cases for long long */
4699 goto do_ftoi;
4700 case VT_INT | VT_UNSIGNED:
4701 switch(sbt) {
4702 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4703 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4704 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4706 break;
4707 default:
4708 /* int case */
4709 switch(sbt) {
4710 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4711 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4712 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4714 break;
4716 } else {
4717 do_ftoi:
4718 gen_cvt_ftoi1(dbt);
4720 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4721 /* additionnal cast for char/short/bool... */
4722 vtop->type.t = dbt;
4723 gen_cast(type);
4725 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4726 if ((sbt & VT_BTYPE) != VT_LLONG) {
4727 /* scalar to long long */
4728 if (c) {
4729 if (sbt == (VT_INT | VT_UNSIGNED))
4730 vtop->c.ll = vtop->c.ui;
4731 else
4732 vtop->c.ll = vtop->c.i;
4733 } else {
4734 /* machine independant conversion */
4735 gv(RC_INT);
4736 /* generate high word */
4737 if (sbt == (VT_INT | VT_UNSIGNED)) {
4738 vpushi(0);
4739 gv(RC_INT);
4740 } else {
4741 gv_dup();
4742 vpushi(31);
4743 gen_op(TOK_SAR);
4745 /* patch second register */
4746 vtop[-1].r2 = vtop->r;
4747 vpop();
4750 } else if (dbt == VT_BOOL) {
4751 /* scalar to bool */
4752 vpushi(0);
4753 gen_op(TOK_NE);
4754 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4755 (dbt & VT_BTYPE) == VT_SHORT) {
4756 force_charshort_cast(dbt);
4757 } else if ((dbt & VT_BTYPE) == VT_INT) {
4758 /* scalar to int */
4759 if (sbt == VT_LLONG) {
4760 /* from long long: just take low order word */
4761 lexpand();
4762 vpop();
4764 /* if lvalue and single word type, nothing to do because
4765 the lvalue already contains the real type size (see
4766 VT_LVAL_xxx constants) */
4769 vtop->type = *type;
4772 /* return type size. Put alignment at 'a' */
4773 int type_size(CType *type, int *a)
4775 Sym *s;
4776 int bt;
4778 bt = type->t & VT_BTYPE;
4779 if (bt == VT_STRUCT) {
4780 /* struct/union */
4781 s = type->ref;
4782 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4783 return s->c;
4784 } else if (bt == VT_PTR) {
4785 if (type->t & VT_ARRAY) {
4786 s = type->ref;
4787 return type_size(&s->type, a) * s->c;
4788 } else {
4789 *a = PTR_SIZE;
4790 return PTR_SIZE;
4792 } else if (bt == VT_LDOUBLE) {
4793 *a = LDOUBLE_ALIGN;
4794 return LDOUBLE_SIZE;
4795 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4796 *a = 8;
4797 return 8;
4798 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4799 *a = 4;
4800 return 4;
4801 } else if (bt == VT_SHORT) {
4802 *a = 2;
4803 return 2;
4804 } else {
4805 /* char, void, function, _Bool */
4806 *a = 1;
4807 return 1;
4811 /* return the pointed type of t */
4812 static inline CType *pointed_type(CType *type)
4814 return &type->ref->type;
4817 /* modify type so that its it is a pointer to type. */
4818 static void mk_pointer(CType *type)
4820 Sym *s;
4821 s = sym_push(SYM_FIELD, type, 0, -1);
4822 type->t = VT_PTR | (type->t & ~VT_TYPE);
4823 type->ref = s;
4826 static int is_compatible_types(CType *type1, CType *type2)
4828 Sym *s1, *s2;
4829 int bt1, bt2, t1, t2;
4831 t1 = type1->t & VT_TYPE;
4832 t2 = type2->t & VT_TYPE;
4833 bt1 = t1 & VT_BTYPE;
4834 bt2 = t2 & VT_BTYPE;
4835 if (bt1 == VT_PTR) {
4836 type1 = pointed_type(type1);
4837 /* if function, then convert implicitely to function pointer */
4838 if (bt2 != VT_FUNC) {
4839 if (bt2 != VT_PTR)
4840 return 0;
4841 type2 = pointed_type(type2);
4843 /* void matches everything */
4844 /* XXX: not fully compliant */
4845 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
4846 return 1;
4847 return is_compatible_types(type1, type2);
4848 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4849 return (t2 == t1);
4850 } else if (bt1 == VT_FUNC) {
4851 if (bt2 != VT_FUNC)
4852 return 0;
4853 s1 = type1->ref;
4854 s2 = type2->ref;
4855 if (!is_compatible_types(&s1->type, &s2->type))
4856 return 0;
4857 /* XXX: not complete */
4858 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4859 return 1;
4860 if (s1->c != s2->c)
4861 return 0;
4862 while (s1 != NULL) {
4863 if (s2 == NULL)
4864 return 0;
4865 if (!is_compatible_types(&s1->type, &s2->type))
4866 return 0;
4867 s1 = s1->next;
4868 s2 = s2->next;
4870 if (s2)
4871 return 0;
4872 return 1;
4873 } else {
4874 /* XXX: not complete */
4875 return 1;
4879 /* print a type. If 'varstr' is not NULL, then the variable is also
4880 printed in the type */
4881 /* XXX: union */
4882 /* XXX: add array and function pointers */
4883 void type_to_str(char *buf, int buf_size,
4884 CType *type, const char *varstr)
4886 int bt, v, t;
4887 Sym *s, *sa;
4888 char buf1[256];
4889 const char *tstr;
4891 t = type->t & VT_TYPE;
4892 bt = t & VT_BTYPE;
4893 buf[0] = '\0';
4894 if (t & VT_UNSIGNED)
4895 pstrcat(buf, buf_size, "unsigned ");
4896 switch(bt) {
4897 case VT_VOID:
4898 tstr = "void";
4899 goto add_tstr;
4900 case VT_BOOL:
4901 tstr = "_Bool";
4902 goto add_tstr;
4903 case VT_BYTE:
4904 tstr = "char";
4905 goto add_tstr;
4906 case VT_SHORT:
4907 tstr = "short";
4908 goto add_tstr;
4909 case VT_INT:
4910 tstr = "int";
4911 goto add_tstr;
4912 case VT_LONG:
4913 tstr = "long";
4914 goto add_tstr;
4915 case VT_LLONG:
4916 tstr = "long long";
4917 goto add_tstr;
4918 case VT_FLOAT:
4919 tstr = "float";
4920 goto add_tstr;
4921 case VT_DOUBLE:
4922 tstr = "double";
4923 goto add_tstr;
4924 case VT_LDOUBLE:
4925 tstr = "long double";
4926 add_tstr:
4927 pstrcat(buf, buf_size, tstr);
4928 break;
4929 case VT_ENUM:
4930 case VT_STRUCT:
4931 if (bt == VT_STRUCT)
4932 tstr = "struct ";
4933 else
4934 tstr = "enum ";
4935 pstrcat(buf, buf_size, tstr);
4936 v = type->ref->v;
4937 if (v >= SYM_FIRST_ANOM)
4938 pstrcat(buf, buf_size, "<anonymous>");
4939 else
4940 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4941 break;
4942 case VT_FUNC:
4943 s = type->ref;
4944 type_to_str(buf, buf_size, &s->type, varstr);
4945 pstrcat(buf, buf_size, "(");
4946 sa = s->next;
4947 while (sa != NULL) {
4948 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
4949 pstrcat(buf, buf_size, buf1);
4950 sa = sa->next;
4951 if (sa)
4952 pstrcat(buf, buf_size, ", ");
4954 pstrcat(buf, buf_size, ")");
4955 goto no_var;
4956 case VT_PTR:
4957 s = type->ref;
4958 pstrcpy(buf1, sizeof(buf1), "*");
4959 if (varstr)
4960 pstrcat(buf1, sizeof(buf1), varstr);
4961 type_to_str(buf, buf_size, &s->type, buf1);
4962 goto no_var;
4964 if (varstr) {
4965 pstrcat(buf, buf_size, " ");
4966 pstrcat(buf, buf_size, varstr);
4968 no_var: ;
4971 /* verify type compatibility to store vtop in 'dt' type, and generate
4972 casts if needed. */
4973 void gen_assign_cast(CType *dt)
4975 CType *st;
4976 char buf1[256], buf2[256];
4978 st = &vtop->type; /* source type */
4979 if ((dt->t & VT_BTYPE) == VT_PTR) {
4980 /* special cases for pointers */
4981 /* a function is implicitely a function pointer */
4982 if ((st->t & VT_BTYPE) == VT_FUNC) {
4983 if (!is_compatible_types(pointed_type(dt), st))
4984 goto error;
4985 else
4986 goto type_ok;
4988 /* '0' can also be a pointer */
4989 if ((st->t & VT_BTYPE) == VT_INT &&
4990 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4991 vtop->c.i == 0)
4992 goto type_ok;
4994 if (!is_compatible_types(dt, st)) {
4995 error:
4996 type_to_str(buf1, sizeof(buf1), st, NULL);
4997 type_to_str(buf2, sizeof(buf2), dt, NULL);
4998 error("cannot cast '%s' to '%s'", buf1, buf2);
5000 type_ok:
5001 gen_cast(dt);
5004 /* store vtop in lvalue pushed on stack */
5005 void vstore(void)
5007 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5008 GFuncContext gf;
5010 ft = vtop[-1].type.t;
5011 sbt = vtop->type.t & VT_BTYPE;
5012 dbt = ft & VT_BTYPE;
5013 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5014 (sbt == VT_INT && dbt == VT_SHORT)) {
5015 /* optimize char/short casts */
5016 delayed_cast = VT_MUSTCAST;
5017 vtop->type.t = ft & VT_TYPE;
5018 } else {
5019 delayed_cast = 0;
5020 gen_assign_cast(&vtop[-1].type);
5023 if (sbt == VT_STRUCT) {
5024 /* if structure, only generate pointer */
5025 /* structure assignment : generate memcpy */
5026 /* XXX: optimize if small size */
5027 if (!nocode_wanted) {
5028 vdup();
5029 gfunc_start(&gf, FUNC_CDECL);
5030 /* type size */
5031 size = type_size(&vtop->type, &align);
5032 vpushi(size);
5033 gfunc_param(&gf);
5034 /* source */
5035 vtop->type.t = VT_INT;
5036 gaddrof();
5037 gfunc_param(&gf);
5038 /* destination */
5039 vswap();
5040 vtop->type.t = VT_INT;
5041 gaddrof();
5042 gfunc_param(&gf);
5044 save_regs(0);
5045 vpush_global_sym(&func_old_type, TOK_memcpy);
5046 gfunc_call(&gf);
5047 } else {
5048 vswap();
5049 vpop();
5051 /* leave source on stack */
5052 } else if (ft & VT_BITFIELD) {
5053 /* bitfield store handling */
5054 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5055 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5056 /* remove bit field info to avoid loops */
5057 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5059 /* duplicate destination */
5060 vdup();
5061 vtop[-1] = vtop[-2];
5063 /* mask and shift source */
5064 vpushi((1 << bit_size) - 1);
5065 gen_op('&');
5066 vpushi(bit_pos);
5067 gen_op(TOK_SHL);
5068 /* load destination, mask and or with source */
5069 vswap();
5070 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5071 gen_op('&');
5072 gen_op('|');
5073 /* store result */
5074 vstore();
5075 } else {
5076 #ifdef CONFIG_TCC_BCHECK
5077 /* bound check case */
5078 if (vtop[-1].r & VT_MUSTBOUND) {
5079 vswap();
5080 gbound();
5081 vswap();
5083 #endif
5084 if (!nocode_wanted) {
5085 rc = RC_INT;
5086 if (is_float(ft))
5087 rc = RC_FLOAT;
5088 r = gv(rc); /* generate value */
5089 /* if lvalue was saved on stack, must read it */
5090 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5091 SValue sv;
5092 t = get_reg(RC_INT);
5093 sv.type.t = VT_INT;
5094 sv.r = VT_LOCAL | VT_LVAL;
5095 sv.c.ul = vtop[-1].c.ul;
5096 load(t, &sv);
5097 vtop[-1].r = t | VT_LVAL;
5099 store(r, vtop - 1);
5100 /* two word case handling : store second register at word + 4 */
5101 if ((ft & VT_BTYPE) == VT_LLONG) {
5102 vswap();
5103 /* convert to int to increment easily */
5104 vtop->type.t = VT_INT;
5105 gaddrof();
5106 vpushi(4);
5107 gen_op('+');
5108 vtop->r |= VT_LVAL;
5109 vswap();
5110 /* XXX: it works because r2 is spilled last ! */
5111 store(vtop->r2, vtop - 1);
5114 vswap();
5115 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5116 vtop->r |= delayed_cast;
5120 /* post defines POST/PRE add. c is the token ++ or -- */
5121 void inc(int post, int c)
5123 test_lvalue();
5124 vdup(); /* save lvalue */
5125 if (post) {
5126 gv_dup(); /* duplicate value */
5127 vrotb(3);
5128 vrotb(3);
5130 /* add constant */
5131 vpushi(c - TOK_MID);
5132 gen_op('+');
5133 vstore(); /* store value */
5134 if (post)
5135 vpop(); /* if post op, return saved value */
5138 /* Parse GNUC __attribute__ extension. Currently, the following
5139 extensions are recognized:
5140 - aligned(n) : set data/function alignment.
5141 - section(x) : generate data/code in this section.
5142 - unused : currently ignored, but may be used someday.
5144 void parse_attribute(AttributeDef *ad)
5146 int t, n;
5148 next();
5149 skip('(');
5150 skip('(');
5151 while (tok != ')') {
5152 if (tok < TOK_IDENT)
5153 expect("attribute name");
5154 t = tok;
5155 next();
5156 switch(t) {
5157 case TOK_SECTION:
5158 case TOK___SECTION__:
5159 skip('(');
5160 if (tok != TOK_STR)
5161 expect("section name");
5162 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5163 next();
5164 skip(')');
5165 break;
5166 case TOK_ALIGNED:
5167 case TOK___ALIGNED__:
5168 skip('(');
5169 n = expr_const();
5170 if (n <= 0 || (n & (n - 1)) != 0)
5171 error("alignment must be a positive power of two");
5172 ad->aligned = n;
5173 skip(')');
5174 break;
5175 case TOK_UNUSED:
5176 case TOK___UNUSED__:
5177 /* currently, no need to handle it because tcc does not
5178 track unused objects */
5179 break;
5180 case TOK_NORETURN:
5181 case TOK___NORETURN__:
5182 /* currently, no need to handle it because tcc does not
5183 track unused objects */
5184 break;
5185 case TOK_CDECL:
5186 case TOK___CDECL:
5187 case TOK___CDECL__:
5188 ad->func_call = FUNC_CDECL;
5189 break;
5190 case TOK_STDCALL:
5191 case TOK___STDCALL:
5192 case TOK___STDCALL__:
5193 ad->func_call = FUNC_STDCALL;
5194 break;
5195 default:
5196 warning("'%s' attribute ignored", get_tok_str(t, NULL));
5197 /* skip parameters */
5198 /* XXX: skip parenthesis too */
5199 if (tok == '(') {
5200 next();
5201 while (tok != ')' && tok != -1)
5202 next();
5203 next();
5205 break;
5207 if (tok != ',')
5208 break;
5209 next();
5211 skip(')');
5212 skip(')');
5215 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5216 static void struct_decl(CType *type, int u)
5218 int a, v, size, align, maxalign, c, offset;
5219 int bit_size, bit_pos, bsize, bt, lbit_pos;
5220 Sym *s, *ss, **ps;
5221 AttributeDef ad;
5222 CType type1, btype;
5224 a = tok; /* save decl type */
5225 next();
5226 if (tok != '{') {
5227 v = tok;
5228 next();
5229 /* struct already defined ? return it */
5230 /* XXX: check consistency */
5231 s = struct_find(v);
5232 if (s) {
5233 if (s->type.t != a)
5234 error("invalid type");
5235 goto do_decl;
5237 } else {
5238 v = anon_sym++;
5240 type1.t = a;
5241 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5242 /* put struct/union/enum name in type */
5243 do_decl:
5244 type->t = u;
5245 type->ref = s;
5247 if (tok == '{') {
5248 next();
5249 if (s->c)
5250 error("struct/union/enum already defined");
5251 /* cannot be empty */
5252 c = 0;
5253 maxalign = 0;
5254 ps = &s->next;
5255 bit_pos = 0;
5256 offset = 0;
5257 while (1) {
5258 if (a == TOK_ENUM) {
5259 v = tok;
5260 next();
5261 if (tok == '=') {
5262 next();
5263 c = expr_const();
5265 /* enum symbols have static storage */
5266 ss = sym_push(v, &int_type, VT_CONST, c);
5267 ss->type.t |= VT_STATIC;
5268 if (tok == ',')
5269 next();
5270 c++;
5271 } else {
5272 parse_btype(&btype, &ad);
5273 while (1) {
5274 bit_size = -1;
5275 v = 0;
5276 type1 = btype;
5277 if (tok != ':') {
5278 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5279 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5280 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
5281 error("invalid type for '%s'",
5282 get_tok_str(v, NULL));
5284 if (tok == ':') {
5285 next();
5286 bit_size = expr_const();
5287 /* XXX: handle v = 0 case for messages */
5288 if (bit_size < 0)
5289 error("negative width in bit-field '%s'",
5290 get_tok_str(v, NULL));
5291 if (v && bit_size == 0)
5292 error("zero width for bit-field '%s'",
5293 get_tok_str(v, NULL));
5295 size = type_size(&type1, &align);
5296 lbit_pos = 0;
5297 if (bit_size >= 0) {
5298 bt = type1.t & VT_BTYPE;
5299 if (bt != VT_INT &&
5300 bt != VT_BYTE &&
5301 bt != VT_SHORT)
5302 error("bitfields must have scalar type");
5303 bsize = size * 8;
5304 if (bit_size > bsize) {
5305 error("width of '%s' exceeds its type",
5306 get_tok_str(v, NULL));
5307 } else if (bit_size == bsize) {
5308 /* no need for bit fields */
5309 bit_pos = 0;
5310 } else if (bit_size == 0) {
5311 /* XXX: what to do if only padding in a
5312 structure ? */
5313 /* zero size: means to pad */
5314 if (bit_pos > 0)
5315 bit_pos = bsize;
5316 } else {
5317 /* we do not have enough room ? */
5318 if ((bit_pos + bit_size) > bsize)
5319 bit_pos = 0;
5320 lbit_pos = bit_pos;
5321 /* XXX: handle LSB first */
5322 type1.t |= VT_BITFIELD |
5323 (bit_pos << VT_STRUCT_SHIFT) |
5324 (bit_size << (VT_STRUCT_SHIFT + 6));
5325 bit_pos += bit_size;
5327 } else {
5328 bit_pos = 0;
5330 if (v) {
5331 /* add new memory data only if starting
5332 bit field */
5333 if (lbit_pos == 0) {
5334 if (a == TOK_STRUCT) {
5335 c = (c + align - 1) & -align;
5336 offset = c;
5337 c += size;
5338 } else {
5339 offset = 0;
5340 if (size > c)
5341 c = size;
5343 if (align > maxalign)
5344 maxalign = align;
5346 #if 0
5347 printf("add field %s offset=%d",
5348 get_tok_str(v, NULL), offset);
5349 if (type1.t & VT_BITFIELD) {
5350 printf(" pos=%d size=%d",
5351 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
5352 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5354 printf("\n");
5355 #endif
5356 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
5357 *ps = ss;
5358 ps = &ss->next;
5360 if (tok == ';' || tok == -1)
5361 break;
5362 skip(',');
5364 skip(';');
5366 if (tok == '}')
5367 break;
5369 skip('}');
5370 /* size for struct/union, dummy for enum */
5371 s->c = (c + maxalign - 1) & -maxalign;
5375 /* return 0 if no type declaration. otherwise, return the basic type
5376 and skip it.
5378 static int parse_btype(CType *type, AttributeDef *ad)
5380 int t, u, type_found;
5381 Sym *s;
5382 CType type1;
5384 memset(ad, 0, sizeof(AttributeDef));
5385 type_found = 0;
5386 t = 0;
5387 while(1) {
5388 switch(tok) {
5389 /* basic types */
5390 case TOK_CHAR:
5391 u = VT_BYTE;
5392 basic_type:
5393 next();
5394 basic_type1:
5395 if ((t & VT_BTYPE) != 0)
5396 error("too many basic types");
5397 t |= u;
5398 break;
5399 case TOK_VOID:
5400 u = VT_VOID;
5401 goto basic_type;
5402 case TOK_SHORT:
5403 u = VT_SHORT;
5404 goto basic_type;
5405 case TOK_INT:
5406 next();
5407 break;
5408 case TOK_LONG:
5409 next();
5410 if ((t & VT_BTYPE) == VT_DOUBLE) {
5411 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5412 } else if ((t & VT_BTYPE) == VT_LONG) {
5413 t = (t & ~VT_BTYPE) | VT_LLONG;
5414 } else {
5415 u = VT_LONG;
5416 goto basic_type1;
5418 break;
5419 case TOK_BOOL:
5420 u = VT_BOOL;
5421 goto basic_type;
5422 case TOK_FLOAT:
5423 u = VT_FLOAT;
5424 goto basic_type;
5425 case TOK_DOUBLE:
5426 next();
5427 if ((t & VT_BTYPE) == VT_LONG) {
5428 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5429 } else {
5430 u = VT_DOUBLE;
5431 goto basic_type1;
5433 break;
5434 case TOK_ENUM:
5435 struct_decl(&type1, VT_ENUM);
5436 basic_type2:
5437 u = type1.t;
5438 type->ref = type1.ref;
5439 goto basic_type1;
5440 case TOK_STRUCT:
5441 case TOK_UNION:
5442 struct_decl(&type1, VT_STRUCT);
5443 goto basic_type2;
5445 /* type modifiers */
5446 case TOK_CONST:
5447 case TOK_VOLATILE:
5448 case TOK_REGISTER:
5449 case TOK_SIGNED:
5450 case TOK___SIGNED__:
5451 case TOK_AUTO:
5452 case TOK_INLINE:
5453 case TOK___INLINE__:
5454 case TOK_RESTRICT:
5455 next();
5456 break;
5457 case TOK_UNSIGNED:
5458 t |= VT_UNSIGNED;
5459 next();
5460 break;
5462 /* storage */
5463 case TOK_EXTERN:
5464 t |= VT_EXTERN;
5465 next();
5466 break;
5467 case TOK_STATIC:
5468 t |= VT_STATIC;
5469 next();
5470 break;
5471 case TOK_TYPEDEF:
5472 t |= VT_TYPEDEF;
5473 next();
5474 break;
5475 /* GNUC attribute */
5476 case TOK___ATTRIBUTE__:
5477 parse_attribute(ad);
5478 break;
5479 /* GNUC typeof */
5480 case TOK_TYPEOF:
5481 next();
5482 parse_expr_type(&type1);
5483 goto basic_type2;
5484 default:
5485 s = sym_find(tok);
5486 if (!s || !(s->type.t & VT_TYPEDEF))
5487 goto the_end;
5488 t |= (s->type.t & ~VT_TYPEDEF);
5489 type->ref = s->type.ref;
5490 next();
5491 break;
5493 type_found = 1;
5495 the_end:
5496 /* long is never used as type */
5497 if ((t & VT_BTYPE) == VT_LONG)
5498 t = (t & ~VT_BTYPE) | VT_INT;
5499 type->t = t;
5500 return type_found;
5503 static void post_type(CType *type, AttributeDef *ad)
5505 int n, l, t1;
5506 Sym **plast, *s, *first;
5507 AttributeDef ad1;
5508 CType pt;
5510 if (tok == '(') {
5511 /* function declaration */
5512 next();
5513 l = 0;
5514 first = NULL;
5515 plast = &first;
5516 while (tok != ')') {
5517 /* read param name and compute offset */
5518 if (l != FUNC_OLD) {
5519 if (!parse_btype(&pt, &ad1)) {
5520 if (l) {
5521 error("invalid type");
5522 } else {
5523 l = FUNC_OLD;
5524 goto old_proto;
5527 l = FUNC_NEW;
5528 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5529 break;
5530 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
5531 if ((pt.t & VT_BTYPE) == VT_VOID)
5532 error("parameter declared as void");
5533 } else {
5534 old_proto:
5535 n = tok;
5536 pt.t = VT_INT;
5537 next();
5539 /* array must be transformed to pointer according to ANSI C */
5540 pt.t &= ~VT_ARRAY;
5541 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
5542 *plast = s;
5543 plast = &s->next;
5544 if (tok == ',') {
5545 next();
5546 if (l == FUNC_NEW && tok == TOK_DOTS) {
5547 l = FUNC_ELLIPSIS;
5548 next();
5549 break;
5553 /* if no parameters, then old type prototype */
5554 if (l == 0)
5555 l = FUNC_OLD;
5556 skip(')');
5557 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5558 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5559 post_type(type, ad);
5560 /* we push a anonymous symbol which will contain the function prototype */
5561 s = sym_push(SYM_FIELD, type, ad->func_call, l);
5562 s->next = first;
5563 type->t = t1 | VT_FUNC;
5564 type->ref = s;
5565 } else if (tok == '[') {
5566 /* array definition */
5567 next();
5568 n = -1;
5569 if (tok != ']') {
5570 n = expr_const();
5571 if (n < 0)
5572 error("invalid array size");
5574 skip(']');
5575 /* parse next post type */
5576 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5577 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5578 post_type(type, ad);
5580 /* we push a anonymous symbol which will contain the array
5581 element type */
5582 s = sym_push(SYM_FIELD, type, 0, n);
5583 type->t = t1 | VT_ARRAY | VT_PTR;
5584 type->ref = s;
5588 /* Parse a type declaration (except basic type), and return the type
5589 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5590 expected. 'type' should contain the basic type. 'ad' is the
5591 attribute definition of the basic type. It can be modified by
5592 type_decl().
5594 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
5596 Sym *s;
5597 CType type1, *type2;
5599 while (tok == '*') {
5600 next();
5601 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
5602 next();
5603 mk_pointer(type);
5606 /* recursive type */
5607 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5608 type1.t = 0; /* XXX: same as int */
5609 if (tok == '(') {
5610 next();
5611 /* XXX: this is not correct to modify 'ad' at this point, but
5612 the syntax is not clear */
5613 if (tok == TOK___ATTRIBUTE__)
5614 parse_attribute(ad);
5615 type_decl(&type1, ad, v, td);
5616 skip(')');
5617 } else {
5618 /* type identifier */
5619 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5620 *v = tok;
5621 next();
5622 } else {
5623 if (!(td & TYPE_ABSTRACT))
5624 expect("identifier");
5625 *v = 0;
5628 post_type(type, ad);
5629 if (tok == TOK___ATTRIBUTE__)
5630 parse_attribute(ad);
5631 if (!type1.t)
5632 return;
5633 /* append type at the end of type1 */
5634 type2 = &type1;
5635 for(;;) {
5636 s = type2->ref;
5637 type2 = &s->type;
5638 if (!type2->t) {
5639 *type2 = *type;
5640 break;
5643 *type = type1;
5646 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5647 static int lvalue_type(int t)
5649 int bt, r;
5650 r = VT_LVAL;
5651 bt = t & VT_BTYPE;
5652 if (bt == VT_BYTE)
5653 r |= VT_LVAL_BYTE;
5654 else if (bt == VT_SHORT)
5655 r |= VT_LVAL_SHORT;
5656 else
5657 return r;
5658 if (t & VT_UNSIGNED)
5659 r |= VT_LVAL_UNSIGNED;
5660 return r;
5663 /* indirection with full error checking and bound check */
5664 static void indir(void)
5666 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5667 expect("pointer");
5668 if ((vtop->r & VT_LVAL) && !nocode_wanted)
5669 gv(RC_INT);
5670 vtop->type = *pointed_type(&vtop->type);
5671 /* an array is never an lvalue */
5672 if (!(vtop->type.t & VT_ARRAY)) {
5673 vtop->r |= lvalue_type(vtop->type.t);
5674 /* if bound checking, the referenced pointer must be checked */
5675 if (do_bounds_check)
5676 vtop->r |= VT_MUSTBOUND;
5680 /* pass a parameter to a function and do type checking and casting */
5681 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
5683 int func_type;
5684 CType type;
5686 func_type = func->c;
5687 if (func_type == FUNC_OLD ||
5688 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5689 /* default casting : only need to convert float to double */
5690 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
5691 type.t = VT_DOUBLE;
5692 gen_cast(&type);
5694 } else if (arg == NULL) {
5695 error("too many arguments to function");
5696 } else {
5697 gen_assign_cast(&arg->type);
5699 if (!nocode_wanted) {
5700 gfunc_param(gf);
5701 } else {
5702 vpop();
5706 /* parse an expression of the form '(type)' or '(expr)' and return its
5707 type */
5708 static void parse_expr_type(CType *type)
5710 int n;
5711 AttributeDef ad;
5713 skip('(');
5714 if (parse_btype(type, &ad)) {
5715 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5716 } else {
5717 expr_type(type);
5719 skip(')');
5722 static void vpush_tokc(int t)
5724 CType type;
5725 type.t = t;
5726 vsetc(&type, VT_CONST, &tokc);
5729 static void unary(void)
5731 int n, t, align, size, r;
5732 CType type;
5733 Sym *s;
5734 GFuncContext gf;
5735 AttributeDef ad;
5737 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5738 vpushi(tokc.i);
5739 next();
5740 } else if (tok == TOK_CUINT) {
5741 vpush_tokc(VT_INT | VT_UNSIGNED);
5742 next();
5743 } else if (tok == TOK_CLLONG) {
5744 vpush_tokc(VT_LLONG);
5745 next();
5746 } else if (tok == TOK_CULLONG) {
5747 vpush_tokc(VT_LLONG | VT_UNSIGNED);
5748 next();
5749 } else if (tok == TOK_CFLOAT) {
5750 vpush_tokc(VT_FLOAT);
5751 next();
5752 } else if (tok == TOK_CDOUBLE) {
5753 vpush_tokc(VT_DOUBLE);
5754 next();
5755 } else if (tok == TOK_CLDOUBLE) {
5756 vpush_tokc(VT_LDOUBLE);
5757 next();
5758 } else if (tok == TOK___FUNC__ || (tok == TOK___FUNCTION__ && gnu_ext)) {
5759 void *ptr;
5760 int len;
5761 /* special function name identifier */
5763 len = strlen(funcname) + 1;
5764 /* generate char[len] type */
5765 type.t = VT_BYTE;
5766 mk_pointer(&type);
5767 type.t |= VT_ARRAY;
5768 type.ref->c = len;
5769 vpush_ref(&type, data_section, data_section->data_offset, len);
5770 ptr = section_ptr_add(data_section, len);
5771 memcpy(ptr, funcname, len);
5772 next();
5773 } else if (tok == TOK_LSTR) {
5774 t = VT_INT;
5775 goto str_init;
5776 } else if (tok == TOK_STR) {
5777 /* string parsing */
5778 t = VT_BYTE;
5779 str_init:
5780 type.t = t;
5781 mk_pointer(&type);
5782 type.t |= VT_ARRAY;
5783 memset(&ad, 0, sizeof(AttributeDef));
5784 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
5785 } else {
5786 t = tok;
5787 next();
5788 if (t == '(') {
5789 /* cast ? */
5790 if (parse_btype(&type, &ad)) {
5791 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
5792 skip(')');
5793 /* check ISOC99 compound literal */
5794 if (tok == '{') {
5795 /* data is allocated locally by default */
5796 if (global_expr)
5797 r = VT_CONST;
5798 else
5799 r = VT_LOCAL;
5800 /* all except arrays are lvalues */
5801 if (!(type.t & VT_ARRAY))
5802 r |= lvalue_type(type.t);
5803 memset(&ad, 0, sizeof(AttributeDef));
5804 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
5805 } else {
5806 unary();
5807 gen_cast(&type);
5809 } else {
5810 gexpr();
5811 skip(')');
5813 } else if (t == '*') {
5814 unary();
5815 indir();
5816 } else if (t == '&') {
5817 unary();
5818 /* functions names must be treated as function pointers,
5819 except for unary '&' and sizeof. Since we consider that
5820 functions are not lvalues, we only have to handle it
5821 there and in function calls. */
5822 /* arrays can also be used although they are not lvalues */
5823 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
5824 !(vtop->type.t & VT_ARRAY))
5825 test_lvalue();
5826 mk_pointer(&vtop->type);
5827 gaddrof();
5828 } else if (t == '!') {
5829 unary();
5830 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
5831 vtop->c.i = !vtop->c.i;
5832 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5833 vtop->c.i = vtop->c.i ^ 1;
5834 else
5835 vseti(VT_JMP, gtst(1, 0));
5836 } else if (t == '~') {
5837 unary();
5838 vpushi(-1);
5839 gen_op('^');
5840 } else if (t == '+') {
5841 /* in order to force cast, we add zero */
5842 unary();
5843 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
5844 error("pointer not accepted for unary plus");
5845 vpushi(0);
5846 gen_op('+');
5847 } else if (t == TOK_SIZEOF || t == TOK_ALIGNOF) {
5848 if (tok == '(') {
5849 parse_expr_type(&type);
5850 } else {
5851 unary_type(&type);
5853 size = type_size(&type, &align);
5854 if (t == TOK_SIZEOF)
5855 vpushi(size);
5856 else
5857 vpushi(align);
5858 } else if (t == TOK_INC || t == TOK_DEC) {
5859 unary();
5860 inc(0, t);
5861 } else if (t == '-') {
5862 vpushi(0);
5863 unary();
5864 gen_op('-');
5865 } else if (t == TOK_LAND && gnu_ext) {
5866 /* allow to take the address of a label */
5867 if (tok < TOK_UIDENT)
5868 expect("label identifier");
5869 s = label_find(tok);
5870 if (!s) {
5871 s = label_push(tok, LABEL_FORWARD);
5873 if (!s->type.t) {
5874 s->type.t = VT_VOID;
5875 mk_pointer(&s->type);
5876 s->type.t |= VT_STATIC;
5878 vset(&s->type, VT_CONST | VT_SYM, 0);
5879 vtop->sym = s;
5880 next();
5881 } else {
5882 if (t < TOK_UIDENT)
5883 expect("identifier");
5884 s = sym_find(t);
5885 if (!s) {
5886 if (tok != '(')
5887 error("'%s' undeclared", get_tok_str(t, NULL));
5888 /* for simple function calls, we tolerate undeclared
5889 external reference to int() function */
5890 s = external_global_sym(t, &func_old_type, 0);
5892 vset(&s->type, s->r, s->c);
5893 /* if forward reference, we must point to s */
5894 if (vtop->r & VT_SYM) {
5895 vtop->sym = s;
5896 vtop->c.ul = 0;
5901 /* post operations */
5902 while (1) {
5903 if (tok == TOK_INC || tok == TOK_DEC) {
5904 inc(1, tok);
5905 next();
5906 } else if (tok == '.' || tok == TOK_ARROW) {
5907 /* field */
5908 if (tok == TOK_ARROW)
5909 indir();
5910 test_lvalue();
5911 gaddrof();
5912 next();
5913 /* expect pointer on structure */
5914 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
5915 expect("struct or union");
5916 s = vtop->type.ref;
5917 /* find field */
5918 tok |= SYM_FIELD;
5919 while ((s = s->next) != NULL) {
5920 if (s->v == tok)
5921 break;
5923 if (!s)
5924 error("field not found");
5925 /* add field offset to pointer */
5926 vtop->type = char_pointer_type; /* change type to 'char *' */
5927 vpushi(s->c);
5928 gen_op('+');
5929 /* change type to field type, and set to lvalue */
5930 vtop->type = s->type;
5931 /* an array is never an lvalue */
5932 if (!(vtop->type.t & VT_ARRAY)) {
5933 vtop->r |= lvalue_type(vtop->type.t);
5934 /* if bound checking, the referenced pointer must be checked */
5935 if (do_bounds_check)
5936 vtop->r |= VT_MUSTBOUND;
5938 next();
5939 } else if (tok == '[') {
5940 next();
5941 gexpr();
5942 gen_op('+');
5943 indir();
5944 skip(']');
5945 } else if (tok == '(') {
5946 SValue ret;
5947 Sym *sa;
5949 /* function call */
5950 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
5951 /* pointer test (no array accepted) */
5952 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5953 vtop->type = *pointed_type(&vtop->type);
5954 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
5955 goto error_func;
5956 } else {
5957 error_func:
5958 expect("function pointer");
5960 } else {
5961 vtop->r &= ~VT_LVAL; /* no lvalue */
5963 /* get return type */
5964 s = vtop->type.ref;
5965 if (!nocode_wanted) {
5966 save_regs(0); /* save used temporary registers */
5967 gfunc_start(&gf, s->r);
5969 next();
5970 sa = s->next; /* first parameter */
5971 #ifdef INVERT_FUNC_PARAMS
5973 int parlevel;
5974 Sym *args, *s1;
5975 ParseState saved_parse_state;
5976 TokenString str;
5978 /* read each argument and store it on a stack */
5979 args = NULL;
5980 if (tok != ')') {
5981 for(;;) {
5982 tok_str_new(&str);
5983 parlevel = 0;
5984 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5985 tok != TOK_EOF) {
5986 if (tok == '(')
5987 parlevel++;
5988 else if (tok == ')')
5989 parlevel--;
5990 tok_str_add_tok(&str);
5991 next();
5993 tok_str_add(&str, -1); /* end of file added */
5994 tok_str_add(&str, 0);
5995 s1 = sym_push2(&args, 0, 0, (int)str.str);
5996 s1->next = sa; /* add reference to argument */
5997 if (sa)
5998 sa = sa->next;
5999 if (tok == ')')
6000 break;
6001 skip(',');
6005 /* now generate code in reverse order by reading the stack */
6006 save_parse_state(&saved_parse_state);
6007 while (args) {
6008 macro_ptr = (int *)args->c;
6009 next();
6010 expr_eq();
6011 if (tok != -1)
6012 expect("',' or ')'");
6013 gfunc_param_typed(&gf, s, args->next);
6014 s1 = args->prev;
6015 tok_str_free((int *)args->c);
6016 tcc_free(args);
6017 args = s1;
6019 restore_parse_state(&saved_parse_state);
6021 #endif
6022 /* compute first implicit argument if a structure is returned */
6023 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6024 /* get some space for the returned structure */
6025 size = type_size(&s->type, &align);
6026 loc = (loc - size) & -align;
6027 ret.type = s->type;
6028 ret.r = VT_LOCAL | VT_LVAL;
6029 /* pass it as 'int' to avoid structure arg passing
6030 problems */
6031 vseti(VT_LOCAL, loc);
6032 ret.c = vtop->c;
6033 if (!nocode_wanted)
6034 gfunc_param(&gf);
6035 else
6036 vtop--;
6037 } else {
6038 ret.type = s->type;
6039 ret.r2 = VT_CONST;
6040 /* return in register */
6041 if (is_float(ret.type.t)) {
6042 ret.r = REG_FRET;
6043 } else {
6044 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6045 ret.r2 = REG_LRET;
6046 ret.r = REG_IRET;
6048 ret.c.i = 0;
6050 #ifndef INVERT_FUNC_PARAMS
6051 if (tok != ')') {
6052 for(;;) {
6053 expr_eq();
6054 gfunc_param_typed(&gf, s, sa);
6055 if (sa)
6056 sa = sa->next;
6057 if (tok == ')')
6058 break;
6059 skip(',');
6062 #endif
6063 if (sa)
6064 error("too few arguments to function");
6065 skip(')');
6066 if (!nocode_wanted)
6067 gfunc_call(&gf);
6068 else
6069 vtop--;
6070 /* return value */
6071 vsetc(&ret.type, ret.r, &ret.c);
6072 vtop->r2 = ret.r2;
6073 } else {
6074 break;
6079 static void uneq(void)
6081 int t;
6083 unary();
6084 if (tok == '=' ||
6085 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6086 tok == TOK_A_XOR || tok == TOK_A_OR ||
6087 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6088 test_lvalue();
6089 t = tok;
6090 next();
6091 if (t == '=') {
6092 expr_eq();
6093 } else {
6094 vdup();
6095 expr_eq();
6096 gen_op(t & 0x7f);
6098 vstore();
6102 static void sum(int l)
6104 int t;
6106 if (l == 0)
6107 uneq();
6108 else {
6109 sum(--l);
6110 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
6111 (l == 1 && (tok == '+' || tok == '-')) ||
6112 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
6113 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
6114 tok == TOK_ULT || tok == TOK_UGE)) ||
6115 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
6116 (l == 5 && tok == '&') ||
6117 (l == 6 && tok == '^') ||
6118 (l == 7 && tok == '|') ||
6119 (l == 8 && tok == TOK_LAND) ||
6120 (l == 9 && tok == TOK_LOR)) {
6121 t = tok;
6122 next();
6123 sum(l);
6124 gen_op(t);
6129 /* only used if non constant */
6130 static void eand(void)
6132 int t;
6134 sum(8);
6135 t = 0;
6136 while (1) {
6137 if (tok != TOK_LAND) {
6138 if (t) {
6139 t = gtst(1, t);
6140 vseti(VT_JMPI, t);
6142 break;
6144 t = gtst(1, t);
6145 next();
6146 sum(8);
6150 static void eor(void)
6152 int t;
6154 eand();
6155 t = 0;
6156 while (1) {
6157 if (tok != TOK_LOR) {
6158 if (t) {
6159 t = gtst(0, t);
6160 vseti(VT_JMP, t);
6162 break;
6164 t = gtst(0, t);
6165 next();
6166 eand();
6170 /* XXX: better constant handling */
6171 static void expr_eq(void)
6173 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
6174 SValue sv;
6175 CType type, type1, type2;
6177 if (const_wanted) {
6178 int c1, c;
6179 sum(10);
6180 if (tok == '?') {
6181 c = vtop->c.i;
6182 vpop();
6183 next();
6184 gexpr();
6185 c1 = vtop->c.i;
6186 vpop();
6187 skip(':');
6188 expr_eq();
6189 if (c)
6190 vtop->c.i = c1;
6192 } else {
6193 eor();
6194 if (tok == '?') {
6195 next();
6196 save_regs(1); /* we need to save all registers here except
6197 at the top because it is a branch point */
6198 tt = gtst(1, 0);
6199 gexpr();
6200 type1 = vtop->type;
6201 sv = *vtop; /* save value to handle it later */
6202 vtop--; /* no vpop so that FP stack is not flushed */
6203 skip(':');
6204 u = gjmp(0);
6206 gsym(tt);
6207 expr_eq();
6208 type2 = vtop->type;
6210 t1 = type1.t;
6211 bt1 = t1 & VT_BTYPE;
6212 t2 = type2.t;
6213 bt2 = t2 & VT_BTYPE;
6214 /* cast operands to correct type according to ISOC rules */
6215 if (is_float(bt1) || is_float(bt2)) {
6216 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
6217 type.t = VT_LDOUBLE;
6218 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
6219 type.t = VT_DOUBLE;
6220 } else {
6221 type.t = VT_FLOAT;
6223 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
6224 /* cast to biggest op */
6225 type.t = VT_LLONG;
6226 /* convert to unsigned if it does not fit in a long long */
6227 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
6228 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
6229 type.t |= VT_UNSIGNED;
6230 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
6231 /* XXX: test pointer compatibility */
6232 type = type1;
6233 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
6234 /* XXX: test structure compatibility */
6235 type = type1;
6236 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
6237 /* NOTE: as an extension, we accept void on only one side */
6238 type.t = VT_VOID;
6239 } else {
6240 /* integer operations */
6241 type.t = VT_INT;
6242 /* convert to unsigned if it does not fit in an integer */
6243 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
6244 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
6245 type.t |= VT_UNSIGNED;
6248 /* now we convert second operand */
6249 gen_cast(&type);
6250 rc = RC_INT;
6251 if (is_float(type.t)) {
6252 rc = RC_FLOAT;
6253 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
6254 /* for long longs, we use fixed registers to avoid having
6255 to handle a complicated move */
6256 rc = RC_IRET;
6258 r2 = gv(rc);
6259 /* this is horrible, but we must also convert first
6260 operand */
6261 tt = gjmp(0);
6262 gsym(u);
6263 /* put again first value and cast it */
6264 *vtop = sv;
6265 gen_cast(&type);
6266 r1 = gv(rc);
6267 move_reg(r2, r1);
6268 vtop->r = r2;
6269 gsym(tt);
6274 static void gexpr(void)
6276 while (1) {
6277 expr_eq();
6278 if (tok != ',')
6279 break;
6280 vpop();
6281 next();
6285 /* parse an expression and return its type without any side effect. */
6286 static void expr_type(CType *type)
6288 int a;
6290 a = nocode_wanted;
6291 nocode_wanted = 1;
6292 gexpr();
6293 *type = vtop->type;
6294 vpop();
6295 nocode_wanted = a;
6298 /* parse a unary expression and return its type without any side
6299 effect. */
6300 static void unary_type(CType *type)
6302 int a;
6304 a = nocode_wanted;
6305 nocode_wanted = 1;
6306 unary();
6307 *type = vtop->type;
6308 vpop();
6309 nocode_wanted = a;
6312 /* parse a constant expression and return value in vtop. */
6313 static void expr_const1(void)
6315 int a;
6316 a = const_wanted;
6317 const_wanted = 1;
6318 expr_eq();
6319 const_wanted = a;
6322 /* parse an integer constant and return its value. */
6323 static int expr_const(void)
6325 int c;
6326 expr_const1();
6327 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
6328 expect("constant expression");
6329 c = vtop->c.i;
6330 vpop();
6331 return c;
6334 /* return the label token if current token is a label, otherwise
6335 return zero */
6336 static int is_label(void)
6338 int t;
6339 CValue c;
6341 /* fast test first */
6342 if (tok < TOK_UIDENT)
6343 return 0;
6344 /* no need to save tokc since we expect an identifier */
6345 t = tok;
6346 c = tokc;
6347 next();
6348 if (tok == ':') {
6349 next();
6350 return t;
6351 } else {
6352 /* XXX: may not work in all cases (macros ?) */
6353 tok1 = tok;
6354 tok1c = tokc;
6355 tok = t;
6356 tokc = c;
6357 return 0;
6361 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
6363 int a, b, c, d;
6364 Sym *s;
6366 /* generate line number info */
6367 if (do_debug &&
6368 (last_line_num != file->line_num || last_ind != ind)) {
6369 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
6370 last_ind = ind;
6371 last_line_num = file->line_num;
6374 if (tok == TOK_IF) {
6375 /* if test */
6376 next();
6377 skip('(');
6378 gexpr();
6379 skip(')');
6380 a = gtst(1, 0);
6381 block(bsym, csym, case_sym, def_sym, case_reg);
6382 c = tok;
6383 if (c == TOK_ELSE) {
6384 next();
6385 d = gjmp(0);
6386 gsym(a);
6387 block(bsym, csym, case_sym, def_sym, case_reg);
6388 gsym(d); /* patch else jmp */
6389 } else
6390 gsym(a);
6391 } else if (tok == TOK_WHILE) {
6392 next();
6393 d = ind;
6394 skip('(');
6395 gexpr();
6396 skip(')');
6397 a = gtst(1, 0);
6398 b = 0;
6399 block(&a, &b, case_sym, def_sym, case_reg);
6400 gjmp_addr(d);
6401 gsym(a);
6402 gsym_addr(b, d);
6403 } else if (tok == '{') {
6404 next();
6405 /* declarations */
6406 s = local_stack;
6407 while (tok != '}') {
6408 decl(VT_LOCAL);
6409 if (tok != '}')
6410 block(bsym, csym, case_sym, def_sym, case_reg);
6412 /* pop locally defined symbols */
6413 sym_pop(&local_stack, s);
6414 next();
6415 } else if (tok == TOK_RETURN) {
6416 next();
6417 if (tok != ';') {
6418 gexpr();
6419 gen_assign_cast(&func_vt);
6420 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
6421 CType type;
6422 /* if returning structure, must copy it to implicit
6423 first pointer arg location */
6424 type = func_vt;
6425 mk_pointer(&type);
6426 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6427 indir();
6428 vswap();
6429 /* copy structure value to pointer */
6430 vstore();
6431 } else if (is_float(func_vt.t)) {
6432 gv(RC_FRET);
6433 } else {
6434 gv(RC_IRET);
6436 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6438 skip(';');
6439 rsym = gjmp(rsym); /* jmp */
6440 } else if (tok == TOK_BREAK) {
6441 /* compute jump */
6442 if (!bsym)
6443 error("cannot break");
6444 *bsym = gjmp(*bsym);
6445 next();
6446 skip(';');
6447 } else if (tok == TOK_CONTINUE) {
6448 /* compute jump */
6449 if (!csym)
6450 error("cannot continue");
6451 *csym = gjmp(*csym);
6452 next();
6453 skip(';');
6454 } else if (tok == TOK_FOR) {
6455 int e;
6456 next();
6457 skip('(');
6458 if (tok != ';') {
6459 gexpr();
6460 vpop();
6462 skip(';');
6463 d = ind;
6464 c = ind;
6465 a = 0;
6466 b = 0;
6467 if (tok != ';') {
6468 gexpr();
6469 a = gtst(1, 0);
6471 skip(';');
6472 if (tok != ')') {
6473 e = gjmp(0);
6474 c = ind;
6475 gexpr();
6476 vpop();
6477 gjmp_addr(d);
6478 gsym(e);
6480 skip(')');
6481 block(&a, &b, case_sym, def_sym, case_reg);
6482 gjmp_addr(c);
6483 gsym(a);
6484 gsym_addr(b, c);
6485 } else
6486 if (tok == TOK_DO) {
6487 next();
6488 a = 0;
6489 b = 0;
6490 d = ind;
6491 block(&a, &b, case_sym, def_sym, case_reg);
6492 skip(TOK_WHILE);
6493 skip('(');
6494 gsym(b);
6495 gexpr();
6496 c = gtst(0, 0);
6497 gsym_addr(c, d);
6498 skip(')');
6499 gsym(a);
6500 skip(';');
6501 } else
6502 if (tok == TOK_SWITCH) {
6503 next();
6504 skip('(');
6505 gexpr();
6506 /* XXX: other types than integer */
6507 case_reg = gv(RC_INT);
6508 vpop();
6509 skip(')');
6510 a = 0;
6511 b = gjmp(0); /* jump to first case */
6512 c = 0;
6513 block(&a, csym, &b, &c, case_reg);
6514 /* if no default, jmp after switch */
6515 if (c == 0)
6516 c = ind;
6517 /* default label */
6518 gsym_addr(b, c);
6519 /* break label */
6520 gsym(a);
6521 } else
6522 if (tok == TOK_CASE) {
6523 int v1, v2;
6524 if (!case_sym)
6525 expect("switch");
6526 next();
6527 v1 = expr_const();
6528 v2 = v1;
6529 if (gnu_ext && tok == TOK_DOTS) {
6530 next();
6531 v2 = expr_const();
6532 if (v2 < v1)
6533 warning("empty case range");
6535 /* since a case is like a label, we must skip it with a jmp */
6536 b = gjmp(0);
6537 gsym(*case_sym);
6538 vseti(case_reg, 0);
6539 vpushi(v1);
6540 if (v1 == v2) {
6541 gen_op(TOK_EQ);
6542 *case_sym = gtst(1, 0);
6543 } else {
6544 gen_op(TOK_GE);
6545 *case_sym = gtst(1, 0);
6546 vseti(case_reg, 0);
6547 vpushi(v2);
6548 gen_op(TOK_LE);
6549 *case_sym = gtst(1, *case_sym);
6551 gsym(b);
6552 skip(':');
6553 block(bsym, csym, case_sym, def_sym, case_reg);
6554 } else
6555 if (tok == TOK_DEFAULT) {
6556 next();
6557 skip(':');
6558 if (!def_sym)
6559 expect("switch");
6560 if (*def_sym)
6561 error("too many 'default'");
6562 *def_sym = ind;
6563 block(bsym, csym, case_sym, def_sym, case_reg);
6564 } else
6565 if (tok == TOK_GOTO) {
6566 next();
6567 if (tok == '*' && gnu_ext) {
6568 /* computed goto */
6569 next();
6570 gexpr();
6571 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6572 expect("pointer");
6573 ggoto();
6574 } else if (tok >= TOK_UIDENT) {
6575 s = label_find(tok);
6576 /* put forward definition if needed */
6577 if (!s) {
6578 s = label_push(tok, LABEL_FORWARD);
6580 /* label already defined */
6581 if (s->r & LABEL_FORWARD)
6582 s->next = (void *)gjmp((long)s->next);
6583 else
6584 gjmp_addr((long)s->next);
6585 next();
6586 } else {
6587 expect("label identifier");
6589 skip(';');
6590 } else {
6591 b = is_label();
6592 if (b) {
6593 /* label case */
6594 s = label_find(b);
6595 if (s) {
6596 if (!(s->r & LABEL_FORWARD))
6597 error("multiple defined label");
6598 gsym((long)s->next);
6599 } else {
6600 s = label_push(b, 0);
6602 s->next = (void *)ind;
6603 s->r = 0;
6604 /* we accept this, but it is a mistake */
6605 if (tok == '}')
6606 warning("deprecated use of label at end of compound statement");
6607 else
6608 block(bsym, csym, case_sym, def_sym, case_reg);
6609 } else {
6610 /* expression case */
6611 if (tok != ';') {
6612 gexpr();
6613 vpop();
6615 skip(';');
6620 /* t is the array or struct type. c is the array or struct
6621 address. cur_index/cur_field is the pointer to the current
6622 value. 'size_only' is true if only size info is needed (only used
6623 in arrays) */
6624 static void decl_designator(CType *type, Section *sec, unsigned long c,
6625 int *cur_index, Sym **cur_field,
6626 int size_only)
6628 Sym *s, *f;
6629 int notfirst, index, align, l;
6630 CType type1;
6632 notfirst = 0;
6633 if (gnu_ext && (l = is_label()) != 0)
6634 goto struct_field;
6636 while (tok == '[' || tok == '.') {
6637 if (tok == '[') {
6638 if (!(type->t & VT_ARRAY))
6639 expect("array type");
6640 s = type->ref;
6641 next();
6642 index = expr_const();
6643 if (index < 0 || (s->c >= 0 && index >= s->c))
6644 expect("invalid index");
6645 skip(']');
6646 if (!notfirst)
6647 *cur_index = index;
6648 type = pointed_type(type);
6649 c += index * type_size(type, &align);
6650 } else {
6651 next();
6652 l = tok;
6653 next();
6654 struct_field:
6655 if ((type->t & VT_BTYPE) != VT_STRUCT)
6656 expect("struct/union type");
6657 s = type->ref;
6658 l |= SYM_FIELD;
6659 f = s->next;
6660 while (f) {
6661 if (f->v == l)
6662 break;
6663 f = f->next;
6665 if (!f)
6666 expect("field");
6667 if (!notfirst)
6668 *cur_field = f;
6669 /* XXX: suppress this mess by using explicit storage field */
6670 type1 = f->type;
6671 type1.t |= (type->t & ~VT_TYPE);
6672 type = &type1;
6673 c += f->c;
6675 notfirst = 1;
6677 if (notfirst) {
6678 if (tok == '=') {
6679 next();
6680 } else {
6681 if (!gnu_ext)
6682 expect("=");
6684 } else {
6685 if (type->t & VT_ARRAY) {
6686 index = *cur_index;
6687 type = pointed_type(type);
6688 c += index * type_size(type, &align);
6689 } else {
6690 f = *cur_field;
6691 if (!f)
6692 error("too many field init");
6693 /* XXX: suppress this mess by using explicit storage field */
6694 type1 = f->type;
6695 type1.t |= (type->t & ~VT_TYPE);
6696 type = &type1;
6697 c += f->c;
6700 decl_initializer(type, sec, c, 0, size_only);
6703 #define EXPR_VAL 0
6704 #define EXPR_CONST 1
6705 #define EXPR_ANY 2
6707 /* store a value or an expression directly in global data or in local array */
6708 static void init_putv(CType *type, Section *sec, unsigned long c,
6709 int v, int expr_type)
6711 int saved_global_expr, bt;
6712 void *ptr;
6714 switch(expr_type) {
6715 case EXPR_VAL:
6716 vpushi(v);
6717 break;
6718 case EXPR_CONST:
6719 /* compound literals must be allocated globally in this case */
6720 saved_global_expr = global_expr;
6721 global_expr = 1;
6722 expr_const1();
6723 global_expr = saved_global_expr;
6724 /* NOTE: symbols are accepted */
6725 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
6726 error("initializer element is not constant");
6727 break;
6728 case EXPR_ANY:
6729 expr_eq();
6730 break;
6733 if (sec) {
6734 /* XXX: not portable */
6735 /* XXX: generate error if incorrect relocation */
6736 gen_assign_cast(type);
6737 bt = type->t & VT_BTYPE;
6738 ptr = sec->data + c;
6739 if ((vtop->r & VT_SYM) &&
6740 (bt == VT_BYTE ||
6741 bt == VT_SHORT ||
6742 bt == VT_DOUBLE ||
6743 bt == VT_LDOUBLE ||
6744 bt == VT_LLONG))
6745 error("initializer element is not computable at load time");
6746 switch(bt) {
6747 case VT_BYTE:
6748 *(char *)ptr = vtop->c.i;
6749 break;
6750 case VT_SHORT:
6751 *(short *)ptr = vtop->c.i;
6752 break;
6753 case VT_DOUBLE:
6754 *(double *)ptr = vtop->c.d;
6755 break;
6756 case VT_LDOUBLE:
6757 *(long double *)ptr = vtop->c.ld;
6758 break;
6759 case VT_LLONG:
6760 *(long long *)ptr = vtop->c.ll;
6761 break;
6762 default:
6763 if (vtop->r & VT_SYM) {
6764 greloc(sec, vtop->sym, c, R_DATA_32);
6766 *(int *)ptr = vtop->c.i;
6767 break;
6769 vtop--;
6770 } else {
6771 vset(type, VT_LOCAL, c);
6772 vswap();
6773 vstore();
6774 vpop();
6778 /* put zeros for variable based init */
6779 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
6781 GFuncContext gf;
6783 if (sec) {
6784 /* nothing to do because globals are already set to zero */
6785 } else {
6786 gfunc_start(&gf, FUNC_CDECL);
6787 vpushi(size);
6788 gfunc_param(&gf);
6789 vpushi(0);
6790 gfunc_param(&gf);
6791 vseti(VT_LOCAL, c);
6792 gfunc_param(&gf);
6793 vpush_global_sym(&func_old_type, TOK_memset);
6794 gfunc_call(&gf);
6798 /* 't' contains the type and storage info. 'c' is the offset of the
6799 object in section 'sec'. If 'sec' is NULL, it means stack based
6800 allocation. 'first' is true if array '{' must be read (multi
6801 dimension implicit array init handling). 'size_only' is true if
6802 size only evaluation is wanted (only for arrays). */
6803 static void decl_initializer(CType *type, Section *sec, unsigned long c,
6804 int first, int size_only)
6806 int index, array_length, n, no_oblock, nb, parlevel, i;
6807 int size1, align1, expr_type;
6808 Sym *s, *f;
6809 CType *t1;
6811 if (type->t & VT_ARRAY) {
6812 s = type->ref;
6813 n = s->c;
6814 array_length = 0;
6815 t1 = pointed_type(type);
6816 size1 = type_size(t1, &align1);
6818 no_oblock = 1;
6819 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
6820 tok == '{') {
6821 skip('{');
6822 no_oblock = 0;
6825 /* only parse strings here if correct type (otherwise: handle
6826 them as ((w)char *) expressions */
6827 if ((tok == TOK_LSTR &&
6828 (t1->t & VT_BTYPE) == VT_INT) ||
6829 (tok == TOK_STR &&
6830 (t1->t & VT_BTYPE) == VT_BYTE)) {
6831 while (tok == TOK_STR || tok == TOK_LSTR) {
6832 int cstr_len, ch;
6833 CString *cstr;
6835 cstr = tokc.cstr;
6836 /* compute maximum number of chars wanted */
6837 if (tok == TOK_STR)
6838 cstr_len = cstr->size;
6839 else
6840 cstr_len = cstr->size / sizeof(int);
6841 cstr_len--;
6842 nb = cstr_len;
6843 if (n >= 0 && nb > (n - array_length))
6844 nb = n - array_length;
6845 if (!size_only) {
6846 if (cstr_len > nb)
6847 warning("initializer-string for array is too long");
6848 /* in order to go faster for common case (char
6849 string in global variable, we handle it
6850 specifically */
6851 if (sec && tok == TOK_STR && size1 == 1) {
6852 memcpy(sec->data + c + array_length, cstr->data, nb);
6853 } else {
6854 for(i=0;i<nb;i++) {
6855 if (tok == TOK_STR)
6856 ch = ((unsigned char *)cstr->data)[i];
6857 else
6858 ch = ((int *)cstr->data)[i];
6859 init_putv(t1, sec, c + (array_length + i) * size1,
6860 ch, EXPR_VAL);
6864 array_length += nb;
6865 next();
6867 /* only add trailing zero if enough storage (no
6868 warning in this case since it is standard) */
6869 if (n < 0 || array_length < n) {
6870 if (!size_only) {
6871 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6873 array_length++;
6875 } else {
6876 index = 0;
6877 while (tok != '}') {
6878 decl_designator(type, sec, c, &index, NULL, size_only);
6879 if (n >= 0 && index >= n)
6880 error("index too large");
6881 /* must put zero in holes (note that doing it that way
6882 ensures that it even works with designators) */
6883 if (!size_only && array_length < index) {
6884 init_putz(t1, sec, c + array_length * size1,
6885 (index - array_length) * size1);
6887 index++;
6888 if (index > array_length)
6889 array_length = index;
6890 /* special test for multi dimensional arrays (may not
6891 be strictly correct if designators are used at the
6892 same time) */
6893 if (index >= n && no_oblock)
6894 break;
6895 if (tok == '}')
6896 break;
6897 skip(',');
6900 if (!no_oblock)
6901 skip('}');
6902 /* put zeros at the end */
6903 if (!size_only && n >= 0 && array_length < n) {
6904 init_putz(t1, sec, c + array_length * size1,
6905 (n - array_length) * size1);
6907 /* patch type size if needed */
6908 if (n < 0)
6909 s->c = array_length;
6910 } else if ((type->t & VT_BTYPE) == VT_STRUCT && tok == '{') {
6911 /* XXX: union needs only one init */
6912 next();
6913 s = type->ref;
6914 f = s->next;
6915 array_length = 0;
6916 index = 0;
6917 n = s->c;
6918 while (tok != '}') {
6919 decl_designator(type, sec, c, NULL, &f, size_only);
6920 /* fill with zero between fields */
6921 index = f->c;
6922 if (!size_only && array_length < index) {
6923 init_putz(type, sec, c + array_length,
6924 index - array_length);
6926 index = index + type_size(&f->type, &align1);
6927 if (index > array_length)
6928 array_length = index;
6929 if (tok == '}')
6930 break;
6931 skip(',');
6932 f = f->next;
6934 /* put zeros at the end */
6935 if (!size_only && array_length < n) {
6936 init_putz(type, sec, c + array_length,
6937 n - array_length);
6939 skip('}');
6940 } else if (tok == '{') {
6941 next();
6942 decl_initializer(type, sec, c, first, size_only);
6943 skip('}');
6944 } else if (size_only) {
6945 /* just skip expression */
6946 parlevel = 0;
6947 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
6948 tok != -1) {
6949 if (tok == '(')
6950 parlevel++;
6951 else if (tok == ')')
6952 parlevel--;
6953 next();
6955 } else {
6956 /* currently, we always use constant expression for globals
6957 (may change for scripting case) */
6958 expr_type = EXPR_CONST;
6959 if (!sec)
6960 expr_type = EXPR_ANY;
6961 init_putv(type, sec, c, 0, expr_type);
6965 /* parse an initializer for type 't' if 'has_init' is non zero, and
6966 allocate space in local or global data space ('r' is either
6967 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6968 variable 'v' of scope 'scope' is declared before initializers are
6969 parsed. If 'v' is zero, then a reference to the new object is put
6970 in the value stack. If 'has_init' is 2, a special parsing is done
6971 to handle string constants. */
6972 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
6973 int has_init, int v, int scope)
6975 int size, align, addr, data_offset;
6976 int level;
6977 ParseState saved_parse_state;
6978 TokenString init_str;
6979 Section *sec;
6981 size = type_size(type, &align);
6982 /* If unknown size, we must evaluate it before
6983 evaluating initializers because
6984 initializers can generate global data too
6985 (e.g. string pointers or ISOC99 compound
6986 literals). It also simplifies local
6987 initializers handling */
6988 tok_str_new(&init_str);
6989 if (size < 0) {
6990 if (!has_init)
6991 error("unknown type size");
6992 /* get all init string */
6993 if (has_init == 2) {
6994 /* only get strings */
6995 while (tok == TOK_STR || tok == TOK_LSTR) {
6996 tok_str_add_tok(&init_str);
6997 next();
6999 } else {
7000 level = 0;
7001 while (level > 0 || (tok != ',' && tok != ';')) {
7002 if (tok < 0)
7003 error("unexpected end of file in initializer");
7004 tok_str_add_tok(&init_str);
7005 if (tok == '{')
7006 level++;
7007 else if (tok == '}') {
7008 if (level == 0)
7009 break;
7010 level--;
7012 next();
7015 tok_str_add(&init_str, -1);
7016 tok_str_add(&init_str, 0);
7018 /* compute size */
7019 save_parse_state(&saved_parse_state);
7021 macro_ptr = init_str.str;
7022 next();
7023 decl_initializer(type, NULL, 0, 1, 1);
7024 /* prepare second initializer parsing */
7025 macro_ptr = init_str.str;
7026 next();
7028 /* if still unknown size, error */
7029 size = type_size(type, &align);
7030 if (size < 0)
7031 error("unknown type size");
7033 /* take into account specified alignment if bigger */
7034 if (ad->aligned > align)
7035 align = ad->aligned;
7036 if ((r & VT_VALMASK) == VT_LOCAL) {
7037 sec = NULL;
7038 if (do_bounds_check && (type->t & VT_ARRAY))
7039 loc--;
7040 #ifdef TCC_TARGET_IL
7041 /* XXX: ugly patch to allocate local variables for IL, just
7042 for testing */
7043 addr = loc;
7044 loc++;
7045 #else
7046 loc = (loc - size) & -align;
7047 addr = loc;
7048 #endif
7049 /* handles bounds */
7050 /* XXX: currently, since we do only one pass, we cannot track
7051 '&' operators, so we add only arrays */
7052 if (do_bounds_check && (type->t & VT_ARRAY)) {
7053 unsigned long *bounds_ptr;
7054 /* add padding between regions */
7055 loc--;
7056 /* then add local bound info */
7057 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
7058 bounds_ptr[0] = addr;
7059 bounds_ptr[1] = size;
7061 } else {
7062 /* compute section */
7063 sec = ad->section;
7064 if (!sec) {
7065 if (has_init)
7066 sec = data_section;
7067 else
7068 sec = bss_section;
7070 data_offset = sec->data_offset;
7071 data_offset = (data_offset + align - 1) & -align;
7072 addr = data_offset;
7073 /* very important to increment global pointer at this time
7074 because initializers themselves can create new initializers */
7075 data_offset += size;
7076 /* add padding if bound check */
7077 if (do_bounds_check)
7078 data_offset++;
7079 sec->data_offset = data_offset;
7080 /* allocate section space to put the data */
7081 if (sec->sh_type != SHT_NOBITS &&
7082 data_offset > sec->data_allocated)
7083 section_realloc(sec, data_offset);
7085 if (!sec) {
7086 if (v) {
7087 /* local variable */
7088 sym_push(v, type, r, addr);
7089 } else {
7090 /* push local reference */
7091 vset(type, r, addr);
7093 } else {
7094 Sym *sym;
7096 if (v) {
7097 if (scope == VT_CONST) {
7098 /* global scope: see if already defined */
7099 sym = sym_find(v);
7100 if (!sym)
7101 goto do_def;
7102 if (!is_compatible_types(&sym->type, type))
7103 error("incompatible types for redefinition of '%s'",
7104 get_tok_str(v, NULL));
7105 if (!(sym->type.t & VT_EXTERN))
7106 error("redefinition of '%s'", get_tok_str(v, NULL));
7107 sym->type.t &= ~VT_EXTERN;
7108 } else {
7109 do_def:
7110 sym = sym_push(v, type, r | VT_SYM, 0);
7112 put_extern_sym(sym, sec, addr, size);
7113 } else {
7114 CValue cval;
7116 /* push global reference */
7117 sym = get_sym_ref(type, sec, addr, size);
7118 cval.ul = 0;
7119 vsetc(type, VT_CONST | VT_SYM, &cval);
7120 vtop->sym = sym;
7123 /* handles bounds now because the symbol must be defined
7124 before for the relocation */
7125 if (do_bounds_check) {
7126 unsigned long *bounds_ptr;
7128 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
7129 /* then add global bound info */
7130 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
7131 bounds_ptr[0] = 0; /* relocated */
7132 bounds_ptr[1] = size;
7135 if (has_init) {
7136 decl_initializer(type, sec, addr, 1, 0);
7137 /* restore parse state if needed */
7138 if (init_str.str) {
7139 tok_str_free(init_str.str);
7140 restore_parse_state(&saved_parse_state);
7145 void put_func_debug(Sym *sym)
7147 char buf[512];
7149 /* stabs info */
7150 /* XXX: we put here a dummy type */
7151 snprintf(buf, sizeof(buf), "%s:%c1",
7152 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
7153 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
7154 cur_text_section, sym->c);
7155 last_ind = 0;
7156 last_line_num = 0;
7159 /* not finished : try to put some local vars in registers */
7160 //#define CONFIG_REG_VARS
7162 #ifdef CONFIG_REG_VARS
7163 void add_var_ref(int t)
7165 printf("%s:%d: &%s\n",
7166 file->filename, file->line_num,
7167 get_tok_str(t, NULL));
7170 /* first pass on a function with heuristic to extract variable usage
7171 and pointer references to local variables for register allocation */
7172 void analyse_function(void)
7174 int level, t;
7176 for(;;) {
7177 if (tok == -1)
7178 break;
7179 /* any symbol coming after '&' is considered as being a
7180 variable whose reference is taken. It is highly unaccurate
7181 but it is difficult to do better without a complete parse */
7182 if (tok == '&') {
7183 next();
7184 /* if '& number', then no need to examine next tokens */
7185 if (tok == TOK_CINT ||
7186 tok == TOK_CUINT ||
7187 tok == TOK_CLLONG ||
7188 tok == TOK_CULLONG) {
7189 continue;
7190 } else if (tok >= TOK_UIDENT) {
7191 /* if '& ident [' or '& ident ->', then ident address
7192 is not needed */
7193 t = tok;
7194 next();
7195 if (tok != '[' && tok != TOK_ARROW)
7196 add_var_ref(t);
7197 } else {
7198 level = 0;
7199 while (tok != '}' && tok != ';' &&
7200 !((tok == ',' || tok == ')') && level == 0)) {
7201 if (tok >= TOK_UIDENT) {
7202 add_var_ref(tok);
7203 } else if (tok == '(') {
7204 level++;
7205 } else if (tok == ')') {
7206 level--;
7208 next();
7211 } else {
7212 next();
7216 #endif
7218 /* parse an old style function declaration list */
7219 /* XXX: check multiple parameter */
7220 static void func_decl_list(Sym *func_sym)
7222 AttributeDef ad;
7223 int v;
7224 Sym *s;
7225 CType btype, type;
7227 /* parse each declaration */
7228 while (tok != '{' && tok != ';' && tok != TOK_EOF) {
7229 if (!parse_btype(&btype, &ad))
7230 expect("declaration list");
7231 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7232 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7233 tok == ';') {
7234 /* we accept no variable after */
7235 } else {
7236 for(;;) {
7237 type = btype;
7238 type_decl(&type, &ad, &v, TYPE_DIRECT);
7239 /* find parameter in function parameter list */
7240 s = func_sym->next;
7241 while (s != NULL) {
7242 if ((s->v & ~SYM_FIELD) == v)
7243 goto found;
7244 s = s->next;
7246 error("declaration for parameter '%s' but no such parameter",
7247 get_tok_str(v, NULL));
7248 found:
7249 /* check that no storage specifier except 'register' was given */
7250 if (type.t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF))
7251 error("storage class specified for '%s'", get_tok_str(v, NULL));
7252 /* we can add the type (NOTE: it could be local to the function) */
7253 s->type = type;
7254 /* accept other parameters */
7255 if (tok == ',')
7256 next();
7257 else
7258 break;
7261 skip(';');
7265 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7266 static void decl(int l)
7268 int v, has_init, r;
7269 CType type, btype;
7270 Sym *sym;
7271 AttributeDef ad;
7273 while (1) {
7274 if (!parse_btype(&btype, &ad)) {
7275 /* skip redundant ';' */
7276 /* XXX: find more elegant solution */
7277 if (tok == ';') {
7278 next();
7279 continue;
7281 /* special test for old K&R protos without explicit int
7282 type. Only accepted when defining global data */
7283 if (l == VT_LOCAL || tok < TOK_DEFINE)
7284 break;
7285 btype.t = VT_INT;
7287 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7288 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7289 tok == ';') {
7290 /* we accept no variable after */
7291 next();
7292 continue;
7294 while (1) { /* iterate thru each declaration */
7295 type = btype;
7296 type_decl(&type, &ad, &v, TYPE_DIRECT);
7297 #if 0
7299 char buf[500];
7300 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
7301 printf("type = '%s'\n", buf);
7303 #endif
7304 if ((type.t & VT_BTYPE) == VT_FUNC) {
7305 /* if old style function prototype, we accept a
7306 declaration list */
7307 sym = type.ref;
7308 if (sym->c == FUNC_OLD)
7309 func_decl_list(sym);
7312 if (tok == '{') {
7313 #ifdef CONFIG_REG_VARS
7314 TokenString func_str;
7315 ParseState saved_parse_state;
7316 int block_level;
7317 #endif
7319 if (l == VT_LOCAL)
7320 error("cannot use local functions");
7321 if (!(type.t & VT_FUNC))
7322 expect("function definition");
7324 #ifdef CONFIG_REG_VARS
7325 /* parse all function code and record it */
7327 tok_str_new(&func_str);
7329 block_level = 0;
7330 for(;;) {
7331 int t;
7332 if (tok == -1)
7333 error("unexpected end of file");
7334 tok_str_add_tok(&func_str);
7335 t = tok;
7336 next();
7337 if (t == '{') {
7338 block_level++;
7339 } else if (t == '}') {
7340 block_level--;
7341 if (block_level == 0)
7342 break;
7345 tok_str_add(&func_str, -1);
7346 tok_str_add(&func_str, 0);
7348 save_parse_state(&saved_parse_state);
7350 macro_ptr = func_str.str;
7351 next();
7352 analyse_function();
7353 #endif
7355 /* compute text section */
7356 cur_text_section = ad.section;
7357 if (!cur_text_section)
7358 cur_text_section = text_section;
7359 ind = cur_text_section->data_offset;
7360 funcname = get_tok_str(v, NULL);
7361 sym = sym_find(v);
7362 if (sym) {
7363 /* if symbol is already defined, then put complete type */
7364 sym->type = type;
7365 } else {
7366 /* put function symbol */
7367 sym = global_identifier_push(v, type.t, 0);
7368 sym->type.ref = type.ref;
7370 /* NOTE: we patch the symbol size later */
7371 put_extern_sym(sym, cur_text_section, ind, 0);
7372 func_ind = ind;
7373 sym->r = VT_SYM | VT_CONST;
7374 /* put debug symbol */
7375 if (do_debug)
7376 put_func_debug(sym);
7377 /* push a dummy symbol to enable local sym storage */
7378 sym_push2(&local_stack, SYM_FIELD, 0, 0);
7379 gfunc_prolog(&type);
7380 loc = 0;
7381 rsym = 0;
7382 #ifdef CONFIG_REG_VARS
7383 macro_ptr = func_str.str;
7384 next();
7385 #endif
7386 block(NULL, NULL, NULL, NULL, 0);
7387 gsym(rsym);
7388 gfunc_epilog();
7389 cur_text_section->data_offset = ind;
7390 /* look if any labels are undefined. Define symbols if
7391 '&&label' was used. */
7393 Sym *s, *s1;
7394 for(s = label_stack; s != NULL; s = s1) {
7395 s1 = s->prev;
7396 if (s->r & LABEL_FORWARD) {
7397 error("label '%s' used but not defined",
7398 get_tok_str(s->v, NULL));
7400 if (s->c) {
7401 /* define corresponding symbol. A size of
7402 1 is put. */
7403 put_extern_sym(s, cur_text_section, (long)s->next, 1);
7405 /* remove label */
7406 table_ident[s->v - TOK_IDENT]->sym_label = NULL;
7407 tcc_free(s);
7409 label_stack = NULL;
7411 sym_pop(&local_stack, NULL); /* reset local stack */
7412 /* end of function */
7413 /* patch symbol size */
7414 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
7415 ind - func_ind;
7416 if (do_debug) {
7417 put_stabn(N_FUN, 0, 0, ind - func_ind);
7419 funcname = ""; /* for safety */
7420 func_vt.t = VT_VOID; /* for safety */
7421 ind = 0; /* for safety */
7423 #ifdef CONFIG_REG_VARS
7424 tok_str_free(func_str.str);
7425 restore_parse_state(&saved_parse_state);
7426 #endif
7427 break;
7428 } else {
7429 if (btype.t & VT_TYPEDEF) {
7430 /* save typedefed type */
7431 /* XXX: test storage specifiers ? */
7432 sym = sym_push(v, &type, 0, 0);
7433 sym->type.t |= VT_TYPEDEF;
7434 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
7435 /* external function definition */
7436 external_sym(v, &type, 0);
7437 } else {
7438 /* not lvalue if array */
7439 r = 0;
7440 if (!(type.t & VT_ARRAY))
7441 r |= lvalue_type(type.t);
7442 if (btype.t & VT_EXTERN) {
7443 /* external variable */
7444 external_sym(v, &type, r);
7445 } else {
7446 if (type.t & VT_STATIC)
7447 r |= VT_CONST;
7448 else
7449 r |= l;
7450 has_init = (tok == '=');
7451 if (has_init)
7452 next();
7453 decl_initializer_alloc(&type, &ad, r,
7454 has_init, v, l);
7457 if (tok != ',') {
7458 skip(';');
7459 break;
7461 next();
7467 /* compile the C file opened in 'file'. Return non zero if errors. */
7468 static int tcc_compile(TCCState *s1)
7470 Sym *define_start;
7471 char buf[512];
7472 volatile int section_sym;
7474 #ifdef INC_DEBUG
7475 printf("%s: **** new file\n", file->filename);
7476 #endif
7477 funcname = "";
7478 s1->include_stack_ptr = s1->include_stack;
7479 /* XXX: move that before to avoid having to initialize
7480 file->ifdef_stack_ptr ? */
7481 s1->ifdef_stack_ptr = s1->ifdef_stack;
7482 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7484 /* XXX: not ANSI compliant: bound checking says error */
7485 vtop = vstack - 1;
7486 anon_sym = SYM_FIRST_ANOM;
7488 /* file info: full path + filename */
7489 section_sym = 0; /* avoid warning */
7490 if (do_debug) {
7491 section_sym = put_elf_sym(symtab_section, 0, 0,
7492 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
7493 text_section->sh_num, NULL);
7494 getcwd(buf, sizeof(buf));
7495 pstrcat(buf, sizeof(buf), "/");
7496 put_stabs_r(buf, N_SO, 0, 0,
7497 text_section->data_offset, text_section, section_sym);
7498 put_stabs_r(file->filename, N_SO, 0, 0,
7499 text_section->data_offset, text_section, section_sym);
7501 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7502 symbols can be safely used */
7503 put_elf_sym(symtab_section, 0, 0,
7504 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
7505 SHN_ABS, file->filename);
7507 /* define some often used types */
7508 int_type.t = VT_INT;
7510 char_pointer_type.t = VT_BYTE;
7511 mk_pointer(&char_pointer_type);
7513 func_old_type.t = VT_FUNC;
7514 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
7516 #if 0
7517 /* define 'void *alloca(unsigned int)' builtin function */
7519 Sym *s1;
7521 p = anon_sym++;
7522 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
7523 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
7524 s1->next = NULL;
7525 sym->next = s1;
7526 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
7528 #endif
7530 define_start = define_stack;
7532 if (setjmp(s1->error_jmp_buf) == 0) {
7533 s1->nb_errors = 0;
7534 s1->error_set_jmp_enabled = 1;
7536 inp();
7537 ch = '\n'; /* needed to parse correctly first preprocessor command */
7538 next();
7539 decl(VT_CONST);
7540 if (tok != -1)
7541 expect("declaration");
7543 /* end of translation unit info */
7544 if (do_debug) {
7545 put_stabs_r(NULL, N_SO, 0, 0,
7546 text_section->data_offset, text_section, section_sym);
7549 s1->error_set_jmp_enabled = 0;
7551 /* reset define stack, but leave -Dsymbols (may be incorrect if
7552 they are undefined) */
7553 free_defines(define_start);
7555 sym_pop(&global_stack, NULL);
7557 return s1->nb_errors != 0 ? -1 : 0;
7560 int tcc_compile_string(TCCState *s, const char *str)
7562 BufferedFile bf1, *bf = &bf1;
7563 int ret;
7565 /* init file structure */
7566 bf->fd = -1;
7567 bf->buf_ptr = (char *)str;
7568 bf->buf_end = (char *)str + strlen(bf->buffer);
7569 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
7570 bf->line_num = 1;
7571 file = bf;
7573 ret = tcc_compile(s);
7575 /* currently, no need to close */
7576 return ret;
7579 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
7580 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
7582 BufferedFile bf1, *bf = &bf1;
7584 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
7585 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
7586 /* default value */
7587 if (!value)
7588 value = "1";
7589 pstrcat(bf->buffer, IO_BUF_SIZE, value);
7591 /* init file structure */
7592 bf->fd = -1;
7593 bf->buf_ptr = bf->buffer;
7594 bf->buf_end = bf->buffer + strlen(bf->buffer);
7595 bf->filename[0] = '\0';
7596 bf->line_num = 1;
7597 file = bf;
7599 s1->include_stack_ptr = s1->include_stack;
7601 /* parse with define parser */
7602 inp();
7603 ch = '\n'; /* needed to parse correctly first preprocessor command */
7604 next_nomacro();
7605 parse_define();
7606 file = NULL;
7609 /* undefine a preprocessor symbol */
7610 void tcc_undefine_symbol(TCCState *s1, const char *sym)
7612 TokenSym *ts;
7613 Sym *s;
7614 ts = tok_alloc(sym, strlen(sym));
7615 s = define_find(ts->tok);
7616 /* undefine symbol by putting an invalid name */
7617 if (s)
7618 define_undef(s);
7621 #include "tccelf.c"
7623 /* print the position in the source file of PC value 'pc' by reading
7624 the stabs debug information */
7625 static void rt_printline(unsigned long wanted_pc)
7627 Stab_Sym *sym, *sym_end;
7628 char func_name[128], last_func_name[128];
7629 unsigned long func_addr, last_pc, pc;
7630 const char *incl_files[INCLUDE_STACK_SIZE];
7631 int incl_index, len, last_line_num, i;
7632 const char *str, *p;
7634 fprintf(stderr, "0x%08lx:", wanted_pc);
7636 func_name[0] = '\0';
7637 func_addr = 0;
7638 incl_index = 0;
7639 last_func_name[0] = '\0';
7640 last_pc = 0xffffffff;
7641 last_line_num = 1;
7642 sym = (Stab_Sym *)stab_section->data + 1;
7643 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
7644 while (sym < sym_end) {
7645 switch(sym->n_type) {
7646 /* function start or end */
7647 case N_FUN:
7648 if (sym->n_strx == 0) {
7649 /* we test if between last line and end of function */
7650 pc = sym->n_value + func_addr;
7651 if (wanted_pc >= last_pc && wanted_pc < pc)
7652 goto found;
7653 func_name[0] = '\0';
7654 func_addr = 0;
7655 } else {
7656 str = stabstr_section->data + sym->n_strx;
7657 p = strchr(str, ':');
7658 if (!p) {
7659 pstrcpy(func_name, sizeof(func_name), str);
7660 } else {
7661 len = p - str;
7662 if (len > sizeof(func_name) - 1)
7663 len = sizeof(func_name) - 1;
7664 memcpy(func_name, str, len);
7665 func_name[len] = '\0';
7667 func_addr = sym->n_value;
7669 break;
7670 /* line number info */
7671 case N_SLINE:
7672 pc = sym->n_value + func_addr;
7673 if (wanted_pc >= last_pc && wanted_pc < pc)
7674 goto found;
7675 last_pc = pc;
7676 last_line_num = sym->n_desc;
7677 /* XXX: slow! */
7678 strcpy(last_func_name, func_name);
7679 break;
7680 /* include files */
7681 case N_BINCL:
7682 str = stabstr_section->data + sym->n_strx;
7683 add_incl:
7684 if (incl_index < INCLUDE_STACK_SIZE) {
7685 incl_files[incl_index++] = str;
7687 break;
7688 case N_EINCL:
7689 if (incl_index > 1)
7690 incl_index--;
7691 break;
7692 case N_SO:
7693 if (sym->n_strx == 0) {
7694 incl_index = 0; /* end of translation unit */
7695 } else {
7696 str = stabstr_section->data + sym->n_strx;
7697 /* do not add path */
7698 len = strlen(str);
7699 if (len > 0 && str[len - 1] != '/')
7700 goto add_incl;
7702 break;
7704 sym++;
7707 /* second pass: we try symtab symbols (no line number info) */
7708 incl_index = 0;
7710 Elf32_Sym *sym, *sym_end;
7711 int type;
7713 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
7714 for(sym = (Elf32_Sym *)symtab_section->data + 1;
7715 sym < sym_end;
7716 sym++) {
7717 type = ELF32_ST_TYPE(sym->st_info);
7718 if (type == STT_FUNC) {
7719 if (wanted_pc >= sym->st_value &&
7720 wanted_pc < sym->st_value + sym->st_size) {
7721 pstrcpy(last_func_name, sizeof(last_func_name),
7722 strtab_section->data + sym->st_name);
7723 goto found;
7728 /* did not find any info: */
7729 fprintf(stderr, " ???\n");
7730 return;
7731 found:
7732 if (last_func_name[0] != '\0') {
7733 fprintf(stderr, " %s()", last_func_name);
7735 if (incl_index > 0) {
7736 fprintf(stderr, " (%s:%d",
7737 incl_files[incl_index - 1], last_line_num);
7738 for(i = incl_index - 2; i >= 0; i--)
7739 fprintf(stderr, ", included from %s", incl_files[i]);
7740 fprintf(stderr, ")");
7742 fprintf(stderr, "\n");
7745 #ifndef WIN32
7747 #ifdef __i386__
7749 #ifndef EIP
7750 #define EIP 14
7751 #define EBP 6
7752 #endif
7754 /* return the PC at frame level 'level'. Return non zero if not found */
7755 static int rt_get_caller_pc(unsigned long *paddr,
7756 struct ucontext *uc, int level)
7758 unsigned long fp;
7759 int i;
7761 if (level == 0) {
7762 *paddr = uc->uc_mcontext.gregs[EIP];
7763 return 0;
7764 } else {
7765 fp = uc->uc_mcontext.gregs[EBP];
7766 for(i=1;i<level;i++) {
7767 /* XXX: check address validity with program info */
7768 if (fp <= 0x1000 || fp >= 0xc0000000)
7769 return -1;
7770 fp = ((unsigned long *)fp)[0];
7772 *paddr = ((unsigned long *)fp)[1];
7773 return 0;
7776 #else
7777 #error add arch specific rt_get_caller_pc()
7778 #endif
7780 /* emit a run time error at position 'pc' */
7781 void rt_error(struct ucontext *uc, const char *fmt, ...)
7783 va_list ap;
7784 unsigned long pc;
7785 int i;
7787 va_start(ap, fmt);
7788 fprintf(stderr, "Runtime error: ");
7789 vfprintf(stderr, fmt, ap);
7790 fprintf(stderr, "\n");
7791 for(i=0;i<num_callers;i++) {
7792 if (rt_get_caller_pc(&pc, uc, i) < 0)
7793 break;
7794 if (i == 0)
7795 fprintf(stderr, "at ");
7796 else
7797 fprintf(stderr, "by ");
7798 rt_printline(pc);
7800 exit(255);
7801 va_end(ap);
7804 /* signal handler for fatal errors */
7805 static void sig_error(int signum, siginfo_t *siginf, void *puc)
7807 struct ucontext *uc = puc;
7809 switch(signum) {
7810 case SIGFPE:
7811 switch(siginf->si_code) {
7812 case FPE_INTDIV:
7813 case FPE_FLTDIV:
7814 rt_error(uc, "division by zero");
7815 break;
7816 default:
7817 rt_error(uc, "floating point exception");
7818 break;
7820 break;
7821 case SIGBUS:
7822 case SIGSEGV:
7823 if (rt_bound_error_msg && *rt_bound_error_msg)
7824 rt_error(uc, *rt_bound_error_msg);
7825 else
7826 rt_error(uc, "dereferencing invalid pointer");
7827 break;
7828 case SIGILL:
7829 rt_error(uc, "illegal instruction");
7830 break;
7831 case SIGABRT:
7832 rt_error(uc, "abort() called");
7833 break;
7834 default:
7835 rt_error(uc, "caught signal %d", signum);
7836 break;
7838 exit(255);
7840 #endif
7842 /* do all relocations (needed before using tcc_get_symbol()) */
7843 int tcc_relocate(TCCState *s1)
7845 Section *s;
7846 int i;
7848 s1->nb_errors = 0;
7850 tcc_add_runtime(s1);
7852 relocate_common_syms();
7854 /* compute relocation address : section are relocated in place. We
7855 also alloc the bss space */
7856 for(i = 1; i < s1->nb_sections; i++) {
7857 s = s1->sections[i];
7858 if (s->sh_flags & SHF_ALLOC) {
7859 if (s->sh_type == SHT_NOBITS)
7860 s->data = tcc_mallocz(s->data_offset);
7861 s->sh_addr = (unsigned long)s->data;
7865 relocate_syms(s1, 1);
7867 if (s1->nb_errors != 0)
7868 return -1;
7870 /* relocate each section */
7871 for(i = 1; i < s1->nb_sections; i++) {
7872 s = s1->sections[i];
7873 if (s->reloc)
7874 relocate_section(s1, s);
7876 return 0;
7879 /* launch the compiled program with the given arguments */
7880 int tcc_run(TCCState *s1, int argc, char **argv)
7882 int (*prog_main)(int, char **);
7884 if (tcc_relocate(s1) < 0)
7885 return -1;
7887 prog_main = tcc_get_symbol(s1, "main");
7889 if (do_debug) {
7890 #ifdef WIN32
7891 error("debug mode currently not available for Windows");
7892 #else
7893 struct sigaction sigact;
7894 /* install TCC signal handlers to print debug info on fatal
7895 runtime errors */
7896 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
7897 sigact.sa_sigaction = sig_error;
7898 sigemptyset(&sigact.sa_mask);
7899 sigaction(SIGFPE, &sigact, NULL);
7900 sigaction(SIGILL, &sigact, NULL);
7901 sigaction(SIGSEGV, &sigact, NULL);
7902 sigaction(SIGBUS, &sigact, NULL);
7903 sigaction(SIGABRT, &sigact, NULL);
7904 #endif
7907 #ifdef CONFIG_TCC_BCHECK
7908 if (do_bounds_check) {
7909 void (*bound_init)(void);
7911 /* set error function */
7912 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
7914 /* XXX: use .init section so that it also work in binary ? */
7915 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
7916 bound_init();
7918 #endif
7919 return (*prog_main)(argc, argv);
7922 TCCState *tcc_new(void)
7924 const char *p, *r;
7925 TCCState *s;
7927 s = tcc_mallocz(sizeof(TCCState));
7928 if (!s)
7929 return NULL;
7930 tcc_state = s;
7931 s->output_type = TCC_OUTPUT_MEMORY;
7933 /* default include paths */
7934 tcc_add_sysinclude_path(s, "/usr/local/include");
7935 tcc_add_sysinclude_path(s, "/usr/include");
7936 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
7938 /* add all tokens */
7939 table_ident = NULL;
7940 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
7942 tok_ident = TOK_IDENT;
7943 p = tcc_keywords;
7944 while (*p) {
7945 r = p;
7946 while (*r++);
7947 tok_alloc(p, r - p - 1);
7948 p = r;
7951 /* we add dummy defines for some special macros to speed up tests
7952 and to have working defined() */
7953 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
7954 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
7955 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
7956 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
7958 /* standard defines */
7959 tcc_define_symbol(s, "__STDC__", NULL);
7960 #if defined(TCC_TARGET_I386)
7961 tcc_define_symbol(s, "__i386__", NULL);
7962 #endif
7963 #if defined(linux)
7964 tcc_define_symbol(s, "linux", NULL);
7965 #endif
7966 /* tiny C specific defines */
7967 tcc_define_symbol(s, "__TINYC__", NULL);
7969 /* default library paths */
7970 tcc_add_library_path(s, "/usr/local/lib");
7971 tcc_add_library_path(s, "/usr/lib");
7972 tcc_add_library_path(s, "/lib");
7974 /* no section zero */
7975 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
7977 /* create standard sections */
7978 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7979 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7980 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
7982 /* symbols are always generated for linking stage */
7983 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
7984 ".strtab",
7985 ".hashtab", SHF_PRIVATE);
7986 strtab_section = symtab_section->link;
7988 /* private symbol table for dynamic symbols */
7989 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
7990 ".dynstrtab",
7991 ".dynhashtab", SHF_PRIVATE);
7992 return s;
7995 void tcc_delete(TCCState *s1)
7997 int i, n;
7999 /* free -D defines */
8000 free_defines(NULL);
8002 /* free tokens */
8003 n = tok_ident - TOK_IDENT;
8004 for(i = 0; i < n; i++)
8005 tcc_free(table_ident[i]);
8006 tcc_free(table_ident);
8008 /* free all sections */
8010 free_section(symtab_section->hash);
8012 free_section(s1->dynsymtab_section->hash);
8013 free_section(s1->dynsymtab_section->link);
8014 free_section(s1->dynsymtab_section);
8016 for(i = 1; i < s1->nb_sections; i++)
8017 free_section(s1->sections[i]);
8018 tcc_free(s1->sections);
8020 /* free loaded dlls array */
8021 for(i = 0; i < s1->nb_loaded_dlls; i++)
8022 tcc_free(s1->loaded_dlls[i]);
8023 tcc_free(s1->loaded_dlls);
8025 /* library paths */
8026 for(i = 0; i < s1->nb_library_paths; i++)
8027 tcc_free(s1->library_paths[i]);
8028 tcc_free(s1->library_paths);
8030 /* cached includes */
8031 for(i = 0; i < s1->nb_cached_includes; i++)
8032 tcc_free(s1->cached_includes[i]);
8033 tcc_free(s1->cached_includes);
8035 for(i = 0; i < s1->nb_include_paths; i++)
8036 tcc_free(s1->include_paths[i]);
8037 tcc_free(s1->include_paths);
8039 for(i = 0; i < s1->nb_sysinclude_paths; i++)
8040 tcc_free(s1->sysinclude_paths[i]);
8041 tcc_free(s1->sysinclude_paths);
8043 tcc_free(s1);
8046 int tcc_add_include_path(TCCState *s1, const char *pathname)
8048 char *pathname1;
8050 pathname1 = tcc_strdup(pathname);
8051 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
8052 return 0;
8055 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
8057 char *pathname1;
8059 pathname1 = tcc_strdup(pathname);
8060 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
8061 return 0;
8064 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
8066 const char *ext;
8067 Elf32_Ehdr ehdr;
8068 int fd, ret;
8069 BufferedFile *saved_file;
8071 /* find source file type with extension */
8072 ext = strrchr(filename, '.');
8073 if (ext)
8074 ext++;
8076 /* open the file */
8077 saved_file = file;
8078 file = tcc_open(s1, filename);
8079 if (!file) {
8080 if (flags & AFF_PRINT_ERROR) {
8081 error_noabort("file '%s' not found", filename);
8083 ret = -1;
8084 goto fail1;
8087 if (!ext || !strcmp(ext, "c")) {
8088 /* C file assumed */
8089 ret = tcc_compile(s1);
8090 } else {
8091 fd = file->fd;
8092 /* assume executable format: auto guess file type */
8093 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
8094 error_noabort("could not read header");
8095 goto fail;
8097 lseek(fd, 0, SEEK_SET);
8099 if (ehdr.e_ident[0] == ELFMAG0 &&
8100 ehdr.e_ident[1] == ELFMAG1 &&
8101 ehdr.e_ident[2] == ELFMAG2 &&
8102 ehdr.e_ident[3] == ELFMAG3) {
8103 file->line_num = 0; /* do not display line number if error */
8104 if (ehdr.e_type == ET_REL) {
8105 ret = tcc_load_object_file(s1, fd, 0);
8106 } else if (ehdr.e_type == ET_DYN) {
8107 ret = tcc_load_dll(s1, fd, filename,
8108 (flags & AFF_REFERENCED_DLL) != 0);
8109 } else {
8110 error_noabort("unrecognized ELF file");
8111 goto fail;
8113 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
8114 file->line_num = 0; /* do not display line number if error */
8115 ret = tcc_load_archive(s1, fd);
8116 } else {
8117 /* as GNU ld, consider it is an ld script if not recognized */
8118 ret = tcc_load_ldscript(s1);
8119 if (ret < 0) {
8120 error_noabort("unrecognized file type");
8121 goto fail;
8125 the_end:
8126 tcc_close(file);
8127 fail1:
8128 file = saved_file;
8129 return ret;
8130 fail:
8131 ret = -1;
8132 goto the_end;
8135 int tcc_add_file(TCCState *s, const char *filename)
8137 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
8140 int tcc_add_library_path(TCCState *s, const char *pathname)
8142 char *pathname1;
8144 pathname1 = tcc_strdup(pathname);
8145 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
8146 return 0;
8149 /* find and load a dll. Return non zero if not found */
8150 /* XXX: add '-rpath' option support ? */
8151 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
8153 char buf[1024];
8154 int i;
8156 for(i = 0; i < s->nb_library_paths; i++) {
8157 snprintf(buf, sizeof(buf), "%s/%s",
8158 s->library_paths[i], filename);
8159 if (tcc_add_file_internal(s, buf, flags) == 0)
8160 return 0;
8162 return -1;
8165 /* the library name is the same as the argument of the '-l' option */
8166 int tcc_add_library(TCCState *s, const char *libraryname)
8168 char buf[1024];
8169 int i;
8170 void *h;
8172 /* first we look for the dynamic library if not static linking */
8173 if (!s->static_link) {
8174 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8175 /* if we output to memory, then we simply we dlopen(). */
8176 if (s->output_type == TCC_OUTPUT_MEMORY) {
8177 /* Since the libc is already loaded, we don't need to load it again */
8178 if (!strcmp(libraryname, "c"))
8179 return 0;
8180 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
8181 if (h)
8182 return 0;
8183 } else {
8184 if (tcc_add_dll(s, buf, 0) == 0)
8185 return 0;
8189 /* then we look for the static library */
8190 for(i = 0; i < s->nb_library_paths; i++) {
8191 snprintf(buf, sizeof(buf), "%s/lib%s.a",
8192 s->library_paths[i], libraryname);
8193 if (tcc_add_file_internal(s, buf, 0) == 0)
8194 return 0;
8196 return -1;
8199 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
8201 add_elf_sym(symtab_section, val, 0,
8202 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
8203 SHN_ABS, name);
8204 return 0;
8207 int tcc_set_output_type(TCCState *s, int output_type)
8209 s->output_type = output_type;
8211 /* if bound checking, then add corresponding sections */
8212 #ifdef CONFIG_TCC_BCHECK
8213 if (do_bounds_check) {
8214 /* define symbol */
8215 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
8216 /* create bounds sections */
8217 bounds_section = new_section(s, ".bounds",
8218 SHT_PROGBITS, SHF_ALLOC);
8219 lbounds_section = new_section(s, ".lbounds",
8220 SHT_PROGBITS, SHF_ALLOC);
8222 #endif
8224 /* add debug sections */
8225 if (do_debug) {
8226 /* stab symbols */
8227 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
8228 stab_section->sh_entsize = sizeof(Stab_Sym);
8229 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
8230 put_elf_str(stabstr_section, "");
8231 stab_section->link = stabstr_section;
8232 /* put first entry */
8233 put_stabs("", 0, 0, 0, 0);
8236 /* add libc crt1/crti objects */
8237 if (output_type == TCC_OUTPUT_EXE ||
8238 output_type == TCC_OUTPUT_DLL) {
8239 if (output_type != TCC_OUTPUT_DLL)
8240 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
8241 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
8243 return 0;
8246 #if !defined(LIBTCC)
8248 static int64_t getclock_us(void)
8250 #ifdef WIN32
8251 struct _timeb tb;
8252 _ftime(&tb);
8253 return (tb.time * 1000LL + tb.millitm) * 1000LL;
8254 #else
8255 struct timeval tv;
8256 gettimeofday(&tv, NULL);
8257 return tv.tv_sec * 1000000LL + tv.tv_usec;
8258 #endif
8261 void help(void)
8263 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8264 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8265 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8266 " [--] infile1 [infile2... --] [infile_args...]\n"
8267 "\n"
8268 "General options:\n"
8269 " -c compile only - generate an object file\n"
8270 " -o outfile set output filename\n"
8271 " -- allows multiples input files if no -o option given. Also\n"
8272 " separate input files from runtime arguments\n"
8273 " -Bdir set tcc internal library path\n"
8274 " -bench output compilation statistics\n"
8275 "Preprocessor options:\n"
8276 " -Idir add include path 'dir'\n"
8277 " -Dsym[=val] define 'sym' with value 'val'\n"
8278 " -Usym undefine 'sym'\n"
8279 "Linker options:\n"
8280 " -Ldir add library path 'dir'\n"
8281 " -llib link with dynamic or static library 'lib'\n"
8282 " -shared generate a shared library\n"
8283 " -static static linking\n"
8284 " -r relocatable output\n"
8285 "Debugger options:\n"
8286 " -g generate runtime debug info\n"
8287 #ifdef CONFIG_TCC_BCHECK
8288 " -b compile with built-in memory and bounds checker (implies -g)\n"
8289 #endif
8290 " -bt N show N callers in stack traces\n"
8294 int main(int argc, char **argv)
8296 char *r, *outfile;
8297 int optind, output_type, multiple_files, i, reloc_output;
8298 TCCState *s;
8299 char **files;
8300 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
8301 char objfilename[1024];
8302 int64_t start_time = 0;
8304 s = tcc_new();
8305 output_type = TCC_OUTPUT_MEMORY;
8307 optind = 1;
8308 outfile = NULL;
8309 multiple_files = 0;
8310 dminus = 0;
8311 files = NULL;
8312 nb_files = 0;
8313 nb_libraries = 0;
8314 reloc_output = 0;
8315 while (1) {
8316 if (optind >= argc) {
8317 if (nb_files == 0)
8318 goto show_help;
8319 else
8320 break;
8322 r = argv[optind++];
8323 if (r[0] != '-') {
8324 /* add a new file */
8325 dynarray_add((void ***)&files, &nb_files, r);
8326 if (!multiple_files) {
8327 optind--;
8328 /* argv[0] will be this file */
8329 break;
8331 } else if (r[1] == '-') {
8332 /* '--' enables multiple files input and also ends several file input */
8333 if (dminus && multiple_files) {
8334 optind--; /* argv[0] will be '--' */
8335 break;
8337 dminus = 1;
8338 multiple_files = 1;
8339 } else if (r[1] == 'h' || r[1] == '?') {
8340 show_help:
8341 help();
8342 return 1;
8343 } else if (r[1] == 'I') {
8344 if (tcc_add_include_path(s, r + 2) < 0)
8345 error("too many include paths");
8346 } else if (r[1] == 'D') {
8347 char *sym, *value;
8348 sym = r + 2;
8349 value = strchr(sym, '=');
8350 if (value) {
8351 *value = '\0';
8352 value++;
8354 tcc_define_symbol(s, sym, value);
8355 } else if (r[1] == 'U') {
8356 tcc_undefine_symbol(s, r + 2);
8357 } else if (r[1] == 'L') {
8358 tcc_add_library_path(s, r + 2);
8359 } else if (r[1] == 'B') {
8360 /* set tcc utilities path (mainly for tcc development) */
8361 tcc_lib_path = r + 2;
8362 } else if (r[1] == 'l') {
8363 dynarray_add((void ***)&files, &nb_files, r);
8364 nb_libraries++;
8365 } else if (!strcmp(r + 1, "bench")) {
8366 do_bench = 1;
8367 } else if (!strcmp(r + 1, "bt")) {
8368 num_callers = atoi(argv[optind++]);
8369 } else
8370 #ifdef CONFIG_TCC_BCHECK
8371 if (r[1] == 'b') {
8372 do_bounds_check = 1;
8373 do_debug = 1;
8374 } else
8375 #endif
8376 if (r[1] == 'g') {
8377 do_debug = 1;
8378 } else if (r[1] == 'c') {
8379 multiple_files = 1;
8380 output_type = TCC_OUTPUT_OBJ;
8381 } else if (!strcmp(r + 1, "static")) {
8382 s->static_link = 1;
8383 } else if (!strcmp(r + 1, "shared")) {
8384 output_type = TCC_OUTPUT_DLL;
8385 } else if (r[1] == 'o') {
8386 if (optind >= argc)
8387 goto show_help;
8388 multiple_files = 1;
8389 outfile = argv[optind++];
8390 } else if (r[1] == 'r') {
8391 /* generate a .o merging several output files */
8392 reloc_output = 1;
8393 output_type = TCC_OUTPUT_OBJ;
8394 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
8395 /* ignore those options to be a drop-in replacement for gcc */
8396 } else {
8397 error("invalid option -- '%s'", r);
8401 nb_objfiles = nb_files - nb_libraries;
8403 /* if outfile provided without other options, we output an
8404 executable */
8405 if (outfile && output_type == TCC_OUTPUT_MEMORY)
8406 output_type = TCC_OUTPUT_EXE;
8408 /* check -c consistency : only single file handled. XXX: checks file type */
8409 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
8410 /* accepts only a single input file */
8411 if (nb_objfiles != 1)
8412 error("cannot specify multiple files with -c");
8413 if (nb_libraries != 0)
8414 error("cannot specify libraries with -c");
8417 /* compute default outfile name */
8418 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
8419 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
8420 char *ext;
8421 /* add .o extension */
8422 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
8423 ext = strrchr(objfilename, '.');
8424 if (!ext)
8425 goto default_outfile;
8426 strcpy(ext + 1, "o");
8427 } else {
8428 default_outfile:
8429 pstrcpy(objfilename, sizeof(objfilename), "a.out");
8431 outfile = objfilename;
8434 if (do_bench) {
8435 start_time = getclock_us();
8438 tcc_set_output_type(s, output_type);
8440 /* compile or add each files or library */
8441 for(i = 0;i < nb_files; i++) {
8442 const char *filename;
8444 filename = files[i];
8445 if (filename[0] == '-') {
8446 if (tcc_add_library(s, filename + 2) < 0)
8447 error("cannot find %s", filename);
8448 } else {
8449 if (tcc_add_file(s, filename) < 0) {
8450 ret = 1;
8451 goto the_end;
8456 /* free all files */
8457 tcc_free(files);
8459 if (do_bench) {
8460 double total_time;
8461 total_time = (double)(getclock_us() - start_time) / 1000000.0;
8462 if (total_time < 0.001)
8463 total_time = 0.001;
8464 if (total_bytes < 1)
8465 total_bytes = 1;
8466 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
8467 tok_ident - TOK_IDENT, total_lines, total_bytes,
8468 total_time, (int)(total_lines / total_time),
8469 total_bytes / total_time / 1000000.0);
8472 if (s->output_type != TCC_OUTPUT_MEMORY) {
8473 tcc_output_file(s, outfile);
8474 ret = 0;
8475 } else {
8476 ret = tcc_run(s, argc - optind, argv + optind);
8478 the_end:
8479 /* XXX: cannot do it with bound checking because of the malloc hooks */
8480 if (!do_bounds_check)
8481 tcc_delete(s);
8483 #ifdef MEM_DEBUG
8484 if (do_bench) {
8485 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
8487 #endif
8488 return ret;
8491 #endif